Skip to content

Commit 6143f9c

Browse files
authored
Add modal dialog helper class (#4558)
* WIP: Add modal dialog helper class * Update comments * Fix build * Fix VS project * Migrate existing modal dialogs to the new class * Fix styling * Add files to VS filters
1 parent 26e8812 commit 6143f9c

File tree

9 files changed

+244
-168
lines changed

9 files changed

+244
-168
lines changed

source/MRCommonPlugins/ViewerButtons/MRAddCustomTheme.cpp

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "MRViewer/MRViewerInstance.h"
66
#include "MRMesh/MRSceneColors.h"
77
#include "MRViewer/ImGuiHelpers.h"
8+
#include "MRViewer/MRModalDialog.h"
89
#include "MRMesh/MRSerializer.h"
910
#include "MRMesh/MRObjectsAccess.h"
1011
#include "MRMesh/MRSceneRoot.h"
@@ -103,38 +104,12 @@ void AddCustomThemePlugin::drawDialog( float menuScaling, ImGuiContext* )
103104
"Please do not any of these symbols: \? * / \\ \" < >", menuScaling );
104105
}
105106

106-
const ImVec2 windowSize{ MR::cModalWindowWidth * menuScaling, -1 };
107-
ImGui::SetNextWindowSize( windowSize, ImGuiCond_Always );
108-
ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, { cModalWindowPaddingX * menuScaling, cModalWindowPaddingY * menuScaling } );
109-
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, { 2.0f * cDefaultItemSpacing * menuScaling, 3.0f * cDefaultItemSpacing * menuScaling } );
110-
if ( ImGui::BeginModalNoAnimation( "File already exists", nullptr,
111-
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar ) )
107+
ModalDialog modalDialog( "File already exists", {
108+
.headline = "File already exists",
109+
.text = "Theme with name " + themeName_ + " already exists, override it?",
110+
} );
111+
if ( modalDialog.beginPopup( menuScaling ) )
112112
{
113-
auto headerFont = RibbonFontManager::getFontByTypeStatic( RibbonFontManager::FontType::Headline );
114-
if ( headerFont )
115-
ImGui::PushFont( headerFont );
116-
117-
const auto headerWidth = ImGui::CalcTextSize( "File already exists" ).x;
118-
119-
ImGui::SetCursorPosX( ( windowSize.x - headerWidth ) * 0.5f );
120-
ImGui::Text( "File already exists" );
121-
122-
if ( headerFont )
123-
ImGui::PopFont();
124-
125-
std::string text = "Theme with name " + themeName_ + " already exists, override it?";
126-
const float textWidth = ImGui::CalcTextSize( text.c_str() ).x;
127-
128-
if ( textWidth < windowSize.x )
129-
{
130-
ImGui::SetCursorPosX( ( windowSize.x - textWidth ) * 0.5f );
131-
ImGui::Text( "%s", text.c_str() );
132-
}
133-
else
134-
{
135-
ImGui::TextWrapped( "%s", text.c_str() );
136-
}
137-
138113
const auto style = ImGui::GetStyle();
139114
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, { style.FramePadding.x, cButtonPadding * menuScaling } );
140115

@@ -156,9 +131,9 @@ void AddCustomThemePlugin::drawDialog( float menuScaling, ImGuiContext* )
156131
}
157132

158133
ImGui::PopStyleVar();
159-
ImGui::EndPopup();
134+
135+
modalDialog.endPopup( menuScaling );
160136
}
161-
ImGui::PopStyleVar( 2 );
162137

163138
ImGui::PopItemWidth();
164139
ImGui::EndCustomStatePlugin();

source/MRViewer/ImGuiHelpers.cpp

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "MRUIStyle.h"
1717
#include "MRDirectionWidget.h"
1818
#include "MRAppendHistory.h"
19+
#include "MRModalDialog.h"
1920
#include "MRMesh/MRColor.h"
2021
#include "MRMesh/MRBitSet.h"
2122
#include "MRMesh/MRStringConvert.h"
@@ -1326,29 +1327,15 @@ PaletteChanges Palette(
13261327
ImGui::SameLine();
13271328
ImGui::PopStyleVar();
13281329

1329-
ImVec2 windowSize( cModalWindowWidth * menuScaling, 0.0f );
1330-
ImGui::SetNextWindowSize( windowSize, ImGuiCond_Always );
1331-
ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, { cModalWindowPaddingX * menuScaling, cModalWindowPaddingY * menuScaling } );
1332-
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, { cDefaultItemSpacing * menuScaling, 3.0f * cDefaultItemSpacing * menuScaling } );
1333-
ImGui::PushStyleVar( ImGuiStyleVar_ItemInnerSpacing, { 2.0f * cDefaultInnerSpacing * menuScaling, cDefaultInnerSpacing * menuScaling } );
1334-
if ( ImGui::BeginModalNoAnimation( popupName.c_str(), nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar ) )
1330+
ModalDialog saveDialog( popupName.c_str(), {
1331+
.headline = "Save Palette",
1332+
} );
1333+
if ( saveDialog.beginPopup( menuScaling ) )
13351334
{
1336-
auto headerFont = RibbonFontManager::getFontByTypeStatic( RibbonFontManager::FontType::Headline );
1337-
if ( headerFont )
1338-
PushFont( headerFont );
1339-
1340-
const auto headerWidth = CalcTextSize( "Save Palette" ).x;
1341-
1342-
ImGui::SetCursorPosX( ( windowSize.x - headerWidth ) * 0.5f );
1343-
Text( "Save Palette" );
1344-
1345-
if ( headerFont )
1346-
PopFont();
1347-
13481335
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, { style.FramePadding.x, cInputPadding * menuScaling } );
13491336
static std::string currentPaletteName;
13501337

1351-
ImGui::SetNextItemWidth( windowSize.x - 2 * style.WindowPadding.x - style.ItemInnerSpacing.x - CalcTextSize( "Palette Name" ).x );
1338+
ImGui::SetNextItemWidth( saveDialog.windowWidth() - 2 * style.WindowPadding.x - style.ItemInnerSpacing.x - CalcTextSize( "Palette Name" ).x );
13521339
UI::inputText( "Palette Name", currentPaletteName );
13531340
ImGui::PopStyleVar();
13541341

@@ -1386,10 +1373,11 @@ PaletteChanges Palette(
13861373
}
13871374

13881375
bool closeTopPopup = false;
1389-
if ( ImGui::BeginModalNoAnimation( "Palette already exists##PaletteHelper", nullptr,
1390-
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar ) )
1376+
ModalDialog warningPopup( "Palette already exists##PaletteHelper", {
1377+
.text = "Palette preset with this name already exists, override?",
1378+
} );
1379+
if ( warningPopup.beginPopup( menuScaling ) )
13911380
{
1392-
ImGui::Text( "Palette preset with this name already exists, override?" );
13931381
auto w = GetContentRegionAvail().x;
13941382
auto p = GetStyle().FramePadding.x;
13951383
if ( UI::buttonCommonSize( "Yes", Vector2f( ( w - p ) * 0.5f, 0 ), ImGuiKey_Enter ) )
@@ -1411,22 +1399,21 @@ PaletteChanges Palette(
14111399
{
14121400
ImGui::CloseCurrentPopup();
14131401
}
1414-
ImGui::EndPopup();
1402+
warningPopup.endPopup( menuScaling );
14151403
}
14161404
if ( closeTopPopup )
14171405
ImGui::CloseCurrentPopup();
14181406

14191407
ImGui::SameLine();
14201408

1421-
ImGui::SetCursorPosX( windowSize.x - btnWidth - style.WindowPadding.x );
1409+
ImGui::SetCursorPosX( saveDialog.windowWidth() - btnWidth - style.WindowPadding.x );
14221410
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, { style.FramePadding.x, cButtonPadding * menuScaling } );
14231411
if ( UI::buttonCommonSize( "Cancel", Vector2f( btnWidth, 0 ), ImGuiKey_Escape ) )
14241412
ImGui::CloseCurrentPopup();
14251413
ImGui::PopStyleVar();
14261414

1427-
ImGui::EndPopup();
1415+
saveDialog.endPopup( menuScaling );
14281416
}
1429-
PopStyleVar( 3 );
14301417

14311418
if ( UI::button( "Reset Palette", Vector2f( widthButton, 0 ) ) )
14321419
{

source/MRViewer/ImGuiMenu.cpp

Lines changed: 19 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "MRPch/MRSpdlog.h"
4444
#include "MRProgressBar.h"
4545
#include "MRFileDialog.h"
46+
#include "MRModalDialog.h"
4647

4748
#include <MRMesh/MRMesh.h>
4849
#include <MRMesh/MRObjectLoad.h>
@@ -834,26 +835,12 @@ void ImGuiMenu::draw_helpers()
834835
}
835836

836837
const auto menuScaling = menu_scaling();
837-
ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, { cModalWindowPaddingX * menuScaling, cModalWindowPaddingY * menuScaling } );
838-
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, { cDefaultItemSpacing * menuScaling, 3.0f * cDefaultItemSpacing * menuScaling } );
839-
ImGui::PushStyleVar( ImGuiStyleVar_ItemInnerSpacing, { 2.0f * cDefaultInnerSpacing * menuScaling, cDefaultInnerSpacing * menuScaling } );
840-
841-
ImVec2 windowSize( cModalWindowWidth * menuScaling, 0.0f );
842-
ImGui::SetNextWindowSize( windowSize, ImGuiCond_Always );
843-
844-
if ( ImGui::BeginModalNoAnimation( "Rename object", nullptr,
845-
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar ) )
838+
ModalDialog renameDialog( "Rename object", {
839+
.headline = "Rename Object",
840+
.closeOnClickOutside = true,
841+
} );
842+
if ( renameDialog.beginPopup( menuScaling ) )
846843
{
847-
auto headerFont = RibbonFontManager::getFontByTypeStatic( RibbonFontManager::FontType::Headline );
848-
if ( headerFont )
849-
ImGui::PushFont( headerFont );
850-
851-
ImGui::SetCursorPosX( ( windowSize.x - ImGui::CalcTextSize( "Rename Object" ).x ) * 0.5f );
852-
ImGui::Text( "Rename Object" );
853-
854-
if ( headerFont )
855-
ImGui::PopFont();
856-
857844
const auto& obj = SceneCache::getAllObjects<Object, ObjectSelectivityType::Selected>().front();
858845
if ( !obj )
859846
{
@@ -864,7 +851,7 @@ void ImGuiMenu::draw_helpers()
864851

865852
const auto& style = ImGui::GetStyle();
866853
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, { style.FramePadding.x, cInputPadding * menuScaling } );
867-
ImGui::SetNextItemWidth( windowSize.x - 2 * style.WindowPadding.x - style.ItemInnerSpacing.x - ImGui::CalcTextSize( "Name" ).x );
854+
ImGui::SetNextItemWidth( renameDialog.windowWidth() - 2 * style.WindowPadding.x - style.ItemInnerSpacing.x - ImGui::CalcTextSize( "Name" ).x );
868855
UI::inputText( "Name", popUpRenameBuffer_, ImGuiInputTextFlags_AutoSelectAll );
869856
ImGui::PopStyleVar();
870857

@@ -877,20 +864,15 @@ void ImGuiMenu::draw_helpers()
877864
ImGui::CloseCurrentPopup();
878865
}
879866
ImGui::SameLine();
880-
ImGui::SetCursorPosX( windowSize.x - btnWidth - style.WindowPadding.x );
867+
ImGui::SetCursorPosX( renameDialog.windowWidth() - btnWidth - style.WindowPadding.x );
881868
if ( UI::button( "Cancel", Vector2f( btnWidth, 0 ), ImGuiKey_Escape ) )
882869
{
883870
ImGui::CloseCurrentPopup();
884871
}
885872
ImGui::PopStyleVar();
886-
if ( ImGui::IsMouseClicked( 0 ) && !( ImGui::IsAnyItemHovered() || ImGui::IsWindowHovered( ImGuiHoveredFlags_AnyWindow ) ) )
887-
{
888-
ImGui::CloseCurrentPopup();
889-
}
890873

891-
ImGui::EndPopup();
874+
renameDialog.endPopup( menuScaling );
892875
}
893-
ImGui::PopStyleVar( 3 );
894876

895877
drawModalMessage_();
896878
}
@@ -960,52 +942,27 @@ void ImGuiMenu::drawModalMessage_()
960942
}
961943

962944
const auto menuScaling = menu_scaling();
963-
const ImVec2 errorWindowSize{ MR::cModalWindowWidth * menuScaling, -1 };
964-
ImGui::SetNextWindowSize( errorWindowSize, ImGuiCond_Always );
965-
ImGui::PushStyleVar( ImGuiStyleVar_WindowPadding, { cModalWindowPaddingX * menuScaling, cModalWindowPaddingY * menuScaling } );
966-
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, { 2.0f * cDefaultItemSpacing * menuScaling, 3.0f * cDefaultItemSpacing * menuScaling } );
967-
if ( ImGui::BeginModalNoAnimation( titleImGui.c_str(), nullptr,
968-
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar ) )
945+
ModalDialog modal( titleImGui, {
946+
.headline = title,
947+
.text = storedModalMessage_,
948+
.closeOnClickOutside = true,
949+
} );
950+
if ( modal.beginPopup( menuScaling ) )
969951
{
970-
auto headerFont = RibbonFontManager::getFontByTypeStatic( RibbonFontManager::FontType::Headline );
971-
if ( headerFont )
972-
ImGui::PushFont( headerFont );
973-
974-
const auto headerWidth = ImGui::CalcTextSize( title.c_str() ).x;
975-
976-
ImGui::SetCursorPosX( ( errorWindowSize.x - headerWidth ) * 0.5f );
977-
ImGui::Text( "%s", title.c_str());
978-
979-
if ( headerFont )
980-
ImGui::PopFont();
981-
982-
const float textWidth = ImGui::CalcTextSize( storedModalMessage_.c_str() ).x;
983-
984-
if ( textWidth + ImGui::GetStyle().WindowPadding.x * 2.0f < errorWindowSize.x )
985-
{
986-
ImGui::SetCursorPosX( ( errorWindowSize.x - textWidth ) * 0.5f );
987-
ImGui::Text( "%s", storedModalMessage_.c_str() );
988-
}
989-
else
990-
{
991-
ImGui::TextWrapped( "%s", storedModalMessage_.c_str() );
992-
}
993952
const auto style = ImGui::GetStyle();
994953
ImGui::PushStyleVar( ImGuiStyleVar_FramePadding, { style.FramePadding.x, cButtonPadding * menuScaling } );
995-
if ( UI::button( "Okay", Vector2f( -1, 0 ) ) || ImGui::IsKeyPressed( ImGuiKey_Enter ) ||
996-
( ImGui::IsMouseClicked( 0 ) && !ImGui::IsWindowAppearing() && !( ImGui::IsAnyItemHovered() || ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow) ) ) )
997-
{
954+
if ( UI::button( "Okay", Vector2f( -1, 0 ), ImGuiKey_Enter ) )
998955
ImGui::CloseCurrentPopup();
999-
}
1000956
ImGui::PopStyleVar();
1001-
ImGui::EndPopup();
957+
958+
modal.endPopup( menuScaling );
1002959
needModalBgChange_ = true;
1003960
}
1004961
else
1005962
{
1006963
needModalBgChange_ = false;
1007964
}
1008-
ImGui::PopStyleVar( 2 );
965+
1009966
ImGui::PopStyleColor();
1010967
}
1011968

0 commit comments

Comments
 (0)