#include "stdafx.h" #include "OptionsWindow.h" #include "Editor.h" using namespace wi::graphics; using namespace wi::ecs; using namespace wi::scene; void OptionsWindow::Create(EditorComponent* _editor) { editor = _editor; wi::gui::Window::Create("Options", wi::gui::Window::WindowControls::RESIZE_TOPRIGHT); SetShadowRadius(2); isTranslatorCheckBox.Create(ICON_TRANSLATE " "); isRotatorCheckBox.Create(ICON_ROTATE " "); isScalatorCheckBox.Create(ICON_SCALE " "); { isScalatorCheckBox.SetTooltip("Scale\nHotkey: 3"); isScalatorCheckBox.OnClick([&](wi::gui::EventArgs args) { editor->translator.isScalator = args.bValue; editor->translator.isTranslator = false; editor->translator.isRotator = false; isTranslatorCheckBox.SetCheck(false); isRotatorCheckBox.SetCheck(false); }); isScalatorCheckBox.SetCheck(editor->translator.isScalator); AddWidget(&isScalatorCheckBox); isRotatorCheckBox.SetTooltip("Rotate\nHotkey: 2"); isRotatorCheckBox.OnClick([&](wi::gui::EventArgs args) { editor->translator.isRotator = args.bValue; editor->translator.isScalator = false; editor->translator.isTranslator = false; isScalatorCheckBox.SetCheck(false); isTranslatorCheckBox.SetCheck(false); }); isRotatorCheckBox.SetCheck(editor->translator.isRotator); AddWidget(&isRotatorCheckBox); isTranslatorCheckBox.SetTooltip("Translate/Move (Ctrl + T)\nHotkey: 1"); isTranslatorCheckBox.OnClick([&](wi::gui::EventArgs args) { editor->translator.isTranslator = args.bValue; editor->translator.isScalator = false; editor->translator.isRotator = false; isScalatorCheckBox.SetCheck(false); isRotatorCheckBox.SetCheck(false); }); isTranslatorCheckBox.SetCheck(editor->translator.isTranslator); AddWidget(&isTranslatorCheckBox); } profilerEnabledCheckBox.Create("Profiler: "); profilerEnabledCheckBox.SetTooltip("Toggle Profiler On/Off"); profilerEnabledCheckBox.OnClick([&](wi::gui::EventArgs args) { wi::profiler::SetEnabled(args.bValue); }); profilerEnabledCheckBox.SetCheck(wi::profiler::IsEnabled()); AddWidget(&profilerEnabledCheckBox); physicsEnabledCheckBox.Create("Physics: "); physicsEnabledCheckBox.SetTooltip("Toggle Physics Simulation On/Off"); if (editor->main->config.GetSection("options").Has("physics")) { wi::physics::SetSimulationEnabled(editor->main->config.GetSection("options").GetBool("physics")); } physicsEnabledCheckBox.OnClick([&](wi::gui::EventArgs args) { wi::physics::SetSimulationEnabled(args.bValue); editor->main->config.GetSection("options").Set("physics", args.bValue); editor->main->config.Commit(); }); physicsEnabledCheckBox.SetCheck(wi::physics::IsSimulationEnabled()); AddWidget(&physicsEnabledCheckBox); cinemaModeCheckBox.Create("Cinema Mode: "); cinemaModeCheckBox.SetTooltip("Toggle Cinema Mode (All HUD disabled). Press ESC to exit."); cinemaModeCheckBox.OnClick([&](wi::gui::EventArgs args) { if (editor->renderPath != nullptr) { editor->renderPath->GetGUI().SetVisible(false); } editor->GetGUI().SetVisible(false); wi::profiler::SetEnabled(false); }); AddWidget(&cinemaModeCheckBox); versionCheckBox.Create("Version: "); versionCheckBox.SetTooltip("Toggle the engine version display text in top left corner."); editor->main->infoDisplay.watermark = editor->main->config.GetSection("options").GetBool("version"); versionCheckBox.SetCheck(editor->main->infoDisplay.watermark); versionCheckBox.OnClick([&](wi::gui::EventArgs args) { editor->main->infoDisplay.watermark = args.bValue; editor->main->config.GetSection("options").Set("version", args.bValue); editor->main->config.Commit(); }); AddWidget(&versionCheckBox); versionCheckBox.SetCheck(editor->main->infoDisplay.watermark); fpsCheckBox.Create("FPS: "); fpsCheckBox.SetTooltip("Toggle the FPS display text in top left corner."); editor->main->infoDisplay.fpsinfo = editor->main->config.GetSection("options").GetBool("fps"); fpsCheckBox.SetCheck(editor->main->infoDisplay.fpsinfo); fpsCheckBox.OnClick([&](wi::gui::EventArgs args) { editor->main->infoDisplay.fpsinfo = args.bValue; editor->main->config.GetSection("options").Set("fps", args.bValue); editor->main->config.Commit(); }); AddWidget(&fpsCheckBox); fpsCheckBox.SetCheck(editor->main->infoDisplay.fpsinfo); otherinfoCheckBox.Create("Info: "); otherinfoCheckBox.SetTooltip("Toggle advanced data in the info display text in top left corner."); bool info = editor->main->config.GetSection("options").GetBool("info"); editor->main->infoDisplay.heap_allocation_counter = info; editor->main->infoDisplay.vram_usage = info; editor->main->infoDisplay.device_name = info; editor->main->infoDisplay.colorspace = info; editor->main->infoDisplay.resolution = info; editor->main->infoDisplay.logical_size = info; editor->main->infoDisplay.pipeline_count = info; otherinfoCheckBox.SetCheck(info); otherinfoCheckBox.OnClick([&](wi::gui::EventArgs args) { editor->main->infoDisplay.heap_allocation_counter = args.bValue; editor->main->infoDisplay.vram_usage = args.bValue; editor->main->infoDisplay.device_name = args.bValue; editor->main->infoDisplay.colorspace = args.bValue; editor->main->infoDisplay.resolution = args.bValue; editor->main->infoDisplay.logical_size = args.bValue; editor->main->infoDisplay.pipeline_count = args.bValue; editor->main->config.GetSection("options").Set("info", args.bValue); editor->main->config.Commit(); }); AddWidget(&otherinfoCheckBox); otherinfoCheckBox.SetCheck(editor->main->infoDisplay.heap_allocation_counter); newCombo.Create("New: "); newCombo.selected_font.anim.typewriter.looped = true; newCombo.selected_font.anim.typewriter.time = 2; newCombo.selected_font.anim.typewriter.character_start = 1; newCombo.SetInvalidSelectionText("..."); newCombo.AddItem("Transform " ICON_TRANSFORM, 0); newCombo.AddItem("Material " ICON_MATERIAL, 1); newCombo.AddItem("Point Light " ICON_POINTLIGHT, 2); newCombo.AddItem("Spot Light " ICON_SPOTLIGHT, 3); newCombo.AddItem("Directional Light " ICON_DIRECTIONALLIGHT, 4); newCombo.AddItem("Environment Probe " ICON_ENVIRONMENTPROBE, 5); newCombo.AddItem("Force " ICON_FORCE, 6); newCombo.AddItem("Decal " ICON_DECAL, 7); newCombo.AddItem("Sound " ICON_SOUND, 8); newCombo.AddItem("Weather " ICON_WEATHER, 9); newCombo.AddItem("Emitter " ICON_EMITTER, 10); newCombo.AddItem("HairParticle " ICON_HAIR, 11); newCombo.AddItem("Camera " ICON_CAMERA, 12); newCombo.AddItem("Cube " ICON_CUBE, 13); newCombo.AddItem("Plane " ICON_SQUARE, 14); newCombo.AddItem("Animation " ICON_ANIMATION, 15); newCombo.AddItem("Script " ICON_SCRIPT, 16); newCombo.AddItem("Collider " ICON_COLLIDER, 17); newCombo.AddItem("Terrain " ICON_TERRAIN, 18); newCombo.OnSelect([&](wi::gui::EventArgs args) { newCombo.SetSelectedWithoutCallback(-1); const EditorComponent::EditorScene& editorscene = editor->GetCurrentEditorScene(); const CameraComponent& camera = editorscene.camera; Scene& scene = editor->GetCurrentScene(); PickResult pick; XMFLOAT3 in_front_of_camera; XMStoreFloat3(&in_front_of_camera, XMVectorAdd(camera.GetEye(), camera.GetAt() * 4)); switch (args.userdata) { case 0: pick.entity = scene.Entity_CreateTransform("transform"); break; case 1: pick.entity = scene.Entity_CreateMaterial("material"); break; case 2: pick.entity = scene.Entity_CreateLight("pointlight", in_front_of_camera, XMFLOAT3(1, 1, 1), 2, 60); scene.lights.GetComponent(pick.entity)->type = LightComponent::POINT; scene.lights.GetComponent(pick.entity)->intensity = 20; break; case 3: pick.entity = scene.Entity_CreateLight("spotlight", in_front_of_camera, XMFLOAT3(1, 1, 1), 2, 60); scene.lights.GetComponent(pick.entity)->type = LightComponent::SPOT; scene.lights.GetComponent(pick.entity)->intensity = 100; break; case 4: pick.entity = scene.Entity_CreateLight("dirlight", XMFLOAT3(0, 3, 0), XMFLOAT3(1, 1, 1), 2, 60); scene.lights.GetComponent(pick.entity)->type = LightComponent::DIRECTIONAL; scene.lights.GetComponent(pick.entity)->intensity = 10; break; case 5: pick.entity = scene.Entity_CreateEnvironmentProbe("envprobe", in_front_of_camera); break; case 6: pick.entity = scene.Entity_CreateForce("force"); break; case 7: pick.entity = scene.Entity_CreateDecal("decal", "images/logo_small.png"); scene.transforms.GetComponent(pick.entity)->RotateRollPitchYaw(XMFLOAT3(XM_PIDIV2, 0, 0)); break; case 8: { wi::helper::FileDialogParams params; params.type = wi::helper::FileDialogParams::OPEN; params.description = "Sound"; params.extensions = wi::resourcemanager::GetSupportedSoundExtensions(); wi::helper::FileDialog(params, [=](std::string fileName) { wi::eventhandler::Subscribe_Once(wi::eventhandler::EVENT_THREAD_SAFE_POINT, [=](uint64_t userdata) { Entity entity = editor->GetCurrentScene().Entity_CreateSound(wi::helper::GetFileNameFromPath(fileName), fileName); wi::Archive& archive = editor->AdvanceHistory(); archive << EditorComponent::HISTORYOP_ADD; editor->RecordSelection(archive); editor->ClearSelected(); editor->AddSelected(entity); editor->RecordSelection(archive); editor->RecordEntity(archive, entity); RefreshEntityTree(); editor->componentsWnd.soundWnd.SetEntity(entity); }); }); return; } break; case 9: pick.entity = CreateEntity(); scene.weathers.Create(pick.entity); scene.names.Create(pick.entity) = "weather"; break; case 10: pick.entity = scene.Entity_CreateEmitter("emitter"); break; case 11: pick.entity = scene.Entity_CreateHair("hair"); break; case 12: pick.entity = scene.Entity_CreateCamera("camera", camera.width, camera.height); *scene.cameras.GetComponent(pick.entity) = camera; *scene.transforms.GetComponent(pick.entity) = editorscene.camera_transform; break; case 13: pick.entity = scene.Entity_CreateCube("cube"); pick.subsetIndex = 0; break; case 14: pick.entity = scene.Entity_CreatePlane("plane"); pick.subsetIndex = 0; break; case 15: pick.entity = CreateEntity(); scene.animations.Create(pick.entity); scene.names.Create(pick.entity) = "animation"; break; case 16: pick.entity = CreateEntity(); scene.scripts.Create(pick.entity); scene.names.Create(pick.entity) = "script"; break; case 17: pick.entity = CreateEntity(); scene.colliders.Create(pick.entity); scene.transforms.Create(pick.entity); scene.names.Create(pick.entity) = "collider"; break; case 18: editor->componentsWnd.terrainWnd.SetupAssets(); pick.entity = CreateEntity(); scene.terrains.Create(pick.entity) = editor->componentsWnd.terrainWnd.terrain_preset; scene.names.Create(pick.entity) = "terrain"; break; default: break; } if (pick.entity != INVALID_ENTITY) { wi::Archive& archive = editor->AdvanceHistory(); archive << EditorComponent::HISTORYOP_ADD; editor->RecordSelection(archive); editor->ClearSelected(); editor->AddSelected(pick); editor->RecordSelection(archive); editor->RecordEntity(archive, pick.entity); } RefreshEntityTree(); }); newCombo.SetEnabled(true); newCombo.SetTooltip("Create new entity"); AddWidget(&newCombo); filterCombo.Create("Filter: "); filterCombo.AddItem("All " ICON_FILTER, (uint64_t)Filter::All); filterCombo.AddItem("Transform " ICON_TRANSFORM, (uint64_t)Filter::Transform); filterCombo.AddItem("Material " ICON_MATERIAL, (uint64_t)Filter::Material); filterCombo.AddItem("Mesh " ICON_MESH, (uint64_t)Filter::Mesh); filterCombo.AddItem("Object " ICON_OBJECT, (uint64_t)Filter::Object); filterCombo.AddItem("Environment Probe " ICON_ENVIRONMENTPROBE, (uint64_t)Filter::EnvironmentProbe); filterCombo.AddItem("Decal " ICON_DECAL, (uint64_t)Filter::Decal); filterCombo.AddItem("Sound " ICON_SOUND, (uint64_t)Filter::Sound); filterCombo.AddItem("Weather " ICON_WEATHER, (uint64_t)Filter::Weather); filterCombo.AddItem("Light " ICON_POINTLIGHT, (uint64_t)Filter::Light); filterCombo.AddItem("Animation " ICON_ANIMATION, (uint64_t)Filter::Animation); filterCombo.AddItem("Force " ICON_FORCE, (uint64_t)Filter::Force); filterCombo.AddItem("Emitter " ICON_EMITTER, (uint64_t)Filter::Emitter); filterCombo.AddItem("Hairparticle " ICON_HAIR, (uint64_t)Filter::Hairparticle); filterCombo.AddItem("Inverse Kinematics " ICON_IK, (uint64_t)Filter::IK); filterCombo.AddItem("Camera " ICON_CAMERA, (uint64_t)Filter::Camera); filterCombo.AddItem("Armature " ICON_ARMATURE, (uint64_t)Filter::Armature); filterCombo.AddItem("Spring " ICON_SPRING, (uint64_t)Filter::Spring); filterCombo.AddItem("Collider " ICON_COLLIDER, (uint64_t)Filter::Collider); filterCombo.AddItem("Script " ICON_SCRIPT, (uint64_t)Filter::Script); filterCombo.AddItem("Expression " ICON_EXPRESSION, (uint64_t)Filter::Expression); filterCombo.AddItem("Humanoid " ICON_HUMANOID, (uint64_t)Filter::Humanoid); filterCombo.AddItem("Terrain " ICON_TERRAIN, (uint64_t)Filter::Terrain); filterCombo.SetTooltip("Apply filtering to the Entities"); filterCombo.OnSelect([&](wi::gui::EventArgs args) { filter = (Filter)args.userdata; RefreshEntityTree(); }); AddWidget(&filterCombo); entityTree.Create("Entities"); entityTree.SetSize(XMFLOAT2(300, 300)); entityTree.OnSelect([this](wi::gui::EventArgs args) { if (args.iValue < 0) return; wi::Archive& archive = editor->AdvanceHistory(); archive << EditorComponent::HISTORYOP_SELECTION; // record PREVIOUS selection state... editor->RecordSelection(archive); editor->translator.selected.clear(); for (int i = 0; i < entityTree.GetItemCount(); ++i) { const wi::gui::TreeList::Item& item = entityTree.GetItem(i); if (item.selected) { wi::scene::PickResult pick; pick.entity = (Entity)item.userdata; editor->AddSelected(pick); } } // record NEW selection state... editor->RecordSelection(archive); }); entityTree.OnDelete([=](wi::gui::EventArgs args) { // Deletions will be performed in a batch next frame: // We don't delete here, because this callback will execute once for each item editor->deleting = true; }); AddWidget(&entityTree); // Renderer and Postprocess windows are created in ChangeRenderPath(), because they deal with // RenderPath related information as well, so it's easier to reset them when changing graphicsWnd.Create(editor); graphicsWnd.SetCollapsed(true); AddWidget(&graphicsWnd); cameraWnd.Create(editor); cameraWnd.SetCollapsed(true); AddWidget(&cameraWnd); paintToolWnd.Create(editor); paintToolWnd.SetCollapsed(true); AddWidget(&paintToolWnd); materialPickerWnd.Create(editor); AddWidget(&materialPickerWnd); sceneComboBox.Create("Scene: "); sceneComboBox.OnSelect([&](wi::gui::EventArgs args) { if (args.iValue >= int(editor->scenes.size())) { editor->NewScene(); } editor->SetCurrentScene(args.iValue); }); sceneComboBox.SetEnabled(true); sceneComboBox.SetColor(wi::Color(50, 100, 255, 180), wi::gui::IDLE); sceneComboBox.SetColor(wi::Color(120, 160, 255, 255), wi::gui::FOCUS); AddWidget(&sceneComboBox); saveModeComboBox.Create("Save Mode: "); saveModeComboBox.AddItem("Embed resources " ICON_SAVE_EMBED, (uint64_t)wi::resourcemanager::Mode::ALLOW_RETAIN_FILEDATA); saveModeComboBox.AddItem("No embedding " ICON_SAVE_NO_EMBED, (uint64_t)wi::resourcemanager::Mode::ALLOW_RETAIN_FILEDATA_BUT_DISABLE_EMBEDDING); saveModeComboBox.AddItem("Dump to header " ICON_SAVE_HEADER, (uint64_t)wi::resourcemanager::Mode::ALLOW_RETAIN_FILEDATA); saveModeComboBox.SetTooltip("Choose whether to embed resources (textures, sounds...) in the scene file when saving, or keep them as separate files.\nThe Dump to header (" ICON_SAVE_HEADER ") option will use embedding and create a C++ header file with byte data of the scene to be used with wi::Archive serialization."); saveModeComboBox.SetColor(wi::Color(50, 180, 100, 180), wi::gui::IDLE); saveModeComboBox.SetColor(wi::Color(50, 220, 140, 255), wi::gui::FOCUS); saveModeComboBox.SetSelected(editor->main->config.GetSection("options").GetInt("save_mode")); saveModeComboBox.OnSelect([=](wi::gui::EventArgs args) { editor->main->config.GetSection("options").Set("save_mode", args.iValue); editor->main->config.Commit(); }); AddWidget(&saveModeComboBox); enum class Theme { Dark, Bright, Soft, Hacking, }; themeCombo.Create("Theme: "); themeCombo.SetTooltip("Choose a color theme..."); themeCombo.AddItem("Dark " ICON_DARK, (uint64_t)Theme::Dark); themeCombo.AddItem("Bright " ICON_BRIGHT, (uint64_t)Theme::Bright); themeCombo.AddItem("Soft " ICON_SOFT, (uint64_t)Theme::Soft); themeCombo.AddItem("Hacking " ICON_HACKING, (uint64_t)Theme::Hacking); themeCombo.OnSelect([=](wi::gui::EventArgs args) { // Dark theme defaults: wi::Color theme_color_idle = wi::Color(30, 40, 60, 200); wi::Color theme_color_focus = wi::Color(70, 150, 170, 220); wi::Color dark_point = wi::Color(10, 10, 20, 220); // darker elements will lerp towards this wi::gui::Theme theme; theme.image.background = true; theme.image.blendFlag = wi::enums::BLENDMODE_OPAQUE; theme.font.color = wi::Color(130, 210, 220, 255); theme.shadow_color = wi::Color(80, 140, 180, 100); switch ((Theme)args.userdata) { default: break; case Theme::Dark: editor->main->config.GetSection("options").Set("theme", "Dark"); break; case Theme::Bright: editor->main->config.GetSection("options").Set("theme", "Bright"); theme_color_idle = wi::Color(200, 210, 220, 230); theme_color_focus = wi::Color(210, 230, 255, 250); dark_point = wi::Color(180, 180, 190, 230); theme.shadow_color = wi::Color::Shadow(); theme.font.color = wi::Color(50, 50, 80, 255); break; case Theme::Soft: editor->main->config.GetSection("options").Set("theme", "Soft"); theme_color_idle = wi::Color(200, 180, 190, 190); theme_color_focus = wi::Color(240, 190, 200, 230); dark_point = wi::Color(100, 80, 90, 220); theme.shadow_color = wi::Color(240, 190, 200, 180); theme.font.color = wi::Color(255, 230, 240, 255); break; case Theme::Hacking: editor->main->config.GetSection("options").Set("theme", "Hacking"); theme_color_idle = wi::Color(0, 0, 0, 255); theme_color_focus = wi::Color(10, 230, 30, 255); dark_point = wi::Color(0, 0, 0, 255); theme.shadow_color = wi::Color(0, 250, 0, 200); theme.font.color = wi::Color(100, 250, 100, 255); theme.font.shadow_color = wi::Color::Shadow(); break; } editor->main->config.Commit(); theme.tooltipImage = theme.image; theme.tooltipImage.color = theme_color_idle; theme.tooltipFont = theme.font; theme.tooltip_shadow_color = theme.shadow_color; wi::Color theme_color_active = wi::Color::White(); wi::Color theme_color_deactivating = wi::Color::lerp(theme_color_focus, wi::Color::White(), 0.5f); // Customize whole gui: wi::gui::GUI& gui = editor->GetGUI(); gui.SetTheme(theme); // set basic params to all states // customize colors for specific states: gui.SetColor(theme_color_idle, wi::gui::IDLE); gui.SetColor(theme_color_focus, wi::gui::FOCUS); gui.SetColor(theme_color_active, wi::gui::ACTIVE); gui.SetColor(theme_color_deactivating, wi::gui::DEACTIVATING); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.7f), wi::gui::WIDGET_ID_WINDOW_BASE); gui.SetColor(theme_color_focus, wi::gui::WIDGET_ID_TEXTINPUTFIELD_ACTIVE); gui.SetColor(theme_color_focus, wi::gui::WIDGET_ID_TEXTINPUTFIELD_DEACTIVATING); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.75f), wi::gui::WIDGET_ID_SLIDER_BASE_IDLE); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.8f), wi::gui::WIDGET_ID_SLIDER_BASE_FOCUS); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.85f), wi::gui::WIDGET_ID_SLIDER_BASE_ACTIVE); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.8f), wi::gui::WIDGET_ID_SLIDER_BASE_DEACTIVATING); gui.SetColor(theme_color_idle, wi::gui::WIDGET_ID_SLIDER_KNOB_IDLE); gui.SetColor(theme_color_focus, wi::gui::WIDGET_ID_SLIDER_KNOB_FOCUS); gui.SetColor(theme_color_active, wi::gui::WIDGET_ID_SLIDER_KNOB_ACTIVE); gui.SetColor(theme_color_deactivating, wi::gui::WIDGET_ID_SLIDER_KNOB_DEACTIVATING); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.75f), wi::gui::WIDGET_ID_SCROLLBAR_BASE_IDLE); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.8f), wi::gui::WIDGET_ID_SCROLLBAR_BASE_FOCUS); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.85f), wi::gui::WIDGET_ID_SCROLLBAR_BASE_ACTIVE); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.8f), wi::gui::WIDGET_ID_SCROLLBAR_BASE_DEACTIVATING); gui.SetColor(theme_color_idle, wi::gui::WIDGET_ID_SCROLLBAR_KNOB_INACTIVE); gui.SetColor(theme_color_focus, wi::gui::WIDGET_ID_SCROLLBAR_KNOB_HOVER); gui.SetColor(theme_color_active, wi::gui::WIDGET_ID_SCROLLBAR_KNOB_GRABBED); gui.SetColor(wi::Color::lerp(theme_color_idle, dark_point, 0.8f), wi::gui::WIDGET_ID_COMBO_DROPDOWN); if ((Theme)args.userdata == Theme::Hacking) { gui.SetColor(wi::Color(0, 200, 0, 255), wi::gui::WIDGET_ID_SLIDER_KNOB_IDLE); gui.SetColor(wi::Color(0, 200, 0, 255), wi::gui::WIDGET_ID_SCROLLBAR_KNOB_INACTIVE); } // customize individual elements: editor->componentsWnd.materialWnd.textureSlotButton.SetColor(wi::Color::White(), wi::gui::IDLE); paintToolWnd.brushTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE); paintToolWnd.revealTextureButton.SetColor(wi::Color::White(), wi::gui::IDLE); editor->aboutLabel.sprites[wi::gui::FOCUS] = editor->aboutLabel.sprites[wi::gui::IDLE]; for (int i = 0; i < arraysize(sprites); ++i) { sprites[i].params.enableCornerRounding(); sprites[i].params.corners_rounding[1].radius = 10; resizeDragger_UpperRight.sprites[i].params.enableCornerRounding(); resizeDragger_UpperRight.sprites[i].params.corners_rounding[1].radius = 10; } for (int i = 0; i < arraysize(editor->componentsWnd.sprites); ++i) { editor->componentsWnd.sprites[i].params.enableCornerRounding(); editor->componentsWnd.sprites[i].params.corners_rounding[0].radius = 10; editor->componentsWnd.resizeDragger_UpperLeft.sprites[i].params.enableCornerRounding(); editor->componentsWnd.resizeDragger_UpperLeft.sprites[i].params.corners_rounding[0].radius = 10; } for (int i = 0; i < arraysize(editor->saveButton.sprites); ++i) { editor->saveButton.sprites[i].params.enableCornerRounding(); editor->saveButton.sprites[i].params.corners_rounding[2].radius = 10; } editor->componentsWnd.weatherWnd.default_sky_horizon = dark_point; editor->componentsWnd.weatherWnd.default_sky_zenith = theme_color_idle; if ((Theme)args.userdata == Theme::Bright) { editor->inactiveEntityColor = theme_color_focus; editor->hoveredEntityColor = theme_color_focus; } else { editor->inactiveEntityColor = theme.font.color; editor->hoveredEntityColor = theme.font.color; } editor->inactiveEntityColor.setA(150); editor->save_text_color = theme.font.color; }); AddWidget(&themeCombo); SetSize(XMFLOAT2(338, 500)); } void OptionsWindow::Update(float dt) { cameraWnd.Update(); paintToolWnd.Update(dt); graphicsWnd.Update(); } void OptionsWindow::ResizeLayout() { wi::gui::Window::ResizeLayout(); const float padding = 4; XMFLOAT2 pos = XMFLOAT2(padding, padding); const float width = GetWidgetAreaSize().x - padding * 2; float x_off = 100; isScalatorCheckBox.SetPos(XMFLOAT2(pos.x + width - isScalatorCheckBox.GetSize().x, pos.y)); isRotatorCheckBox.SetPos(XMFLOAT2(isScalatorCheckBox.GetPos().x - isRotatorCheckBox.GetSize().x - 80, pos.y)); isTranslatorCheckBox.SetPos(XMFLOAT2(isRotatorCheckBox.GetPos().x - isTranslatorCheckBox.GetSize().x - 70, pos.y)); pos.y += isTranslatorCheckBox.GetSize().y; pos.y += padding; otherinfoCheckBox.SetPos(XMFLOAT2(pos.x + width - otherinfoCheckBox.GetSize().x, pos.y)); fpsCheckBox.SetPos(XMFLOAT2(otherinfoCheckBox.GetPos().x - fpsCheckBox.GetSize().x - 80, pos.y)); versionCheckBox.SetPos(XMFLOAT2(fpsCheckBox.GetPos().x - versionCheckBox.GetSize().x - 70, pos.y)); pos.y += versionCheckBox.GetSize().y; pos.y += padding; physicsEnabledCheckBox.SetPos(XMFLOAT2(pos.x + width - physicsEnabledCheckBox.GetSize().x, pos.y)); profilerEnabledCheckBox.SetPos(XMFLOAT2(physicsEnabledCheckBox.GetPos().x - profilerEnabledCheckBox.GetSize().x - 80, pos.y)); cinemaModeCheckBox.SetPos(XMFLOAT2(profilerEnabledCheckBox.GetPos().x - cinemaModeCheckBox.GetSize().x - 70, pos.y)); pos.y += cinemaModeCheckBox.GetSize().y; pos.y += padding; sceneComboBox.SetPos(XMFLOAT2(pos.x + x_off, pos.y)); sceneComboBox.SetSize(XMFLOAT2(width - x_off - sceneComboBox.GetScale().y - 1, sceneComboBox.GetScale().y)); pos.y += sceneComboBox.GetSize().y; pos.y += padding; saveModeComboBox.SetPos(XMFLOAT2(pos.x + x_off, pos.y)); saveModeComboBox.SetSize(XMFLOAT2(width - x_off - saveModeComboBox.GetScale().y - 1, saveModeComboBox.GetScale().y)); pos.y += saveModeComboBox.GetSize().y; pos.y += padding; themeCombo.SetPos(XMFLOAT2(pos.x + x_off, pos.y)); themeCombo.SetSize(XMFLOAT2(width - x_off - themeCombo.GetScale().y - 1, themeCombo.GetScale().y)); pos.y += themeCombo.GetSize().y; pos.y += padding; graphicsWnd.SetPos(pos); graphicsWnd.SetSize(XMFLOAT2(width, graphicsWnd.GetScale().y)); pos.y += graphicsWnd.GetSize().y; pos.y += padding; cameraWnd.SetPos(pos); cameraWnd.SetSize(XMFLOAT2(width, cameraWnd.GetScale().y)); pos.y += cameraWnd.GetSize().y; pos.y += padding; materialPickerWnd.SetPos(pos); materialPickerWnd.SetSize(XMFLOAT2(width, materialPickerWnd.GetScale().y)); pos.y += materialPickerWnd.GetSize().y; pos.y += padding; paintToolWnd.SetPos(pos); paintToolWnd.SetSize(XMFLOAT2(width, paintToolWnd.GetScale().y)); pos.y += paintToolWnd.GetSize().y; pos.y += padding; x_off = 45; newCombo.SetPos(XMFLOAT2(pos.x + x_off, pos.y)); newCombo.SetSize(XMFLOAT2(width - x_off - newCombo.GetScale().y - 1, newCombo.GetScale().y)); pos.y += newCombo.GetSize().y; pos.y += padding; filterCombo.SetPos(XMFLOAT2(pos.x + x_off, pos.y)); filterCombo.SetSize(XMFLOAT2(width - x_off - filterCombo.GetScale().y - 1, filterCombo.GetScale().y)); pos.y += filterCombo.GetSize().y; pos.y += padding; entityTree.SetPos(pos); entityTree.SetSize(XMFLOAT2(width, std::max(editor->GetLogicalHeight() * 0.75f, editor->GetLogicalHeight() - pos.y))); pos.y += entityTree.GetSize().y; pos.y += padding; } void OptionsWindow::PushToEntityTree(wi::ecs::Entity entity, int level) { if (entitytree_added_items.count(entity) != 0) { return; } const Scene& scene = editor->GetCurrentScene(); wi::gui::TreeList::Item item; item.level = level; item.userdata = entity; item.selected = editor->IsSelected(entity); item.open = entitytree_opened_items.count(entity) != 0; // Icons: if (scene.layers.Contains(entity)) { item.name += ICON_LAYER " "; } if (scene.transforms.Contains(entity)) { item.name += ICON_TRANSFORM " "; } if (scene.terrains.Contains(entity)) { item.name += ICON_TERRAIN " "; } if (scene.meshes.Contains(entity)) { item.name += ICON_MESH " "; } if (scene.objects.Contains(entity)) { item.name += ICON_OBJECT " "; } if (scene.rigidbodies.Contains(entity)) { item.name += ICON_RIGIDBODY " "; } if (scene.softbodies.Contains(entity)) { item.name += ICON_SOFTBODY " "; } if (scene.emitters.Contains(entity)) { item.name += ICON_EMITTER " "; } if (scene.hairs.Contains(entity)) { item.name += ICON_HAIR " "; } if (scene.forces.Contains(entity)) { item.name += ICON_FORCE " "; } if (scene.sounds.Contains(entity)) { item.name += ICON_SOUND " "; } if (scene.decals.Contains(entity)) { item.name += ICON_DECAL " "; } if (scene.cameras.Contains(entity)) { item.name += ICON_CAMERA " "; } if (scene.probes.Contains(entity)) { item.name += ICON_ENVIRONMENTPROBE " "; } if (scene.animations.Contains(entity)) { item.name += ICON_ANIMATION " "; } if (scene.armatures.Contains(entity)) { item.name += ICON_ARMATURE " "; } if (scene.humanoids.Contains(entity)) { item.name += ICON_HUMANOID " "; } if (scene.lights.Contains(entity)) { const LightComponent* light = scene.lights.GetComponent(entity); switch (light->type) { default: case LightComponent::POINT: item.name += ICON_POINTLIGHT " "; break; case LightComponent::SPOT: item.name += ICON_SPOTLIGHT " "; break; case LightComponent::DIRECTIONAL: item.name += ICON_DIRECTIONALLIGHT " "; break; } } if (scene.materials.Contains(entity)) { item.name += ICON_MATERIAL " "; } if (scene.weathers.Contains(entity)) { item.name += ICON_WEATHER " "; } if (scene.inverse_kinematics.Contains(entity)) { item.name += ICON_IK " "; } if (scene.springs.Contains(entity)) { item.name += ICON_SPRING " "; } if (scene.colliders.Contains(entity)) { item.name += ICON_COLLIDER " "; } if (scene.scripts.Contains(entity)) { item.name += ICON_SCRIPT " "; } if (scene.expressions.Contains(entity)) { item.name += ICON_EXPRESSION " "; } bool bone_found = false; for (size_t i = 0; i < scene.armatures.GetCount() && !bone_found; ++i) { const ArmatureComponent& armature = scene.armatures[i]; for (Entity bone : armature.boneCollection) { if (entity == bone) { item.name += ICON_BONE " "; bone_found = true; break; } } } const NameComponent* name = scene.names.GetComponent(entity); if (name == nullptr) { item.name += "[no_name] " + std::to_string(entity); } else if (name->name.empty()) { item.name += "[name_empty] " + std::to_string(entity); } else { item.name += name->name; } entityTree.AddItem(item); entitytree_added_items.insert(entity); for (size_t i = 0; i < scene.hierarchy.GetCount(); ++i) { if (scene.hierarchy[i].parentID == entity) { PushToEntityTree(scene.hierarchy.GetEntity(i), level + 1); } } } void OptionsWindow::RefreshEntityTree() { const Scene& scene = editor->GetCurrentScene(); materialPickerWnd.RecreateButtons(); for (int i = 0; i < entityTree.GetItemCount(); ++i) { const wi::gui::TreeList::Item& item = entityTree.GetItem(i); if (item.open) { entitytree_opened_items.insert((Entity)item.userdata); } } entityTree.ClearItems(); if (has_flag(filter, Filter::All)) { // Add hierarchy: for (size_t i = 0; i < scene.hierarchy.GetCount(); ++i) { if (scene.hierarchy[i].parentID == INVALID_ENTITY) continue; PushToEntityTree(scene.hierarchy[i].parentID, 0); } } // Add any left over entities that might not have had a hierarchy: if (has_flag(filter, Filter::Terrain)) { // Any transform left that is not part of a hierarchy: for (size_t i = 0; i < scene.terrains.GetCount(); ++i) { PushToEntityTree(scene.terrains.GetEntity(i), 0); } } if (has_flag(filter, Filter::Transform)) { // Any transform left that is not part of a hierarchy: for (size_t i = 0; i < scene.transforms.GetCount(); ++i) { PushToEntityTree(scene.transforms.GetEntity(i), 0); } } if (has_flag(filter, Filter::Light)) { for (size_t i = 0; i < scene.lights.GetCount(); ++i) { PushToEntityTree(scene.lights.GetEntity(i), 0); } } if (has_flag(filter, Filter::Decal)) { for (size_t i = 0; i < scene.decals.GetCount(); ++i) { PushToEntityTree(scene.decals.GetEntity(i), 0); } } if (has_flag(filter, Filter::Camera)) { for (size_t i = 0; i < scene.cameras.GetCount(); ++i) { PushToEntityTree(scene.cameras.GetEntity(i), 0); } } if (has_flag(filter, Filter::Material)) { for (size_t i = 0; i < scene.materials.GetCount(); ++i) { PushToEntityTree(scene.materials.GetEntity(i), 0); } } if (has_flag(filter, Filter::Mesh)) { for (size_t i = 0; i < scene.meshes.GetCount(); ++i) { PushToEntityTree(scene.meshes.GetEntity(i), 0); } } if (has_flag(filter, Filter::Armature)) { for (size_t i = 0; i < scene.armatures.GetCount(); ++i) { PushToEntityTree(scene.armatures.GetEntity(i), 0); } } if (has_flag(filter, Filter::Object)) { for (size_t i = 0; i < scene.objects.GetCount(); ++i) { PushToEntityTree(scene.objects.GetEntity(i), 0); } } if (has_flag(filter, Filter::Weather)) { for (size_t i = 0; i < scene.weathers.GetCount(); ++i) { PushToEntityTree(scene.weathers.GetEntity(i), 0); } } if (has_flag(filter, Filter::Sound)) { for (size_t i = 0; i < scene.sounds.GetCount(); ++i) { PushToEntityTree(scene.sounds.GetEntity(i), 0); } } if (has_flag(filter, Filter::Hairparticle)) { for (size_t i = 0; i < scene.hairs.GetCount(); ++i) { PushToEntityTree(scene.hairs.GetEntity(i), 0); } } if (has_flag(filter, Filter::Emitter)) { for (size_t i = 0; i < scene.emitters.GetCount(); ++i) { PushToEntityTree(scene.emitters.GetEntity(i), 0); } } if (has_flag(filter, Filter::Animation)) { for (size_t i = 0; i < scene.animations.GetCount(); ++i) { PushToEntityTree(scene.animations.GetEntity(i), 0); } } if (has_flag(filter, Filter::EnvironmentProbe)) { for (size_t i = 0; i < scene.probes.GetCount(); ++i) { PushToEntityTree(scene.probes.GetEntity(i), 0); } } if (has_flag(filter, Filter::Force)) { for (size_t i = 0; i < scene.forces.GetCount(); ++i) { PushToEntityTree(scene.forces.GetEntity(i), 0); } } if (has_flag(filter, Filter::All)) { for (size_t i = 0; i < scene.rigidbodies.GetCount(); ++i) { PushToEntityTree(scene.rigidbodies.GetEntity(i), 0); } } if (has_flag(filter, Filter::All)) { for (size_t i = 0; i < scene.softbodies.GetCount(); ++i) { PushToEntityTree(scene.softbodies.GetEntity(i), 0); } } if (has_flag(filter, Filter::Spring)) { for (size_t i = 0; i < scene.springs.GetCount(); ++i) { PushToEntityTree(scene.springs.GetEntity(i), 0); } } if (has_flag(filter, Filter::Collider)) { for (size_t i = 0; i < scene.colliders.GetCount(); ++i) { PushToEntityTree(scene.colliders.GetEntity(i), 0); } } if (has_flag(filter, Filter::IK)) { for (size_t i = 0; i < scene.inverse_kinematics.GetCount(); ++i) { PushToEntityTree(scene.inverse_kinematics.GetEntity(i), 0); } } if (has_flag(filter, Filter::All)) { for (size_t i = 0; i < scene.names.GetCount(); ++i) { PushToEntityTree(scene.names.GetEntity(i), 0); } } if (has_flag(filter, Filter::Script)) { for (size_t i = 0; i < scene.scripts.GetCount(); ++i) { PushToEntityTree(scene.scripts.GetEntity(i), 0); } } if (has_flag(filter, Filter::Humanoid)) { for (size_t i = 0; i < scene.humanoids.GetCount(); ++i) { PushToEntityTree(scene.humanoids.GetEntity(i), 0); } } if (has_flag(filter, Filter::Expression)) { for (size_t i = 0; i < scene.expressions.GetCount(); ++i) { PushToEntityTree(scene.expressions.GetEntity(i), 0); } } if (has_flag(filter, Filter::Terrain)) { for (size_t i = 0; i < scene.terrains.GetCount(); ++i) { PushToEntityTree(scene.terrains.GetEntity(i), 0); } } entitytree_added_items.clear(); entitytree_opened_items.clear(); }