TabBarButton *CtrlrLuaMethodEditorTabs::createTabButton (const String &tabName, int tabIndex) { TabBarButton *btn = new TabBarButton (tabName, getTabbedButtonBar()); CtrlrMethodEditorTabCloseButton *close = new CtrlrMethodEditorTabCloseButton(owner, tabIndex); close->setSize (20,20); btn->setExtraComponent (close, TabBarButton::afterText); return (btn); }
Colour IntrojucerLookAndFeel::getTabBackgroundColour (TabBarButton& button) { const Colour normalBkg (button.findColour (mainBackgroundColourId)); Colour bkg (normalBkg.contrasting (0.15f)); if (button.isFrontTab()) bkg = bkg.overlaidWith (Colours::yellow.withAlpha (0.5f)); return bkg; }
void IntrojucerLookAndFeel::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); }
void ProjucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) { const auto area = button.getActiveArea(); auto backgroundColour = findColour (button.isFrontTab() ? secondaryBackgroundColourId : inactiveTabBackgroundColourId); auto iconColour = findColour (button.isFrontTab() ? activeTabIconColourId : inactiveTabIconColourId); g.setColour (backgroundColour); g.fillRect (area); const auto alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f; #ifndef BUILDING_JUCE_COMPILEENGINE if (button.getName() == "Project") { auto icon = Icon (getIcons().closedFolder, iconColour.withMultipliedAlpha (alpha)); icon.draw (g, button.getTextArea().reduced (8, 8).toFloat(), false); } else if (button.getName() == "Build") { auto icon = Icon (getIcons().buildTab, iconColour.withMultipliedAlpha (alpha)); icon.draw (g, button.getTextArea().reduced (8, 8).toFloat(), false); } else #endif { auto textColour = findColour (defaultTextColourId).withMultipliedAlpha (alpha); TextLayout textLayout; LookAndFeel_V3::createTabTextLayout (button, (float) area.getWidth(), (float) area.getHeight(), textColour, textLayout); textLayout.draw (g, button.getTextArea().toFloat()); } }
void CtrlrLuaMethodEditorTabsLF::createTabTextLayout (const TabBarButton& button, float length, float depth, Colour colour, TextLayout& textLayout) { Font font (12.0f); font.setUnderline (button.hasKeyboardFocus (false)); AttributedString s; s.setJustification (Justification::centred); s.append (button.getButtonText().trim(), font, colour); textLayout.createLayout (s, length); }
void LookAndFeel_E1::createTabTextLayout (const TabBarButton& button, float length, float depth, Colour colour, TextLayout& textLayout) { Font font (depth * 0.5f); font.setUnderline (button.hasKeyboardFocus (false)); AttributedString s; s.setJustification (Justification::centred); s.append (button.getButtonText().trim(), font, colour); textLayout.createLayout (s, length); }
void CtrlrMethodEditorTabCloseButton::mouseDown (const MouseEvent& e) { //[UserCode_mouseDown] -- Add your code here... Button::mouseDown (e); TabBarButton *parent = dynamic_cast<TabBarButton*>(getParentComponent()); if (parent) { owner.closeTab (parent->getIndex()); } //[/UserCode_mouseDown] }
void CtrlrTabsLF::fillTabButtonShape (TabBarButton& button, Graphics& g, const Path& path, bool /*isMouseOver*/, bool /*isMouseDown*/) { const Colour tabBackground (button.getTabBackgroundColour()); const bool isFrontTab = button.isFrontTab(); g.setColour (isFrontTab ? tabBackground : tabBackground.withMultipliedAlpha (0.9f)); g.fillPath (path); g.setColour (button.findColour (isFrontTab ? TabbedButtonBar::frontOutlineColourId : TabbedButtonBar::tabOutlineColourId, false) .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f)); g.strokePath (path, PathStrokeType (isFrontTab ? owner.getProperty(Ids::uiTabsFrontTabOutline) : owner.getProperty(Ids::uiTabsTabOutline))); }
void IntrojucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) { const Rectangle<int> activeArea (button.getActiveArea()); const 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.findColour (mainBackgroundColourId).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); }
void TabbedButtonBar::setCurrentTabIndex (int newIndex, const bool sendChangeMessage_) { if (currentTabIndex != newIndex) { if (! isPositiveAndBelow (newIndex, tabs.size())) newIndex = -1; currentTabIndex = newIndex; for (int i = 0; i < tabs.size(); ++i) { TabBarButton* tb = tabs.getUnchecked(i)->component; tb->setToggleState (i == newIndex, false); } resized(); if (sendChangeMessage_) sendChangeMessage(); currentTabChanged (newIndex, getCurrentTabName()); } }
void TabbedButtonBar::resized() { int depth = getWidth(); int length = getHeight(); if (orientation == TabsAtTop || orientation == TabsAtBottom) std::swap (depth, length); const int overlap = getLookAndFeel().getTabButtonOverlap (depth) + getLookAndFeel().getTabButtonSpaceAroundImage() * 2; int i, totalLength = overlap; int numVisibleButtons = tabs.size(); for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = tabs.getUnchecked(i)->component; totalLength += tb->getBestTabLength (depth) - overlap; tb->overlapPixels = overlap / 2; } double scale = 1.0; if (totalLength > length) scale = jmax (minimumScale, length / (double) totalLength); const bool isTooBig = totalLength * scale > length; int tabsButtonPos = 0; if (isTooBig) { if (extraTabsButton == nullptr) { addAndMakeVisible (extraTabsButton = getLookAndFeel().createTabBarExtrasButton()); extraTabsButton->addListener (behindFrontTab); extraTabsButton->setAlwaysOnTop (true); extraTabsButton->setTriggeredOnMouseDown (true); } const int buttonSize = jmin (proportionOfWidth (0.7f), proportionOfHeight (0.7f)); extraTabsButton->setSize (buttonSize, buttonSize); if (orientation == TabsAtTop || orientation == TabsAtBottom) { tabsButtonPos = getWidth() - buttonSize / 2 - 1; extraTabsButton->setCentrePosition (tabsButtonPos, getHeight() / 2); } else { tabsButtonPos = getHeight() - buttonSize / 2 - 1; extraTabsButton->setCentrePosition (getWidth() / 2, tabsButtonPos); } totalLength = 0; for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = tabs.getUnchecked(i)->component; const int newLength = totalLength + tb->getBestTabLength (depth); if (i > 0 && newLength * minimumScale > tabsButtonPos) { totalLength += overlap; break; } numVisibleButtons = i + 1; totalLength = newLength - overlap; } scale = jmax (minimumScale, tabsButtonPos / (double) totalLength); } else { extraTabsButton = nullptr; } int pos = 0; TabBarButton* frontTab = nullptr; for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = getTabButton (i); if (tb != nullptr) { const int bestLength = roundToInt (scale * tb->getBestTabLength (depth)); if (i < numVisibleButtons) { if (orientation == TabsAtTop || orientation == TabsAtBottom) tb->setBounds (pos, 0, bestLength, getHeight()); else tb->setBounds (0, pos, getWidth(), bestLength); tb->toBack(); if (i == currentTabIndex) frontTab = tb; tb->setVisible (true); } else { tb->setVisible (false); } pos += bestLength - overlap; } } behindFrontTab->setBounds (getLocalBounds()); if (frontTab != nullptr) { frontTab->toFront (false); behindFrontTab->toBehind (frontTab); } }
void CtrlrLuaMethodEditorTabsLF::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) { const Rectangle<int> activeArea (button.getActiveArea()); const TabbedButtonBar::Orientation o = button.getTabbedButtonBar().getOrientation(); const Colour bkg (button.getTabBackgroundColour()); if (button.getToggleState()) { g.setColour (bkg); } else { Point<int> p1, p2; switch (o) { case TabbedButtonBar::TabsAtBottom: p1 = activeArea.getBottomLeft(); p2 = activeArea.getTopLeft(); break; case TabbedButtonBar::TabsAtTop: p1 = activeArea.getTopLeft(); p2 = activeArea.getBottomLeft(); break; case TabbedButtonBar::TabsAtRight: p1 = activeArea.getTopRight(); p2 = activeArea.getTopLeft(); break; case TabbedButtonBar::TabsAtLeft: p1 = activeArea.getTopLeft(); p2 = activeArea.getTopRight(); break; default: jassertfalse; break; } g.setGradientFill (ColourGradient (bkg.brighter (0.2f), (float) p1.x, (float) p1.y, bkg.darker (0.1f), (float) p2.x, (float) p2.y, false)); } g.fillRect (activeArea); g.setColour (button.findColour (TabbedButtonBar::tabOutlineColourId)); Rectangle<int> r (activeArea); if (o != TabbedButtonBar::TabsAtBottom) g.fillRect (r.removeFromTop (1)); if (o != TabbedButtonBar::TabsAtTop) g.fillRect (r.removeFromBottom (1)); if (o != TabbedButtonBar::TabsAtRight) g.fillRect (r.removeFromLeft (1)); if (o != TabbedButtonBar::TabsAtLeft) g.fillRect (r.removeFromRight (1)); const float alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f; Colour col (bkg.contrasting().withMultipliedAlpha (alpha)); if (TabbedButtonBar* bar = button.findParentComponentOfClass<TabbedButtonBar>()) { TabbedButtonBar::ColourIds colID = button.isFrontTab() ? TabbedButtonBar::frontTextColourId : TabbedButtonBar::tabTextColourId; if (bar->isColourSpecified (colID)) col = bar->findColour (colID); else if (isColourSpecified (colID)) col = findColour (colID); } const Rectangle<float> area (button.getTextArea().toFloat()); float length = area.getWidth(); float depth = area.getHeight(); if (button.getTabbedButtonBar().isVertical()) std::swap (length, depth); TextLayout textLayout; createTabTextLayout (button, length, depth, col, textLayout); AffineTransform t; switch (o) { case TabbedButtonBar::TabsAtLeft: t = t.rotated (float_Pi * -0.5f).translated (area.getX(), area.getBottom()); break; case TabbedButtonBar::TabsAtRight: t = t.rotated (float_Pi * 0.5f).translated (area.getRight(), area.getY()); break; case TabbedButtonBar::TabsAtTop: case TabbedButtonBar::TabsAtBottom: t = t.translated (area.getX(), area.getY()); break; default: jassertfalse; break; } g.addTransform (t); textLayout.draw (g, Rectangle<float> (length, depth)); }
void preenfmLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) { const Rectangle<int> activeArea (button.getActiveArea()); const TabbedButtonBar::Orientation o = button.getTabbedButtonBar().getOrientation(); const Colour bkg (button.getTabBackgroundColour()); if (button.getToggleState()) { g.setColour (bkg); } else { Point<int> p1, p2; switch (o) { case TabbedButtonBar::TabsAtBottom: p1 = activeArea.getBottomLeft(); p2 = activeArea.getTopLeft(); break; case TabbedButtonBar::TabsAtTop: p1 = activeArea.getTopLeft(); p2 = activeArea.getBottomLeft(); break; case TabbedButtonBar::TabsAtRight: p1 = activeArea.getTopRight(); p2 = activeArea.getTopLeft(); break; case TabbedButtonBar::TabsAtLeft: p1 = activeArea.getTopLeft(); p2 = activeArea.getTopRight(); break; default: jassertfalse; break; } g.setGradientFill (ColourGradient (bkg.brighter (0.2f), (float) p1.x, (float) p1.y, bkg.darker (0.1f), (float) p2.x, (float) p2.y, false)); } g.fillRect (activeArea); g.setColour (button.findColour (TabbedButtonBar::tabOutlineColourId)); Rectangle<int> r (activeArea); if (o != TabbedButtonBar::TabsAtBottom) g.fillRect (r.removeFromTop (1)); if (o != TabbedButtonBar::TabsAtTop) g.fillRect (r.removeFromBottom (1)); if (o != TabbedButtonBar::TabsAtRight) g.fillRect (r.removeFromLeft (1)); if (o != TabbedButtonBar::TabsAtLeft) g.fillRect (r.removeFromRight (1)); const float alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f; Colour col (bkg.contrasting().withMultipliedAlpha (alpha)); if (TabbedButtonBar* bar = button.findParentComponentOfClass<TabbedButtonBar>()) { TabbedButtonBar::ColourIds colID = button.isFrontTab() ? TabbedButtonBar::frontTextColourId : TabbedButtonBar::tabTextColourId; if (bar->isColourSpecified (colID)) col = bar->findColour (colID); else if (isColourSpecified (colID)) col = findColour (colID); } const Rectangle<float> area (button.getTextArea().toFloat()); float length = area.getWidth(); float depth = area.getHeight(); if (button.getTabbedButtonBar().isVertical()) std::swap (length, depth); g.setColour (col); g.setFont (Font (depth * .5)); g.drawFittedText (button.getName().trim(), 0, 0,length, depth, Justification::centred, 1); }
Rectangle <int> CtrlrLuaMethodEditorTabsLF::getTabButtonExtraComponentBounds (const TabBarButton &button, Rectangle <int> &textArea, Component &extraComp) { return (Rectangle<int> (button.getWidth() - 20, 2, 20, 22)); }
int CtrlrLuaMethodEditorTabsLF::getTabButtonBestWidth (TabBarButton &button, int tabDepth) { Font f(14.0f); return (f.getStringWidth (button.getButtonText()) + 24); }
void CtrlrTabsLF::drawTabButtonText (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown) { const Rectangle<float> area (button.getTextArea().toFloat()); float length = area.getWidth(); float depth = area.getHeight(); if (button.getTabbedButtonBar().isVertical()) std::swap (length, depth); Font otherTabFont = owner.getOwner().getOwner().getOwner().getFontManager().getFontFromString (owner.getProperty(Ids::uiTabsTabFont)); Font activeTabFont = owner.getOwner().getOwner().getOwner().getFontManager().getFontFromString (owner.getProperty(Ids::uiTabsFrontTabFont)); otherTabFont.setUnderline (button.hasKeyboardFocus (false)); activeTabFont.setUnderline (button.hasKeyboardFocus (false)); GlyphArrangement textLayout; textLayout.addFittedText (button.isFrontTab() ? activeTabFont : otherTabFont, button.getButtonText().trim(), 0.0f, 0.0f, (float) length, (float) depth, Justification::centred, jmax<int> (1, depth / 12)); AffineTransform t; switch (button.getTabbedButtonBar().getOrientation()) { case TabbedButtonBar::TabsAtLeft: t = t.rotated (float_Pi * -0.5f).translated (area.getX(), area.getBottom()); break; case TabbedButtonBar::TabsAtRight: t = t.rotated (float_Pi * 0.5f).translated (area.getRight(), area.getY()); break; case TabbedButtonBar::TabsAtTop: case TabbedButtonBar::TabsAtBottom: t = t.translated (area.getX(), area.getY()); break; default: jassertfalse; break; } Colour col; if (button.isFrontTab() && (button.isColourSpecified (TabbedButtonBar::frontTextColourId) || isColourSpecified (TabbedButtonBar::frontTextColourId))) col = findColour (TabbedButtonBar::frontTextColourId); else if (button.isColourSpecified (TabbedButtonBar::tabTextColourId) || isColourSpecified (TabbedButtonBar::tabTextColourId)) col = findColour (TabbedButtonBar::tabTextColourId); else col = button.getTabBackgroundColour().contrasting(); const float alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f; g.setColour (col.withMultipliedAlpha (alpha)); textLayout.draw (g, t); }
//============================================================================== void TabbedButtonBar::updateTabPositions (bool animate) { LookAndFeel& lf = getLookAndFeel(); int depth = getWidth(); int length = getHeight(); if (! isVertical()) std::swap (depth, length); const int overlap = lf.getTabButtonOverlap (depth) + lf.getTabButtonSpaceAroundImage() * 2; int totalLength = jmax (0, overlap); int numVisibleButtons = tabs.size(); for (int i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = tabs.getUnchecked(i)->button; totalLength += tb->getBestTabLength (depth) - overlap; tb->overlapPixels = jmax (0, overlap / 2); } double scale = 1.0; if (totalLength > length) scale = jmax (minimumScale, length / (double) totalLength); const bool isTooBig = (int) (totalLength * scale) > length; int tabsButtonPos = 0; if (isTooBig) { if (extraTabsButton == nullptr) { addAndMakeVisible (extraTabsButton = lf.createTabBarExtrasButton()); extraTabsButton->addListener (behindFrontTab); extraTabsButton->setAlwaysOnTop (true); extraTabsButton->setTriggeredOnMouseDown (true); } const int buttonSize = jmin (proportionOfWidth (0.7f), proportionOfHeight (0.7f)); extraTabsButton->setSize (buttonSize, buttonSize); if (isVertical()) { tabsButtonPos = getHeight() - buttonSize / 2 - 1; extraTabsButton->setCentrePosition (getWidth() / 2, tabsButtonPos); } else { tabsButtonPos = getWidth() - buttonSize / 2 - 1; extraTabsButton->setCentrePosition (tabsButtonPos, getHeight() / 2); } totalLength = 0; for (int i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = tabs.getUnchecked(i)->button; const int newLength = totalLength + tb->getBestTabLength (depth); if (i > 0 && newLength * minimumScale > tabsButtonPos) { totalLength += overlap; break; } numVisibleButtons = i + 1; totalLength = newLength - overlap; } scale = jmax (minimumScale, tabsButtonPos / (double) totalLength); } else { extraTabsButton = nullptr; } int pos = 0; TabBarButton* frontTab = nullptr; ComponentAnimator& animator = Desktop::getInstance().getAnimator(); for (int i = 0; i < tabs.size(); ++i) { if (TabBarButton* const tb = getTabButton (i)) { const int bestLength = roundToInt (scale * tb->getBestTabLength (depth)); if (i < numVisibleButtons) { const Rectangle<int> newBounds (isVertical() ? Rectangle<int> (0, pos, getWidth(), bestLength) : Rectangle<int> (pos, 0, bestLength, getHeight())); if (animate) { animator.animateComponent (tb, newBounds, 1.0f, 200, false, 3.0, 0.0); } else { animator.cancelAnimation (tb, false); tb->setBounds (newBounds); } tb->toBack(); if (i == currentTabIndex) frontTab = tb; tb->setVisible (true); } else { tb->setVisible (false); } pos += bestLength - overlap; } } behindFrontTab->setBounds (getLocalBounds()); if (frontTab != nullptr) { frontTab->toFront (false); behindFrontTab->toBehind (frontTab); } }