Skip to content

Commit 2029055

Browse files
authored
Palette: added saving / loading window position and moving it to a free space (#4982)
* added saving / loading window position and moving it to a free space * fix * added separated method to beginning window * added struct for parameters
1 parent 094c473 commit 2029055

File tree

3 files changed

+87
-25
lines changed

3 files changed

+87
-25
lines changed

source/MRViewer/ImGuiHelpers.cpp

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -551,32 +551,23 @@ float GetTitleBarHeght( float menuScaling )
551551
return 2 * MR::cRibbonItemInterval * menuScaling + ImGui::GetTextLineHeight() + 2 * ImGui::GetStyle().WindowBorderSize * menuScaling;
552552
}
553553

554-
bool BeginCustomStatePlugin( const char* label, bool* open, const CustomStatePluginWindowParameters& params )
554+
std::pair<ImVec2, bool> LoadSavedWindowPos( const char* label, ImGuiWindow* window, float width, const ImVec2* position /*= nullptr*/ )
555555
{
556-
const auto& style = ImGui::GetStyle();
557-
558-
const float borderSize = style.WindowBorderSize * params.menuScaling;
559-
const float titleBarHeight = GetTitleBarHeght( params.menuScaling );
560-
auto height = params.height;
561-
if ( params.collapsed && *params.collapsed )
562-
height = titleBarHeight;
563-
564-
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, ImVec2( 12 * params.menuScaling, 8 * params.menuScaling ) );
556+
bool haveSavedWindowPos = false;
557+
ImVec2 initialWindowPos;
565558

566-
ImGuiWindow* window = FindWindowByName( label );
567559
auto menu = ImGuiMenu::instance();
568-
ImVec2 initialWindowPos;
569-
bool haveSavedWindowPos = false;
570560
bool windowIsInactive = window && !window->WasActive;
561+
571562
if ( !window || windowIsInactive )
572563
{
573-
auto ribMenu = std::dynamic_pointer_cast<MR::RibbonMenu>( menu );
574-
float xPos = GetIO().DisplaySize.x - params.width;
564+
auto ribMenu = std::dynamic_pointer_cast< MR::RibbonMenu >( menu );
565+
float xPos = GetIO().DisplaySize.x - width;
575566
float yPos = 0.0f;
576-
if ( params.position )
567+
if ( position )
577568
{
578-
xPos = params.position->x;
579-
yPos = params.position->y;
569+
xPos = position->x;
570+
yPos = position->y;
580571
}
581572
else if ( ribMenu )
582573
yPos = ( ribMenu->getTopPanelOpenedHeight() - 1.0f ) * menu->menu_scaling();
@@ -600,7 +591,46 @@ bool BeginCustomStatePlugin( const char* label, bool* open, const CustomStatePlu
600591
initialWindowPos = ImVec2( xPos, yPos );
601592
}
602593
}
594+
return { initialWindowPos, haveSavedWindowPos };
595+
}
603596

597+
void SaveWindowPosition( const char* label, ImGuiWindow* window )
598+
{
599+
if ( window )
600+
{
601+
auto& config = Config::instance();
602+
auto dpJson = config.getJsonValue( "DialogPositions" );
603+
serializeToJson( Vector2i{ int( window->Pos.x ), int( window->Pos.y ) }, dpJson[label] );
604+
config.setJsonValue( "DialogPositions", dpJson );
605+
}
606+
}
607+
608+
bool BeginSavedWindowPos( const std::string& name, bool* open, const SavedWindowPosParams& params )
609+
{
610+
ImGuiWindow* window = ImGui::FindWindowByName( name.c_str() );
611+
auto [initialWindowPos, haveSavedWindowPos] = LoadSavedWindowPos( name.c_str(), window, params.size.y, params.pos );
612+
UI::getDefaultWindowRectAllocator().setFreeNextWindowPos( name.c_str(), initialWindowPos, haveSavedWindowPos ? ImGuiCond_FirstUseEver : ImGuiCond_Appearing, ImVec2( 0, 0 ) );
613+
ImGui::SetNextWindowSize( params.size, ImGuiCond_Appearing );
614+
const bool res = Begin( name.c_str(), open, params.flags );
615+
SaveWindowPosition( name.c_str(), window);
616+
return res;
617+
}
618+
619+
bool BeginCustomStatePlugin( const char* label, bool* open, const CustomStatePluginWindowParameters& params )
620+
{
621+
const auto& style = ImGui::GetStyle();
622+
623+
const float borderSize = style.WindowBorderSize * params.menuScaling;
624+
const float titleBarHeight = GetTitleBarHeght( params.menuScaling );
625+
auto height = params.height;
626+
if ( params.collapsed && *params.collapsed )
627+
height = titleBarHeight;
628+
629+
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, ImVec2( 12 * params.menuScaling, 8 * params.menuScaling ) );
630+
631+
ImGuiWindow* window = FindWindowByName( label );
632+
auto menu = ImGuiMenu::instance();
633+
auto [initialWindowPos, haveSavedWindowPos] = LoadSavedWindowPos( label, params.width, params.position );
604634
UI::getDefaultWindowRectAllocator().setFreeNextWindowPos( label, initialWindowPos, haveSavedWindowPos ? ImGuiCond_FirstUseEver : ImGuiCond_Appearing, haveSavedWindowPos ? ImVec2( 0, 0 ) : params.pivot );
605635

606636
if ( params.changedSize )

source/MRViewer/ImGuiHelpers.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,43 @@ struct CustomStatePluginWindowParameters
205205
/// for a value pivot = ( 0.0f, 1.0f )
206206
MRVIEWER_API ImVec2 GetDownPosition( const float width );
207207

208-
// Calculate and return the height of the window title
208+
/// Calculate and return the height of the window title
209209
MRVIEWER_API float GetTitleBarHeght( float menuScaling );
210+
211+
/// Load saved window position, if possible
212+
/// \details if can't load - get \p position (if setted) or default (upper-right viewport corner)
213+
/// see also \ref SaveWindowPosition
214+
/// \param label window label
215+
/// \param width window width
216+
/// \param position (optional) preliminary window position
217+
/// \return pair of the final position of the window and flag whether the position was loaded
218+
MRVIEWER_API std::pair<ImVec2, bool> LoadSavedWindowPos( const char* label, ImGuiWindow* window, float width, const ImVec2* position = nullptr );
219+
inline std::pair<ImVec2, bool> LoadSavedWindowPos( const char* label, float width, const ImVec2* position = nullptr )
220+
{
221+
return LoadSavedWindowPos( label, FindWindowByName( label ), width, position );
222+
}
223+
/// Save window position
224+
/// \details saved only if window exist
225+
/// see also \ref LoadSavedWindowPos
226+
MRVIEWER_API void SaveWindowPosition( const char* label, ImGuiWindow* window );
227+
inline void SaveWindowPosition( const char* label )
228+
{
229+
SaveWindowPosition( label, FindWindowByName( label ) );
230+
}
231+
232+
/// Parameters drawing classic ImGui::Begin with loading / saving window position
233+
struct SavedWindowPosParams
234+
{
235+
/// window size
236+
ImVec2 size = { -1, -1 };
237+
/// (optional) preliminary window position
238+
const ImVec2* pos = 0;
239+
ImGuiWindowFlags flags = 0;
240+
};
241+
/// Same as ImGui::Begin, but with loading and saving the window position
242+
/// \details see also \ref LoadSavedWindowPos and \ref SaveWindowPosition
243+
MRVIEWER_API bool BeginSavedWindowPos( const std::string& name, bool* open, const SavedWindowPosParams& params );
244+
210245
/// begin state plugin window with custom style. if you use this function, you must call EndCustomStatePlugin to close the plugin correctly.
211246
/// the flags ImGuiWindowFlags_NoScrollbar and ImGuiWindow_NoScrollingWithMouse are forced in the function.
212247
MRVIEWER_API bool BeginCustomStatePlugin( const char* label, bool* open, const CustomStatePluginWindowParameters& params = {} );

source/MRViewer/MRPalette.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include "MRViewer/MRViewer.h"
66
#include "imgui_internal.h"
77
#include "MRViewport.h"
8+
#include "MRUIRectAllocator.h"
9+
#include "MRMesh/MRConfig.h"
810
#include "MRMesh/MRSerializer.h"
911
#include "MRMesh/MRSceneColors.h"
1012
#include "MRMesh/MRSystem.h"
@@ -376,9 +378,6 @@ void Palette::draw( const std::string& windowName, const ImVec2& pose, const ImV
376378
const auto menu = ImGuiMenu::instance();
377379
const auto& viewportSize = Viewport::get().getViewportRect();
378380

379-
ImGui::SetNextWindowPos( pose, ImGuiCond_Appearing );
380-
ImGui::SetNextWindowSize( size, ImGuiCond_Appearing );
381-
382381
const auto style = getStyleVariables_( menu->menu_scaling() );
383382
const auto maxLabelWidth = getMaxLabelWidth_( onlyTopHalf );
384383
const ImVec2 windowSizeMin {
@@ -421,9 +420,7 @@ void Palette::draw( const std::string& windowName, const ImVec2& pose, const ImV
421420
prevMaxLabelWidth_ = maxLabelWidth;
422421
}
423422
}
424-
425-
ImGui::Begin( windowName.c_str(), &isWindowOpen_,
426-
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBackground );
423+
ImGui::BeginSavedWindowPos( windowName, &isWindowOpen_, { size, &pose, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBackground } );
427424

428425
MR_FINALLY{ ImGui::End(); };
429426

0 commit comments

Comments
 (0)