Skip to content

Commit a3b7fd1

Browse files
Improve in-game window positioning
1) Remember the window position set by a move and try to restore this position after every resize. 2) If the window is moved to a screen edge save Point::MaxElementValue instead, to make the window "stick" to the edge when resizing.
1 parent a130223 commit a3b7fd1

5 files changed

Lines changed: 65 additions & 28 deletions

File tree

libs/s25main/Settings.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,13 @@ void Settings::LoadIngame()
347347
const auto* iniWindow = static_cast<const libsiedler2::ArchivItem_Ini*>(settingsIngame.find(window.second));
348348
if(!iniWindow)
349349
continue;
350-
windows.persistentSettings[window.first].lastPos.x = iniWindow->getIntValue("pos_x");
351-
windows.persistentSettings[window.first].lastPos.y = iniWindow->getIntValue("pos_y");
352-
windows.persistentSettings[window.first].isOpen = iniWindow->getIntValue("is_open");
353-
windows.persistentSettings[window.first].isMinimized = iniWindow->getValue("is_minimized", false);
350+
auto& settings = windows.persistentSettings[window.first];
351+
const auto lastPos = settings.lastPos =
352+
DrawPoint(iniWindow->getIntValue("pos_x"), iniWindow->getIntValue("pos_y"));
353+
settings.restorePos = DrawPoint(iniWindow->getValue("restore_pos_x", lastPos.x),
354+
iniWindow->getValue("restore_pos_y", lastPos.y));
355+
settings.isOpen = iniWindow->getIntValue("is_open");
356+
settings.isMinimized = iniWindow->getValue("is_minimized", false);
354357
}
355358
} catch(std::runtime_error& e)
356359
{
@@ -500,10 +503,17 @@ void Settings::SaveIngame()
500503
auto* iniWindow = static_cast<libsiedler2::ArchivItem_Ini*>(settingsIngame.find(window.second));
501504
if(!iniWindow)
502505
continue;
503-
iniWindow->setValue("pos_x", windows.persistentSettings[window.first].lastPos.x);
504-
iniWindow->setValue("pos_y", windows.persistentSettings[window.first].lastPos.y);
505-
iniWindow->setValue("is_open", windows.persistentSettings[window.first].isOpen);
506-
iniWindow->setValue("is_minimized", windows.persistentSettings[window.first].isMinimized);
506+
const auto& settings = windows.persistentSettings[window.first];
507+
iniWindow->setValue("pos_x", settings.lastPos.x);
508+
iniWindow->setValue("pos_y", settings.lastPos.y);
509+
if(settings.restorePos != settings.lastPos)
510+
{
511+
// only save if different; defaults to lastPos on load
512+
iniWindow->setValue("restore_pos_x", settings.restorePos.x);
513+
iniWindow->setValue("restore_pos_y", settings.restorePos.y);
514+
}
515+
iniWindow->setValue("is_open", settings.isOpen);
516+
iniWindow->setValue("is_minimized", settings.isMinimized);
507517
}
508518

509519
bfs::path settingsPathIngame = RTTRCONFIG.ExpandPath(s25::resources::ingameOptions);

libs/s25main/Settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ bool checkPort(int port);
2525
struct PersistentWindowSettings
2626
{
2727
DrawPoint lastPos = DrawPoint::Invalid();
28+
DrawPoint restorePos = DrawPoint::Invalid();
2829
bool isOpen = false;
2930
bool isMinimized = false;
3031
};

libs/s25main/ingameWindows/IngameWindow.cpp

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,32 @@ IngameWindow::IngameWindow(unsigned id, const DrawPoint& pos, const Extent& size
5151
// Save to settings that window is open
5252
SaveOpenStatus(true);
5353

54-
// Restore minimized state
55-
if(windowSettings_ && windowSettings_->isMinimized)
54+
if(windowSettings_)
5655
{
57-
isMinimized_ = true;
58-
Extent minimizedSize(GetSize().x, contentOffset.y + contentOffsetEnd.y);
59-
Window::Resize(minimizedSize);
56+
// Restore minimized state
57+
if(windowSettings_ && windowSettings_->isMinimized)
58+
{
59+
isMinimized_ = true;
60+
Extent minimizedSize(GetSize().x, contentOffset.y + contentOffsetEnd.y);
61+
Window::Resize(minimizedSize);
62+
}
63+
// Load restorePos
64+
restorePos_ = windowSettings_->restorePos;
6065
}
6166

6267
// Load last position or center the window
6368
if(pos == posLastOrCenter)
6469
{
6570
if(windowSettings_ && windowSettings_->lastPos.isValid())
66-
SetPos(windowSettings_->lastPos);
71+
SetPos(windowSettings_->lastPos, !restorePos_.isValid());
6772
else
6873
MoveToCenter();
6974
} else if(pos == posCenter)
7075
MoveToCenter();
7176
else if(pos == posAtMouse)
7277
MoveNextToMouse();
78+
else
79+
SetPos(pos); // always call SetPos() to update restorePos
7380
}
7481

7582
void IngameWindow::Resize(const Extent& newSize)
@@ -81,15 +88,23 @@ void IngameWindow::Resize(const Extent& newSize)
8188

8289
void IngameWindow::SetIwSize(const Extent& newSize)
8390
{
91+
// Is the window connecting with the bottom screen edge?
92+
const auto atBottom = (GetPos().y + GetSize().y) >= VIDEODRIVER.GetRenderSize().y;
93+
8494
iwHeight = newSize.y;
8595
Extent wndSize = newSize;
8696
if(isMinimized_)
8797
wndSize.y = 0;
8898
wndSize += contentOffset + contentOffsetEnd;
8999
Window::Resize(wndSize);
90100

91-
// Reset the position to check if parts of the window are out of the visible area
92-
SetPos(GetPos());
101+
// Adjust restorePos if the window was connecting with the bottom screen edge before being minimized
102+
const auto pos = (atBottom && isMinimized_) ? DrawPoint(restorePos_.x, DrawPoint::MaxElementValue) : restorePos_;
103+
104+
// Reset the position
105+
// 1) to check if parts of the window are out of the visible area
106+
// 2) to re-connect the window with the bottom screen edge, if needed
107+
SetPos(pos, false);
93108
}
94109

95110
Extent IngameWindow::GetIwSize() const
@@ -102,24 +117,38 @@ DrawPoint IngameWindow::GetRightBottomBoundary()
102117
return DrawPoint(GetSize() - contentOffsetEnd);
103118
}
104119

105-
void IngameWindow::SetPos(DrawPoint newPos)
120+
void IngameWindow::SetPos(DrawPoint newPos, bool saveRestorePos)
106121
{
107122
const Extent screenSize = VIDEODRIVER.GetRenderSize();
123+
DrawPoint newRestorePos = newPos;
108124
// Too far left or right?
109125
if(newPos.x < 0)
110-
newPos.x = 0;
111-
else if(newPos.x + GetSize().x > screenSize.x)
126+
newRestorePos.x = newPos.x = 0;
127+
else if(newPos.x + GetSize().x >= screenSize.x)
128+
{
112129
newPos.x = screenSize.x - GetSize().x;
130+
newRestorePos.x = DrawPoint::MaxElementValue; // make window stick to the right
131+
}
113132

114133
// Too high or low?
115134
if(newPos.y < 0)
116-
newPos.y = 0;
117-
else if(newPos.y + GetSize().y > screenSize.y)
135+
newRestorePos.y = newPos.y = 0;
136+
else if(newPos.y + GetSize().y >= screenSize.y)
137+
{
118138
newPos.y = screenSize.y - GetSize().y;
139+
newRestorePos.y = DrawPoint::MaxElementValue; // make window stick to the bottom
140+
}
119141

120-
// if possible save the position to settings
142+
if(saveRestorePos)
143+
restorePos_ = newRestorePos;
144+
145+
// if possible save the positions to settings
121146
if(windowSettings_)
147+
{
122148
windowSettings_->lastPos = newPos;
149+
if(saveRestorePos)
150+
windowSettings_->restorePos = newRestorePos;
151+
}
123152

124153
Window::SetPos(newPos);
125154
}

libs/s25main/ingameWindows/IngameWindow.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#pragma once
66

7+
#include "DrawPoint.h"
78
#include "Window.h"
89
#include "helpers/EnumArray.h"
910
#include "gameData/const_gui_ids.h"
@@ -71,7 +72,7 @@ class IngameWindow : public Window
7172
DrawPoint GetRightBottomBoundary();
7273

7374
/// Set the position for the window after adjusting newPos so the window is in the visible area
74-
void SetPos(DrawPoint newPos);
75+
void SetPos(DrawPoint newPos, bool saveRestorePos = true);
7576

7677
/// merkt das Fenster zum Schließen vor.
7778
virtual void Close();
@@ -128,4 +129,5 @@ class IngameWindow : public Window
128129
CloseBehavior closeBehavior_;
129130
helpers::EnumArray<ButtonState, IwButton> buttonStates_;
130131
PersistentWindowSettings* windowSettings_;
132+
DrawPoint restorePos_;
131133
};

libs/s25main/ingameWindows/iwObservate.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,6 @@ void iwObservate::Msg_ButtonClick(const unsigned ctrl_id)
143143
for(unsigned i = 1; i <= 4; ++i)
144144
GetCtrl<ctrlImageButton>(i)->SetPos(
145145
DrawPoint(GetCtrl<ctrlImageButton>(i)->GetPos().x - diff, GetSize().y - 50));
146-
147-
DrawPoint maxPos(VIDEODRIVER.GetRenderSize() - GetSize() - Extent::all(1));
148-
DrawPoint newPos = elMin(maxPos, GetPos());
149-
if(newPos != GetPos())
150-
SetPos(newPos);
151146
}
152147
}
153148

0 commit comments

Comments
 (0)