diff --git a/extras/Introjucer/Source/Application/jucer_AppearanceSettings.cpp b/extras/Introjucer/Source/Application/jucer_AppearanceSettings.cpp index 91d63ad227..83cf37bf4e 100644 --- a/extras/Introjucer/Source/Application/jucer_AppearanceSettings.cpp +++ b/extras/Introjucer/Source/Application/jucer_AppearanceSettings.cpp @@ -38,7 +38,6 @@ namespace AppearanceColours static const ColourInfo colours[] = { { "Main Window Bkgd", mainBackgroundColourId, true }, - { "Project Panel Bkgd", projectPanelBackgroundColourId, true }, { "Treeview Highlight", treeviewHighlightColourId, false }, { "Code Background", CodeEditorComponent::backgroundColourId, true }, @@ -460,7 +459,6 @@ Component* AppearanceSettings::createEditorWindow() IntrojucerLookAndFeel::IntrojucerLookAndFeel() { setColour (mainBackgroundColourId, Colour::greyLevel (0.8f)); - setColour (projectPanelBackgroundColourId, Colour::greyLevel (0.93f)); setColour (treeviewHighlightColourId, Colour (0x401111ee)); } diff --git a/extras/Introjucer/Source/Application/jucer_AppearanceSettings.h b/extras/Introjucer/Source/Application/jucer_AppearanceSettings.h index 0e0f980f26..1d15ee8fd9 100644 --- a/extras/Introjucer/Source/Application/jucer_AppearanceSettings.h +++ b/extras/Introjucer/Source/Application/jucer_AppearanceSettings.h @@ -78,13 +78,72 @@ class IntrojucerLookAndFeel : public LookAndFeel public: IntrojucerLookAndFeel(); + int getTabButtonOverlap (int tabDepth) { return -1; } + int getTabButtonSpaceAroundImage() { return 1; } + int getTabButtonBestWidth (TabBarButton& button, int tabDepth) { return 120; } + + void createTabTextLayout (const TabBarButton& button, const Rectangle& textArea, GlyphArrangement& textLayout) + { + Font font (textArea.getHeight() * 0.5f); + font.setUnderline (button.hasKeyboardFocus (false)); + + textLayout.addFittedText (font, button.getButtonText().trim(), + (float) textArea.getX(), (float) textArea.getY(), (float) textArea.getWidth(), (float) textArea.getHeight(), + Justification::centred, 1); + } + + static Colour getTabBackgroundColour (TabBarButton& button) + { + Colour normalBkg (button.getTabBackgroundColour()); + Colour bkg (normalBkg.contrasting (0.15f)); + if (button.isFrontTab()) + bkg = bkg.overlaidWith (Colours::yellow.withAlpha (0.5f)); + + return bkg; + } + + void drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) + { + const Rectangle activeArea (button.getActiveArea()); + + Colour bkg (getTabBackgroundColour (button)); + + g.setGradientFill (ColourGradient (bkg.brighter (0.1f), 0, (float) activeArea.getY(), + bkg.darker (0.1f), 0, (float) activeArea.getBottom(), false)); + g.fillRect (activeArea); + + g.setColour (button.getTabBackgroundColour().darker (0.3f)); + g.drawRect (activeArea); + + GlyphArrangement textLayout; + createTabTextLayout (button, button.getTextArea(), textLayout); + + const float alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f; + g.setColour (bkg.contrasting().withMultipliedAlpha (alpha)); + textLayout.draw (g); + } + + Rectangle getTabButtonExtraComponentBounds (const TabBarButton& button, Rectangle& textArea, Component& comp) + { + GlyphArrangement textLayout; + createTabTextLayout (button, textArea, textLayout); + const int textWidth = (int) textLayout.getBoundingBox (0, -1, false).getWidth(); + const int extraSpace = jmax (0, textArea.getWidth() - (textWidth + comp.getWidth())) / 2; + + textArea.removeFromRight (extraSpace); + textArea.removeFromLeft (extraSpace); + return textArea.removeFromRight (comp.getWidth()); + } + + void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int, int) {} + void drawStretchableLayoutResizerBar (Graphics& g, int /*w*/, int /*h*/, bool /*isVerticalBar*/, bool isMouseOver, bool isMouseDragging) { if (isMouseOver || isMouseDragging) - g.fillAll (Colours::grey.withAlpha (0.4f)); + g.fillAll (Colours::yellow.withAlpha (0.4f)); } - Rectangle getPropertyComponentContentPosition (PropertyComponent& component); + Rectangle getPropertyComponentContentPosition (PropertyComponent&); }; diff --git a/extras/Introjucer/Source/Application/jucer_CommonHeaders.h b/extras/Introjucer/Source/Application/jucer_CommonHeaders.h index 2ac8cdb148..332dfa87ff 100644 --- a/extras/Introjucer/Source/Application/jucer_CommonHeaders.h +++ b/extras/Introjucer/Source/Application/jucer_CommonHeaders.h @@ -51,7 +51,6 @@ const char* const sourceOrHeaderFileExtensions = "cpp;mm;m;c;cc;cxx;h;hpp;hxx"; enum ColourIds { mainBackgroundColourId = 0x2340000, - projectPanelBackgroundColourId = 0x2340001, treeviewHighlightColourId = 0x2340002, }; diff --git a/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp b/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp index db9458dc1b..61cc207b9f 100644 --- a/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp +++ b/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp @@ -26,76 +26,6 @@ #include "jucer_SourceCodeEditor.h" #include "../Application/jucer_OpenDocumentManager.h" - -//============================================================================== -SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* document_) - : DocumentEditorComponent (document_) -{ -} - -SourceCodeEditor::~SourceCodeEditor() -{ - getAppSettings().appearance.settings.removeListener (this); - - SourceCodeDocument* doc = dynamic_cast (getDocument()); - - if (doc != nullptr) - doc->updateLastState (*editor); -} - -void SourceCodeEditor::createEditor (CodeDocument& codeDocument) -{ - if (document->getFile().hasFileExtension (sourceOrHeaderFileExtensions)) - setEditor (new CppCodeEditorComponent (codeDocument)); - else - setEditor (new CodeEditorComponent (codeDocument, nullptr)); -} - -void SourceCodeEditor::setEditor (CodeEditorComponent* newEditor) -{ - addAndMakeVisible (editor = newEditor); - - #if JUCE_MAC - Font font (13.0f); - font.setTypefaceName ("Menlo"); - #else - Font font (12.0f); - font.setTypefaceName (Font::getDefaultMonospacedFontName()); - #endif - editor->setFont (font); - - editor->setTabSize (4, true); - - updateColourScheme(); - getAppSettings().appearance.settings.addListener (this); -} - -void SourceCodeEditor::highlightLine (int lineNum, int characterIndex) -{ - if (lineNum <= editor->getFirstLineOnScreen() - || lineNum >= editor->getFirstLineOnScreen() + editor->getNumLinesOnScreen() - 1) - { - editor->scrollToLine (jmax (0, jmin (lineNum - editor->getNumLinesOnScreen() / 3, - editor->getDocument().getNumLines() - editor->getNumLinesOnScreen()))); - } - - editor->moveCaretTo (CodeDocument::Position (&editor->getDocument(), lineNum - 1, characterIndex), false); -} - -void SourceCodeEditor::resized() -{ - editor->setBounds (getLocalBounds()); -} - -void SourceCodeEditor::updateColourScheme() { getAppSettings().appearance.applyToCodeEditor (*editor); } - -void SourceCodeEditor::valueTreePropertyChanged (ValueTree&, const Identifier&) { updateColourScheme(); } -void SourceCodeEditor::valueTreeChildAdded (ValueTree&, ValueTree&) { updateColourScheme(); } -void SourceCodeEditor::valueTreeChildRemoved (ValueTree&, ValueTree&) { updateColourScheme(); } -void SourceCodeEditor::valueTreeChildOrderChanged (ValueTree&) { updateColourScheme(); } -void SourceCodeEditor::valueTreeParentChanged (ValueTree&) { updateColourScheme(); } -void SourceCodeEditor::valueTreeRedirected (ValueTree&) { updateColourScheme(); } - //============================================================================== SourceCodeDocument::SourceCodeDocument (Project* project_, const File& file_) : modDetector (file_), project (project_) @@ -167,3 +97,72 @@ void SourceCodeDocument::applyLastState (CodeEditorComponent& editor) const if (lastState != nullptr) lastState->restoreState (editor); } + +//============================================================================== +SourceCodeEditor::SourceCodeEditor (OpenDocumentManager::Document* document_) + : DocumentEditorComponent (document_) +{ +} + +SourceCodeEditor::~SourceCodeEditor() +{ + getAppSettings().appearance.settings.removeListener (this); + + SourceCodeDocument* doc = dynamic_cast (getDocument()); + + if (doc != nullptr) + doc->updateLastState (*editor); +} + +void SourceCodeEditor::createEditor (CodeDocument& codeDocument) +{ + if (document->getFile().hasFileExtension (sourceOrHeaderFileExtensions)) + setEditor (new CppCodeEditorComponent (codeDocument)); + else + setEditor (new CodeEditorComponent (codeDocument, nullptr)); +} + +void SourceCodeEditor::setEditor (CodeEditorComponent* newEditor) +{ + addAndMakeVisible (editor = newEditor); + + #if JUCE_MAC + Font font (13.0f); + font.setTypefaceName ("Menlo"); + #else + Font font (12.0f); + font.setTypefaceName (Font::getDefaultMonospacedFontName()); + #endif + editor->setFont (font); + + editor->setTabSize (4, true); + + updateColourScheme(); + getAppSettings().appearance.settings.addListener (this); +} + +void SourceCodeEditor::highlightLine (int lineNum, int characterIndex) +{ + if (lineNum <= editor->getFirstLineOnScreen() + || lineNum >= editor->getFirstLineOnScreen() + editor->getNumLinesOnScreen() - 1) + { + editor->scrollToLine (jmax (0, jmin (lineNum - editor->getNumLinesOnScreen() / 3, + editor->getDocument().getNumLines() - editor->getNumLinesOnScreen()))); + } + + editor->moveCaretTo (CodeDocument::Position (&editor->getDocument(), lineNum - 1, characterIndex), false); +} + +void SourceCodeEditor::resized() +{ + editor->setBounds (getLocalBounds()); +} + +void SourceCodeEditor::updateColourScheme() { getAppSettings().appearance.applyToCodeEditor (*editor); } + +void SourceCodeEditor::valueTreePropertyChanged (ValueTree&, const Identifier&) { updateColourScheme(); } +void SourceCodeEditor::valueTreeChildAdded (ValueTree&, ValueTree&) { updateColourScheme(); } +void SourceCodeEditor::valueTreeChildRemoved (ValueTree&, ValueTree&) { updateColourScheme(); } +void SourceCodeEditor::valueTreeChildOrderChanged (ValueTree&) { updateColourScheme(); } +void SourceCodeEditor::valueTreeParentChanged (ValueTree&) { updateColourScheme(); } +void SourceCodeEditor::valueTreeRedirected (ValueTree&) { updateColourScheme(); } diff --git a/extras/Introjucer/Source/Project/jucer_ConfigPage.h b/extras/Introjucer/Source/Project/jucer_ConfigPage.h index fbbb272cf6..1ba614b663 100644 --- a/extras/Introjucer/Source/Project/jucer_ConfigPage.h +++ b/extras/Introjucer/Source/Project/jucer_ConfigPage.h @@ -50,7 +50,7 @@ public: int updateSize (int x, int y, int width) { - int height = 36; + int height = 38; for (int i = 0; i < properties.size(); ++i) { @@ -66,15 +66,14 @@ public: void paint (Graphics& g) { - g.setColour (Colours::white.withAlpha (0.3f)); - g.fillRect (0, 28, getWidth(), getHeight() - 38); + const Colour bkg (findColour (mainBackgroundColourId)); - g.setColour (Colours::black.withAlpha (0.4f)); - g.drawRect (0, 28, getWidth(), getHeight() - 38); + g.setColour (Colours::white.withAlpha (0.35f)); + g.fillRect (0, 30, getWidth(), getHeight() - 38); - g.setFont (Font (14.0f, Font::bold)); - g.setColour (Colours::black); - g.drawFittedText (getName(), 12, 0, getWidth() - 16, 26, Justification::bottomLeft, 1); + g.setFont (Font (15.0f, Font::bold)); + g.setColour (bkg.contrasting (0.7f)); + g.drawFittedText (getName(), 12, 0, getWidth() - 16, 25, Justification::bottomLeft, 1); } OwnedArray properties; @@ -96,11 +95,7 @@ public: void paint (Graphics& g) { - g.setTiledImageFill (ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, - BinaryData::brushed_aluminium_pngSize), - 0, 0, 1.0f); - g.fillAll(); - drawRecessedShadows (g, getWidth(), getHeight(), 14); + drawTexturedBackground (g); } void resized() diff --git a/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h b/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h index 80713352cd..f6c518c206 100644 --- a/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h +++ b/extras/Introjucer/Source/Project/jucer_GroupInformationComponent.h @@ -57,12 +57,12 @@ public: //============================================================================== void paint (Graphics& g) { - g.fillAll (findColour (projectPanelBackgroundColourId)); + drawTexturedBackground (g); } void resized() { - list.setBounds (getLocalBounds().reduced (4, 2)); + list.setBounds (getLocalBounds().reduced (5, 4)); } int getNumRows() diff --git a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp index dc3886aacb..1165088894 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp +++ b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp @@ -70,7 +70,7 @@ public: void resized() { - Rectangle r (getLocalBounds()); + Rectangle r (getAvailableBounds()); r.removeFromBottom (6); if (saveAndOpenButton.isVisible()) @@ -98,6 +98,7 @@ ProjectContentComponent::ProjectContentComponent() treeSizeConstrainer.setMaximumWidth (500); treeViewTabs.setOutline (0); + treeViewTabs.getTabbedButtonBar().setMinimumTabScaleFactor (0.3); JucerApplication::getApp().openDocumentManager.addListener (this); } @@ -117,6 +118,23 @@ void ProjectContentComponent::paint (Graphics& g) g.fillAll (findColour (mainBackgroundColourId)); } +void ProjectContentComponent::paintOverChildren (Graphics& g) +{ + if (contentView != nullptr) + { + const int shadowSize = 15; + const int x = contentView->getX(); + + ColourGradient cg (Colours::black.withAlpha (0.25f), (float) x, 0, + Colours::transparentBlack, (float) (x - shadowSize), 0, false); + cg.addColour (0.4, Colours::black.withAlpha (0.07f)); + cg.addColour (0.6, Colours::black.withAlpha (0.02f)); + + g.setGradientFill (cg); + g.fillRect (x - shadowSize, 0, shadowSize, getHeight()); + } +} + void ProjectContentComponent::resized() { Rectangle r (getLocalBounds()); @@ -132,7 +150,7 @@ void ProjectContentComponent::resized() void ProjectContentComponent::lookAndFeelChanged() { - const Colour tabColour (findColour (projectPanelBackgroundColourId)); + const Colour tabColour (findColour (mainBackgroundColourId)); for (int i = treeViewTabs.getNumTabs(); --i >= 0;) treeViewTabs.setTabBackgroundColour (i, tabColour); @@ -207,7 +225,7 @@ void ProjectContentComponent::setProject (Project* newProject) void ProjectContentComponent::createProjectTabs() { jassert (project != nullptr); - const Colour tabColour (findColour (projectPanelBackgroundColourId)); + const Colour tabColour (findColour (mainBackgroundColourId)); treeViewTabs.addTab ("Files", tabColour, new FileTreeTab (*project), true); treeViewTabs.addTab ("Config", tabColour, new ConfigTreeTab (*project), true); diff --git a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.h b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.h index da76812959..53c22204f0 100644 --- a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.h +++ b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.h @@ -76,7 +76,8 @@ public: bool isCommandActive (const CommandID commandID); bool perform (const InvocationInfo& info); - void paint (Graphics& g); + void paint (Graphics&); + void paintOverChildren (Graphics&); void resized(); void childBoundsChanged (Component* child); void lookAndFeelChanged(); diff --git a/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.cpp b/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.cpp index 59c65c0629..718122d0e2 100644 --- a/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.cpp +++ b/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.cpp @@ -66,13 +66,13 @@ void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, int width, int height else p.addTriangle (width * 0.25f, height * 0.25f, width * 0.8f, height * 0.5f, width * 0.25f, height * 0.75f); - g.setColour (getOwnerView()->findColour (projectPanelBackgroundColourId).contrasting (0.3f)); + g.setColour (getOwnerView()->findColour (mainBackgroundColourId).contrasting (0.3f)); g.fillPath (p); } Colour JucerTreeViewBase::getBackgroundColour() const { - Colour background (getOwnerView()->findColour (projectPanelBackgroundColourId)); + Colour background (getOwnerView()->findColour (mainBackgroundColourId)); if (isSelected()) background = background.overlaidWith (getOwnerView()->findColour (treeviewHighlightColourId)); diff --git a/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.h b/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.h index d3f5548260..b0eda0fe97 100644 --- a/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.h +++ b/extras/Introjucer/Source/Utility/jucer_JucerTreeViewBase.h @@ -162,7 +162,12 @@ public: void resized() { - tree.setBounds (getLocalBounds()); + tree.setBounds (getAvailableBounds()); + } + + Rectangle getAvailableBounds() const + { + return Rectangle (0, 2, getWidth() - 2, getHeight() - 2); } TreeView tree; diff --git a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp index 065cde9553..c5bcbbb1a2 100644 --- a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp +++ b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp @@ -198,30 +198,39 @@ void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text) g.drawFittedText (text, 2, 2, w - 4, h - 4, Justification::centredTop, 2); } -void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize) +static Image createTexturisedBackgroundTile() { - ColourGradient cg (Colours::black.withAlpha (0.15f), 0, 0, - Colours::transparentBlack, 0, (float) shadowSize, false); - cg.addColour (0.4, Colours::black.withAlpha (0.07f)); - cg.addColour (0.6, Colours::black.withAlpha (0.02f)); + const Colour bkg (LookAndFeel::getDefaultLookAndFeel().findColour (mainBackgroundColourId)); + const int64 hash = bkg.getARGB() + 0x3474572a; - g.setGradientFill (cg); - g.fillRect (0, 0, w, shadowSize); + Image tile (ImageCache::getFromHashCode (hash)); - cg.point1.setXY (0.0f, (float) h); - cg.point2.setXY (0.0f, (float) h - shadowSize); - g.setGradientFill (cg); - g.fillRect (0, h - shadowSize, w, shadowSize); + if (tile.isNull()) + { + const Image original (ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, + BinaryData::brushed_aluminium_pngSize)); - cg.point1.setXY (0.0f, 0.0f); - cg.point2.setXY ((float) shadowSize, 0.0f); - g.setGradientFill (cg); - g.fillRect (0, 0, shadowSize, h); + tile = Image (Image::RGB, original.getWidth(), original.getHeight(), false); - cg.point1.setXY ((float) w, 0.0f); - cg.point2.setXY ((float) w - shadowSize, 0.0f); - g.setGradientFill (cg); - g.fillRect (w - shadowSize, 0, shadowSize, h); + for (int y = 0; y < tile.getHeight(); ++y) + { + for (int x = 0; x < tile.getWidth(); ++x) + { + const float b = original.getPixelAt (x, y).getBrightness(); + tile.setPixelAt (x, y, bkg.withMultipliedBrightness (b + 0.4f)); + } + } + + ImageCache::addImageToCache (tile, hash); + } + + return tile; +} + +void drawTexturedBackground (Graphics& g) +{ + g.setTiledImageFill (createTexturisedBackgroundTile(), 0, 0, 1.0f); + g.fillAll(); } //============================================================================== diff --git a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h index eee3863386..a770d248e0 100644 --- a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h +++ b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h @@ -47,7 +47,7 @@ int indexOfLineStartingWith (const StringArray& lines, const String& text, int s void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX = true, bool scrollY = true); void drawComponentPlaceholder (Graphics& g, int w, int h, const String& text); -void drawRecessedShadows (Graphics& g, int w, int h, int shadowSize); +void drawTexturedBackground (Graphics& g); void showUTF8ToolWindow();