diff --git a/Source/MainWindow.cpp b/Source/MainWindow.cpp index 6cad4ffd..ca1ecfb9 100644 --- a/Source/MainWindow.cpp +++ b/Source/MainWindow.cpp @@ -11,26 +11,26 @@ #include "Main.h" MainWindow::MainWindow(ComponentBoundsConstrainer* constrainerIn) : DocumentWindow("Lumatone Editor", - TerpstraSysExApplication::getApp().getLookAndFeel().findColour(LumatoneEditorColourIDs::MediumBackground), - DocumentWindow::minimiseButton + DocumentWindow::closeButton), - constrainer(constrainerIn) + TerpstraSysExApplication::getApp().getLookAndFeel().findColour(LumatoneEditorColourIDs::MediumBackground), + DocumentWindow::minimiseButton + DocumentWindow::closeButton), + constrainer(constrainerIn) { - setContentOwned(new MainContentComponent(), true); + setContentOwned(new MainContentComponent(), true); - setResizable(true, true); + setResizable(true, true); #if JUCE_ANDROID - setFullScreen(true); + setFullScreen(true); #else // Window aspect ratio constrainer->setFixedAspectRatio(DEFAULTMAINWINDOWASPECT); constrainer->setMinimumSize(800, round(800 / DEFAULTMAINWINDOWASPECT)); - setConstrainer(constrainer); - updateMaxHeight(); + setConstrainer(constrainer); + updateBounds(); startTimer(2000); #endif - setLookAndFeel(&TerpstraSysExApplication::getApp().getLookAndFeel()); + setLookAndFeel(&TerpstraSysExApplication::getApp().getLookAndFeel()); } MainWindow::~MainWindow() @@ -41,15 +41,15 @@ MainWindow::~MainWindow() void MainWindow::closeButtonPressed() { - // This is called when the user tries to close this window. Here, we'll just - // ask the app to quit when this happens, but you can change this to do - // whatever you need. - JUCEApplication::getInstance()->systemRequestedQuit(); + // This is called when the user tries to close this window. Here, we'll just + // ask the app to quit when this happens, but you can change this to do + // whatever you need. + JUCEApplication::getInstance()->systemRequestedQuit(); } BorderSize MainWindow::getBorderThickness() { - return BorderSize (1); + return BorderSize (1); } bool MainWindow::isLargerThanCurrentScreen() const @@ -60,60 +60,88 @@ bool MainWindow::isLargerThanCurrentScreen() const return false; // shouldn't happen } -bool MainWindow::isHandleOutOfBounds() const +bool MainWindow::isOutOfVerticalBounds() const { - return getScreenY() < 0; + return getScreenY() < 0 + || getScreenY() >= (maxWindowHeight - verticalBoundsThreshold); +} + +bool MainWindow::isOutOfHorizontalBounds() const +{ + return getScreenBounds().getRight() < horizontalBoundsThreshold + || getScreenX() >= (maxWindowWidth - horizontalBoundsThreshold); } void MainWindow::saveStateToPropertiesFile(PropertiesFile* propertiesFile) { - // Save state of main window - propertiesFile->setValue("MainWindowState", getWindowStateAsString()); - ((MainContentComponent*)(getContentComponent()))->saveStateToPropertiesFile(propertiesFile); + // Save state of main window + propertiesFile->setValue("MainWindowState", getWindowStateAsString()); + ((MainContentComponent*)(getContentComponent()))->saveStateToPropertiesFile(propertiesFile); } void MainWindow::restoreStateFromPropertiesFile(PropertiesFile* propertiesFile) { - bool useSavedState = false;//restoreWindowStateFromString(propertiesFile->getValue("MainWindowState")); + bool useSavedState = restoreWindowStateFromString(propertiesFile->getValue("MainWindowState")); - fixWindowPositionAndSize(!useSavedState); + fixWindowPositionAndSize(!useSavedState); - setVisible(true); + setVisible(true); - ((MainContentComponent*)(getContentComponent()))->restoreStateFromPropertiesFile(propertiesFile); + ((MainContentComponent*)(getContentComponent()))->restoreStateFromPropertiesFile(propertiesFile); } -void MainWindow::updateMaxHeight() +void MainWindow::updateBounds() { auto thisDisplay = Desktop::getInstance().getDisplays().getDisplayForRect(getScreenBounds()); if (thisDisplay != nullptr) { + int screenWidth = thisDisplay->userArea.getWidth(); int screenHeight = thisDisplay->userArea.getHeight(); - if (screenHeight != maxWindowHeight) + if (screenWidth != maxWindowWidth || screenHeight != maxWindowHeight) { + maxWindowWidth = screenWidth; maxWindowHeight = screenHeight; constrainer->setMaximumHeight(maxWindowHeight); fixWindowPositionAndSize(); + return; } } + + if (isOutOfVerticalBounds()) + fixWindowPositionAndSize(); } void MainWindow::fixWindowPositionAndSize(bool setToDefault) { - if (setToDefault || isLargerThanCurrentScreen()) - { - // Default window state - setSize(DEFAULTMAINWINDOWWIDTH, DEFAULTMAINWINDOWHEIGHT); - } - else if (isHandleOutOfBounds()) - { - setTopLeftPosition(getScreenX(), 0); - } + if (setToDefault || isLargerThanCurrentScreen()) + { + // Default window state + setSize(DEFAULTMAINWINDOWWIDTH, DEFAULTMAINWINDOWHEIGHT); + return; + } + + if (isOutOfVerticalBounds()) + { + int correctedY = (getScreenY() < 0) ? 0 + : maxWindowHeight - verticalBoundsThreshold; + setTopLeftPosition(getScreenX(), correctedY); + } + + if (isOutOfHorizontalBounds()) + { + auto bounds = getScreenBounds(); + int correctedX = (bounds.getX() < 0) ? horizontalBoundsThreshold - maxWindowWidth + : maxWindowWidth - horizontalBoundsThreshold; + setTopLeftPosition(correctedX, getScreenY()); + } } void MainWindow::timerCallback() { - updateMaxHeight(); + // Set threshold to be a quarter of the window handle height + verticalBoundsThreshold = round(getTitleBarHeight() * 0.25f); + + updateBounds(); } diff --git a/Source/MainWindow.h b/Source/MainWindow.h index 14c24056..35fe7e52 100644 --- a/Source/MainWindow.h +++ b/Source/MainWindow.h @@ -18,43 +18,50 @@ our MainContentComponent class. class MainWindow : public DocumentWindow, public Timer { public: - MainWindow(ComponentBoundsConstrainer* constrainerIn); + MainWindow(ComponentBoundsConstrainer* constrainerIn); virtual ~MainWindow(); - void closeButtonPressed() override; + void closeButtonPressed() override; - BorderSize getBorderThickness() override; + BorderSize getBorderThickness() override; - /* Note: Be careful if you override any DocumentWindow methods - the base - class uses a lot of them, so by overriding you might break its functionality. - It's best to do all your work in your content component instead, but if - you really have to override any DocumentWindow methods, make sure your - subclass also calls the superclass's method. - */ + /* Note: Be careful if you override any DocumentWindow methods - the base + class uses a lot of them, so by overriding you might break its functionality. + It's best to do all your work in your content component instead, but if + you really have to override any DocumentWindow methods, make sure your + subclass also calls the superclass's method. + */ - // Returns true if the height is larger than current screen - bool isLargerThanCurrentScreen() const; + // Returns true if the height is larger than current screen + bool isLargerThanCurrentScreen() const; - // Returns true if the top of the window is out of the screen - bool isHandleOutOfBounds() const; + // Returns true if the top of the window is out of the screen + bool isOutOfVerticalBounds() const; - void saveStateToPropertiesFile(PropertiesFile* propertiesFile); + // Returns true if left side of window is too far right, or if right side of window is too far left + bool isOutOfHorizontalBounds() const; - void restoreStateFromPropertiesFile(PropertiesFile* propertiesFile); + void saveStateToPropertiesFile(PropertiesFile* propertiesFile); + + void restoreStateFromPropertiesFile(PropertiesFile* propertiesFile); // Checks size of current display and updates constraint - void updateMaxHeight(); + void updateBounds(); - void fixWindowPositionAndSize(bool setToDefault=false); + void fixWindowPositionAndSize(bool setToDefault=false); void timerCallback() override; private: - ComponentBoundsConstrainer* constrainer; + ComponentBoundsConstrainer* constrainer; + int maxWindowWidth = 0; int maxWindowHeight = 0; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow) + int horizontalBoundsThreshold = 10; + int verticalBoundsThreshold = 10; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow) };