Skip to content

Save size, position for Main Window, Output Window on program start #630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,23 @@ GlobalSettings::GlobalSettings()
, THEME(CONSTRUCT_TOKEN)
, WINDOW_SIZE(
CONSTRUCT_TOKEN,
"Window Size:",
"Set the size of the window. Takes effect immediately.<br>"
"Window Size/Position:",
"Set the size/position of the window. Takes effect immediately.<br>"
"Use this to easily set the window to a specific resolution for streaming alignment.",
1280, 1000
1280, 1000,
0, 0
)
, LOG_WINDOW_SIZE(
CONSTRUCT_TOKEN,
"Output Window Size/Position:",
"Set the size/position of the output window. Takes effect immediately.<br>",
600, 1200,
0, 0
)
, LOG_WINDOW_STARTUP(
"<b>Open Output Window at startup:</b>",
LockMode::UNLOCK_WHILE_RUNNING,
false
)
, STREAM_HISTORY(CONSTRUCT_TOKEN)
, SLEEP_SUPPRESS(CONSTRUCT_TOKEN)
Expand Down Expand Up @@ -196,6 +209,8 @@ GlobalSettings::GlobalSettings()
PA_ADD_OPTION(TEMP_FOLDER);
PA_ADD_OPTION(THEME);
PA_ADD_OPTION(WINDOW_SIZE);
PA_ADD_OPTION(LOG_WINDOW_SIZE);
PA_ADD_OPTION(LOG_WINDOW_STARTUP);
#if (QT_VERSION_MAJOR == 6) && (QT_VERSION_MINOR >= 8)
if (IS_BETA_VERSION || PreloadSettings::instance().DEVELOPER_MODE){
PA_ADD_OPTION(STREAM_HISTORY);
Expand Down
2 changes: 2 additions & 0 deletions SerialPrograms/Source/CommonFramework/GlobalSettingsPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class GlobalSettings : public BatchOption, private ConfigOption::Listener{

Pimpl<ThemeSelectorOption> THEME;
Pimpl<ResolutionOption> WINDOW_SIZE;
Pimpl<ResolutionOption> LOG_WINDOW_SIZE;
BooleanCheckBoxOption LOG_WINDOW_STARTUP;

Pimpl<StreamHistoryOption> STREAM_HISTORY;
Pimpl<SleepSuppressOptions> SLEEP_SUPPRESS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
#include <QMenuBar>
#include <QDir>
#include "CommonFramework/Globals.h"
#include "CommonFramework/GlobalSettingsPanel.h"
#include "CommonFramework/Windows/DpiScaler.h"
#include "CommonFramework/Windows/WindowTracker.h"
#include "CommonFramework/Windows/MainWindow.h"
#include "CommonFramework/Options/ResolutionOption.h"
#include "FileWindowLogger.h"

//#include <iostream>
Expand Down Expand Up @@ -212,7 +215,9 @@ FileWindowLoggerWindow::FileWindowLoggerWindow(FileWindowLogger& logger, QWidget
if (objectName().isEmpty()){
setObjectName(QString::fromUtf8("TextWindow"));
}
resize(scale_dpi_width(1200), scale_dpi_height(600));
uint32_t width = GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH;
uint32_t height = GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT;
resize(scale_dpi_width(width), scale_dpi_height(height));
m_text = new QTextEdit(this);
m_text->setObjectName(QString::fromUtf8("centralwidget"));
setCentralWidget(m_text);
Expand All @@ -236,6 +241,11 @@ FileWindowLoggerWindow::FileWindowLoggerWindow(FileWindowLogger& logger, QWidget
}
);

GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH.add_listener(*this);
GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT.add_listener(*this);
GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS.add_listener(*this);
GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS.add_listener(*this);

m_logger += *this;
log("================================================================================");
log("<b>Window Startup...</b>");
Expand All @@ -248,13 +258,53 @@ FileWindowLoggerWindow::FileWindowLoggerWindow(FileWindowLogger& logger, QWidget
FileWindowLoggerWindow::~FileWindowLoggerWindow(){
remove_window(*this);
m_logger -= *this;
GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH.remove_listener(*this);
GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT.remove_listener(*this);
GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS.remove_listener(*this);
GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS.remove_listener(*this);
}

void FileWindowLoggerWindow::log(QString msg){
// cout << "FileWindowLoggerWindow::log(): " << msg.toStdString() << endl;
emit signal_log(msg);
}

void FileWindowLoggerWindow::resizeEvent(QResizeEvent* event){
m_pending_resize = true;
GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH.set(width());
GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT.set(height());
m_pending_resize = false;
}

void FileWindowLoggerWindow::moveEvent(QMoveEvent* event){
m_pending_move = true;
GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS.set(x());
GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS.set(y());
m_pending_move = false;
}

void FileWindowLoggerWindow::on_config_value_changed(void* object){
if (object == &GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH || object == &GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT){
QMetaObject::invokeMethod(this, [this]{
if (!m_pending_resize){
resize(
GlobalSettings::instance().LOG_WINDOW_SIZE->WIDTH,
GlobalSettings::instance().LOG_WINDOW_SIZE->HEIGHT
);
}
});
}else if (object == &GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS || object == &GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS){
QMetaObject::invokeMethod(this, [this]{
if (!m_pending_move){
move(
move_x_within_screen_bounds(GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS),
move_y_within_screen_bounds(GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS)
);
}
});
}
}




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <QTextEdit>
#include <QMainWindow>
#include "Common/Cpp/AbstractLogger.h"
#include "Common/Cpp/Options/ConfigOption.h"
//#include "Common/Cpp/LifetimeSanitizer.h"

namespace PokemonAutomation{
Expand Down Expand Up @@ -72,22 +73,27 @@ class FileWindowLogger : public Logger{
};


class FileWindowLoggerWindow : public QMainWindow{
class FileWindowLoggerWindow : public QMainWindow, public ConfigOption::Listener{
Q_OBJECT

public:
FileWindowLoggerWindow(FileWindowLogger& logger, QWidget* parent = nullptr);
virtual ~FileWindowLoggerWindow();

void log(QString msg);
virtual void resizeEvent(QResizeEvent* event) override;
virtual void moveEvent(QMoveEvent* event) override;

signals:
void signal_log(QString msg);

private:
virtual void on_config_value_changed(void* object) override;
FileWindowLogger& m_logger;
QMenuBar* m_menubar;
QTextEdit* m_text;
bool m_pending_resize = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this get used? I see it set, but it's never read.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be honest, I just copy pasted it without understanding its purpose.
I now understand what it's for and I don't need it at this time.

bool m_pending_move = false;
};


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*
*/

#include "CommonFramework/GlobalSettingsPanel.h"
#include "CommonFramework/Windows/DpiScaler.h"
#include "ResolutionOption.h"

Expand All @@ -12,16 +13,21 @@ namespace PokemonAutomation{

ResolutionOption::ResolutionOption(
std::string label, std::string description,
int default_width, int default_height
int default_width, int default_height,
int initial_x_pos, int initial_y_pos
)
: GroupOption(std::move(label), LockMode::LOCK_WHILE_RUNNING)
, DESCRIPTION(std::move(description))
, WIDTH("<b>Width:</b>", LockMode::LOCK_WHILE_RUNNING, scale_dpi_width(default_width))
, HEIGHT("<b>Height:</b>", LockMode::LOCK_WHILE_RUNNING, scale_dpi_height(default_height))
, X_POS("<b>X-position:</b>", LockMode::LOCK_WHILE_RUNNING, scale_dpi_width(initial_x_pos))
, Y_POS("<b>Y-position:</b>", LockMode::LOCK_WHILE_RUNNING, scale_dpi_height(initial_y_pos))
{
PA_ADD_STATIC(DESCRIPTION);
PA_ADD_OPTION(WIDTH);
PA_ADD_OPTION(HEIGHT);
PA_ADD_OPTION(X_POS);
PA_ADD_OPTION(Y_POS);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ class ResolutionOption : public GroupOption{
public:
ResolutionOption(
std::string label, std::string description,
int default_width, int default_height
int default_width, int default_height,
int initial_x_pos, int initial_y_pos
);

StaticTextOption DESCRIPTION;
SimpleIntegerOption<uint32_t> WIDTH;
SimpleIntegerOption<uint32_t> HEIGHT;
SimpleIntegerOption<int32_t> X_POS;
SimpleIntegerOption<int32_t> Y_POS;
};


Expand Down
88 changes: 76 additions & 12 deletions SerialPrograms/Source/CommonFramework/Windows/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@
#include "CommonFramework/Startup/NewVersionCheck.h"
#include "CommonFramework/Options/ResolutionOption.h"
#include "CommonFramework/Options/Environment/ThemeSelectorOption.h"
#include "CommonFramework/Windows/DpiScaler.h"
#include "PanelLists.h"
#include "WindowTracker.h"
#include "ButtonDiagram.h"
#include "MainWindow.h"


//#include <iostream>
//using std::cout;
//using std::endl;
#include <iostream>
using std::cout;
using std::endl;

namespace PokemonAutomation{

Expand All @@ -46,6 +47,16 @@ MainWindow::MainWindow(QWidget* parent)
GlobalSettings::instance().WINDOW_SIZE->WIDTH,
GlobalSettings::instance().WINDOW_SIZE->HEIGHT
);
// move main window to desired position on startup
// auto const screen_geometry = QGuiApplication::primaryScreen()->availableGeometry();
// uint32_t const screen_width = (uint32_t)screen_geometry.width();
// uint32_t const screen_height = (uint32_t)screen_geometry.height();
int32_t x_pos_main = GlobalSettings::instance().WINDOW_SIZE->X_POS;
int32_t y_pos_main = GlobalSettings::instance().WINDOW_SIZE->Y_POS;
int32_t move_x_main = move_x_within_screen_bounds(x_pos_main);
int32_t move_y_main = move_y_within_screen_bounds(y_pos_main);
move(move_x_main, move_y_main);

centralwidget = new QWidget(this);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
setCentralWidget(centralwidget);
Expand Down Expand Up @@ -203,12 +214,27 @@ MainWindow::MainWindow(QWidget* parent)
buttons->addWidget(output);
connect(
output, &QPushButton::clicked,
this, [this](bool){
this, [&](bool){
m_output_window->show();
m_output_window->raise(); // bring the window to front on macOS
m_output_window->activateWindow(); // bring the window to front on Windows
}
);
// get snapshot of the saved initial x/y position, since activating the window seems to change the window coordinates,
// which then causes initial x/y position to change, due to triggering moveEvent().
int32_t x_pos_log = GlobalSettings::instance().LOG_WINDOW_SIZE->X_POS;
int32_t y_pos_log = GlobalSettings::instance().LOG_WINDOW_SIZE->Y_POS;

if (GlobalSettings::instance().LOG_WINDOW_STARTUP){ // show the Output Window on startup
m_output_window->show();
m_output_window->raise(); // bring the window to front on macOS
m_output_window->activateWindow(); // bring the window to front on Windows
}

// move the output window to desired position on startup
int32_t move_x_log = move_x_within_screen_bounds(x_pos_log);
int32_t move_y_log = move_y_within_screen_bounds(y_pos_log);
m_output_window->move(move_x_log, move_y_log);
}
{
QPushButton* settings = new QPushButton("Settings", support_box);
Expand All @@ -234,6 +260,8 @@ MainWindow::MainWindow(QWidget* parent)

GlobalSettings::instance().WINDOW_SIZE->WIDTH.add_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->HEIGHT.add_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->X_POS.add_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->Y_POS.add_listener(*this);
SystemSleepController::instance().add_listener(*this);
// cout << "Done constructing" << endl;
}
Expand All @@ -242,6 +270,24 @@ MainWindow::~MainWindow(){
SystemSleepController::instance().remove_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->WIDTH.remove_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->HEIGHT.remove_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->X_POS.remove_listener(*this);
GlobalSettings::instance().WINDOW_SIZE->Y_POS.remove_listener(*this);
}

int32_t move_x_within_screen_bounds(int32_t x_pos){
auto static const screen_geometry = QGuiApplication::primaryScreen()->availableGeometry();
uint32_t static const screen_width = (uint32_t)screen_geometry.width();
// ensure move_x is greater than 0, but less than screen_width
return scale_dpi_width(std::max(0, std::min(x_pos, (int32_t)(screen_width*0.97))));

}

int32_t move_y_within_screen_bounds(int32_t y_pos){
auto static const screen_geometry = QGuiApplication::primaryScreen()->availableGeometry();
uint32_t const screen_height = (uint32_t)screen_geometry.height();
// ensure move_y is greater than 0, but less than screen_height
return scale_dpi_width(std::max(0, std::min(y_pos, (int32_t)(screen_height*0.97))));

}


Expand All @@ -256,6 +302,13 @@ void MainWindow::resizeEvent(QResizeEvent* event){
m_pending_resize = false;
}

void MainWindow::moveEvent(QMoveEvent* event){
m_pending_move = true;
GlobalSettings::instance().WINDOW_SIZE->X_POS.set(x());
GlobalSettings::instance().WINDOW_SIZE->Y_POS.set(y());
m_pending_move = false;
}

void MainWindow::close_panel() noexcept{
// cout << "close_panel(): enter: " << m_current_panel_widget << endl;
// Must destroy the widget first since it references the instance.
Expand Down Expand Up @@ -342,14 +395,25 @@ void MainWindow::on_idle(){


void MainWindow::on_config_value_changed(void* object){
QMetaObject::invokeMethod(this, [this]{
if (!m_pending_resize){
resize(
GlobalSettings::instance().WINDOW_SIZE->WIDTH,
GlobalSettings::instance().WINDOW_SIZE->HEIGHT
);
}
});
if (object == &GlobalSettings::instance().WINDOW_SIZE->WIDTH || object == &GlobalSettings::instance().WINDOW_SIZE->HEIGHT){
QMetaObject::invokeMethod(this, [this]{
if (!m_pending_resize){
resize(
GlobalSettings::instance().WINDOW_SIZE->WIDTH,
GlobalSettings::instance().WINDOW_SIZE->HEIGHT
);
}
});
}else if (object == &GlobalSettings::instance().WINDOW_SIZE->X_POS || object == &GlobalSettings::instance().WINDOW_SIZE->Y_POS){
QMetaObject::invokeMethod(this, [this]{
if (!m_pending_move){
move(
move_x_within_screen_bounds(GlobalSettings::instance().WINDOW_SIZE->X_POS),
move_y_within_screen_bounds(GlobalSettings::instance().WINDOW_SIZE->Y_POS)
);
}
});
}
}
void MainWindow::sleep_suppress_state_changed(SleepSuppress new_state){
QMetaObject::invokeMethod(this, [=, this]{
Expand Down
8 changes: 7 additions & 1 deletion SerialPrograms/Source/CommonFramework/Windows/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ class MainWindow :
MainWindow(QWidget* parent = nullptr);
~MainWindow();


private:
virtual void closeEvent(QCloseEvent* event) override;
virtual void resizeEvent(QResizeEvent* event) override;
virtual void moveEvent(QMoveEvent* event) override;

void close_panel() noexcept;

Expand Down Expand Up @@ -85,10 +87,14 @@ class MainWindow :
std::unique_ptr<SleepSuppressScope> m_sleep_scope;

bool m_pending_resize = false;
bool m_pending_move = false;
bool m_panel_transition = false;
};


// returns given X value, but bounded by 0 and screen_width
int32_t move_x_within_screen_bounds(int32_t x_pos);
// returns given y value, but bounded by 0 and screen_height
int32_t move_y_within_screen_bounds(int32_t y_pos);


}
Expand Down