Browse Source

Projucer: Accessibility updates

v6.1.6
ed 4 years ago
parent
commit
69085b2a61
31 changed files with 566 additions and 332 deletions
  1. +4
    -0
      extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h
  2. +21
    -5
      extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp
  3. +16
    -8
      extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h
  4. +6
    -0
      extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h
  5. +2
    -2
      extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h
  6. +4
    -0
      extras/Projucer/Source/Application/jucer_MainWindow.cpp
  7. +7
    -8
      extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h
  8. +2
    -2
      extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp
  9. +2
    -2
      extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h
  10. +7
    -4
      extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp
  11. +2
    -2
      extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h
  12. +2
    -2
      extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp
  13. +2
    -2
      extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp
  14. +7
    -3
      extras/Projucer/Source/LiveBuildEngine/UI/jucer_ComponentListComponent.h
  15. +6
    -11
      extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h
  16. +7
    -7
      extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h
  17. +12
    -12
      extras/Projucer/Source/Project/UI/Sidebar/jucer_FileTreeItems.h
  18. +8
    -8
      extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h
  19. +29
    -8
      extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h
  20. +3
    -4
      extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h
  21. +51
    -8
      extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h
  22. +112
    -0
      extras/Projucer/Source/Project/UI/jucer_ContentViewComponent.h
  23. +97
    -54
      extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h
  24. +3
    -0
      extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp
  25. +62
    -119
      extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp
  26. +10
    -28
      extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.h
  27. +29
    -2
      extras/Projucer/Source/Project/UI/jucer_ProjectMessagesComponent.h
  28. +14
    -0
      extras/Projucer/Source/Project/UI/jucer_UserAvatarComponent.h
  29. +16
    -0
      extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h
  30. +6
    -17
      extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp
  31. +17
    -14
      extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.h

+ 4
- 0
extras/Projucer/Source/Application/StartPage/jucer_ContentComponents.h View File

@@ -254,6 +254,9 @@ public:
header (metadata[Ids::name].toString(), metadata[Ids::description].toString(), BinaryData::background_logo_svg),
codeViewer (doc, &cppTokeniser)
{
setTitle (exampleFile.getFileName());
setFocusContainerType (FocusContainerType::focusContainer);
addAndMakeVisible (header);
openExampleButton.onClick = [this] { exampleSelectedCallback (exampleFile); };
@@ -286,6 +289,7 @@ private:
codeViewer.setScrollbarThickness (6);
codeViewer.setReadOnly (true);
codeViewer.setTitle ("Code");
getAppSettings().appearance.applyToCodeEditor (codeViewer);
codeViewer.scrollToLine (findBestLineToScrollToForClass (StringArray::fromLines (fileString),


+ 21
- 5
extras/Projucer/Source/Application/StartPage/jucer_StartPageComponent.cpp View File

@@ -34,6 +34,12 @@
//==============================================================================
struct ContentComponent : public Component
{
ContentComponent()
{
setTitle ("Content");
setFocusContainerType (FocusContainerType::focusContainer);
}
void resized() override
{
if (content != nullptr)
@@ -88,7 +94,8 @@ static std::unique_ptr<Component> createExampleProjectsTab (ContentComponent& co
content.setContent (std::make_unique<ExampleComponent> (findExampleFile (category, index), cb));
};
return std::make_unique<StartPageTreeHolder> (exampleCategories,
return std::make_unique<StartPageTreeHolder> ("Examples",
exampleCategories,
examples,
std::move (selectedCallback),
StartPageTreeHolder::Open::no);
@@ -144,7 +151,8 @@ static std::unique_ptr<Component> createProjectTemplatesTab (ContentComponent& c
content.setContent (std::make_unique<TemplateComponent> (templates[(size_t) index], std::move (cb)));
};
auto holder = std::make_unique<StartPageTreeHolder> (categories,
auto holder = std::make_unique<StartPageTreeHolder> ("Templates",
categories,
templateNames,
std::move (selectedCallback),
StartPageTreeHolder::Open::yes);
@@ -165,7 +173,14 @@ struct ProjectTemplatesAndExamples : public TabbedComponent
content (c),
exampleSelectedCallback (std::move (exampleCb))
{
addTab ("New Project", Colours::transparentBlack, createProjectTemplatesTab (content, std::move (newProjectCb)).release(), true);
setTitle ("Templates and Examples");
setFocusContainerType (FocusContainerType::focusContainer);
addTab ("New Project",
Colours::transparentBlack,
createProjectTemplatesTab (content, std::move (newProjectCb)).release(),
true);
refreshExamplesTab();
}
@@ -177,8 +192,9 @@ struct ProjectTemplatesAndExamples : public TabbedComponent
auto exampleTabs = createExampleProjectsTab (content, exampleSelectedCallback);
addTab ("Open Example", Colours::transparentBlack, exampleTabs == nullptr ? new SetJUCEPathComponent (*this)
: exampleTabs.release(),
addTab ("Open Example",
Colours::transparentBlack,
exampleTabs == nullptr ? new SetJUCEPathComponent (*this) : exampleTabs.release(),
true);
if (wasOpen)


+ 16
- 8
extras/Projucer/Source/Application/StartPage/jucer_StartPageTreeHolder.h View File

@@ -31,14 +31,18 @@ class StartPageTreeHolder : public Component
public:
enum class Open { no, yes };
StartPageTreeHolder (const StringArray& headerNames, const std::vector<StringArray>& itemNames,
std::function<void (int, int)>&& selectedCallback, Open shouldBeOpen)
StartPageTreeHolder (const String& title,
const StringArray& headerNames,
const std::vector<StringArray>& itemNames,
std::function<void (int, int)>&& selectedCallback,
Open shouldBeOpen)
: headers (headerNames),
items (itemNames),
itemSelectedCallback (std::move (selectedCallback))
{
jassert (headers.size() == (int) items.size());
tree.setTitle (title);
tree.setRootItem (new TreeRootItem (*this));
tree.setRootItemVisible (false);
tree.setIndentSize (15);
@@ -88,13 +92,14 @@ private:
addSubItem (new TreeSubItem (owner, s, {}));
}
bool mightContainSubItems() override { return isHeader; }
bool canBeSelected() const override { return ! isHeader; }
bool mightContainSubItems() override { return isHeader; }
bool canBeSelected() const override { return ! isHeader; }
int getItemWidth() const override { return -1; }
int getItemHeight() const override { return 25; }
int getItemWidth() const override { return -1; }
int getItemHeight() const override { return 25; }
String getUniqueName() const override { return name; }
String getUniqueName() const override { return name; }
String getAccessibilityName() override { return getUniqueName(); }
void paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour, bool isMouseOver) override
{
@@ -122,10 +127,13 @@ private:
g.drawFittedText (name, bounds.reduced (5).withTrimmedLeft (10), Justification::centredLeft, 1);
}
void itemClicked (const MouseEvent&) override
void itemClicked (const MouseEvent& e) override
{
if (isSelected())
itemSelectionChanged (true);
if (e.mods.isPopupMenu() && mightContainSubItems())
setOpen (! isOpen());
}
void itemSelectionChanged (bool isNowSelected) override


+ 6
- 0
extras/Projucer/Source/Application/UserAccount/jucer_LoginFormComponent.h View File

@@ -35,16 +35,21 @@ public:
LoginFormComponent (MainWindow& window)
: mainWindow (window)
{
setTitle ("Login");
setFocusContainerType (FocusContainerType::focusContainer);
addAndMakeVisible (emailBox);
emailBox.setTextToShowWhenEmpty ("Email", Colours::black.withAlpha (0.2f));
emailBox.setJustification (Justification::centredLeft);
emailBox.onReturnKey = [this] { submitDetails(); };
emailBox.setTitle ("Email");
addAndMakeVisible (passwordBox);
passwordBox.setTextToShowWhenEmpty ("Password", Colours::black.withAlpha (0.2f));
passwordBox.setPasswordCharacter ((juce_wchar) 0x2022);
passwordBox.setJustification (Justification::centredLeft);
passwordBox.onReturnKey = [this] { submitDetails(); };
passwordBox.setTitle ("Password");
addAndMakeVisible (logInButton);
logInButton.onClick = [this] { submitDetails(); };
@@ -72,6 +77,7 @@ public:
dismissButton.setShape (getLookAndFeel().getCrossShape (1.0f), false, true, false);
addAndMakeVisible (dismissButton);
dismissButton.onClick = [this] { mainWindow.hideLoginFormOverlay(); };
dismissButton.setTitle ("Dismiss");
setWantsKeyboardFocus (true);
setOpaque (true);


+ 2
- 2
extras/Projucer/Source/Application/Windows/jucer_GlobalPathsWindowComponent.h View File

@@ -127,9 +127,9 @@ public:
PropertyComponent* jucePathPropertyComponent = nullptr;
for (auto* prop : propertyGroup.properties)
for (const auto& prop : propertyGroup.getProperties())
if (prop->getName() == "Path to JUCE")
jucePathPropertyComponent = prop;
jucePathPropertyComponent = prop.get();
if (jucePathPropertyComponent != nullptr)
{


+ 4
- 0
extras/Projucer/Source/Application/jucer_MainWindow.cpp View File

@@ -487,6 +487,10 @@ void MainWindow::showLoginFormOverlay()
{
blurOverlayComponent = std::make_unique<BlurOverlayWithComponent> (*this, std::make_unique<LoginFormComponent> (*this));
loginFormOpen = true;
if (auto* loginForm = blurOverlayComponent->getChildComponent (0))
if (auto* handler = loginForm->getAccessibilityHandler())
handler->grabFocus();
}
void MainWindow::hideLoginFormOverlay()


+ 7
- 8
extras/Projucer/Source/CodeEditor/jucer_LiveBuildCodeEditor.h View File

@@ -708,17 +708,16 @@ public:
}
};
Component* createEditor() override
std::unique_ptr<Component> createEditor() override
{
SourceCodeEditor* e = nullptr;
if (fileNeedsCppSyntaxHighlighting (getFile()))
e = new SourceCodeEditor (this, new LiveBuildCodeEditor (*this, getCodeDocument()));
else
e = new SourceCodeEditor (this, getCodeDocument());
auto e = fileNeedsCppSyntaxHighlighting (getFile()) ? std::make_unique<SourceCodeEditor> (this, new LiveBuildCodeEditor (*this, getCodeDocument()))
: std::make_unique<SourceCodeEditor> (this, getCodeDocument());
applyLastState (*(e->editor));
return e;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move")
return std::move (e);
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}
// override save() to make a few more attempts at saving if it fails, since on Windows


+ 2
- 2
extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.cpp View File

@@ -59,8 +59,8 @@ public:
void reloadFromFile() override { fileModificationTime = file.getLastModificationTime(); }
String getName() const override { return file.getFileName(); }
File getFile() const override { return file; }
Component* createEditor() override { return new ItemPreviewComponent (file); }
Component* createViewer() override { return createEditor(); }
std::unique_ptr<Component> createEditor() override { return std::make_unique<ItemPreviewComponent> (file); }
std::unique_ptr<Component> createViewer() override { return createEditor(); }
void fileHasBeenRenamed (const File& newFile) override { file = newFile; }
String getState() const override { return {}; }
void restoreState (const String&) override {}


+ 2
- 2
extras/Projucer/Source/CodeEditor/jucer_OpenDocumentManager.h View File

@@ -55,8 +55,8 @@ public:
virtual bool saveAs() = 0;
virtual bool hasFileBeenModifiedExternally() = 0;
virtual void reloadFromFile() = 0;
virtual Component* createEditor() = 0;
virtual Component* createViewer() = 0;
virtual std::unique_ptr<Component> createEditor() = 0;
virtual std::unique_ptr<Component> createViewer() = 0;
virtual void fileHasBeenRenamed (const File& newFile) = 0;
virtual String getState() const = 0;
virtual void restoreState (const String& state) = 0;


+ 7
- 4
extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.cpp View File

@@ -45,11 +45,14 @@ CodeDocument& SourceCodeDocument::getCodeDocument()
return *codeDoc;
}
Component* SourceCodeDocument::createEditor()
std::unique_ptr<Component> SourceCodeDocument::createEditor()
{
auto* e = new SourceCodeEditor (this, getCodeDocument());
auto e = std::make_unique<SourceCodeEditor> (this, getCodeDocument());
applyLastState (*(e->editor));
return e;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move")
return std::move (e);
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}
void SourceCodeDocument::reloadFromFile()
@@ -380,7 +383,7 @@ public:
addAndMakeVisible (findNext);
setWantsKeyboardFocus (false);
setFocusContainer (true);
setFocusContainerType (FocusContainerType::keyboardFocusContainer);
findPrev.setWantsKeyboardFocus (false);
findNext.setWantsKeyboardFocus (false);


+ 2
- 2
extras/Projucer/Source/CodeEditor/jucer_SourceCodeEditor.h View File

@@ -83,8 +83,8 @@ public:
bool save() override;
bool saveAs() override;
Component* createEditor() override;
Component* createViewer() override { return createEditor(); }
std::unique_ptr<Component> createEditor() override;
std::unique_ptr<Component> createViewer() override { return createEditor(); }
void updateLastState (CodeEditorComponent&);
void applyLastState (CodeEditorComponent&) const;


+ 2
- 2
extras/Projucer/Source/ComponentEditor/UI/jucer_ComponentLayoutEditor.cpp View File

@@ -41,7 +41,7 @@ public:
{
setInterceptsMouseClicks (false, false);
setWantsKeyboardFocus (false);
setFocusContainer (true);
setFocusContainerType (FocusContainerType::keyboardFocusContainer);
}
void paint (Graphics& g) override
@@ -254,7 +254,7 @@ void ComponentLayoutEditor::refreshAllComponents()
lastComp = c;
c->setWantsKeyboardFocus (false);
c->setFocusContainer (true);
c->setFocusContainerType (FocusContainerType::keyboardFocusContainer);
if (isNewOverlay)
overlay->updateBoundsToMatchTarget();


+ 2
- 2
extras/Projucer/Source/ComponentEditor/jucer_JucerDocument.cpp View File

@@ -713,14 +713,14 @@ public:
return false;
}
Component* createEditor() override
std::unique_ptr<Component> createEditor() override
{
if (ProjucerApplication::getApp().isGUIEditorEnabled())
{
std::unique_ptr<JucerDocument> jucerDoc (JucerDocument::createForCppFile (getProject(), getFile()));
if (jucerDoc != nullptr)
return new JucerDocumentEditor (jucerDoc.release());
return std::make_unique<JucerDocumentEditor> (jucerDoc.release());
}
return SourceCodeDocument::createEditor();


+ 7
- 3
extras/Projucer/Source/LiveBuildEngine/UI/jucer_ComponentListComponent.h View File

@@ -158,15 +158,19 @@ private:
bool mightContainSubItems() override { return false; }
String getUniqueName() const override { return comp.getName(); }
int getRightHandButtonSpace() override { return canBeLaunched() ? 60 : 40; }
Component* createItemComponent() override
std::unique_ptr<Component> createItemComponent() override
{
auto* content = new TreeItemComponent (*this);
auto content = std::make_unique<TreeItemComponent> (*this);
content->addRightHandButton (new ClassItemButton (*this, true));
if (canBeLaunched())
content->addRightHandButton (new ClassItemButton (*this, false));
return content;
JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move")
return std::move (content);
JUCE_END_IGNORE_WARNINGS_GCC_LIKE
}
Colour getContentColour (bool isIcon) const override


+ 6
- 11
extras/Projucer/Source/LiveBuildEngine/UI/jucer_ErrorListComponent.h View File

@@ -274,11 +274,11 @@ private:
: defaultTextColourId);
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
PopupMenu menu;
menu.addItem (1, "Copy");
launchPopupMenu (menu);
launchPopupMenu (menu, p);
}
void handlePopupMenuResult (int resultCode) override
@@ -294,17 +294,12 @@ private:
SourceCodeEditor* getEditor()
{
if (ProjectContentComponent* pcc = getProjectContentComponent())
if (auto* pcc = getProjectContentComponent())
{
const File file (File::createFileWithoutCheckingPath (message.range.file));
const auto file = File::createFileWithoutCheckingPath (message.range.file);
if (message.range.isValid() && file.exists() && pcc->showEditorForFile (file, false))
{
if (SourceCodeEditor* ed = dynamic_cast<SourceCodeEditor*> (pcc->getEditorComponent()))
{
return ed;
}
}
return dynamic_cast<SourceCodeEditor*> (pcc->getEditorComponent());
}
return nullptr;
@@ -337,7 +332,7 @@ private:
if (ProjectContentComponent* pcc = getProjectContentComponent())
{
if (SourceCodeEditor* ed = dynamic_cast<SourceCodeEditor*> (pcc->getEditorComponent()))
if (auto* ed = dynamic_cast<SourceCodeEditor*> (pcc->getEditorComponent()))
{
auto start = CodeDocument::Position (ed->editor->getDocument(), message.range.range.getStart());
auto end = CodeDocument::Position (ed->editor->getDocument(), message.range.range.getEnd());


+ 7
- 7
extras/Projucer/Source/Project/UI/Sidebar/jucer_ExporterTreeItems.h View File

@@ -93,7 +93,7 @@ public:
addSubItem (new ConfigItem (config.config, *exporter));
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
PopupMenu menu;
menu.addItem (1, "Add a new configuration", exporter->supportsUserDefinedConfigurations());
@@ -101,15 +101,15 @@ public:
menu.addSeparator();
menu.addItem (3, "Delete this exporter");
launchPopupMenu (menu);
launchPopupMenu (menu, p);
}
void showAddMenu() override
void showAddMenu (Point<int> p) override
{
PopupMenu menu;
menu.addItem (1, "Add a new configuration", exporter->supportsUserDefinedConfigurations());
launchPopupMenu (menu);
launchPopupMenu (menu, p);
}
void handlePopupMenuResult (int resultCode) override
@@ -239,7 +239,7 @@ public:
}
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
bool enabled = exporter.supportsUserDefinedConfigurations();
@@ -248,7 +248,7 @@ public:
menu.addSeparator();
menu.addItem (2, "Delete this configuration", enabled);
launchPopupMenu (menu);
launchPopupMenu (menu, p);
}
void handlePopupMenuResult (int resultCode) override
@@ -320,7 +320,7 @@ public:
void setName (const String&) override {}
Icon getIcon() const override { return project.getMainGroup().getIcon (isOpen()).withColour (getContentColour (true)); }
void showPopupMenu() override
void showPopupMenu (Point<int>) override
{
if (auto* pcc = getProjectContentComponent())
pcc->showNewExporterMenu();


+ 12
- 12
extras/Projucer/Source/Project/UI/Sidebar/jucer_FileTreeItems.h View File

@@ -131,7 +131,7 @@ public:
{
if (auto* pcc = treeRootItem->getProjectContentComponent())
{
if (auto* fileInfoComp = dynamic_cast<FileGroupInformationComponent*> (pcc->getEditorComponentContent()))
if (auto* fileInfoComp = dynamic_cast<FileGroupInformationComponent*> (pcc->getEditorComponent()))
if (fileInfoComp->getGroupPath() == itemToRemove->getFile().getFullPathName())
pcc->hideEditor();
}
@@ -197,12 +197,12 @@ public:
jassertfalse;
}
void showMultiSelectionPopupMenu() override
void showMultiSelectionPopupMenu (Point<int> p) override
{
PopupMenu m;
m.addItem (1, "Delete");
m.showMenuAsync (PopupMenu::Options(),
m.showMenuAsync (PopupMenu::Options().withTargetScreenArea ({ p.x, p.y, 1, 1 }),
ModalCallbackFunction::create (treeViewMultiSelectItemChosen, this));
}
@@ -548,7 +548,7 @@ public:
pcc->showEditorForFile (f, false);
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
PopupMenu m;
@@ -571,13 +571,13 @@ public:
m.addItem (3, "Delete");
launchPopupMenu (m);
launchPopupMenu (m, p);
}
void showAddMenu() override
void showAddMenu (Point<int> p) override
{
if (auto* group = dynamic_cast<GroupItem*> (getParentItem()))
group->showAddMenu();
group->showAddMenu (p);
}
void handlePopupMenuResult (int resultCode) override
@@ -696,7 +696,7 @@ public:
void showDocument() override
{
if (auto* pcc = getProjectContentComponent())
pcc->setEditorComponent (new FileGroupInformationComponent (item), nullptr);
pcc->setScrollableEditorComponent (std::make_unique<FileGroupInformationComponent> (item));
}
static void openAllGroups (TreeViewItem* root)
@@ -731,7 +731,7 @@ public:
setFilesToCompile (projectItem.getChild (i), shouldCompile);
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
PopupMenu m;
addCreateFileMenuItems (m);
@@ -764,15 +764,15 @@ public:
m.addItem (10, "Delete");
}
launchPopupMenu (m);
launchPopupMenu (m, p);
}
void showAddMenu() override
void showAddMenu (Point<int> p) override
{
PopupMenu m;
addCreateFileMenuItems (m);
launchPopupMenu (m);
launchPopupMenu (m, p);
}
void handlePopupMenuResult (int resultCode) override


+ 8
- 8
extras/Projucer/Source/Project/UI/Sidebar/jucer_ModuleTreeItems.h View File

@@ -78,17 +78,17 @@ public:
return Icon (getIcons().singleModule, iconColour);
}
void showAddMenu() override
void showAddMenu (Point<int> p) override
{
if (auto* parent = dynamic_cast<EnabledModulesItem*> (getParentItem()))
parent->showPopupMenu();
parent->showPopupMenu (p);
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
PopupMenu menu;
menu.addItem (1, "Remove this module");
launchPopupMenu (menu);
launchPopupMenu (menu, p);
}
void handlePopupMenuResult (int resultCode) override
@@ -149,7 +149,7 @@ private:
if (modules.doesModuleHaveHigherCppStandardThanProject (moduleID))
props.add (new CppStandardWarningComponent());
group.properties.clear();
group.clearProperties();
exporterModulePathDefaultValues.clear();
exporterModulePathValues.clear();
globalPathValues.clear();
@@ -471,7 +471,7 @@ public:
void showDocument() override
{
if (auto* pcc = getProjectContentComponent())
pcc->setEditorComponent (new ModulesInformationComponent (project), nullptr);
pcc->setScrollableEditorComponent (std::make_unique<ModulesInformationComponent> (project));
}
static File getModuleFolder (const File& draggedFile)
@@ -515,7 +515,7 @@ public:
addSubItem (new ModuleItem (project, project.getEnabledModules().getModuleID (i)));
}
void showPopupMenu() override
void showPopupMenu (Point<int> p) override
{
auto& enabledModules = project.getEnabledModules();
PopupMenu allModules;
@@ -563,7 +563,7 @@ public:
menu.addSeparator();
menu.addItem (1001, "Add a module from a specified folder...");
launchPopupMenu (menu);
launchPopupMenu (menu, p);
}
void handlePopupMenuResult (int resultCode) override


+ 29
- 8
extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTab.h View File

@@ -35,6 +35,9 @@ struct ProjectSettingsComponent : public Component,
group (project.getProjectFilenameRootString(),
Icon (getIcons().settings, Colours::transparentBlack))
{
setTitle ("Project Settings");
setFocusContainerType (FocusContainerType::focusContainer);
addAndMakeVisible (group);
updatePropertyList();
@@ -238,16 +241,34 @@ private:
headers.clear();
if (project != nullptr)
auto addPanel = [this] (const String& name,
TreePanelBase* tree,
ConcertinaTreeComponent::AdditionalComponents components,
const Path& icon)
{
concertinaPanel.addPanel (0, new ConcertinaTreeComponent (new FileTreePanel (*project), true, false, true), true);
concertinaPanel.addPanel (1, new ConcertinaTreeComponent (new ModuleTreePanel (*project), true, true), true);
concertinaPanel.addPanel (2, new ConcertinaTreeComponent (new ExportersTreePanel (*project), true), true);
}
if (project != nullptr)
concertinaPanel.addPanel (-1, new ConcertinaTreeComponent (name, tree, components), true);
headers.add (new ConcertinaHeader (name, icon));
};
using AdditionalComponents = ConcertinaTreeComponent::AdditionalComponents;
addPanel ("File Explorer", new FileTreePanel (*project),
AdditionalComponents{}
.with (AdditionalComponents::addButton)
.with (AdditionalComponents::findPanel),
getIcons().fileExplorer);
addPanel ("Modules", new ModuleTreePanel (*project),
AdditionalComponents{}
.with (AdditionalComponents::addButton)
.with (AdditionalComponents::settingsButton),
getIcons().modules);
headers.add (new ConcertinaHeader ("File explorer", getIcons().fileExplorer));
headers.add (new ConcertinaHeader ("Modules", getIcons().modules));
headers.add (new ConcertinaHeader ("Exporters", getIcons().exporter));
addPanel ("Exporters", new ExportersTreePanel (*project),
AdditionalComponents{}.with (AdditionalComponents::addButton),
getIcons().exporter);
for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
{


+ 3
- 4
extras/Projucer/Source/Project/UI/Sidebar/jucer_ProjectTreeItemBase.h View File

@@ -35,17 +35,16 @@ struct ProjectTreeItemBase : public JucerTreeViewBase,
void showSettingsPage (Component* content)
{
content->setComponentID (getUniqueName());
std::unique_ptr<Component> comp (content);
if (ProjectContentComponent* pcc = getProjectContentComponent())
pcc->setEditorComponent (comp.release(), nullptr);
if (auto* pcc = getProjectContentComponent())
pcc->setScrollableEditorComponent (std::move (comp));
}
void closeSettingsPage()
{
if (auto* pcc = getProjectContentComponent())
if (auto* content = pcc->getEditorComponentContent())
if (auto* content = pcc->getEditorComponent())
if (content->getComponentID() == getUniqueName())
pcc->hideEditor();
}


+ 51
- 8
extras/Projucer/Source/Project/UI/Sidebar/jucer_TabComponents.h View File

@@ -34,11 +34,14 @@ public:
ConcertinaHeader (String n, Path p)
: Component (n), name (n), iconPath (p)
{
setTitle (getName());
panelIcon = Icon (iconPath, Colours::white);
nameLabel.setText (name, dontSendNotification);
nameLabel.setJustificationType (Justification::centredLeft);
nameLabel.setInterceptsMouseClicks (false, false);
nameLabel.setAccessible (false);
nameLabel.setColour (Label::textColourId, Colours::white);
addAndMakeVisible (nameLabel);
@@ -72,6 +75,14 @@ public:
sendChangeMessage();
}
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
{
return std::make_unique<AccessibilityHandler> (*this,
AccessibilityRole::button,
AccessibilityActions().addAction (AccessibilityActionType::press,
[this] { sendChangeMessage(); }));
}
int direction = 0;
int yPosition = 0;
@@ -166,25 +177,57 @@ private:
class ConcertinaTreeComponent : public Component
{
public:
ConcertinaTreeComponent (TreePanelBase* tree, bool hasAddButton = false,
bool hasSettingsButton = false, bool hasFindPanel = false)
: treeToDisplay (tree)
class AdditionalComponents
{
if (hasAddButton)
public:
enum Type
{
addButton = (1 << 0),
settingsButton = (1 << 1),
findPanel = (1 << 2)
};
AdditionalComponents with (Type t)
{
auto copy = *this;
copy.componentTypes |= t;
return copy;
}
bool has (Type t) const noexcept
{
return (componentTypes & t) != 0;
}
private:
int componentTypes = 0;
};
ConcertinaTreeComponent (const String& name,
TreePanelBase* tree,
AdditionalComponents additionalComponents)
: Component (name),
treeToDisplay (tree)
{
setTitle (getName());
setFocusContainerType (FocusContainerType::focusContainer);
if (additionalComponents.has (AdditionalComponents::addButton))
{
addButton = std::make_unique<IconButton> ("Add", getIcons().plus);
addAndMakeVisible (addButton.get());
addButton->onClick = [this] { showAddMenu(); };
}
if (hasSettingsButton)
if (additionalComponents.has (AdditionalComponents::settingsButton))
{
settingsButton = std::make_unique<IconButton> ("Settings", getIcons().settings);
addAndMakeVisible (settingsButton.get());
settingsButton->onClick = [this] { showSettings(); };
}
if (hasFindPanel)
if (additionalComponents.has (AdditionalComponents::findPanel))
{
findPanel = std::make_unique<FindPanel> ([this] (const String& filter) { treeToDisplay->rootItem->setSearchFilter (filter); });
addAndMakeVisible (findPanel.get());
@@ -232,12 +275,12 @@ private:
if (numSelected == 0)
{
if (auto* root = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getRootItem()))
root->showPopupMenu();
root->showPopupMenu (addButton->getScreenBounds().getCentre());
}
else
{
if (auto* item = dynamic_cast<JucerTreeViewBase*> (treeToDisplay->tree.getSelectedItem (0)))
item->showAddMenu();
item->showAddMenu (addButton->getScreenBounds().getCentre());
}
}


+ 112
- 0
extras/Projucer/Source/Project/UI/jucer_ContentViewComponent.h View File

@@ -0,0 +1,112 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
class ContentViewComponent : public Component
{
public:
ContentViewComponent()
{
setTitle ("Content");
setFocusContainerType (Component::FocusContainerType::focusContainer);
addAndMakeVisible (logoComponent);
addAndMakeVisible (fileNameLabel);
fileNameLabel.setJustificationType (Justification::centred);
}
void resized() override
{
auto bounds = getLocalBounds();
fileNameLabel.setBounds (bounds.removeFromTop (15));
if (content != nullptr)
content->setBounds (bounds);
else
logoComponent.setBounds (bounds);
}
Component* getCurrentComponent() noexcept
{
return content.get();
}
void setContent (std::unique_ptr<Component> newContent,
const String& labelText)
{
content = std::move (newContent);
addAndMakeVisible (content.get());
fileNameLabel.setVisible (labelText.isNotEmpty());
fileNameLabel.setText (labelText, dontSendNotification);
resized();
}
private:
class LogoComponent : public Component
{
public:
void paint (Graphics& g) override
{
g.setColour (findColour (defaultTextColourId));
auto bounds = getLocalBounds();
bounds.reduce (bounds.getWidth() / 6, bounds.getHeight() / 6);
g.setFont (15.0f);
g.drawFittedText (versionInfo, bounds.removeFromBottom (50), Justification::centredBottom, 3);
if (logo != nullptr)
logo->drawWithin (g, bounds.withTrimmedBottom (bounds.getHeight() / 4).toFloat(),
RectanglePlacement (RectanglePlacement::centred), 1.0f);
}
private:
std::unique_ptr<Drawable> logo = []() -> std::unique_ptr<Drawable>
{
if (auto svg = parseXML (BinaryData::background_logo_svg))
return Drawable::createFromSVG (*svg);
jassertfalse;
return {};
}();
String versionInfo = SystemStats::getJUCEVersion()
+ newLine
+ ProjucerApplication::getApp().getVersionDescription();
};
std::unique_ptr<Component> content;
LogoComponent logoComponent;
Label fileNameLabel;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentViewComponent)
};

+ 97
- 54
extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h View File

@@ -25,6 +25,7 @@
#pragma once
#include "../../Utility/UI/PropertyComponents/jucer_LabelPropertyComponent.h"
//==============================================================================
struct ContentViewHeader : public Component
@@ -32,6 +33,7 @@ struct ContentViewHeader : public Component
ContentViewHeader (String headerName, Icon headerIcon)
: name (headerName), icon (headerIcon)
{
setTitle (name);
}
void paint (Graphics& g) override
@@ -152,14 +154,18 @@ private:
};
//==============================================================================
class InfoButton : public Button
class InfoButton : public Button
{
public:
InfoButton (const String& infoToDisplay = {})
: Button ({})
{
setTitle ("Info");
if (infoToDisplay.isNotEmpty())
setInfoToDisplay (infoToDisplay);
setSize (20, 20);
}
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
@@ -196,6 +202,8 @@ public:
width = jmin (300, stringWidth);
numLines += static_cast<int> (stringWidth / width);
setHelpText (info);
}
}
@@ -242,37 +250,48 @@ public:
description (desc)
{
addAndMakeVisible (header);
description.setFont ({ 16.0f });
description.setColour (getLookAndFeel().findColour (defaultTextColourId));
description.setLineSpacing (5.0f);
description.setJustification (Justification::centredLeft);
}
void setProperties (const PropertyListBuilder& newProps)
{
infoButtons.clear();
properties.clear();
properties.addArray (newProps.components);
clearProperties();
for (auto* prop : properties)
if (description.isNotEmpty())
properties.push_back (std::make_unique<LabelPropertyComponent> (description, 16, Font (16.0f),
Justification::centredLeft));
for (auto* comp : newProps.components)
properties.push_back (std::unique_ptr<PropertyComponent> (comp));
for (auto& prop : properties)
{
addAndMakeVisible (prop);
const auto propertyTooltip = prop->getTooltip();
if (propertyTooltip.isNotEmpty())
{
// set the tooltip to empty so it only displays when its button is clicked
prop->setTooltip ({});
auto infoButton = std::make_unique<InfoButton> (propertyTooltip);
infoButton->setAssociatedComponent (prop.get());
if (! prop->getTooltip().isEmpty())
auto propertyAndInfoWrapper = std::make_unique<PropertyAndInfoWrapper> (*prop, *infoButton.get());
addAndMakeVisible (propertyAndInfoWrapper.get());
propertyComponentsWithInfo.push_back (std::move (propertyAndInfoWrapper));
infoButtons.push_back (std::move (infoButton));
}
else
{
addAndMakeVisible (infoButtons.add (new InfoButton (prop->getTooltip())));
infoButtons.getLast()->setAssociatedComponent (prop);
prop->setTooltip ({}); // set the tooltip to empty so it only displays when its button is clicked
addAndMakeVisible (prop.get());
}
if (auto* multiChoice = dynamic_cast<MultiChoicePropertyComponent*> (prop))
if (auto* multiChoice = dynamic_cast<MultiChoicePropertyComponent*> (prop.get()))
multiChoice->onHeightChange = [this] { updateSize(); };
if (auto* text = dynamic_cast<TextPropertyComponent*> (prop))
if (auto* text = dynamic_cast<TextPropertyComponent*> (prop.get()))
if (text->isTextEditorMultiLine())
text->addListener (this);
}
}
@@ -281,31 +300,21 @@ public:
header.setBounds (0, 0, width, headerSize);
auto height = header.getBottom() + 10;
descriptionLayout.createLayout (description, (float) (width - 40));
auto descriptionHeight = (int) descriptionLayout.getHeight();
if (descriptionHeight > 0)
height += (int) descriptionLayout.getHeight() + 25;
for (auto* pp : properties)
for (auto& pp : properties)
{
auto propertyHeight = pp->getPreferredHeight() + (getHeightMultiplier (pp) * pp->getPreferredHeight());
const auto propertyHeight = pp->getPreferredHeight()
+ (getHeightMultiplier (pp.get()) * pp->getPreferredHeight());
InfoButton* buttonToUse = nullptr;
for (auto* b : infoButtons)
if (b->getAssociatedComponent() == pp)
buttonToUse = b;
auto iter = std::find_if (propertyComponentsWithInfo.begin(), propertyComponentsWithInfo.end(),
[&pp] (const std::unique_ptr<PropertyAndInfoWrapper>& w) { return &w->propertyComponent == pp.get(); });
if (buttonToUse != nullptr)
{
buttonToUse->setSize (20, 20);
buttonToUse->setCentrePosition (20, height + (propertyHeight / 2));
}
pp->setBounds (40, height, width - 50, propertyHeight);
if (iter != propertyComponentsWithInfo.end())
(*iter)->setBounds (0, height, width - 10, propertyHeight);
else
pp->setBounds (40, height, width - 50, propertyHeight);
if (shouldResizePropertyComponent (pp))
resizePropertyComponent (pp);
if (shouldResizePropertyComponent (pp.get()))
resizePropertyComponent (pp.get());
height += pp->getHeight() + 10;
}
@@ -319,19 +328,51 @@ public:
void paint (Graphics& g) override
{
g.setColour (findColour (secondaryBackgroundColourId));
g.fillRect (getLocalBounds());
auto textArea = getLocalBounds().toFloat()
.withTop ((float) headerSize)
.reduced (20.0f, 10.0f)
.withHeight (descriptionLayout.getHeight());
descriptionLayout.draw (g, textArea);
g.fillAll (findColour (secondaryBackgroundColourId));
}
const std::vector<std::unique_ptr<PropertyComponent>>& getProperties() const noexcept
{
return properties;
}
OwnedArray<PropertyComponent> properties;
void clearProperties()
{
propertyComponentsWithInfo.clear();
infoButtons.clear();
properties.clear();
}
private:
//==============================================================================
struct PropertyAndInfoWrapper : public Component
{
PropertyAndInfoWrapper (PropertyComponent& c, InfoButton& i)
: propertyComponent (c),
infoButton (i)
{
setFocusContainerType (FocusContainerType::focusContainer);
setTitle (propertyComponent.getName());
addAndMakeVisible (propertyComponent);
addAndMakeVisible (infoButton);
}
void resized() override
{
auto bounds = getLocalBounds();
bounds.removeFromLeft (40);
bounds.removeFromRight (10);
propertyComponent.setBounds (bounds);
infoButton.setCentrePosition (20, bounds.getHeight() / 2);
}
PropertyComponent& propertyComponent;
InfoButton& infoButton;
};
//==============================================================================
void textPropertyComponentChanged (TextPropertyComponent* comp) override
{
@@ -348,7 +389,6 @@ private:
updateSize();
}
//==============================================================================
void updateSize()
{
updateSize (getX(), getY(), getWidth());
@@ -357,7 +397,6 @@ private:
parent->parentSizeChanged();
}
//==============================================================================
bool shouldResizePropertyComponent (PropertyComponent* p)
{
if (auto* textComp = dynamic_cast<TextPropertyComponent*> (p))
@@ -392,11 +431,15 @@ private:
return static_cast<int> (nameWidth / (float) availableTextWidth);
}
OwnedArray<InfoButton> infoButtons;
//==============================================================================
static constexpr int headerSize = 40;
std::vector<std::unique_ptr<PropertyComponent>> properties;
std::vector<std::unique_ptr<InfoButton>> infoButtons;
std::vector<std::unique_ptr<PropertyAndInfoWrapper>> propertyComponentsWithInfo;
ContentViewHeader header;
AttributedString description;
TextLayout descriptionLayout;
int headerSize = 40;
String description;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyGroupComponent)


+ 3
- 0
extras/Projucer/Source/Project/UI/jucer_HeaderComponent.cpp View File

@@ -40,6 +40,9 @@
HeaderComponent::HeaderComponent (ProjectContentComponent* pcc)
: projectContentComponent (pcc)
{
setTitle ("Header");
setFocusContainerType (FocusContainerType::focusContainer);
addAndMakeVisible (configLabel);
addAndMakeVisible (exporterBox);


+ 62
- 119
extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.cpp View File

@@ -34,63 +34,23 @@
NewFileWizard::Type* createGUIComponentWizard();
//==============================================================================
ProjectContentComponent::LogoComponent::LogoComponent()
{
if (auto svg = parseXML (BinaryData::background_logo_svg))
logo = Drawable::createFromSVG (*svg);
}
void ProjectContentComponent::LogoComponent::paint (Graphics& g)
{
g.setColour (findColour (defaultTextColourId));
auto r = getLocalBounds();
g.setFont (15.0f);
g.drawFittedText (getVersionInfo(), r.removeFromBottom (50), Justification::centredBottom, 3);
logo->drawWithin (g, r.withTrimmedBottom (r.getHeight() / 4).toFloat(),
RectanglePlacement (RectanglePlacement::centred), 1.0f);
}
String ProjectContentComponent::LogoComponent::getVersionInfo()
{
return SystemStats::getJUCEVersion()
+ newLine
+ ProjucerApplication::getApp().getVersionDescription();
}
//==============================================================================
ProjectContentComponent::ContentViewport::ContentViewport (Component* content)
{
addAndMakeVisible (viewport);
viewport.setViewedComponent (content, true);
}
void ProjectContentComponent::ContentViewport::resized()
{
viewport.setBounds (getLocalBounds());
}
//==============================================================================
ProjectContentComponent::ProjectContentComponent()
{
setOpaque (true);
setWantsKeyboardFocus (true);
addAndMakeVisible (logoComponent);
addAndMakeVisible (headerComponent);
addAndMakeVisible (projectMessagesComponent);
addAndMakeVisible (fileNameLabel);
fileNameLabel.setJustificationType (Justification::centred);
addAndMakeVisible (contentViewComponent);
sidebarSizeConstrainer.setMinimumWidth (200);
sidebarSizeConstrainer.setMaximumWidth (500);
sidebarTabs.setOutline (0);
sidebarTabs.getTabbedButtonBar().setMinimumTabScaleFactor (0.5);
sidebarTabs.setTitle ("Sidebar");
sidebarTabs.setFocusContainerType (FocusContainerType::focusContainer);
ProjucerApplication::getApp().openDocumentManager.addListener (this);
@@ -140,15 +100,9 @@ void ProjectContentComponent::resized()
if (resizerBar != nullptr)
resizerBar->setBounds (r.withWidth (4));
headerComponent.sidebarTabsWidthChanged (sidebarTabs.getWidth());
if (contentView != nullptr)
{
fileNameLabel.setBounds (r.removeFromTop (15));
contentView->setBounds (r);
}
contentViewComponent.setBounds (r);
logoComponent.setBounds (r.reduced (r.getWidth() / 6, r.getHeight() / 6));
headerComponent.sidebarTabsWidthChanged (sidebarTabs.getWidth());
}
void ProjectContentComponent::lookAndFeelChanged()
@@ -175,8 +129,8 @@ void ProjectContentComponent::setProject (Project* newProject)
if (project != nullptr)
project->removeChangeListener (this);
contentView.reset();
resizerBar.reset();
hideEditor();
resizerBar = nullptr;
deleteProjectTabs();
project = newProject;
@@ -360,16 +314,12 @@ void ProjectContentComponent::updateMissingFileStatuses()
tree->updateMissingFileStatuses();
}
bool ProjectContentComponent::showEditorForFile (const File& f, bool grabFocus)
bool ProjectContentComponent::showEditorForFile (const File& fileToShow, bool grabFocus)
{
if (getCurrentFile() == f
|| showDocument (ProjucerApplication::getApp().openDocumentManager.openFile (project, f), grabFocus))
{
fileNameLabel.setText (f.getFileName(), dontSendNotification);
return true;
}
if (getCurrentFile() != fileToShow)
return showDocument (ProjucerApplication::getApp().openDocumentManager.openFile (project, fileToShow), grabFocus);
return false;
return true;
}
bool ProjectContentComponent::hasFileInRecentList (const File& f) const
@@ -391,30 +341,22 @@ bool ProjectContentComponent::showDocument (OpenDocumentManager::Document* doc,
if (doc->hasFileBeenModifiedExternally())
doc->reloadFromFile();
if (doc == getCurrentDocument() && contentView != nullptr)
if (doc != getCurrentDocument())
{
if (grabFocus)
contentView->grabKeyboardFocus();
return true;
recentDocumentList.newDocumentOpened (doc);
setEditorDocument (doc->createEditor(), doc);
}
recentDocumentList.newDocumentOpened (doc);
auto opened = setEditorComponent (doc->createEditor(), doc);
if (opened && grabFocus && isShowing())
contentView->grabKeyboardFocus();
if (grabFocus)
contentViewComponent.grabKeyboardFocus();
return opened;
return true;
}
void ProjectContentComponent::hideEditor()
{
currentDocument = nullptr;
contentView.reset();
fileNameLabel.setVisible (false);
contentViewComponent.setContent ({}, {});
ProjucerApplication::getCommandManager().commandStatusChanged();
resized();
@@ -422,68 +364,69 @@ void ProjectContentComponent::hideEditor()
void ProjectContentComponent::hideDocument (OpenDocumentManager::Document* doc)
{
if (doc == currentDocument)
{
if (auto* replacement = recentDocumentList.getClosestPreviousDocOtherThan (doc))
showDocument (replacement, true);
else
hideEditor();
}
if (doc != currentDocument)
return;
if (auto* replacement = recentDocumentList.getClosestPreviousDocOtherThan (currentDocument))
showDocument (replacement, true);
else
hideEditor();
}
bool ProjectContentComponent::setEditorComponent (Component* editor,
OpenDocumentManager::Document* doc)
void ProjectContentComponent::setScrollableEditorComponent (std::unique_ptr<Component> component)
{
if (editor != nullptr)
{
contentView.reset();
jassert (component.get() != nullptr);
if (doc == nullptr)
class ContentViewport : public Component
{
public:
ContentViewport (std::unique_ptr<Component> content)
{
auto* viewport = new ContentViewport (editor);
contentView.reset (viewport);
currentDocument = nullptr;
fileNameLabel.setVisible (false);
addAndMakeVisible (viewport);
contentViewport.setViewedComponent (content.release(), true);
addAndMakeVisible (contentViewport);
}
else
{
contentView.reset (editor);
currentDocument = doc;
fileNameLabel.setText (doc->getFile().getFileName(), dontSendNotification);
fileNameLabel.setVisible (true);
addAndMakeVisible (editor);
void resized() override
{
contentViewport.setBounds (getLocalBounds());
}
resized();
private:
Viewport contentViewport;
};
ProjucerApplication::getCommandManager().commandStatusChanged();
return true;
}
contentViewComponent.setContent (std::make_unique<ContentViewport> (std::move (component)), {});
currentDocument = nullptr;
return false;
ProjucerApplication::getCommandManager().commandStatusChanged();
}
Component* ProjectContentComponent::getEditorComponentContent() const
void ProjectContentComponent::setEditorDocument (std::unique_ptr<Component> component, OpenDocumentManager::Document* doc)
{
if (contentView != nullptr)
if (auto* vp = dynamic_cast<ContentViewport*> (contentView.get()))
return vp->viewport.getViewedComponent();
currentDocument = doc;
contentViewComponent.setContent (std::move (component),
currentDocument != nullptr ? currentDocument->getFile().getFileName()
: String());
return nullptr;
ProjucerApplication::getCommandManager().commandStatusChanged();
}
Component* ProjectContentComponent::getEditorComponent()
{
return contentViewComponent.getCurrentComponent();
}
void ProjectContentComponent::closeDocument()
{
if (currentDocument != nullptr)
{
ProjucerApplication::getApp().openDocumentManager
.closeDocument (currentDocument, OpenDocumentManager::SaveIfNeeded::yes);
else if (contentView != nullptr)
if (! goToPreviousFile())
hideEditor();
return;
}
if (! goToPreviousFile())
hideEditor();
}
static void showSaveWarning (OpenDocumentManager::Document* currentDocument)
@@ -570,7 +513,7 @@ void ProjectContentComponent::closeProject()
void ProjectContentComponent::showProjectSettings()
{
setEditorComponent (new ProjectSettingsComponent (*project), nullptr);
setScrollableEditorComponent (std::make_unique<ProjectSettingsComponent> (*project));
}
void ProjectContentComponent::showCurrentExporterSettings()
@@ -634,7 +577,7 @@ void ProjectContentComponent::showModule (const String& moduleID)
void ProjectContentComponent::showLiveBuildSettings()
{
setEditorComponent (new LiveBuildSettingsComponent (*project), nullptr);
setScrollableEditorComponent (std::make_unique<LiveBuildSettingsComponent> (*project));
}
StringArray ProjectContentComponent::getExportersWhichCanLaunch() const
@@ -851,7 +794,7 @@ void ProjectContentComponent::getCommandInfo (const CommandID commandID, Applica
result.setInfo ("Close" + documentName,
"Closes the current document",
CommandCategories::general, 0);
result.setActive (contentView != nullptr);
result.setActive (currentDocument != nullptr);
result.defaultKeypresses.add ({ 'w', cmdCtrl, 0 });
break;


+ 10
- 28
extras/Projucer/Source/Project/UI/jucer_ProjectContentComponent.h View File

@@ -28,6 +28,7 @@
#include "../../CodeEditor/jucer_OpenDocumentManager.h"
#include "jucer_HeaderComponent.h"
#include "jucer_ProjectMessagesComponent.h"
#include "jucer_ContentViewComponent.h"
class CompileEngineChildProcess;
class ProjectTab;
@@ -65,10 +66,11 @@ public:
void saveAs();
void hideEditor();
bool setEditorComponent (Component* editor, OpenDocumentManager::Document* doc);
Component* getEditorComponentContent() const;
Component* getEditorComponent() const { return contentView.get(); }
Component& getSidebarComponent() { return sidebarTabs; }
void setScrollableEditorComponent (std::unique_ptr<Component> component);
void setEditorDocument (std::unique_ptr<Component> component, OpenDocumentManager::Document* doc);
Component* getEditorComponent();
Component& getSidebarComponent() { return sidebarTabs; }
bool goToPreviousFile();
bool goToNextFile();
@@ -144,26 +146,6 @@ public:
static String getBuildTabName() { return "Build"; }
private:
//==============================================================================
struct LogoComponent : public Component
{
LogoComponent();
void paint (Graphics& g) override;
static String getVersionInfo();
std::unique_ptr<Drawable> logo;
};
struct ContentViewport : public Component
{
ContentViewport (Component* content);
void resized() override;
Viewport viewport;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentViewport)
};
//==============================================================================
bool documentAboutToClose (OpenDocumentManager::Document*) override;
void changeListenerCallback (ChangeBroadcaster*) override;
@@ -196,14 +178,14 @@ private:
OpenDocumentManager::Document* currentDocument = nullptr;
RecentDocumentList recentDocumentList;
LogoComponent logoComponent;
HeaderComponent headerComponent { this };
TabbedComponent sidebarTabs { TabbedButtonBar::TabsAtTop };
ProjectMessagesComponent projectMessagesComponent;
Label fileNameLabel;
TabbedComponent sidebarTabs { TabbedButtonBar::TabsAtTop };
ContentViewComponent contentViewComponent;
std::unique_ptr<ResizableEdgeComponent> resizerBar;
ComponentBoundsConstrainer sidebarSizeConstrainer;
std::unique_ptr<Component> translationTool, contentView;
std::unique_ptr<Component> translationTool;
BubbleMessageComponent bubbleMessage;
ReferenceCountedObjectPtr<CompileEngineChildProcess> childProcess;


+ 29
- 2
extras/Projucer/Source/Project/UI/jucer_ProjectMessagesComponent.h View File

@@ -392,6 +392,9 @@ class ProjectMessagesComponent : public Component
public:
ProjectMessagesComponent()
{
setFocusContainerType (FocusContainerType::focusContainer);
setTitle ("Project Messages");
addAndMakeVisible (warningsComponent);
addAndMakeVisible (notificationsComponent);
@@ -445,8 +448,15 @@ public:
isMouseDown = false;
repaint();
if (messagesWindow != nullptr)
showOrHideAllMessages (! messagesWindow->isListShowing());
showOrHideMessagesWindow();
}
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
{
return std::make_unique<AccessibilityHandler> (*this,
AccessibilityRole::button,
AccessibilityActions().addAction (AccessibilityActionType::press,
[this] { showOrHideMessagesWindow(); }));
}
//==============================================================================
@@ -475,6 +485,20 @@ public:
}
}
void numMessagesChanged()
{
const auto total = warningsComponent.getNumMessages()
+ notificationsComponent.getNumMessages();
setHelpText (String (total) + (total == 1 ? " message" : " messages"));
}
void showOrHideMessagesWindow()
{
if (messagesWindow != nullptr)
showOrHideAllMessages (! messagesWindow->isListShowing());
}
private:
//==============================================================================
struct MessageCountComponent : public Component,
@@ -511,9 +535,12 @@ private:
void updateNumMessages()
{
numMessages = messagesTree.getNumChildren();
owner.numMessagesChanged();
repaint();
}
int getNumMessages() const noexcept { return numMessages; }
private:
void valueTreeChildAdded (ValueTree&, ValueTree&) override { updateNumMessages(); }
void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override { updateNumMessages(); }


+ 14
- 0
extras/Projucer/Source/Project/UI/jucer_UserAvatarComponent.h View File

@@ -64,6 +64,11 @@ public:
}
void mouseUp (const MouseEvent&) override
{
triggerClick();
}
void triggerClick()
{
if (interactive)
{
@@ -76,6 +81,15 @@ public:
bool isDisplaingGPLLogo() const noexcept { return isGPL; }
std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
{
return interactive ? std::make_unique<AccessibilityHandler> (*this,
AccessibilityRole::button,
AccessibilityActions().addAction (AccessibilityActionType::press,
[this] { triggerClick(); }))
: nullptr;
}
private:
//==============================================================================
static Image createGPLAvatarImage()


+ 16
- 0
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_MSVC.h View File

@@ -845,6 +845,17 @@ public:
{
auto extraCompilerFlags = owner.compilerFlagSchemesMap[projectItem.getCompilerFlagSchemeString()].get().toString();
if (shouldAddBigobjFlag (path))
{
const String bigobjFlag ("/bigobj");
if (! extraCompilerFlags.contains (bigobjFlag))
{
extraCompilerFlags << " " << bigobjFlag;
extraCompilerFlags.trim();
}
}
if (extraCompilerFlags.isNotEmpty())
e->createNewChildElement ("AdditionalOptions")->addTextElement (extraCompilerFlags + " %(AdditionalOptions)");
@@ -1729,6 +1740,11 @@ protected:
return path.getFileNameWithoutExtension().startsWithIgnoreCase ("include_juce_audio_plugin_client_RTAS_");
}
static bool shouldAddBigobjFlag (const build_tools::RelativePath& path)
{
return path.getFileNameWithoutExtension().equalsIgnoreCase ("include_juce_gui_basics");
}
StringArray getModuleLibs() const
{
StringArray result;


+ 6
- 17
extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.cpp View File

@@ -119,9 +119,9 @@ void JucerTreeViewBase::paintContent (Graphics& g, Rectangle<int> area)
g.drawFittedText (getDisplayName(), area, Justification::centredLeft, 1, 1.0f);
}
Component* JucerTreeViewBase::createItemComponent()
std::unique_ptr<Component> JucerTreeViewBase::createItemComponent()
{
return new TreeItemComponent (*this);
return std::make_unique<TreeItemComponent> (*this);
}
//==============================================================================
@@ -177,9 +177,9 @@ void JucerTreeViewBase::itemClicked (const MouseEvent& e)
if (e.mods.isPopupMenu())
{
if (getOwnerView()->getNumSelectedItems() > 1)
showMultiSelectionPopupMenu();
showMultiSelectionPopupMenu (e.getMouseDownScreenPosition());
else
showPopupMenu();
showPopupMenu (e.getMouseDownScreenPosition());
}
else if (isSelected())
{
@@ -187,29 +187,18 @@ void JucerTreeViewBase::itemClicked (const MouseEvent& e)
}
}
void JucerTreeViewBase::deleteItem() {}
void JucerTreeViewBase::deleteAllSelectedItems() {}
void JucerTreeViewBase::showDocument() {}
void JucerTreeViewBase::showPopupMenu() {}
void JucerTreeViewBase::showAddMenu() {}
void JucerTreeViewBase::showMultiSelectionPopupMenu() {}
static void treeViewMenuItemChosen (int resultCode, WeakReference<JucerTreeViewBase> item)
{
if (item != nullptr)
item->handlePopupMenuResult (resultCode);
}
void JucerTreeViewBase::launchPopupMenu (PopupMenu& m)
void JucerTreeViewBase::launchPopupMenu (PopupMenu& m, Point<int> p)
{
m.showMenuAsync (PopupMenu::Options(),
m.showMenuAsync (PopupMenu::Options().withTargetScreenArea ({ p.x, p.y, 1, 1 }),
ModalCallbackFunction::create (treeViewMenuItemChosen, WeakReference<JucerTreeViewBase> (this)));
}
void JucerTreeViewBase::handlePopupMenuResult (int)
{
}
ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const
{
for (Component* c = getOwnerView(); c != nullptr; c = c->getParentComponent())


+ 17
- 14
extras/Projucer/Source/Utility/UI/jucer_JucerTreeViewBase.h View File

@@ -44,8 +44,9 @@ public:
void itemClicked (const MouseEvent& e) override;
void itemSelectionChanged (bool isNowSelected) override;
void itemDoubleClicked (const MouseEvent&) override;
Component* createItemComponent() override;
String getTooltip() override { return {}; }
std::unique_ptr<Component> createItemComponent() override;
String getTooltip() override { return {}; }
String getAccessibilityName() override { return getDisplayName(); }
void cancelDelayedSelectionTimer();
@@ -67,17 +68,18 @@ public:
virtual File getDraggableFile() const { return {}; }
void refreshSubItems();
virtual void deleteItem();
virtual void deleteAllSelectedItems();
virtual void showDocument();
virtual void showMultiSelectionPopupMenu();
virtual void showRenameBox();
void launchPopupMenu (PopupMenu&); // runs asynchronously, and produces a callback to handlePopupMenuResult().
virtual void showPopupMenu();
virtual void showAddMenu();
virtual void handlePopupMenuResult (int resultCode);
virtual void setSearchFilter (const String&) {}
void showRenameBox();
virtual void deleteItem() {}
virtual void deleteAllSelectedItems() {}
virtual void showDocument() {}
virtual void showMultiSelectionPopupMenu (Point<int>) {}
virtual void showPopupMenu (Point<int>) {}
virtual void showAddMenu (Point<int>) {}
virtual void handlePopupMenuResult (int) {}
virtual void setSearchFilter (const String&) {}
void launchPopupMenu (PopupMenu&, Point<int>); // runs asynchronously, and produces a callback to handlePopupMenuResult().
//==============================================================================
// To handle situations where an item gets deleted before openness is
@@ -187,7 +189,7 @@ public:
tree.clearSelectedItems();
if (e.mods.isRightButtonDown())
rootItem->showPopupMenu();
rootItem->showPopupMenu (e.getMouseDownScreenPosition());
}
}
@@ -205,6 +207,7 @@ class TreeItemComponent : public Component
public:
TreeItemComponent (JucerTreeViewBase& i) : item (&i)
{
setAccessible (false);
setInterceptsMouseClicks (false, true);
item->textX = iconWidth;
}


Loading…
Cancel
Save