|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2022 - 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 7 End-User License
- Agreement and JUCE Privacy Policy.
-
- End User License Agreement: www.juce.com/juce-7-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.
-
- ==============================================================================
- */
-
- #include "../jucer_Headers.h"
- #include "../jucer_Application.h"
-
- #include "jucer_StartPageComponent.h"
- #include "jucer_StartPageTreeHolder.h"
- #include "jucer_NewProjectTemplates.h"
- #include "jucer_ContentComponents.h"
-
- //==============================================================================
- struct ContentComponent : public Component
- {
- ContentComponent()
- {
- setTitle ("Content");
- setFocusContainerType (FocusContainerType::focusContainer);
- }
-
- void resized() override
- {
- if (content != nullptr)
- content->setBounds (getLocalBounds());
- }
-
- void setContent (std::unique_ptr<Component>&& newContent)
- {
- if (content.get() != newContent.get())
- {
- content = std::move (newContent);
- addAndMakeVisible (content.get());
- resized();
- }
- }
-
- private:
- std::unique_ptr<Component> content;
-
- //==============================================================================
- JUCE_LEAK_DETECTOR (ContentComponent)
- };
-
- //==============================================================================
- static File findExampleFile (int dirIndex, int index)
- {
- auto dir = ProjucerApplication::getSortedExampleDirectories()[dirIndex];
- return ProjucerApplication::getSortedExampleFilesInDirectory (dir)[index];
- }
-
- static std::unique_ptr<Component> createExampleProjectsTab (ContentComponent& content, std::function<void (const File&)> cb)
- {
- StringArray exampleCategories;
- std::vector<StringArray> examples;
-
- for (auto& dir : ProjucerApplication::getSortedExampleDirectories())
- {
- exampleCategories.add (dir.getFileName());
-
- StringArray ex;
- for (auto& f : ProjucerApplication::getSortedExampleFilesInDirectory (dir))
- ex.add (f.getFileNameWithoutExtension());
-
- examples.push_back (ex);
- }
-
- if (exampleCategories.isEmpty())
- return nullptr;
-
- auto selectedCallback = [&, cb] (int category, int index) mutable
- {
- content.setContent (std::make_unique<ExampleComponent> (findExampleFile (category, index), cb));
- };
-
- return std::make_unique<StartPageTreeHolder> ("Examples",
- exampleCategories,
- examples,
- std::move (selectedCallback),
- StartPageTreeHolder::Open::no);
- }
-
- //==============================================================================
- static StringArray getAllTemplateCategoryStrings()
- {
- StringArray categories;
-
- for (auto& t : NewProjectTemplates::getAllTemplates())
- categories.addIfNotAlreadyThere (NewProjectTemplates::getProjectCategoryString (t.category));
-
- return categories;
- }
-
- static std::vector<NewProjectTemplates::ProjectTemplate> getTemplatesInCategory (const String& category)
- {
- std::vector<NewProjectTemplates::ProjectTemplate> templates;
-
- for (auto& t : NewProjectTemplates::getAllTemplates())
- if (NewProjectTemplates::getProjectCategoryString (t.category) == category)
- templates.push_back (t);
-
- return templates;
- }
-
- static StringArray getAllTemplateNamesForCategory (const String& category)
- {
- StringArray types;
-
- for (auto& t : getTemplatesInCategory (category))
- types.add (t.displayName);
-
- return types;
- }
-
- static std::unique_ptr<Component> createProjectTemplatesTab (ContentComponent& content,
- std::function<void (std::unique_ptr<Project>&&)>&& cb)
- {
- auto categories = getAllTemplateCategoryStrings();
-
- std::vector<StringArray> templateNames;
-
- for (auto& c : categories)
- templateNames.push_back (getAllTemplateNamesForCategory (c));
-
- auto selectedCallback = [&, cb] (int category, int index)
- {
- auto categoryString = getAllTemplateCategoryStrings()[category];
- auto templates = getTemplatesInCategory (categoryString);
-
- content.setContent (std::make_unique<TemplateComponent> (templates[(size_t) index], std::move (cb)));
- };
-
- auto holder = std::make_unique<StartPageTreeHolder> ("Templates",
- categories,
- templateNames,
- std::move (selectedCallback),
- StartPageTreeHolder::Open::yes);
- holder->setSelectedItem (categories[0], 1);
-
- JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wredundant-move")
- return std::move (holder);
- JUCE_END_IGNORE_WARNINGS_GCC_LIKE
- }
-
- //==============================================================================
- struct ProjectTemplatesAndExamples : public TabbedComponent
- {
- ProjectTemplatesAndExamples (ContentComponent& c,
- std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb,
- std::function<void (const File&)>&& exampleCb)
- : TabbedComponent (TabbedButtonBar::Orientation::TabsAtTop),
- content (c),
- exampleSelectedCallback (std::move (exampleCb))
- {
- setTitle ("Templates and Examples");
- setFocusContainerType (FocusContainerType::focusContainer);
-
- addTab ("New Project",
- Colours::transparentBlack,
- createProjectTemplatesTab (content, std::move (newProjectCb)).release(),
- true);
-
- refreshExamplesTab();
- }
-
- void refreshExamplesTab()
- {
- auto wasOpen = (getCurrentTabIndex() == 1);
-
- removeTab (1);
-
- auto exampleTabs = createExampleProjectsTab (content, exampleSelectedCallback);
-
- addTab ("Open Example",
- Colours::transparentBlack,
- exampleTabs == nullptr ? new SetJUCEPathComponent (*this) : exampleTabs.release(),
- true);
-
- if (wasOpen)
- setCurrentTabIndex (1);
- }
-
- private:
- //==============================================================================
- struct SetJUCEPathComponent : public Component,
- private ChangeListener
- {
- explicit SetJUCEPathComponent (ProjectTemplatesAndExamples& o)
- : owner (o)
- {
- getGlobalProperties().addChangeListener (this);
-
- setPathButton.setButtonText ("Set path to JUCE...");
- setPathButton.onClick = [] { ProjucerApplication::getApp().showPathsWindow (true); };
-
- addAndMakeVisible (setPathButton);
- }
-
- ~SetJUCEPathComponent() override
- {
- getGlobalProperties().removeChangeListener (this);
- }
-
- void paint (Graphics& g) override
- {
- g.fillAll (findColour (secondaryBackgroundColourId));
- }
-
- void resized() override
- {
- auto bounds = getLocalBounds().reduced (5);
- bounds.removeFromTop (25);
-
- setPathButton.setBounds (bounds.removeFromTop (25));
- }
-
- private:
- void changeListenerCallback (ChangeBroadcaster*) override
- {
- if (isValidJUCEExamplesDirectory (ProjucerApplication::getJUCEExamplesDirectoryPathFromGlobal()))
- owner.refreshExamplesTab();
- }
-
- ProjectTemplatesAndExamples& owner;
- TextButton setPathButton;
- };
-
- ContentComponent& content;
- std::function<void (const File&)> exampleSelectedCallback;
- };
-
- //==============================================================================
- StartPageComponent::StartPageComponent (std::function<void (std::unique_ptr<Project>&&)>&& newProjectCb,
- std::function<void (const File&)>&& exampleCb)
- : content (std::make_unique<ContentComponent>()),
- tabs (std::make_unique<ProjectTemplatesAndExamples> (*content, std::move (newProjectCb), std::move (exampleCb)))
- {
- tabs->setOutline (0);
- addAndMakeVisible (*tabs);
-
- addAndMakeVisible (openExistingButton);
- openExistingButton.setCommandToTrigger (&ProjucerApplication::getCommandManager(), CommandIDs::open, true);
-
- addAndMakeVisible (*content);
-
- setSize (900, 600);
- }
-
- void StartPageComponent::paint (Graphics& g)
- {
- g.fillAll (findColour (backgroundColourId));
- }
-
- void StartPageComponent::resized()
- {
- auto bounds = getLocalBounds().reduced (10);
-
- auto tabBounds = bounds.removeFromLeft (bounds.getWidth() / 3);
-
- openExistingButton.setBounds (tabBounds.removeFromBottom (30).reduced (10, 0));
- tabBounds.removeFromBottom (5);
-
- tabs->setBounds (tabBounds);
- bounds.removeFromLeft (10);
-
- content->setBounds (bounds);
- }
|