/
Dimon4ik
/
VRLabs
Обзор
Документация
Войти
/
Dimon4ik
/
VRLabs
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
LabLauncher/uLabLauncher.cpp
293 строки
12 KB
Dimon4ik
Add launcher and runnable lab binaries
03 май 2026, 05:06
03 май 2026, 05:06
21516cf
Код
Авторство
О чём код?
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "uLabLauncher.h" #include <System.SysUtils.hpp> #include <Vcl.Imaging.GIFImg.hpp> #include <ShellAPI.h> //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TFormLabLauncher *FormLabLauncher; //--------------------------------------------------------------------------- __fastcall TFormLabLauncher::TFormLabLauncher(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TFormLabLauncher::FormCreate(TObject *Sender) { RepositoryRoot = DetectRepositoryRoot(); LoadLabs(); BuildInterface(); LabListBox->ItemIndex = 0; ShowSelectedLab(); } //--------------------------------------------------------------------------- UnicodeString TFormLabLauncher::DetectRepositoryRoot() { UnicodeString dir = IncludeTrailingPathDelimiter(ExtractFilePath(Application->ExeName)); for (int i = 0; i < 8; ++i) { if (FileExists(dir + L"README.md") && (DirectoryExists(dir + L"Lab1_BaseObjects") || DirectoryExists(dir + L"NIKITIN 1"))) return dir; UnicodeString parent = IncludeTrailingPathDelimiter(ExtractFileDir(ExcludeTrailingPathDelimiter(dir))); if (SameText(parent, dir)) break; dir = parent; } return IncludeTrailingPathDelimiter(ExtractFilePath(Application->ExeName)); } //--------------------------------------------------------------------------- UnicodeString TFormLabLauncher::AbsPath(const UnicodeString &relativePath) { return RepositoryRoot + relativePath; } //--------------------------------------------------------------------------- void TFormLabLauncher::LoadLabs() { Labs.clear(); Labs.push_back({L"Лабораторная работа 1. Базовые 3D-объекты", L"Многогранники, материалы граней, вращение сцены и базовая работа с GLScene.", L"NIKITIN 1\\Lab1_BaseObjects\\Win32\\Debug\\L1_BaseObjects.exe", L"docs\\previews\\lab1-base-objects.gif"}); Labs.push_back({L"Лабораторная работа 2. Точки обзора и камера", L"Интерактивная сцена с несколькими точками обзора, управлением камерой и вращением объектов.", L"NIKITIN 2\\Lab2_ViewPoints\\Win32\\Debug\\L2_ViewPoints.exe", L"docs\\previews\\lab2-view-points.gif"}); Labs.push_back({L"Лабораторная работа 3. Кубическая карта отражений", L"Отражающие материалы, cube map и демонстрация окружения на 3D-объектах.", L"NIKITIN 3\\bin\\L3_CubeMap_a.exe", L"docs\\previews\\lab3-cubemap.gif"}); Labs.push_back({L"Лабораторная работа 4. Глобус с тематическими слоями", L"Интерактивная модель Земли: карты, облака, координатная сетка и небесные тела.", L"NIKITIN 4\\Никтин 4\\Лаб_земля\\Лаб_земля\\MapGlobus_Lab4_new\\Globuc.exe", L"docs\\previews\\lab4-globus.gif"}); Labs.push_back({L"Лабораторная работа 5. Таблица Менделеева и атом", L"Связка 2D-таблицы элементов с 3D-моделью атома и электронными оболочками.", L"NIKITIN 5\\Atomc.exe", L"docs\\previews\\lab5-mendeleev.gif"}); Labs.push_back({L"Лабораторная работа 6. Модель Солнечной системы", L"Планеты, спутники, текстуры поверхностей, орбиты и анимация движения.", L"NIKITIN 6\\SolarSys_Lab6_new\\Globuc.exe", L"docs\\previews\\lab6-solar-system.gif"}); Labs.push_back({L"Лабораторная работа 7. Гравитационная симуляция", L"Модель системы тел с гравитационным взаимодействием и пресетами параметров.", L"NIKITIN 7\\Win32\\Debug\\L11_NewtonSimple_Variant2.exe", L"docs\\previews\\lab7-newton-simple.gif"}); Labs.push_back({L"Лабораторная работа 8. Огонь, молния и атмосфера", L"Графические эффекты GLScene: огонь, молния, атмосфера, lens flare и динамическое небо.", L"NIKITIN 8\\Win32\\Debug\\L8_FireLightningAtmosphere_Variant2.exe", L"docs\\previews\\lab8-effects.gif"}); Labs.push_back({L"Лабораторная работа 9. Зеркало и водная поверхность", L"Отражения, water plane, кубическая карта окружения и параметры водной поверхности.", L"NIKITIN 9\\Win32\\Debug\\L9_MirrorAndWater.exe", L"docs\\previews\\lab9-mirror-water.gif"}); Labs.push_back({L"Лабораторная работа 10. Архипелаг и живая 3D-сцена", L"Большая природная сцена с terrain, морем, лодкой, моделями, небом и анимацией.", L"NIKITIN 10\\bin\\L14_SeaIsland.exe", L"docs\\previews\\lab10-archipelago.gif"}); } //--------------------------------------------------------------------------- void TFormLabLauncher::BuildInterface() { Caption = L"Методы и средства научной визуализации"; ClientWidth = 1040; ClientHeight = 660; Color = (TColor)0x00F4F1EC; Font->Name = L"Segoe UI"; Font->Height = -14; Position = poScreenCenter; HeaderPanel = new TPanel(this); HeaderPanel->Parent = this; HeaderPanel->Align = alTop; HeaderPanel->Height = 88; HeaderPanel->BevelOuter = bvNone; HeaderPanel->Color = (TColor)0x00221F1B; TitleLabel = new TLabel(this); TitleLabel->Parent = HeaderPanel; TitleLabel->Left = 24; TitleLabel->Top = 16; TitleLabel->Caption = L"Каталог лабораторных работ"; TitleLabel->Font->Color = clWhite; TitleLabel->Font->Height = -24; TitleLabel->Font->Style = TFontStyles() << fsBold; TitleLabel->Transparent = true; SubtitleLabel = new TLabel(this); SubtitleLabel->Parent = HeaderPanel; SubtitleLabel->Left = 24; SubtitleLabel->Top = 52; SubtitleLabel->Caption = L"Выберите лабораторную и запустите её отдельную программу"; SubtitleLabel->Font->Color = (TColor)0x00D6D0C7; SubtitleLabel->Transparent = true; LabListBox = new TListBox(this); LabListBox->Parent = this; LabListBox->Left = 24; LabListBox->Top = 112; LabListBox->Width = 360; LabListBox->Height = 500; LabListBox->ItemHeight = 40; LabListBox->OnClick = LabListChanged; LabListBox->OnDblClick = LabListDblClick; for (size_t i = 0; i < Labs.size(); ++i) LabListBox->Items->Add(Labs[i].Title); PreviewImage = new TImage(this); PreviewImage->Parent = this; PreviewImage->Left = 420; PreviewImage->Top = 112; PreviewImage->Width = 590; PreviewImage->Height = 300; PreviewImage->Stretch = true; PreviewImage->Proportional = true; PreviewImage->Center = true; LabTitleLabel = new TLabel(this); LabTitleLabel->Parent = this; LabTitleLabel->Left = 420; LabTitleLabel->Top = 430; LabTitleLabel->Width = 590; LabTitleLabel->Height = 48; LabTitleLabel->WordWrap = true; LabTitleLabel->Font->Height = -20; LabTitleLabel->Font->Style = TFontStyles() << fsBold; LabTitleLabel->Transparent = true; DescriptionMemo = new TMemo(this); DescriptionMemo->Parent = this; DescriptionMemo->Left = 420; DescriptionMemo->Top = 486; DescriptionMemo->Width = 590; DescriptionMemo->Height = 74; DescriptionMemo->ReadOnly = true; DescriptionMemo->BorderStyle = bsNone; DescriptionMemo->Color = Color; DescriptionMemo->TabStop = false; PathLabel = new TLabel(this); PathLabel->Parent = this; PathLabel->Left = 420; PathLabel->Top = 568; PathLabel->Width = 590; PathLabel->Height = 32; PathLabel->WordWrap = true; PathLabel->Font->Color = clGrayText; PathLabel->Transparent = true; RunButton = new TButton(this); RunButton->Parent = this; RunButton->Left = 420; RunButton->Top = 614; RunButton->Width = 180; RunButton->Height = 34; RunButton->Caption = L"Запустить"; RunButton->Default = true; RunButton->OnClick = RunClicked; OpenFolderButton = new TButton(this); OpenFolderButton->Parent = this; OpenFolderButton->Left = 612; OpenFolderButton->Top = 614; OpenFolderButton->Width = 180; OpenFolderButton->Height = 34; OpenFolderButton->Caption = L"Открыть папку"; OpenFolderButton->OnClick = OpenFolderClicked; } //--------------------------------------------------------------------------- const TLabInfo* TFormLabLauncher::SelectedLab() const { int index = LabListBox ? LabListBox->ItemIndex : -1; if (index < 0 || index >= static_cast<int>(Labs.size())) return nullptr; return &Labs[index]; } //--------------------------------------------------------------------------- void TFormLabLauncher::ShowSelectedLab() { const TLabInfo *lab = SelectedLab(); if (!lab) return; LabTitleLabel->Caption = lab->Title; DescriptionMemo->Lines->Text = lab->Description; UnicodeString exePath = AbsPath(lab->ExecutablePath); PathLabel->Caption = exePath; RunButton->Enabled = FileExists(exePath); OpenFolderButton->Enabled = DirectoryExists(ExtractFilePath(exePath)); UnicodeString previewPath = AbsPath(lab->PreviewPath); PreviewImage->Picture->Graphic = nullptr; if (FileExists(previewPath)) PreviewImage->Picture->LoadFromFile(previewPath); } //--------------------------------------------------------------------------- void TFormLabLauncher::RunSelectedLab() { const TLabInfo *lab = SelectedLab(); if (!lab) return; UnicodeString exePath = AbsPath(lab->ExecutablePath); if (!FileExists(exePath)) { ShowMessage(L"Исполняемый файл не найден:\n" + exePath); return; } UnicodeString workDir = ExtractFilePath(exePath); HINSTANCE result = ShellExecuteW(Handle, L"open", exePath.c_str(), nullptr, workDir.c_str(), SW_SHOWNORMAL); if (reinterpret_cast<intptr_t>(result) <= 32) ShowMessage(L"Не удалось запустить лабораторную работу."); } //--------------------------------------------------------------------------- void TFormLabLauncher::OpenSelectedFolder() { const TLabInfo *lab = SelectedLab(); if (!lab) return; UnicodeString folder = ExtractFilePath(AbsPath(lab->ExecutablePath)); if (DirectoryExists(folder)) ShellExecuteW(Handle, L"open", folder.c_str(), nullptr, nullptr, SW_SHOWNORMAL); } //--------------------------------------------------------------------------- void __fastcall TFormLabLauncher::LabListChanged(TObject *Sender) { ShowSelectedLab(); } //--------------------------------------------------------------------------- void __fastcall TFormLabLauncher::LabListDblClick(TObject *Sender) { RunSelectedLab(); } //--------------------------------------------------------------------------- void __fastcall TFormLabLauncher::RunClicked(TObject *Sender) { RunSelectedLab(); } //--------------------------------------------------------------------------- void __fastcall TFormLabLauncher::OpenFolderClicked(TObject *Sender) { OpenSelectedFolder(); } //---------------------------------------------------------------------------