@@ -1180,7 +1180,10 @@ namespace Lux {
11801180
11811181 ImGui::Separator ();
11821182 if (ImGui::MenuItem (" Exit" ))
1183- Application::Get ().DispatchEvent <WindowCloseEvent, true >();
1183+ Application::Get ().QueueEvent ([]()
1184+ {
1185+ Application::Get ().DispatchEvent <WindowCloseEvent, true >();
1186+ });
11841187
11851188 ImGui::EndMenu ();
11861189 }
@@ -1230,28 +1233,32 @@ namespace Lux {
12301233 const ImVec2 windowPos = window->Pos ;
12311234 const ImVec2 windowMax = ImVec2 (window->Pos .x + window->Size .x , window->Pos .y + m_TitlebarHeight);
12321235
1233- ImU32 targetTitlebarColor = Colors::Theme::titlebar;
1236+ ImU32 stateAccentColor = Colors::Theme::titlebar;
12341237 if (m_SceneState == SceneState::Play)
1235- targetTitlebarColor = Colors::Theme::titlebarOrange ;
1238+ stateAccentColor = Colors::Theme::titlebarGreen ;
12361239 else if (m_SceneState == SceneState::Simulate)
1237- targetTitlebarColor = Colors::Theme::titlebarGreen ;
1240+ stateAccentColor = Colors::Theme::titlebarOrange ;
12381241
1239- const ImVec4 targetColor = ImGui::ColorConvertU32ToFloat4 (targetTitlebarColor );
1242+ const ImVec4 targetColor = ImGui::ColorConvertU32ToFloat4 (stateAccentColor );
12401243 const float dt = ImGui::GetIO ().DeltaTime ;
12411244 m_AnimatedTitlebarColor = ImLerp (m_AnimatedTitlebarColor, targetColor, std::clamp (dt * 8 .0f , 0 .0f , 1 .0f ));
1242- drawList->AddRectFilled (windowPos, windowMax, ImGui::ColorConvertFloat4ToU32 (m_AnimatedTitlebarColor));
1245+ const ImU32 activeTitlebarColor = ImGui::ColorConvertFloat4ToU32 (m_AnimatedTitlebarColor);
1246+ drawList->AddRectFilled (windowPos, windowMax, Colors::Theme::titlebar);
1247+ drawList->AddRectFilledMultiColor (windowPos, ImVec2 (windowPos.x + 380 .0f , windowMax.y ),
1248+ activeTitlebarColor, Colors::Theme::titlebar, Colors::Theme::titlebar, activeTitlebarColor);
12431249
12441250 drawList->AddLine (ImVec2 (windowPos.x , windowPos.y + m_TitlebarHeight), ImVec2 (windowPos.x + window->Size .x , windowPos.y + m_TitlebarHeight), Colors::Theme::backgroundDark);
12451251
1246- const float logoPadding = 16 .0f ;
1247- const float logoSize = 30 .0f ;
1248- const float logoTop = (m_TitlebarHeight - logoSize) * 0 .5f ;
1249- const ImVec2 logoMin (windowPos.x + logoPadding, windowPos.y + logoTop);
1250- const ImVec2 logoMax (logoMin.x + logoSize, logoMin.y + logoSize);
12511252 if (EditorResources::HazelLogoTexture)
1253+ {
1254+ const float logoWidth = (float )EditorResources::HazelLogoTexture->GetWidth ();
1255+ const float logoHeight = (float )EditorResources::HazelLogoTexture->GetHeight ();
1256+ const ImVec2 logoMin (windowPos.x + 14 .0f , windowPos.y + 6 .0f );
1257+ const ImVec2 logoMax (logoMin.x + logoWidth, logoMin.y + logoHeight);
12521258 drawList->AddImage (GetImGuiTextureID (EditorResources::HazelLogoTexture), logoMin, logoMax);
1259+ }
12531260
1254- const float menuBarX = logoPadding * 2 .0f + logoSize + 8 .0f ;
1261+ const float menuBarX = 16 . 0f * 2 .0f + 41 .0f ;
12551262 ImGui::SetCursorPos (ImVec2 (menuBarX, 4 .0f ));
12561263 UI_DrawMenubar ();
12571264
@@ -1268,15 +1275,63 @@ namespace Lux {
12681275 GLFWwindow* nativeWindow = Application::Get ().GetWindow ().GetNativeWindow ();
12691276 const bool isMaximized = nativeWindow && glfwGetWindowAttrib (nativeWindow, GLFW_MAXIMIZED );
12701277
1271- const float controlsWidth = 120 .0f ;
1278+ const float iconWidth = 14 .0f ;
1279+ const float iconHeight = 14 .0f ;
1280+ const float buttonWidth = 46 .0f ;
1281+ const float buttonHeight = m_TitlebarHeight;
1282+ const float buttonY = 0 .0f ;
1283+ const float closeButtonX = window->Size .x - buttonWidth;
1284+ const float maximizeButtonX = closeButtonX - buttonWidth;
1285+ const float minimizeButtonX = maximizeButtonX - buttonWidth;
1286+ const float titlebarGap = 12 .0f ;
1287+
1288+ const std::string projectName = GetProjectDisplayName ();
1289+ const float projectBoxPaddingX = 10 .0f ;
1290+ const float projectBoxHeight = 26 .0f ;
1291+ const float projectBoxMinWidth = 76 .0f ;
1292+ const float projectBoxMaxX = minimizeButtonX - titlebarGap;
1293+ const float sceneNameRightX = ((window->Size .x - sceneNameSize.x ) * 0 .5f ) + sceneNameSize.x ;
1294+ const float projectBoxMinAllowedX = std::max (menuBarX + 280 .0f , sceneNameRightX + 28 .0f );
1295+ const float maxProjectBoxWidth = projectBoxMaxX - projectBoxMinAllowedX;
1296+
1297+ bool drawProjectBox = maxProjectBoxWidth >= projectBoxMinWidth;
1298+ std::string displayedProjectName = projectName;
1299+ float projectBoxWidth = 0 .0f ;
1300+ if (drawProjectBox)
1301+ {
1302+ const float maxProjectTextWidth = std::max (0 .0f , maxProjectBoxWidth - projectBoxPaddingX * 2 .0f );
1303+ if (ImGui::CalcTextSize (displayedProjectName.c_str ()).x > maxProjectTextWidth)
1304+ {
1305+ const std::string ellipsis = " ..." ;
1306+ while (!displayedProjectName.empty ())
1307+ {
1308+ const std::string candidate = displayedProjectName + ellipsis;
1309+ if (ImGui::CalcTextSize (candidate.c_str ()).x <= maxProjectTextWidth)
1310+ {
1311+ displayedProjectName = candidate;
1312+ break ;
1313+ }
1314+ displayedProjectName.pop_back ();
1315+ }
1316+ if (displayedProjectName.empty ())
1317+ drawProjectBox = false ;
1318+ }
1319+
1320+ if (drawProjectBox)
1321+ projectBoxWidth = std::min (ImGui::CalcTextSize (displayedProjectName.c_str ()).x + projectBoxPaddingX * 2 .0f , maxProjectBoxWidth);
1322+ }
1323+
1324+ const float projectBoxMinX = drawProjectBox ? projectBoxMaxX - projectBoxWidth : projectBoxMaxX;
12721325 const float dragZoneMinX = 70 .0f ;
1273- const float dragZoneMaxX = window-> Size . x - controlsWidth - 220 . 0f ;
1326+ const float dragZoneMaxX = std::max (dragZoneMinX, (drawProjectBox ? projectBoxMinX : minimizeButtonX) - titlebarGap) ;
12741327 ImGui::SetCursorPos (ImVec2 (dragZoneMinX, 0 .0f ));
12751328 ImGui::InvisibleButton (" ##titleBarDragZone" , ImVec2 (std::max (0 .0f , dragZoneMaxX - dragZoneMinX), m_TitlebarHeight));
12761329 const ImVec2 dragMin = ImGui::GetItemRectMin ();
12771330 const ImVec2 dragMax = ImGui::GetItemRectMax ();
12781331 m_TitleBarDragRectMin = ImVec2 (dragMin.x - windowPos.x , dragMin.y - windowPos.y );
12791332 m_TitleBarDragRectMax = ImVec2 (dragMax.x - windowPos.x , dragMax.y - windowPos.y );
1333+ m_TitleBarDragRectMin = ImVec2 (dragZoneMinX, 0 .0f );
1334+ m_TitleBarDragRectMax = ImVec2 (dragZoneMaxX, m_TitlebarHeight);
12801335
12811336#if !defined(LUX_PLATFORM_WINDOWS)
12821337 if (nativeWindow && !isMaximized && ImGui::IsItemActive () && ImGui::IsMouseDragging (ImGuiMouseButton_Left))
@@ -1288,39 +1343,57 @@ namespace Lux {
12881343 }
12891344#endif
12901345
1291- const std::string projectName = GetProjectDisplayName ();
1292- const ImVec2 projectNameSize = ImGui::CalcTextSize (projectName.c_str ());
1293- const ImVec2 projectBoxMin (windowPos.x + window->Size .x - controlsWidth - projectNameSize.x - 36 .0f , windowPos.y + 14 .0f );
1294- const ImVec2 projectBoxMax (projectBoxMin.x + projectNameSize.x + 20 .0f , projectBoxMin.y + 26 .0f );
1295- drawList->AddRect (projectBoxMin, projectBoxMax, Colors::Theme::muted, 6 .0f , 0 , 1 .0f );
1296- drawList->AddText (ImVec2 (projectBoxMin.x + 10 .0f , projectBoxMin.y + 5 .0f ), Colors::Theme::text, projectName.c_str ());
1297-
1298- const float buttonSize = 34 .0f ;
1299- const float buttonY = (m_TitlebarHeight - buttonSize) * 0 .5f ;
1300- const float buttonsStartX = window->Size .x - controlsWidth;
1301- const ImU32 normalTint = IM_COL32 (220 , 220 , 220 , 220 );
1302- const ImU32 hoverTint = IM_COL32 (255 , 255 , 255 , 255 );
1303- const ImU32 activeTint = IM_COL32 (200 , 200 , 200 , 255 );
1346+ if (drawProjectBox)
1347+ {
1348+ const ImVec2 projectBoxMin (windowPos.x + projectBoxMinX, windowPos.y + 14 .0f );
1349+ const ImVec2 projectBoxMax (projectBoxMin.x + projectBoxWidth, projectBoxMin.y + projectBoxHeight);
1350+ drawList->AddRect (projectBoxMin, projectBoxMax, Colors::Theme::muted, 6 .0f , 0 , 1 .0f );
1351+ drawList->AddText (ImVec2 (projectBoxMin.x + projectBoxPaddingX, projectBoxMin.y + 5 .0f ), Colors::Theme::text, displayedProjectName.c_str ());
1352+ }
1353+
1354+ const ImU32 buttonColN = ImGuiEx::ColourWithMultipliedValue (Colors::Theme::text, 0 .9f );
1355+ const ImU32 buttonColH = ImGuiEx::ColourWithMultipliedValue (Colors::Theme::text, 1 .2f );
1356+ const ImU32 buttonColP = Colors::Theme::textDarker;
13041357
13051358 auto drawWindowControlButton = [&](const char * id, const Ref<Texture2D>& icon, float localX, auto && onClick)
13061359 {
13071360 ImGui::SetCursorPos (ImVec2 (localX, buttonY));
1308- ImGui::InvisibleButton (id, ImVec2 (buttonSize, buttonSize ));
1361+ ImGui::InvisibleButton (id, ImVec2 (buttonWidth, buttonHeight ));
13091362 if (icon)
1310- ImGuiEx::DrawButtonImage (icon, normalTint, hoverTint, activeTint, ImGui::GetItemRectMin (), ImGui::GetItemRectMax (), ImVec2 (0 .0f , 0 .0f ), ImVec2 (1 .0f , 1 .0f ));
1363+ {
1364+ const ImVec2 buttonMin = ImGui::GetItemRectMin ();
1365+ const ImVec2 iconMin (
1366+ buttonMin.x + (buttonWidth - iconWidth) * 0 .5f ,
1367+ buttonMin.y + (buttonHeight - iconHeight) * 0 .5f );
1368+ const ImVec2 iconMax (iconMin.x + iconWidth, iconMin.y + iconHeight);
1369+ ImGuiEx::DrawButtonImage (icon, buttonColN, buttonColH, buttonColP, iconMin, iconMax, ImVec2 (0 .0f , 0 .0f ), ImVec2 (1 .0f , 1 .0f ));
1370+ }
13111371
13121372 if (ImGui::IsItemClicked (ImGuiMouseButton_Left))
13131373 onClick ();
13141374 };
13151375
1316- drawWindowControlButton (" ##minimizeWindow" , EditorResources::MinimizeIcon, buttonsStartX + 4 .0f , [nativeWindow]()
1317- {
1318- if (!nativeWindow)
1319- return ;
1376+ ImGui::SetCursorPos (ImVec2 (minimizeButtonX, buttonY));
1377+ ImGui::InvisibleButton (" ##minimizeWindow" , ImVec2 (buttonWidth, buttonHeight));
1378+ if (EditorResources::MinimizeIcon)
1379+ {
1380+ const float iconHeight = (float )EditorResources::MinimizeIcon->GetHeight ();
1381+ const ImVec2 buttonMin = ImGui::GetItemRectMin ();
1382+ const float padY = (14 .0f - iconHeight) * 0 .5f ;
1383+ const ImVec2 iconMin (
1384+ buttonMin.x + (buttonWidth - iconWidth) * 0 .5f ,
1385+ buttonMin.y + (buttonHeight - 14 .0f ) * 0 .5f );
1386+ const ImVec2 iconMax (iconMin.x + iconWidth, iconMin.y + 14 .0f );
1387+ ImGuiEx::DrawButtonImage (EditorResources::MinimizeIcon, buttonColN, buttonColH, buttonColP,
1388+ ImGuiEx::RectExpanded (ImRect (iconMin, iconMax), 0 .0f , -padY));
1389+ }
1390+ if (ImGui::IsItemClicked (ImGuiMouseButton_Left))
1391+ {
1392+ if (nativeWindow)
13201393 Application::Get ().QueueEvent ([nativeWindow]() { glfwIconifyWindow (nativeWindow); });
1321- });
1394+ }
13221395
1323- drawWindowControlButton (" ##maximizeRestoreWindow" , isMaximized ? EditorResources::RestoreIcon : EditorResources::MaximizeIcon, buttonsStartX + 42 . 0f , [nativeWindow, isMaximized]()
1396+ drawWindowControlButton (" ##maximizeRestoreWindow" , isMaximized ? EditorResources::RestoreIcon : EditorResources::MaximizeIcon, maximizeButtonX , [nativeWindow, isMaximized]()
13241397 {
13251398 if (!nativeWindow)
13261399 return ;
@@ -1329,13 +1402,16 @@ namespace Lux {
13291402 if (isMaximized)
13301403 glfwRestoreWindow (nativeWindow);
13311404 else
1332- glfwMaximizeWindow (nativeWindow );
1405+ Application::Get (). GetWindow (). Maximize ( );
13331406 });
13341407 });
13351408
1336- drawWindowControlButton (" ##closeWindow" , EditorResources::CloseIcon, buttonsStartX + 80 . 0f , []()
1409+ drawWindowControlButton (" ##closeWindow" , EditorResources::CloseIcon, closeButtonX , []()
13371410 {
1338- Application::Get ().DispatchEvent <WindowCloseEvent, true >();
1411+ Application::Get ().QueueEvent ([]()
1412+ {
1413+ Application::Get ().DispatchEvent <WindowCloseEvent, true >();
1414+ });
13391415 });
13401416 }
13411417
0 commit comments