1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Projucer: Added a simple sign-in form, added notification tray for project messages, general refactoring

This commit is contained in:
ed 2020-04-17 10:02:21 +01:00
parent 6610a1959f
commit fba0295a44
69 changed files with 4915 additions and 2205 deletions

View file

@ -22,6 +22,90 @@
#include "../Wizards/jucer_NewProjectWizardClasses.h"
#include "../Utility/UI/jucer_JucerTreeViewBase.h"
#include "../ProjectSaving/jucer_ProjectSaver.h"
#include "UserAccount/jucer_LoginFormComponent.h"
#include "../Project/UI/jucer_ProjectContentComponent.h"
//==============================================================================
class BlurOverlayWithComponent : public Component,
private ComponentMovementWatcher,
private AsyncUpdater
{
public:
BlurOverlayWithComponent (MainWindow& window, std::unique_ptr<Component> comp)
: ComponentMovementWatcher (&window),
mainWindow (window),
componentToShow (std::move (comp))
{
kernel.createGaussianBlur (1.25f);
addAndMakeVisible (*componentToShow);
setAlwaysOnTop (true);
setOpaque (true);
setVisible (true);
static_cast<Component&> (mainWindow).addChildComponent (this);
componentMovedOrResized (true, true);
}
void resized() override
{
setBounds (mainWindow.getLocalBounds());
componentToShow->centreWithSize (componentToShow->getWidth(), componentToShow->getHeight());
refreshBackgroundImage();
}
void paint (Graphics& g) override
{
g.drawImage (componentImage, getLocalBounds().toFloat());
}
private:
void componentPeerChanged() override {}
void componentVisibilityChanged() override {}
using ComponentMovementWatcher::componentVisibilityChanged;
void componentMovedOrResized (bool, bool) override { triggerAsyncUpdate(); }
using ComponentMovementWatcher::componentMovedOrResized;
void handleAsyncUpdate() override { resized(); }
void mouseUp (const MouseEvent& event) override
{
if (event.eventComponent == this)
mainWindow.hideLoginFormOverlay();
}
void lookAndFeelChanged() override
{
refreshBackgroundImage();
repaint();
}
void refreshBackgroundImage()
{
setVisible (false);
auto parentBounds = mainWindow.getBounds();
componentImage = mainWindow.createComponentSnapshot (mainWindow.getLocalBounds())
.rescaled (roundToInt (parentBounds.getWidth() / 1.75f), roundToInt (parentBounds.getHeight() / 1.75f));
kernel.applyToImage (componentImage, componentImage, getLocalBounds());
setVisible (true);
}
//==============================================================================
MainWindow& mainWindow;
std::unique_ptr<Component> componentToShow;
ImageConvolutionKernel kernel { 3 };
Image componentImage;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BlurOverlayWithComponent)
};
//==============================================================================
MainWindow::MainWindow()
@ -32,6 +116,8 @@ MainWindow::MainWindow()
false)
{
setUsingNativeTitleBar (true);
setResizable (true, false);
setResizeLimits (600, 500, 32000, 32000);
#if ! JUCE_MAC
setMenuBar (ProjucerApplication::getApp().getMenuModel());
@ -39,9 +125,6 @@ MainWindow::MainWindow()
createProjectContentCompIfNeeded();
setResizable (true, false);
centreWithSize (800, 600);
auto& commandManager = ProjucerApplication::getCommandManager();
auto registerAllAppCommands = [&]
@ -65,9 +148,10 @@ MainWindow::MainWindow()
setWantsKeyboardFocus (false);
getLookAndFeel().setColour (ColourSelector::backgroundColourId, Colours::transparentBlack);
projectNameValue.addListener (this);
setResizeLimits (600, 500, 32000, 32000);
centreWithSize (800, 600);
}
MainWindow::~MainWindow()
@ -77,10 +161,11 @@ MainWindow::~MainWindow()
#endif
removeKeyListener (ProjucerApplication::getCommandManager().getKeyMappings());
// save the current size and position to our settings file..
getGlobalProperties().setValue ("lastMainWindowPos", getWindowStateAsString());
clearContentComponent();
currentProject.reset();
}
void MainWindow::createProjectContentCompIfNeeded()
@ -127,7 +212,7 @@ void MainWindow::closeButtonPressed()
ProjucerApplication::getApp().mainWindowList.closeWindow (this);
}
bool MainWindow::closeCurrentProject (bool askUserToSave)
bool MainWindow::closeCurrentProject (OpenDocumentManager::SaveIfNeeded askUserToSave)
{
if (currentProject == nullptr)
return true;
@ -144,7 +229,8 @@ bool MainWindow::closeCurrentProject (bool askUserToSave)
if (ProjucerApplication::getApp().openDocumentManager
.closeAllDocumentsUsingProject (*currentProject, askUserToSave))
{
if (! askUserToSave || (currentProject->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk))
if (askUserToSave == OpenDocumentManager::SaveIfNeeded::no
|| (currentProject->saveIfNeededAndUserAgrees() == FileBasedDocument::savedOk))
{
setProject (nullptr);
return true;
@ -154,19 +240,16 @@ bool MainWindow::closeCurrentProject (bool askUserToSave)
return false;
}
void MainWindow::moveProject (File newProjectFileToOpen)
void MainWindow::moveProject (File newProjectFileToOpen, OpenInIDE openInIDE)
{
auto openInIDE = currentProject->shouldOpenInIDEAfterSaving();
closeCurrentProject (false);
closeCurrentProject (OpenDocumentManager::SaveIfNeeded::no);
openFile (newProjectFileToOpen);
if (currentProject != nullptr)
{
ProjucerApplication::getApp().getCommandManager().invokeDirectly (openInIDE ? CommandIDs::saveAndOpenInIDE
: CommandIDs::saveProject,
false);
}
ProjucerApplication::getApp().getCommandManager()
.invokeDirectly (openInIDE == OpenInIDE::yes ? CommandIDs::saveAndOpenInIDE
: CommandIDs::saveProject,
false);
}
void MainWindow::setProject (std::unique_ptr<Project> newProject)
@ -174,7 +257,7 @@ void MainWindow::setProject (std::unique_ptr<Project> newProject)
if (newProject == nullptr)
{
getProjectContentComponent()->setProject (nullptr);
projectNameValue.referTo (Value());
projectNameValue.referTo ({});
currentProject.reset();
}
@ -222,7 +305,7 @@ bool MainWindow::openFile (const File& file)
auto newDoc = std::make_unique<Project> (file);
auto result = newDoc->loadFrom (file, true);
if (result.wasOk() && closeCurrentProject (true))
if (result.wasOk() && closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes))
{
setProject (std::move (newDoc));
currentProject->setChangedFlag (false);
@ -350,7 +433,7 @@ void MainWindow::openPIP (PIPGenerator& generator)
{
project->setTemporaryDirectory (generator.getOutputDirectory());
ProjectSaver liveBuildSaver (*project, project->getFile());
ProjectSaver liveBuildSaver (*project);
liveBuildSaver.saveContentNeededForLiveBuild();
if (auto* pcc = window->getProjectContentComponent())
@ -440,49 +523,6 @@ void MainWindow::activeWindowStatusChanged()
pcc->updateMissingFileStatuses();
ProjucerApplication::getApp().openDocumentManager.reloadModifiedFiles();
if (auto* p = getProject())
{
if (p->hasProjectBeenModified())
{
Component::SafePointer<Component> safePointer (this);
MessageManager::callAsync ([=] ()
{
if (safePointer == nullptr)
return; // bail out if the window has been deleted
auto result = AlertWindow::showOkCancelBox (AlertWindow::QuestionIcon,
TRANS ("The .jucer file has been modified since the last save."),
TRANS ("Do you want to keep the current project or re-load from disk?"),
TRANS ("Keep"),
TRANS ("Re-load from disk"));
if (safePointer == nullptr)
return;
if (result == 0)
{
if (auto* project = getProject())
{
auto oldTemporaryDirectory = project->getTemporaryDirectory();
auto projectFile = project->getFile();
setProject (nullptr);
openFile (projectFile);
if (oldTemporaryDirectory != File())
if (auto* newProject = getProject())
newProject->setTemporaryDirectory (oldTemporaryDirectory);
}
}
else
{
ProjucerApplication::getApp().getCommandManager().invokeDirectly (CommandIDs::saveProject, true);
}
});
}
}
}
void MainWindow::showStartPage()
@ -498,6 +538,18 @@ void MainWindow::showStartPage()
getContentComponent()->grabKeyboardFocus();
}
void MainWindow::showLoginFormOverlay()
{
blurOverlayComponent = std::make_unique<BlurOverlayWithComponent> (*this, std::make_unique<LoginFormComponent> (*this));
loginFormOpen = true;
}
void MainWindow::hideLoginFormOverlay()
{
blurOverlayComponent.reset();
loginFormOpen = false;
}
//==============================================================================
ApplicationCommandTarget* MainWindow::getNextCommandTarget()
{
@ -565,12 +617,11 @@ bool MainWindow::perform (const InvocationInfo& info)
return true;
}
void MainWindow::valueChanged (Value&)
void MainWindow::valueChanged (Value& value)
{
if (currentProject != nullptr)
setName (currentProject->getProjectNameString() + " - Projucer");
else
setName ("Projucer");
if (value == projectNameValue)
setName (currentProject != nullptr ? currentProject->getProjectNameString() + " - Projucer"
: "Projucer");
}
//==============================================================================
@ -589,7 +640,7 @@ bool MainWindowList::askAllWindowsToClose()
while (windows.size() > 0)
{
if (! windows[0]->closeCurrentProject (true))
if (! windows[0]->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes))
return false;
windows.remove (0);
@ -616,7 +667,7 @@ void MainWindowList::closeWindow (MainWindow* w)
else
#endif
{
if (w->closeCurrentProject (true))
if (w->closeCurrentProject (OpenDocumentManager::SaveIfNeeded::yes))
{
windows.removeObject (w);
saveCurrentlyOpenProjectList();
@ -766,6 +817,15 @@ MainWindow* MainWindowList::getMainWindowForFile (const File& file)
return nullptr;
}
MainWindow* MainWindowList::getMainWindowWithLoginFormOpen()
{
for (auto* window : windows)
if (window->isShowingLoginForm())
return window;
return nullptr;
}
void MainWindowList::checkWindowBounds (MainWindow& windowToCheck)
{
auto avoidSuperimposedWindows = [&]