|
|
|
@@ -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());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// don't want the window to take focus when the title-bar is clicked..
|
|
|
|
setWantsKeyboardFocus (false);
|
|
|
|
registerAllAppCommands();
|
|
|
|
updateAppKeyMappings();
|
|
|
|
|
|
|
|
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<Project> 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<Project> newDoc (new Project (file));
|
|
|
|
|
|
|
|
auto newDoc = std::make_unique<Project> (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<Component> 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);
|
|
|
|
if (openInBackground && previousFrontWindow != nullptr)
|
|
|
|
previousFrontWindow->toFront (true);
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
for (auto* otherWindow : windows)
|
|
|
|
{
|
|
|
|
if (otherWindow == windowToCheck)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
auto b1 = mw->getBounds();
|
|
|
|
auto b2 = other->getBounds();
|
|
|
|
auto boundsToCheck = windowToCheck->getScreenBounds();
|
|
|
|
auto otherBounds = otherWindow->getScreenBounds();
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
int dx = 40, dy = 30;
|
|
|
|
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 (b1.getCentreX() >= mw->getScreenBounds().getCentreX()) dx = -dx;
|
|
|
|
if (b1.getCentreY() >= mw->getScreenBounds().getCentreY()) dy = -dy;
|
|
|
|
if (otherBounds.getCentreX() >= boundsToCheck.getCentreX()) dx = -dx;
|
|
|
|
if (otherBounds.getCentreY() >= boundsToCheck.getCentreY()) dy = -dy;
|
|
|
|
|
|
|
|
mw->setBounds (b1.translated (dx, 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<int> constrainedTopLeft (constrainedX, constrainedY);
|
|
|
|
|
|
|
|
if (windowBounds.getPosition() != constrainedTopLeft)
|
|
|
|
windowToCheck->setTopLeftPosition (constrainedTopLeft);
|
|
|
|
};
|
|
|
|
|
|
|
|
avoidSuperimposedWindows();
|
|
|
|
ensureWindowIsFullyOnscreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindowList::saveCurrentlyOpenProjectList()
|
|
|
|
|