| @@ -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)); | |||
| } | |||
| @@ -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<int>& 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<int> 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<int> getTabButtonExtraComponentBounds (const TabBarButton& button, Rectangle<int>& 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<int> getPropertyComponentContentPosition (PropertyComponent& component); | |||
| Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&); | |||
| }; | |||
| @@ -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, | |||
| }; | |||
| @@ -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 <SourceCodeDocument*> (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 <SourceCodeDocument*> (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(); } | |||
| @@ -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<PropertyComponent> 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() | |||
| @@ -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() | |||
| @@ -70,7 +70,7 @@ public: | |||
| void resized() | |||
| { | |||
| Rectangle<int> r (getLocalBounds()); | |||
| Rectangle<int> 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<int> 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); | |||
| @@ -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(); | |||
| @@ -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)); | |||
| @@ -162,7 +162,12 @@ public: | |||
| void resized() | |||
| { | |||
| tree.setBounds (getLocalBounds()); | |||
| tree.setBounds (getAvailableBounds()); | |||
| } | |||
| Rectangle<int> getAvailableBounds() const | |||
| { | |||
| return Rectangle<int> (0, 2, getWidth() - 2, getHeight() - 2); | |||
| } | |||
| TreeView tree; | |||
| @@ -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)); | |||
| g.setGradientFill (cg); | |||
| g.fillRect (0, 0, w, shadowSize); | |||
| 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); | |||
| cg.point1.setXY (0.0f, 0.0f); | |||
| cg.point2.setXY ((float) shadowSize, 0.0f); | |||
| g.setGradientFill (cg); | |||
| g.fillRect (0, 0, shadowSize, h); | |||
| 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); | |||
| const Colour bkg (LookAndFeel::getDefaultLookAndFeel().findColour (mainBackgroundColourId)); | |||
| const int64 hash = bkg.getARGB() + 0x3474572a; | |||
| Image tile (ImageCache::getFromHashCode (hash)); | |||
| if (tile.isNull()) | |||
| { | |||
| const Image original (ImageCache::getFromMemory (BinaryData::brushed_aluminium_png, | |||
| BinaryData::brushed_aluminium_pngSize)); | |||
| tile = Image (Image::RGB, original.getWidth(), original.getHeight(), false); | |||
| 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(); | |||
| } | |||
| //============================================================================== | |||
| @@ -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(); | |||