mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-26 02:14:22 +00:00
Projucer: Accessibility updates
This commit is contained in:
parent
ec990202b1
commit
69085b2a61
31 changed files with 567 additions and 333 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ("File explorer", getIcons().fileExplorer));
|
||||
headers.add (new ConcertinaHeader ("Modules", getIcons().modules));
|
||||
headers.add (new ConcertinaHeader ("Exporters", getIcons().exporter));
|
||||
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);
|
||||
|
||||
addPanel ("Exporters", new ExportersTreePanel (*project),
|
||||
AdditionalComponents{}.with (AdditionalComponents::addButton),
|
||||
getIcons().exporter);
|
||||
|
||||
for (int i = 0; i < concertinaPanel.getNumPanels(); ++i)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
extras/Projucer/Source/Project/UI/jucer_ContentViewComponent.h
Normal file
112
extras/Projucer/Source/Project/UI/jucer_ContentViewComponent.h
Normal 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)
|
||||
};
|
||||
|
|
@ -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 (! prop->getTooltip().isEmpty())
|
||||
if (propertyTooltip.isNotEmpty())
|
||||
{
|
||||
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
|
||||
// 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());
|
||||
|
||||
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 (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));
|
||||
}
|
||||
if (iter != propertyComponentsWithInfo.end())
|
||||
(*iter)->setBounds (0, height, width - 10, propertyHeight);
|
||||
else
|
||||
pp->setBounds (40, height, width - 50, propertyHeight);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
OwnedArray<PropertyComponent> properties;
|
||||
const std::vector<std::unique_ptr<PropertyComponent>>& getProperties() const noexcept
|
||||
{
|
||||
return 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)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@
|
|||
HeaderComponent::HeaderComponent (ProjectContentComponent* pcc)
|
||||
: projectContentComponent (pcc)
|
||||
{
|
||||
setTitle ("Header");
|
||||
setFocusContainerType (FocusContainerType::focusContainer);
|
||||
|
||||
addAndMakeVisible (configLabel);
|
||||
addAndMakeVisible (exporterBox);
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
contentViewComponent.setBounds (r);
|
||||
|
||||
headerComponent.sidebarTabsWidthChanged (sidebarTabs.getWidth());
|
||||
|
||||
if (contentView != nullptr)
|
||||
{
|
||||
fileNameLabel.setBounds (r.removeFromTop (15));
|
||||
contentView->setBounds (r);
|
||||
}
|
||||
|
||||
logoComponent.setBounds (r.reduced (r.getWidth() / 6, r.getHeight() / 6));
|
||||
}
|
||||
|
||||
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);
|
||||
if (grabFocus)
|
||||
contentViewComponent.grabKeyboardFocus();
|
||||
|
||||
auto opened = setEditorComponent (doc->createEditor(), doc);
|
||||
|
||||
if (opened && grabFocus && isShowing())
|
||||
contentView->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)
|
||||
jassert (component.get() != nullptr);
|
||||
|
||||
class ContentViewport : public Component
|
||||
{
|
||||
contentView.reset();
|
||||
|
||||
if (doc == nullptr)
|
||||
public:
|
||||
ContentViewport (std::unique_ptr<Component> content)
|
||||
{
|
||||
auto* viewport = new ContentViewport (editor);
|
||||
|
||||
contentView.reset (viewport);
|
||||
currentDocument = nullptr;
|
||||
fileNameLabel.setVisible (false);
|
||||
|
||||
addAndMakeVisible (viewport);
|
||||
}
|
||||
else
|
||||
{
|
||||
contentView.reset (editor);
|
||||
currentDocument = doc;
|
||||
fileNameLabel.setText (doc->getFile().getFileName(), dontSendNotification);
|
||||
fileNameLabel.setVisible (true);
|
||||
|
||||
addAndMakeVisible (editor);
|
||||
contentViewport.setViewedComponent (content.release(), true);
|
||||
addAndMakeVisible (contentViewport);
|
||||
}
|
||||
|
||||
resized();
|
||||
void resized() override
|
||||
{
|
||||
contentViewport.setBounds (getLocalBounds());
|
||||
}
|
||||
|
||||
ProjucerApplication::getCommandManager().commandStatusChanged();
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
Viewport contentViewport;
|
||||
};
|
||||
|
||||
return false;
|
||||
contentViewComponent.setContent (std::make_unique<ContentViewport> (std::move (component)), {});
|
||||
currentDocument = nullptr;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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 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&) {}
|
||||
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…
Add table
Add a link
Reference in a new issue