diff --git a/extras/Projucer/Source/Application/jucer_Application.cpp b/extras/Projucer/Source/Application/jucer_Application.cpp index b1f8aef02b..b4533ed142 100644 --- a/extras/Projucer/Source/Application/jucer_Application.cpp +++ b/extras/Projucer/Source/Application/jucer_Application.cpp @@ -1165,7 +1165,7 @@ void ProjucerApplication::createNewProject() auto* mw = mainWindowList.getOrCreateEmptyWindow(); mw->showStartPage(); - mainWindowList.avoidSuperimposedWindows (mw); + mainWindowList.checkWindowBounds (mw); } void ProjucerApplication::createNewProjectFromClipboard() diff --git a/extras/Projucer/Source/Application/jucer_MainWindow.cpp b/extras/Projucer/Source/Application/jucer_MainWindow.cpp index 68d2ddab0a..7e5c12e547 100644 --- a/extras/Projucer/Source/Application/jucer_MainWindow.cpp +++ b/extras/Projucer/Source/Application/jucer_MainWindow.cpp @@ -50,13 +50,15 @@ MainWindow::MainWindow() setResizable (true, false); centreWithSize (800, 600); - ApplicationCommandManager& commandManager = ProjucerApplication::getCommandManager(); + auto& commandManager = ProjucerApplication::getCommandManager(); - // Register all the app commands.. - commandManager.registerAllCommandsForTarget (this); - commandManager.registerAllCommandsForTarget (getProjectContentComponent()); + auto registerAllAppCommands = [&] + { + commandManager.registerAllCommandsForTarget (this); + commandManager.registerAllCommandsForTarget (getProjectContentComponent()); + }; - // update key mappings.. + auto updateAppKeyMappings = [&] { commandManager.getKeyMappings()->resetToDefaultMappings(); @@ -64,13 +66,13 @@ MainWindow::MainWindow() commandManager.getKeyMappings()->restoreFromXml (*keys); addKeyListener (commandManager.getKeyMappings()); - } + }; + + registerAllAppCommands(); + updateAppKeyMappings(); - // don't want the window to take focus when the title-bar is clicked.. setWantsKeyboardFocus (false); - getLookAndFeel().setColour (ColourSelector::backgroundColourId, Colours::transparentBlack); - projectNameValue.addListener (this); setResizeLimits (600, 500, 32000, 32000); @@ -83,8 +85,6 @@ MainWindow::~MainWindow() #endif removeKeyListener (ProjucerApplication::getCommandManager().getKeyMappings()); - - // save the current size and position to our settings file.. getGlobalProperties().setValue ("lastMainWindowPos", getWindowStateAsString()); clearContentComponent(); @@ -97,7 +97,6 @@ void MainWindow::createProjectContentCompIfNeeded() { clearContentComponent(); setContentOwned (new ProjectContentComponent(), false); - jassert (getProjectContentComponent() != nullptr); } } @@ -119,12 +118,10 @@ void MainWindow::setTitleBarIcon() void MainWindow::makeVisible() { - restoreWindowPosition(); setVisible (true); - addToDesktop(); // (must add before restoring size so that fullscreen will work) + addToDesktop(); restoreWindowPosition(); setTitleBarIcon(); - getContentComponent()->grabKeyboardFocus(); } @@ -138,14 +135,12 @@ void MainWindow::closeButtonPressed() ProjucerApplication::getApp().mainWindowList.closeWindow (this); } -bool MainWindow::closeProject (Project* project, bool askUserToSave) +bool MainWindow::closeCurrentProject (bool askUserToSave) { - jassert (project == currentProject.get() && project != nullptr); - - if (project == nullptr) + if (currentProject == nullptr) return true; - project->getStoredProperties().setValue (getProjectWindowPosName(), getWindowStateAsString()); + currentProject->getStoredProperties().setValue (getProjectWindowPosName(), getWindowStateAsString()); if (auto* pcc = getProjectContentComponent()) { @@ -154,28 +149,24 @@ bool MainWindow::closeProject (Project* project, bool askUserToSave) pcc->hideEditor(); } - if (! ProjucerApplication::getApp().openDocumentManager.closeAllDocumentsUsingProject (*project, askUserToSave)) - return false; - - if (! askUserToSave || (project->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)) + if (ProjucerApplication::getApp().openDocumentManager + .closeAllDocumentsUsingProject (*currentProject, askUserToSave)) { - setProject (nullptr); - return true; + if (! askUserToSave || (currentProject->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk)) + { + setProject (nullptr); + return true; + } } return false; } -bool MainWindow::closeCurrentProject() -{ - return currentProject == nullptr || closeProject (currentProject.get()); -} - void MainWindow::moveProject (File newProjectFileToOpen) { auto openInIDE = currentProject->shouldOpenInIDEAfterSaving(); - closeProject (currentProject.get(), false); + closeCurrentProject (false); openFile (newProjectFileToOpen); if (currentProject != nullptr) @@ -186,21 +177,25 @@ void MainWindow::moveProject (File newProjectFileToOpen) } } -void MainWindow::setProject (Project* newProject) +void MainWindow::setProject (std::unique_ptr newProject) { - createProjectContentCompIfNeeded(); - getProjectContentComponent()->setProject (newProject); - currentProject.reset (newProject); - - if (currentProject != nullptr) - projectNameValue.referTo (currentProject->getProjectValue (Ids::name)); - else + if (newProject == nullptr) + { + getProjectContentComponent()->setProject (nullptr); projectNameValue.referTo (Value()); - if (newProject != nullptr) + currentProject.reset(); + } + else { + currentProject = std::move (newProject); + + createProjectContentCompIfNeeded(); + getProjectContentComponent()->setProject (currentProject.get()); + projectNameValue.referTo (currentProject->getProjectValue (Ids::name)); + if (auto* peer = getPeer()) - peer->setRepresentedFile (newProject->getFile()); + peer->setRepresentedFile (currentProject->getFile()); } ProjucerApplication::getCommandManager().commandStatusChanged(); @@ -232,20 +227,16 @@ bool MainWindow::openFile (const File& file) if (file.hasFileExtension (Project::projectFileExtension)) { - std::unique_ptr newDoc (new Project (file)); - + auto newDoc = std::make_unique (file); auto result = newDoc->loadFrom (file, true); - if (result.wasOk() && closeCurrentProject()) + if (result.wasOk() && closeCurrentProject (true)) { - setProject (newDoc.get()); - newDoc.release()->setChangedFlag (false); + setProject (std::move (newDoc)); + currentProject->setChangedFlag (false); - jassert (getProjectContentComponent() != nullptr); getProjectContentComponent()->reloadLastOpenDocuments(); - - if (auto* p = getProject()) - p->updateDeprecatedProjectSettingsInteractively(); + currentProject->updateDeprecatedProjectSettingsInteractively(); return true; } @@ -606,7 +597,7 @@ bool MainWindowList::askAllWindowsToClose() while (windows.size() > 0) { - if (! windows[0]->closeCurrentProject()) + if (! windows[0]->closeCurrentProject (true)) return false; windows.remove (0); @@ -617,7 +608,7 @@ bool MainWindowList::askAllWindowsToClose() void MainWindowList::createWindowIfNoneAreOpen() { - if (windows.size() == 0) + if (windows.isEmpty()) createNewMainWindow()->showStartPage(); } @@ -633,7 +624,7 @@ void MainWindowList::closeWindow (MainWindow* w) else #endif { - if (w->closeCurrentProject()) + if (w->closeCurrentProject (true)) { windows.removeObject (w); saveCurrentlyOpenProjectList(); @@ -689,22 +680,20 @@ bool MainWindowList::openFile (const File& file, bool openInBackground) WeakReference previousFrontWindow (getFrontmostWindow()); auto* w = getOrCreateEmptyWindow(); - bool ok = w->openFile (file); - if (ok) + if (w->openFile (file)) { w->makeVisible(); - avoidSuperimposedWindows (w); - } - else - { - closeWindow (w); + checkWindowBounds (w); + + if (openInBackground && previousFrontWindow != nullptr) + previousFrontWindow->toFront (true); + + return true; } - if (openInBackground && previousFrontWindow != nullptr) - previousFrontWindow->toFront (true); - - return ok; + closeWindow (w); + return false; } if (getFrontmostWindow()->tryToOpenPIP (file)) @@ -718,11 +707,8 @@ bool MainWindowList::openFile (const File& file, bool openInBackground) MainWindow* MainWindowList::createNewMainWindow() { - auto w = new MainWindow(); - windows.add (w); - w->restoreWindowPosition(); - avoidSuperimposedWindows (w); - return w; + windows.add (new MainWindow()); + return windows.getLast(); } MainWindow* MainWindowList::getFrontmostWindow (bool createIfNotFound) @@ -732,8 +718,9 @@ MainWindow* MainWindowList::getFrontmostWindow (bool createIfNotFound) if (createIfNotFound) { auto* w = createNewMainWindow(); - avoidSuperimposedWindows (w); w->makeVisible(); + checkWindowBounds (w); + return w; } @@ -784,29 +771,49 @@ MainWindow* MainWindowList::getMainWindowForFile (const File& file) return nullptr; } -void MainWindowList::avoidSuperimposedWindows (MainWindow* const mw) +void MainWindowList::checkWindowBounds (MainWindow* windowToCheck) { - for (int i = windows.size(); --i >= 0;) + auto avoidSuperimposedWindows = [&] { - auto* other = windows.getUnchecked(i); - - auto b1 = mw->getBounds(); - auto b2 = other->getBounds(); - - if (mw != other - && std::abs (b1.getX() - b2.getX()) < 3 - && std::abs (b1.getY() - b2.getY()) < 3 - && std::abs (b1.getRight() - b2.getRight()) < 3 - && std::abs (b1.getBottom() - b2.getBottom()) < 3) + for (auto* otherWindow : windows) { - int dx = 40, dy = 30; + if (otherWindow == windowToCheck) + continue; - if (b1.getCentreX() >= mw->getScreenBounds().getCentreX()) dx = -dx; - if (b1.getCentreY() >= mw->getScreenBounds().getCentreY()) dy = -dy; + auto boundsToCheck = windowToCheck->getScreenBounds(); + auto otherBounds = otherWindow->getScreenBounds(); - mw->setBounds (b1.translated (dx, dy)); + if (std::abs (boundsToCheck.getX() - otherBounds.getX()) < 3 + && std::abs (boundsToCheck.getY() - otherBounds.getY()) < 3 + && std::abs (boundsToCheck.getRight() - otherBounds.getRight()) < 3 + && std::abs (boundsToCheck.getBottom() - otherBounds.getBottom()) < 3) + { + int dx = 40, dy = 30; + + if (otherBounds.getCentreX() >= boundsToCheck.getCentreX()) dx = -dx; + if (otherBounds.getCentreY() >= boundsToCheck.getCentreY()) dy = -dy; + + windowToCheck->setBounds (boundsToCheck.translated (dx, dy)); + } } - } + }; + + auto ensureWindowIsFullyOnscreen = [&] + { + auto windowBounds = windowToCheck->getScreenBounds(); + auto screenLimits = Desktop::getInstance().getDisplays().findDisplayForRect (windowBounds).userArea; + + auto constrainedX = jlimit (screenLimits.getX(), screenLimits.getRight() - windowBounds.getWidth(), windowBounds.getX()); + auto constrainedY = jlimit (screenLimits.getY(), screenLimits.getBottom() - windowBounds.getHeight(), windowBounds.getY()); + + Point constrainedTopLeft (constrainedX, constrainedY); + + if (windowBounds.getPosition() != constrainedTopLeft) + windowToCheck->setTopLeftPosition (constrainedTopLeft); + }; + + avoidSuperimposedWindows(); + ensureWindowIsFullyOnscreen(); } void MainWindowList::saveCurrentlyOpenProjectList() diff --git a/extras/Projucer/Source/Application/jucer_MainWindow.h b/extras/Projucer/Source/Application/jucer_MainWindow.h index 919691f7ab..c949c1c1c9 100644 --- a/extras/Projucer/Source/Application/jucer_MainWindow.h +++ b/extras/Projucer/Source/Application/jucer_MainWindow.h @@ -50,14 +50,15 @@ public: //============================================================================== bool canOpenFile (const File& file) const; bool openFile (const File& file); - void setProject (Project* newProject); - Project* getProject() const { return currentProject.get(); } + + void setProject (std::unique_ptr newProject); + Project* getProject() const { return currentProject.get(); } + bool tryToOpenPIP (const File& f); void makeVisible(); void restoreWindowPosition(); - bool closeProject (Project* project, bool askToSave = true); - bool closeCurrentProject(); + bool closeCurrentProject (bool askToSave); void moveProject (File newProjectFile); void showStartPage(); @@ -118,7 +119,7 @@ public: void reopenLastProjects(); void saveCurrentlyOpenProjectList(); - void avoidSuperimposedWindows (MainWindow*); + void checkWindowBounds (MainWindow*); void sendLookAndFeelChange(); diff --git a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp index 8e3a367c3e..052e3c0015 100644 --- a/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp +++ b/extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp @@ -559,7 +559,7 @@ bool ProjectContentComponent::saveProject (bool shouldWait, bool openInIDE) void ProjectContentComponent::closeProject() { if (auto* mw = findParentComponentOfClass()) - mw->closeCurrentProject(); + mw->closeCurrentProject (true); } void ProjectContentComponent::showProjectSettings() diff --git a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h index 44cf002a2c..49c3042f31 100644 --- a/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h +++ b/extras/Projucer/Source/Wizards/jucer_NewProjectWizardComponent.h @@ -433,7 +433,7 @@ public: if (project != nullptr) { - mw->setProject (project.release()); + mw->setProject (std::move (project)); getAppSettings().lastWizardFolder = projectDir.getParentDirectory(); } }