30LookAndFeel_V2::LookAndFeel_V2()
33 const uint32 textButtonColour = 0xffbbbbff;
34 const uint32 textHighlightColour = 0x401111ee;
35 const uint32 standardOutlineColour = 0xb2808080;
37 static const uint32 standardColours[] =
158 0x1000440, 0x66dddddd,
159 0x1000441, 0x99111111,
161 0x1004000, 0xffd3d3d3,
162 0x1004001, 0xff000000,
164 0x1005000, 0xffffffff,
165 0x1005001, 0xff000000,
166 0x1005002, 0x66000000,
167 0x1005003, 0x80ffff00,
168 0x1005004, 0xffb6b600,
169 0x1005005, 0xff000000,
170 0x1005006, 0x4c000000,
172 0x1006000, 0xff1a1c27,
173 0x1006001, 0x99f1f1f1,
174 0x1006002, 0xfff1f1f1,
175 0x1006003, 0x99ba00ff,
176 0x1006004, 0xfff1f1f1,
178 0x1004500, 0xffffffff,
179 0x1004502, textHighlightColour,
180 0x1004503, 0xff000000,
181 0x1004504, 0x44999999,
182 0x1004505, 0x44000000,
184 0x1007000, 0xffe5e5e5,
185 0x1007001, 0xff000000,
187 0x100ad00, 0x00000000,
188 0x100ad01, 0xff000000,
194 SidePanel::backgroundColour, 0xffffffff,
195 SidePanel::titleTextColour, 0xff000000,
196 SidePanel::shadowBaseColour, 0xff000000,
197 SidePanel::dismissButtonNormalColour, textButtonColour,
198 SidePanel::dismissButtonOverColour, textButtonColour,
199 SidePanel::dismissButtonDownColour, 0xff4444ff,
209 setColour ((
int) standardColours [i], Colour ((
uint32) standardColours [i + 1]));
214LookAndFeel_V2::~LookAndFeel_V2() {}
217void LookAndFeel_V2::drawButtonBackground (Graphics& g,
219 const Colour& backgroundColour,
220 bool shouldDrawButtonAsHighlighted,
221 bool shouldDrawButtonAsDown)
223 const int width = button.getWidth();
224 const int height = button.getHeight();
226 const float outlineThickness = button.isEnabled() ? ((shouldDrawButtonAsDown || shouldDrawButtonAsHighlighted) ? 1.2f : 0.7f) : 0.4f;
227 const float halfThickness = outlineThickness * 0.5f;
229 const float indentL = button.isConnectedOnLeft() ? 0.1f : halfThickness;
230 const float indentR = button.isConnectedOnRight() ? 0.1f : halfThickness;
231 const float indentT = button.isConnectedOnTop() ? 0.1f : halfThickness;
232 const float indentB = button.isConnectedOnBottom() ? 0.1f : halfThickness;
234 const Colour baseColour (detail::LookAndFeelHelpers::createBaseColour (backgroundColour,
235 button.hasKeyboardFocus (
true),
236 shouldDrawButtonAsHighlighted,
237 shouldDrawButtonAsDown)
238 .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
243 (
float) width - indentL - indentR,
244 (
float) height - indentT - indentB,
245 baseColour, outlineThickness, -1.0f,
246 button.isConnectedOnLeft(),
247 button.isConnectedOnRight(),
248 button.isConnectedOnTop(),
249 button.isConnectedOnBottom());
252Font LookAndFeel_V2::getTextButtonFont (TextButton&,
int buttonHeight)
254 return Font (
jmin (15.0f, (
float) buttonHeight * 0.6f));
257int LookAndFeel_V2::getTextButtonWidthToFitText (TextButton& b,
int buttonHeight)
259 return getTextButtonFont (b, buttonHeight).
getStringWidth (b.getButtonText()) + buttonHeight;
265 Font font (getTextButtonFont (button, button.getHeight()));
268 : TextButton::textColourOffId)
269 .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
271 const int yIndent =
jmin (4, button.proportionOfHeight (0.3f));
272 const int cornerSize =
jmin (button.getHeight(), button.getWidth()) / 2;
274 const int fontHeight =
roundToInt (font.getHeight() * 0.6f);
275 const int leftIndent =
jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnLeft() ? 4 : 2));
276 const int rightIndent =
jmin (fontHeight, 2 + cornerSize / (button.isConnectedOnRight() ? 4 : 2));
277 const int textWidth = button.getWidth() - leftIndent - rightIndent;
280 g.drawFittedText (button.getButtonText(),
281 leftIndent, yIndent, textWidth, button.getHeight() - yIndent * 2,
285void LookAndFeel_V2::drawTickBox (Graphics& g, Component& component,
286 float x,
float y,
float w,
float h,
288 const bool isEnabled,
289 const bool shouldDrawButtonAsHighlighted,
290 const bool shouldDrawButtonAsDown)
292 const float boxSize = w * 0.7f;
296 .withMultipliedAlpha (isEnabled ? 1.0f : 0.5f),
297 true, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown),
298 isEnabled ? ((shouldDrawButtonAsDown || shouldDrawButtonAsHighlighted) ? 1.1f : 0.5f) : 0.3f);
303 tick.startNewSubPath (1.5f, 3.0f);
304 tick.lineTo (3.0f, 6.0f);
305 tick.lineTo (6.0f, 0.0f);
308 : ToggleButton::tickDisabledColourId));
313 g.strokePath (tick, PathStrokeType (2.5f), trans);
318 bool shouldDrawButtonAsHighlighted,
bool shouldDrawButtonAsDown)
320 if (button.hasKeyboardFocus (
true))
323 g.drawRect (0, 0, button.getWidth(), button.getHeight());
326 float fontSize =
jmin (15.0f, (
float) button.getHeight() * 0.75f);
327 const float tickWidth = fontSize * 1.1f;
329 drawTickBox (g, button, 4.0f, ((
float) button.getHeight() - tickWidth) * 0.5f,
330 tickWidth, tickWidth,
331 button.getToggleState(),
333 shouldDrawButtonAsHighlighted,
334 shouldDrawButtonAsDown);
337 g.setFont (fontSize);
339 if (! button.isEnabled())
342 g.drawFittedText (button.getButtonText(),
343 button.getLocalBounds().withTrimmedLeft (
roundToInt (tickWidth) + 5)
344 .withTrimmedRight (2),
348void LookAndFeel_V2::changeToggleButtonWidthToFitText (ToggleButton& button)
350 auto fontSize =
jmin (15.0f, (
float) button.getHeight() * 0.75f);
351 auto tickWidth = fontSize * 1.1f;
353 Font font (fontSize);
355 button.setSize (font.getStringWidth (button.getButtonText()) +
roundToInt (tickWidth) + 9,
359void LookAndFeel_V2::drawDrawableButton (Graphics& g, DrawableButton& button,
362 bool toggleState = button.getToggleState();
365 : DrawableButton::backgroundColourId));
368 ?
jmin (16, button.proportionOfHeight (0.25f))
373 g.setFont ((
float) textH);
376 : DrawableButton::textColourId)
377 .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.4f));
379 g.drawFittedText (button.getButtonText(),
380 2, button.getHeight() - textH - 1,
381 button.getWidth() - 4, textH,
387AlertWindow* LookAndFeel_V2::createAlertWindow (
const String& title,
const String& message,
388 const String& button1,
const String& button2,
const String& button3,
390 int numButtons, Component* associatedComponent)
392 AlertWindow* aw =
new AlertWindow (title, message, iconType, associatedComponent);
396 aw->addButton (button1, 0,
404 if (button1ShortCut == button2ShortCut)
405 button2ShortCut = KeyPress();
412 else if (numButtons == 3)
414 aw->addButton (button1, 1, button1ShortCut);
415 aw->addButton (button2, 2, button2ShortCut);
423void LookAndFeel_V2::drawAlertBox (Graphics& g, AlertWindow& alert,
424 const Rectangle<int>& textArea, TextLayout& textLayout)
428 int iconSpaceUsed = 0;
430 const int iconWidth = 80;
431 int iconSize =
jmin (iconWidth + 50, alert.getHeight() + 20);
433 if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2)
434 iconSize =
jmin (iconSize, textArea.getHeight() + 50);
436 const Rectangle<int> iconRect (iconSize / -10, iconSize / -10,
450 icon.addTriangle ((
float) iconRect.getX() + (
float) iconRect.getWidth() * 0.5f, (
float) iconRect.getY(),
451 (
float) iconRect.getRight(), (
float) iconRect.getBottom(),
452 (
float) iconRect.getX(), (
float) iconRect.getBottom());
454 icon = icon.createPathWithRoundedCorners (5.0f);
461 icon.addEllipse (iconRect.toFloat());
465 ga.addFittedText (Font ((
float) iconRect.getHeight() * 0.9f,
Font::bold),
467 (
float) iconRect.getX(), (
float) iconRect.getY(),
468 (
float) iconRect.getWidth(), (
float) iconRect.getHeight(),
470 ga.createPath (icon);
472 icon.setUsingNonZeroWinding (
false);
473 g.setColour (Colour (colour));
476 iconSpaceUsed = iconWidth;
481 textLayout.draw (g, Rectangle<int> (textArea.getX() + iconSpaceUsed,
483 textArea.getWidth() - iconSpaceUsed,
484 textArea.getHeight()).toFloat());
487 g.drawRect (0, 0, alert.getWidth(), alert.getHeight());
490int LookAndFeel_V2::getAlertBoxWindowFlags()
496Array<int> LookAndFeel_V2::getWidthsForTextButtons (AlertWindow&,
const Array<TextButton*>& buttons)
498 const int n = buttons.size();
499 Array<int> buttonWidths;
501 const int buttonHeight = getAlertWindowButtonHeight();
503 for (
int i = 0; i < n; ++i)
504 buttonWidths.add (getTextButtonWidthToFitText (*buttons.getReference (i), buttonHeight));
509int LookAndFeel_V2::getAlertWindowButtonHeight()
517 return messageFont.withHeight (messageFont.getHeight() * 1.1f).boldened();
525Font LookAndFeel_V2::getAlertWindowFont()
532 int width,
int height,
533 double progress,
const String& textToShow)
538 g.fillAll (background);
540 if (progress >= 0.0f && progress < 1.0f)
543 (
float)
jlimit (0.0, width - 2.0, progress * (width - 2.0)),
544 (
float) (height - 2),
547 true,
true,
true,
true);
552 g.setColour (foreground);
554 const int stripeWidth = height * 2;
559 for (
float x = (
float) (- position); x < (
float) (width + stripeWidth); x += (
float) stripeWidth)
560 p.addQuadrilateral (x, 0.0f,
561 x + (
float) stripeWidth * 0.5f, 0.0f,
563 x - (
float) stripeWidth * 0.5f, (
float) height);
571 (
float) (height - 2),
574 true,
true,
true,
true);
577 g.setTiledImageFill (im, 0, 0, 0.85f);
581 if (textToShow.isNotEmpty())
584 g.setFont ((
float) height * 0.6f);
592 const float radius = (
float)
jmin (w, h) * 0.4f;
593 const float thickness = radius * 0.15f;
595 p.addRoundedRectangle (radius * 0.4f, thickness * -0.5f,
596 radius * 0.6f, thickness,
599 const float cx = (
float) x + (
float) w * 0.5f;
600 const float cy = (
float) y + (
float) h * 0.5f;
604 for (
uint32 i = 0; i < 12; ++i)
606 const uint32 n = (i + 12 - animationIndex) % 12;
608 g.setColour (colour.withMultipliedAlpha ((
float) (n + 1) / 12.0f));
614bool LookAndFeel_V2::isProgressBarOpaque (ProgressBar& progressBar)
624bool LookAndFeel_V2::areScrollbarButtonsVisible()
630 int width,
int height,
int buttonDirection,
633 bool shouldDrawButtonAsDown)
637 const auto w = (
float) width;
638 const auto h = (
float) height;
640 if (buttonDirection == 0)
641 p.addTriangle (w * 0.5f, h * 0.2f,
644 else if (buttonDirection == 1)
645 p.addTriangle (w * 0.8f, h * 0.5f,
648 else if (buttonDirection == 2)
649 p.addTriangle (w * 0.5f, h * 0.8f,
652 else if (buttonDirection == 3)
653 p.addTriangle (w * 0.2f, h * 0.5f,
657 if (shouldDrawButtonAsDown)
664 g.setColour (Colour (0x80000000));
665 g.strokePath (p, PathStrokeType (0.5f));
669 ScrollBar& scrollbar,
671 int width,
int height,
672 bool isScrollbarVertical,
673 int thumbStartPosition,
680 Path slotPath, thumbPath;
682 const float slotIndent =
jmin (width, height) > 15 ? 1.0f : 0.0f;
683 const float slotIndentx2 = slotIndent * 2.0f;
684 const float thumbIndent = slotIndent + 1.0f;
685 const float thumbIndentx2 = thumbIndent * 2.0f;
687 float gx1 = 0.0f, gy1 = 0.0f, gx2 = 0.0f, gy2 = 0.0f;
689 if (isScrollbarVertical)
691 slotPath.addRoundedRectangle ((
float) x + slotIndent,
692 (
float) y + slotIndent,
693 (
float) width - slotIndentx2,
694 (
float) height - slotIndentx2,
695 ((
float) width - slotIndentx2) * 0.5f);
698 thumbPath.addRoundedRectangle ((
float) x + thumbIndent,
699 (
float) thumbStartPosition + thumbIndent,
700 (
float) width - thumbIndentx2,
701 (
float) thumbSize - thumbIndentx2,
702 ((
float) width - thumbIndentx2) * 0.5f);
704 gx2 = (
float) x + (
float) width * 0.7f;
708 slotPath.addRoundedRectangle ((
float) x + slotIndent,
709 (
float) y + slotIndent,
710 (
float) width - slotIndentx2,
711 (
float) height - slotIndentx2,
712 ((
float) height - slotIndentx2) * 0.5f);
715 thumbPath.addRoundedRectangle ((
float) thumbStartPosition + thumbIndent,
716 (
float) y + thumbIndent,
717 (
float) thumbSize - thumbIndentx2,
718 (
float) height - thumbIndentx2,
719 ((
float) height - thumbIndentx2) * 0.5f);
721 gy2 = (
float) y + (
float) height * 0.7f;
725 Colour trackColour1, trackColour2;
734 trackColour1 = thumbColour.overlaidWith (Colour (0x44000000));
735 trackColour2 = thumbColour.overlaidWith (Colour (0x19000000));
738 g.setGradientFill (ColourGradient (trackColour1, gx1, gy1,
739 trackColour2, gx2, gy2,
false));
740 g.fillPath (slotPath);
742 if (isScrollbarVertical)
744 gx1 = (
float) x + (
float) width * 0.6f;
745 gx2 = (
float) x + (
float) width;
749 gy1 = (
float) y + (
float) height * 0.6f;
750 gy2 = (
float) y + (
float) height;
753 g.setGradientFill (ColourGradient (Colours::transparentBlack,gx1, gy1,
754 Colour (0x19000000), gx2, gy2,
false));
755 g.fillPath (slotPath);
757 g.setColour (thumbColour);
758 g.fillPath (thumbPath);
760 g.setGradientFill (ColourGradient (Colour (0x10000000), gx1, gy1,
761 Colours::transparentBlack, gx2, gy2,
false));
764 Graphics::ScopedSaveState ss (g);
766 if (isScrollbarVertical)
767 g.reduceClipRegion (x + width / 2, y, width, height);
769 g.reduceClipRegion (x, y + height / 2, width, height);
771 g.fillPath (thumbPath);
774 g.setColour (Colour (0x4c000000));
775 g.strokePath (thumbPath, PathStrokeType (0.4f));
785 return jmin (scrollbar.getWidth(), scrollbar.getHeight()) * 2;
795 return 2 + (scrollbar.isVertical() ? scrollbar.getWidth()
796 : scrollbar.getHeight());
800void LookAndFeel_V2::drawTreeviewPlusMinusBox (Graphics& g,
const Rectangle<float>& area,
801 Colour ,
bool isOpen,
bool )
803 auto boxSize =
roundToInt (
jmin (16.0f, area.getWidth(), area.getHeight()) * 0.7f) | 1;
805 auto x = ((
int) area.getWidth() - boxSize) / 2 + (
int) area.getX();
806 auto y = ((
int) area.getHeight() - boxSize) / 2 + (
int) area.getY();
808 Rectangle<float> boxArea ((
float) x, (
float) y, (
float) boxSize, (
float) boxSize);
810 g.setColour (Colour (0xe5ffffff));
811 g.fillRect (boxArea);
813 g.setColour (Colour (0x80000000));
814 g.drawRect (boxArea);
816 auto size = (
float) boxSize * 0.5f + 1.0f;
817 auto centre = (
float) (boxSize / 2);
819 g.fillRect ((
float) x + ((
float) boxSize - size) * 0.5f, (
float) y + centre, size, 1.0f);
822 g.fillRect ((
float) x + centre, (
float) y + ((
float) boxSize -
size) * 0.5f, 1.0f, size);
825bool LookAndFeel_V2::areLinesDrawnForTreeView (TreeView&)
830int LookAndFeel_V2::getTreeViewIndentSize (TreeView&)
837 const Point<float>& tip,
const Rectangle<float>& body)
840 p.addBubble (body.reduced (0.5f), body.getUnion (Rectangle<float> (tip.x, tip.y, 1.0f, 1.0f)),
841 tip, 5.0f,
jmin (15.0f, body.getWidth() * 0.2f, body.getHeight() * 0.2f));
847 g.strokePath (p, PathStrokeType (1.0f));
852 bubbleComponent.setComponentEffect (&bubbleShadow);
862 int standardMenuItemHeight,
int& idealWidth,
int& idealHeight)
867 idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight / 2 : 10;
873 if (standardMenuItemHeight > 0 && font.getHeight() > (
float) standardMenuItemHeight / 1.3f)
874 font.setHeight ((
float) standardMenuItemHeight / 1.3f);
876 idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight :
roundToInt (font.getHeight() * 1.3f);
877 idealWidth = font.getStringWidth (text) + idealHeight * 2;
883 int standardMenuItemHeight,
886 const PopupMenu::Options&)
890 standardMenuItemHeight,
899 g.fillAll (background);
900 g.setColour (background.overlaidWith (Colour (0x2badd8e6)));
902 for (
int i = 0; i < height; i += 3)
903 g.fillRect (0, i, width, 1);
907 g.drawRect (0, 0, width, height);
914 const PopupMenu::Options&)
919void LookAndFeel_V2::drawPopupMenuUpDownArrow (Graphics& g,
int width,
int height,
bool isScrollUpArrow)
923 g.setGradientFill (ColourGradient (background, 0.0f, (
float) height * 0.5f,
924 background.withAlpha (0.0f),
925 0.0f, isScrollUpArrow ? ((
float) height) : 0.0f,
928 g.fillRect (1, 1, width - 2, height - 2);
930 auto hw = (
float) width * 0.5f;
931 auto arrowW = (
float) height * 0.3f;
932 auto y1 = (
float) height * (isScrollUpArrow ? 0.6f : 0.3f);
933 auto y2 = (
float) height * (isScrollUpArrow ? 0.3f : 0.6f);
936 p.addTriangle (hw - arrowW, y1,
944void LookAndFeel_V2::drawPopupMenuUpDownArrowWithOptions (Graphics& g,
945 int width,
int height,
946 bool isScrollUpArrow,
947 const PopupMenu::Options&)
949 drawPopupMenuUpDownArrow (g, width, height, isScrollUpArrow);
953 const bool isSeparator,
const bool isActive,
954 const bool isHighlighted,
const bool isTicked,
955 const bool hasSubMenu,
const String& text,
956 const String& shortcutKeyText,
957 const Drawable* icon,
const Colour*
const textColourToUse)
961 auto r = area.reduced (5, 0);
962 r.removeFromTop (r.getHeight() / 2 - 1);
964 g.setColour (Colour (0x33000000));
965 g.fillRect (r.removeFromTop (1));
967 g.setColour (Colour (0x66ffffff));
968 g.fillRect (r.removeFromTop (1));
974 if (textColourToUse !=
nullptr)
975 textColour = *textColourToUse;
977 auto r = area.reduced (1);
988 g.setColour (textColour);
996 auto maxFontHeight = (
float) area.getHeight() / 1.3f;
998 if (font.getHeight() > maxFontHeight)
999 font.setHeight (maxFontHeight);
1003 auto iconArea = r.removeFromLeft ((r.getHeight() * 5) / 4).reduced (3).toFloat();
1005 if (icon !=
nullptr)
1012 g.fillPath (tick, tick.getTransformToScaleToFit (iconArea,
true));
1019 auto x = (
float) r.removeFromRight ((
int) arrowH).getX();
1020 auto halfH = (
float) r.getCentreY();
1023 p.addTriangle (x, halfH - arrowH * 0.5f,
1024 x, halfH + arrowH * 0.5f,
1025 x + arrowH * 0.6f, halfH);
1030 r.removeFromRight (3);
1033 if (shortcutKeyText.isNotEmpty())
1036 f2.setHeight (f2.getHeight() * 0.75f);
1037 f2.setHorizontalScale (0.95f);
1047 const PopupMenu::Item& item,
1048 const PopupMenu::Options&)
1050 const auto colour = item.colour != Colour() ? &item.colour :
nullptr;
1051 const auto hasSubMenu = item.subMenu !=
nullptr
1052 && (item.itemID == 0 || item.subMenu->getNumItems() > 0);
1062 item.shortcutKeyDescription,
1067void LookAndFeel_V2::drawPopupMenuSectionHeader (Graphics& g,
1068 const Rectangle<int>& area,
1069 const String& sectionName)
1074 g.drawFittedText (sectionName,
1075 area.getX() + 12, area.getY(), area.getWidth() - 16, (
int) ((
float) area.getHeight() * 0.8f),
1079void LookAndFeel_V2::drawPopupMenuSectionHeaderWithOptions (Graphics& g,
const Rectangle<int>& area,
1080 const String& sectionName,
1081 const PopupMenu::Options&)
1083 drawPopupMenuSectionHeader (g, area, sectionName);
1087int LookAndFeel_V2::getMenuWindowFlags()
1092void LookAndFeel_V2::drawMenuBarBackground (Graphics& g,
int width,
int height,
bool, MenuBarComponent& menuBar)
1095 false,
false,
false);
1097 if (menuBar.isEnabled())
1098 drawShinyButtonShape (g, -4.0f, 0.0f, (
float) width + 8.0f, (
float) height,
1099 0.0f, baseColour, 0.4f,
true,
true,
true,
true);
1101 g.fillAll (baseColour);
1104Font LookAndFeel_V2::getMenuBarFont (MenuBarComponent& menuBar,
int ,
const String& )
1106 return Font ((
float) menuBar.getHeight() * 0.7f);
1109int LookAndFeel_V2::getMenuBarItemWidth (MenuBarComponent& menuBar,
int itemIndex,
const String& itemText)
1111 return getMenuBarFont (menuBar, itemIndex, itemText)
1115void LookAndFeel_V2::drawMenuBarItem (Graphics& g,
int width,
int height,
1116 int itemIndex,
const String& itemText,
1117 bool isMouseOverItem,
bool isMenuOpen,
1118 bool , MenuBarComponent& menuBar)
1120 if (! menuBar.isEnabled())
1123 .withMultipliedAlpha (0.5f));
1125 else if (isMenuOpen || isMouseOverItem)
1135 g.setFont (getMenuBarFont (menuBar, itemIndex, itemText));
1139Component* LookAndFeel_V2::getParentComponentForMenuOptions (
const PopupMenu::Options& options)
1141 return options.getParentComponent();
1144void LookAndFeel_V2::preparePopupMenuWindow (Component&) {}
1148int LookAndFeel_V2::getPopupMenuBorderSize() {
return 2; }
1150int LookAndFeel_V2::getPopupMenuBorderSizeWithOptions (
const PopupMenu::Options&)
1152 return getPopupMenuBorderSize();
1156 const Rectangle<int>&,
1157 const PopupMenu::Options&) {}
1165void LookAndFeel_V2::fillTextEditorBackground (Graphics& g,
int ,
int , TextEditor& textEditor)
1170void LookAndFeel_V2::drawTextEditorOutline (Graphics& g,
int width,
int height, TextEditor& textEditor)
1172 if (textEditor.isEnabled())
1174 if (textEditor.hasKeyboardFocus (
true) && ! textEditor.isReadOnly())
1176 const int border = 2;
1179 g.drawRect (0, 0, width, height, border);
1181 g.setOpacity (1.0f);
1183 drawBevel (g, 0, 0, width, height + 2, border + 2, shadowColour, shadowColour);
1188 g.drawRect (0, 0, width, height);
1190 g.setOpacity (1.0f);
1192 drawBevel (g, 0, 0, width, height + 2, 3, shadowColour, shadowColour);
1197CaretComponent* LookAndFeel_V2::createCaretComponent (Component* keyFocusOwner)
1199 return new CaretComponent (keyFocusOwner);
1203void LookAndFeel_V2::drawComboBox (Graphics& g,
int width,
int height,
const bool isMouseButtonDown,
1204 int buttonX,
int buttonY,
int buttonW,
int buttonH, ComboBox& box)
1208 if (box.isEnabled() && box.hasKeyboardFocus (
false))
1211 g.drawRect (0, 0, width, height, 2);
1216 g.drawRect (0, 0, width, height);
1219 auto outlineThickness = box.isEnabled() ? (isMouseButtonDown ? 1.2f : 0.5f) : 0.3f;
1222 box.hasKeyboardFocus (
true),
1223 false, isMouseButtonDown)
1224 .withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.5f);
1227 (
float) buttonX + outlineThickness, (
float) buttonY + outlineThickness,
1228 (
float) buttonW - outlineThickness * 2.0f, (
float) buttonH - outlineThickness * 2.0f,
1229 baseColour, outlineThickness, -1.0f,
1230 true,
true,
true,
true);
1232 if (box.isEnabled())
1234 const float arrowX = 0.3f;
1235 const float arrowH = 0.2f;
1237 const auto x = (
float) buttonX;
1238 const auto y = (
float) buttonY;
1239 const auto w = (
float) buttonW;
1240 const auto h = (
float) buttonH;
1243 p.addTriangle (x + w * 0.5f, y + h * (0.45f - arrowH),
1244 x + w * (1.0f - arrowX), y + h * 0.45f,
1245 x + w * arrowX, y + h * 0.45f);
1247 p.addTriangle (x + w * 0.5f, y + h * (0.55f + arrowH),
1248 x + w * (1.0f - arrowX), y + h * 0.55f,
1249 x + w * arrowX, y + h * 0.55f);
1256Font LookAndFeel_V2::getComboBoxFont (ComboBox& box)
1258 return Font (
jmin (15.0f, (
float) box.getHeight() * 0.85f));
1261Label* LookAndFeel_V2::createComboBoxTextBox (ComboBox&)
1263 return new Label (String(), String());
1266void LookAndFeel_V2::positionComboBoxText (ComboBox& box, Label& label)
1268 label.setBounds (1, 1,
1269 box.getWidth() + 3 - box.getHeight(),
1270 box.getHeight() - 2);
1272 label.setFont (getComboBoxFont (box));
1275PopupMenu::Options LookAndFeel_V2::getOptionsForComboBoxPopupMenu (ComboBox& box, Label& label)
1277 return PopupMenu::Options().withTargetComponent (&box)
1278 .withItemThatMustBeVisible (box.getSelectedId())
1279 .withInitiallySelectedItem (box.getSelectedId())
1280 .withMinimumWidth (box.getWidth())
1281 .withMaximumNumColumns (1)
1282 .withStandardItemHeight (label.getHeight());
1285void LookAndFeel_V2::drawComboBoxTextWhenNothingSelected (Graphics& g, ComboBox& box, Label& label)
1289 auto font = label.getLookAndFeel().getLabelFont (label);
1293 auto textArea = getLabelBorderSize (label).
subtractedFrom (label.getLocalBounds());
1295 g.drawFittedText (box.getTextWhenNothingSelected(), textArea, label.getJustificationType(),
1296 jmax (1, (
int) ((
float) textArea.getHeight() / font.getHeight())),
1297 label.getMinimumHorizontalScale());
1301Font LookAndFeel_V2::getLabelFont (Label& label)
1303 return label.getFont();
1306void LookAndFeel_V2::drawLabel (Graphics& g, Label& label)
1310 if (! label.isBeingEdited())
1312 auto alpha = label.isEnabled() ? 1.0f : 0.5f;
1313 const Font font (getLabelFont (label));
1318 auto textArea = getLabelBorderSize (label).
subtractedFrom (label.getLocalBounds());
1320 g.drawFittedText (label.getText(), textArea, label.getJustificationType(),
1321 jmax (1, (
int) ((
float) textArea.getHeight() / font.getHeight())),
1322 label.getMinimumHorizontalScale());
1326 else if (label.isEnabled())
1331 g.drawRect (label.getLocalBounds());
1334BorderSize<int> LookAndFeel_V2::getLabelBorderSize (Label& label)
1336 return label.getBorderSize();
1340void LookAndFeel_V2::drawLinearSliderBackground (Graphics& g,
int x,
int y,
int width,
int height,
1346 auto sliderRadius = (
float) (getSliderThumbRadius (slider) - 2);
1348 auto gradCol1 = trackColour.overlaidWith (Colours::black.withAlpha (slider.isEnabled() ? 0.25f : 0.13f));
1349 auto gradCol2 = trackColour.overlaidWith (Colour (0x14000000));
1353 if (slider.isHorizontal())
1355 const float iy = (
float) y + (
float) height * 0.5f - sliderRadius * 0.5f;
1356 const float ih = sliderRadius;
1360 indent.addRoundedRectangle ((
float) x - sliderRadius * 0.5f, iy,
1361 (
float) width + sliderRadius, ih,
1366 const float ix = (
float) x + (
float) width * 0.5f - sliderRadius * 0.5f;
1367 const float iw = sliderRadius;
1371 indent.addRoundedRectangle (ix, (
float) y - sliderRadius * 0.5f,
1372 iw, (
float) height + sliderRadius,
1376 g.fillPath (indent);
1378 g.setColour (Colour (0x4c000000));
1379 g.strokePath (indent, PathStrokeType (0.5f));
1382void LookAndFeel_V2::drawLinearSliderOutline (Graphics& g,
int,
int,
int,
int,
1388 g.drawRect (0, 0, slider.getWidth(), slider.getHeight(), 1);
1392void LookAndFeel_V2::drawLinearSliderThumb (Graphics& g,
int x,
int y,
int width,
int height,
1393 float sliderPos,
float minSliderPos,
float maxSliderPos,
1396 auto sliderRadius = (
float) (getSliderThumbRadius (slider) - 2);
1398 auto knobColour = detail::LookAndFeelHelpers::createBaseColour (slider.findColour (
Slider::thumbColourId),
1399 slider.hasKeyboardFocus (
false) && slider.isEnabled(),
1400 slider.isMouseOverOrDragging() && slider.isEnabled(),
1401 slider.isMouseButtonDown() && slider.isEnabled());
1403 const float outlineThickness = slider.isEnabled() ? 0.8f : 0.3f;
1411 kx = (
float) x + (
float) width * 0.5f;
1417 ky = (
float) y + (
float) height * 0.5f;
1423 sliderRadius * 2.0f,
1424 knobColour, outlineThickness);
1431 sliderPos - sliderRadius,
1432 sliderRadius * 2.0f,
1433 knobColour, outlineThickness);
1438 (
float) y + (
float) height * 0.5f - sliderRadius,
1439 sliderRadius * 2.0f,
1440 knobColour, outlineThickness);
1445 auto sr =
jmin (sliderRadius, (
float) width * 0.4f);
1447 drawGlassPointer (g,
jmax (0.0f, (
float) x + (
float) width * 0.5f - sliderRadius * 2.0f),
1448 minSliderPos - sliderRadius,
1449 sliderRadius * 2.0f, knobColour, outlineThickness, 1);
1451 drawGlassPointer (g,
1452 jmin ((
float) x + (
float) width - sliderRadius * 2.0f,
1453 (
float) x + (
float) width * 0.5f),
1455 sliderRadius * 2.0f,
1462 auto sr =
jmin (sliderRadius, (
float) height * 0.4f);
1464 drawGlassPointer (g, minSliderPos - sr,
1465 jmax (0.0f, (
float) y + (
float) height * 0.5f - sliderRadius * 2.0f),
1466 sliderRadius * 2.0f, knobColour, outlineThickness, 2);
1468 drawGlassPointer (g,
1469 maxSliderPos - sliderRadius,
1470 jmin ((
float) y + (
float) height - sliderRadius * 2.0f,
1471 (
float) y + (
float) height * 0.5f),
1472 sliderRadius * 2.0f,
1480void LookAndFeel_V2::drawLinearSlider (Graphics& g,
int x,
int y,
int width,
int height,
1481 float sliderPos,
float minSliderPos,
float maxSliderPos,
1488 const bool isMouseOver = slider.isMouseOverOrDragging() && slider.isEnabled();
1490 auto baseColour = detail::LookAndFeelHelpers::createBaseColour (slider.findColour (
Slider::thumbColourId)
1491 .withMultipliedSaturation (slider.isEnabled() ? 1.0f : 0.5f),
1493 isMouseOver || slider.isMouseButtonDown());
1495 drawShinyButtonShape (g,
1499 style == Slider::LinearBarVertical ? (
float) width
1500 : (sliderPos - (
float) x),
1501 style == Slider::LinearBarVertical ? ((
float) height - sliderPos)
1502 : (
float) height, 0.0f,
1504 slider.isEnabled() ? 0.9f : 0.3f,
1505 true, true, true, true);
1507 drawLinearSliderOutline (g, x, y, width, height, style, slider);
1511 drawLinearSliderBackground (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider);
1512 drawLinearSliderThumb (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider);
1516int LookAndFeel_V2::getSliderThumbRadius (Slider& slider)
1519 slider.getHeight() / 2,
1520 slider.getWidth() / 2) + 2;
1523void LookAndFeel_V2::drawRotarySlider (Graphics& g,
int x,
int y,
int width,
int height,
float sliderPos,
1524 const float rotaryStartAngle,
const float rotaryEndAngle, Slider& slider)
1526 const float radius =
jmin ((
float) width * 0.5f, (
float) height * 0.5f) - 2.0f;
1527 const float centreX = (
float) x + (
float) width * 0.5f;
1528 const float centreY = (
float) y + (
float) height * 0.5f;
1529 const float rx = centreX - radius;
1530 const float ry = centreY - radius;
1531 const float rw = radius * 2.0f;
1532 const float angle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
1533 const bool isMouseOver = slider.isMouseOverOrDragging() && slider.isEnabled();
1537 if (slider.isEnabled())
1540 g.setColour (Colour (0x80808080));
1542 const float thickness = 0.7f;
1546 filledArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, angle, thickness);
1547 g.fillPath (filledArc);
1551 const float innerRadius = radius * 0.2f;
1553 p.addTriangle (-innerRadius, 0.0f,
1554 0.0f, -radius * thickness * 1.1f,
1557 p.addEllipse (-innerRadius, -innerRadius, innerRadius * 2.0f, innerRadius * 2.0f);
1562 if (slider.isEnabled())
1565 g.setColour (Colour (0x80808080));
1568 outlineArc.addPieSegment (rx, ry, rw, rw, rotaryStartAngle, rotaryEndAngle, thickness);
1569 outlineArc.closeSubPath();
1571 g.strokePath (outlineArc, PathStrokeType (slider.isEnabled() ? (isMouseOver ? 2.0f : 1.2f) : 0.3f));
1575 if (slider.isEnabled())
1578 g.setColour (Colour (0x80808080));
1581 p.addEllipse (-0.4f * rw, -0.4f * rw, rw * 0.8f, rw * 0.8f);
1582 PathStrokeType (rw * 0.1f).createStrokedPath (p, p);
1584 p.addLineSegment (Line<float> (0.0f, 0.0f, 0.0f, -radius), rw * 0.2f);
1590Button* LookAndFeel_V2::createSliderButton (Slider&,
const bool isIncrement)
1592 return new TextButton (isIncrement ?
"+" :
"-", String());
1595class LookAndFeel_V2::SliderLabelComp final :
public Label
1598 SliderLabelComp() : Label ({}, {}) {}
1600 void mouseWheelMove (
const MouseEvent&,
const MouseWheelDetails&)
override {}
1604 return createIgnoredAccessibilityHandler (*
this);
1608Label* LookAndFeel_V2::createSliderTextBox (Slider& slider)
1610 auto l =
new SliderLabelComp();
1613 l->setKeyboardType (TextInputTarget::decimalKeyboard);
1618 ? Colours::transparentBlack
1619 : slider.
findColour (Slider::textBoxBackgroundColourId));
1632ImageEffectFilter* LookAndFeel_V2::getSliderEffect (Slider&)
1637Font LookAndFeel_V2::getSliderPopupFont (Slider&)
1642int LookAndFeel_V2::getSliderPopupPlacement (Slider&)
1644 return BubbleComponent::above
1645 | BubbleComponent::below
1646 | BubbleComponent::left
1647 | BubbleComponent::right;
1651Slider::SliderLayout LookAndFeel_V2::getSliderLayout (Slider& slider)
1658 auto textBoxPos = slider.getTextBoxPosition();
1665 auto localBounds = slider.getLocalBounds();
1667 auto textBoxWidth =
jmax (0,
jmin (slider.getTextBoxWidth(), localBounds.getWidth() - minXSpace));
1668 auto textBoxHeight =
jmax (0,
jmin (slider.getTextBoxHeight(), localBounds.getHeight() - minYSpace));
1670 Slider::SliderLayout layout;
1678 layout.textBoxBounds = localBounds;
1682 layout.textBoxBounds.setWidth (textBoxWidth);
1683 layout.textBoxBounds.setHeight (textBoxHeight);
1686 else if (textBoxPos ==
Slider::TextBoxRight) layout.textBoxBounds.setX (localBounds.getWidth() - textBoxWidth);
1687 else layout.textBoxBounds.setX ((localBounds.getWidth() - textBoxWidth) / 2);
1690 else if (textBoxPos ==
Slider::TextBoxBelow) layout.textBoxBounds.setY (localBounds.getHeight() - textBoxHeight);
1691 else layout.textBoxBounds.setY ((localBounds.getHeight() - textBoxHeight) / 2);
1697 layout.sliderBounds = localBounds;
1701 layout.sliderBounds.reduce (1, 1);
1706 else if (textBoxPos ==
Slider::TextBoxRight) layout.sliderBounds.removeFromRight (textBoxWidth);
1707 else if (textBoxPos ==
Slider::TextBoxAbove) layout.sliderBounds.removeFromTop (textBoxHeight);
1708 else if (textBoxPos ==
Slider::TextBoxBelow) layout.sliderBounds.removeFromBottom (textBoxHeight);
1710 const int thumbIndent = getSliderThumbRadius (slider);
1712 if (slider.isHorizontal()) layout.sliderBounds.reduce (thumbIndent, 0);
1713 else if (slider.isVertical()) layout.sliderBounds.reduce (0, thumbIndent);
1722 const TextLayout tl (detail::LookAndFeelHelpers::layoutTooltipText (tipText, Colours::black));
1724 auto w = (
int) (tl.getWidth() + 14.0f);
1725 auto h = (
int) (tl.getHeight() + 6.0f);
1727 return Rectangle<int> (screenPos.x > parentArea.getCentreX() ? screenPos.x - (w + 12) : screenPos.x + 24,
1728 screenPos.y > parentArea.getCentreY() ? screenPos.y - (h + 6) : screenPos.y + 6,
1730 .constrainedWithin (parentArea);
1733void LookAndFeel_V2::drawTooltip (Graphics& g,
const String& text,
int width,
int height)
1739 g.drawRect (0, 0, width, height, 1);
1743 .draw (g, Rectangle<float> ((
float) width, (
float) height));
1747Button* LookAndFeel_V2::createFilenameComponentBrowseButton (
const String& text)
1749 return new TextButton (text,
TRANS (
"click to browse for a different file"));
1752void LookAndFeel_V2::layoutFilenameComponent (FilenameComponent& filenameComp,
1753 ComboBox* filenameBox, Button* browseButton)
1755 if (browseButton ==
nullptr || filenameBox ==
nullptr)
1758 browseButton->setSize (80, filenameComp.getHeight());
1760 if (
auto* tb =
dynamic_cast<TextButton*
> (browseButton))
1761 tb->changeWidthToFitText();
1763 browseButton->setTopRightPosition (filenameComp.getWidth(), 0);
1765 filenameBox->setBounds (0, 0, browseButton->getX(), filenameComp.getHeight());
1769void LookAndFeel_V2::drawConcertinaPanelHeader (Graphics& g,
const Rectangle<int>& area,
1770 bool isMouseOver,
bool ,
1771 ConcertinaPanel&, Component& panel)
1773 g.fillAll (Colours::grey.withAlpha (isMouseOver ? 0.9f : 0.7f));
1774 g.setColour (Colours::black.withAlpha (0.5f));
1777 g.setColour (Colours::white);
1778 g.setFont (Font ((
float) area.getHeight() * 0.7f).boldened());
1783void LookAndFeel_V2::drawImageButton (Graphics& g, Image* image,
1784 int imageX,
int imageY,
int imageW,
int imageH,
1785 const Colour& overlayColour,
1787 ImageButton& button)
1789 if (! button.isEnabled())
1790 imageOpacity *= 0.3f;
1793 .getTransformToFit (image->getBounds().toFloat(),
1794 Rectangle<int> (imageX, imageY, imageW, imageH).toFloat());
1796 if (! overlayColour.isOpaque())
1798 g.setOpacity (imageOpacity);
1799 g.drawImageTransformed (*image, t,
false);
1802 if (! overlayColour.isTransparent())
1804 g.setColour (overlayColour);
1805 g.drawImageTransformed (*image, t,
true);
1810void LookAndFeel_V2::drawCornerResizer (Graphics& g,
int w,
int h,
bool ,
bool )
1812 auto lineThickness =
jmin ((
float) w, (
float) h) * 0.075f;
1814 for (
float i = 0.0f; i < 1.0f; i += 0.3f)
1816 g.setColour (Colours::lightgrey);
1818 g.drawLine ((
float) w * i,
1824 g.setColour (Colours::darkgrey);
1826 g.drawLine ((
float) w * i + lineThickness,
1829 (
float) h * i + lineThickness,
1834void LookAndFeel_V2::drawResizableFrame (Graphics& g,
int w,
int h,
const BorderSize<int>& border)
1836 if (! border.isEmpty())
1838 const Rectangle<int> fullSize (0, 0, w, h);
1839 auto centreArea = border.subtractedFrom (fullSize);
1841 Graphics::ScopedSaveState ss (g);
1843 g.excludeClipRegion (centreArea);
1845 g.setColour (Colour (0x50000000));
1846 g.drawRect (fullSize);
1848 g.setColour (Colour (0x19000000));
1849 g.drawRect (centreArea.expanded (1, 1));
1854void LookAndFeel_V2::fillResizableWindowBackground (Graphics& g,
int ,
int ,
1855 const BorderSize<int>& , ResizableWindow& window)
1857 g.fillAll (window.getBackgroundColour());
1860void LookAndFeel_V2::drawResizableWindowBorder (Graphics&,
int ,
int ,
1861 const BorderSize<int>& , ResizableWindow&)
1865void LookAndFeel_V2::drawDocumentWindowTitleBar (DocumentWindow& window, Graphics& g,
1866 int w,
int h,
int titleSpaceX,
int titleSpaceW,
1867 const Image* icon,
bool drawTitleTextOnLeft)
1872 const bool isActive = window.isActiveWindow();
1875 window.getBackgroundColour().contrasting (isActive ? 0.15f : 0.05f), (
float) h));
1881 int textW = font.getStringWidth (window.getName());
1885 if (icon !=
nullptr)
1887 iconH = (
int) font.getHeight();
1888 iconW = icon->getWidth() * iconH / icon->getHeight() + 4;
1891 textW =
jmin (titleSpaceW, textW + iconW);
1892 int textX = drawTitleTextOnLeft ? titleSpaceX
1893 :
jmax (titleSpaceX, (w - textW) / 2);
1895 if (textX + textW > titleSpaceX + titleSpaceW)
1896 textX = titleSpaceX + titleSpaceW - textW;
1898 if (icon !=
nullptr)
1900 g.setOpacity (isActive ? 1.0f : 0.6f);
1901 g.drawImageWithin (*icon, textX, (h - iconH) / 2, iconW, iconH,
1910 g.setColour (window.getBackgroundColour().contrasting (isActive ? 0.7f : 0.4f));
1916class LookAndFeel_V2::GlassWindowButton final :
public Button
1919 GlassWindowButton (
const String& name, Colour col,
1920 const Path& normalShape_,
1921 const Path& toggledShape_) noexcept
1924 normalShape (normalShape_),
1925 toggledShape (toggledShape_)
1930 void paintButton (Graphics& g,
bool shouldDrawButtonAsHighlighted,
bool shouldDrawButtonAsDown)
override
1932 float alpha = shouldDrawButtonAsHighlighted ? (shouldDrawButtonAsDown ? 1.0f : 0.8f) : 0.55f;
1937 float x = 0, y = 0, diam;
1939 if (getWidth() < getHeight())
1941 diam = (
float) getWidth();
1942 y = (
float) (getHeight() - getWidth()) * 0.5f;
1946 diam = (
float) getHeight();
1947 y = (
float) (getWidth() - getHeight()) * 0.5f;
1954 g.setGradientFill (ColourGradient (Colour::greyLevel (0.9f).withAlpha (alpha), 0, y + diam,
1955 Colour::greyLevel (0.6f).withAlpha (alpha), 0, y,
false));
1956 g.fillEllipse (x, y, diam, diam);
1962 LookAndFeel_V2::drawGlassSphere (g, x, y, diam, colour.withAlpha (alpha), 1.0f);
1964 Path& p = getToggleState() ? toggledShape : normalShape;
1966 const AffineTransform t (p.getTransformToScaleToFit (x + diam * 0.3f, y + diam * 0.3f,
1967 diam * 0.4f, diam * 0.4f,
true));
1969 g.setColour (Colours::black.withAlpha (alpha * 0.6f));
1975 Path normalShape, toggledShape;
1980Button* LookAndFeel_V2::createDocumentWindowButton (
int buttonType)
1983 const float crossThickness = 0.25f;
1985 if (buttonType == DocumentWindow::closeButton)
1987 shape.addLineSegment (Line<float> (0.0f, 0.0f, 1.0f, 1.0f), crossThickness * 1.4f);
1988 shape.addLineSegment (Line<float> (1.0f, 0.0f, 0.0f, 1.0f), crossThickness * 1.4f);
1990 return new GlassWindowButton (
"close", Colour (0xffdd1100), shape, shape);
1993 if (buttonType == DocumentWindow::minimiseButton)
1995 shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), crossThickness);
1997 return new GlassWindowButton (
"minimise", Colour (0xffaa8811), shape, shape);
2000 if (buttonType == DocumentWindow::maximiseButton)
2002 shape.addLineSegment (Line<float> (0.5f, 0.0f, 0.5f, 1.0f), crossThickness);
2003 shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), crossThickness);
2005 Path fullscreenShape;
2006 fullscreenShape.startNewSubPath (45.0f, 100.0f);
2007 fullscreenShape.lineTo (0.0f, 100.0f);
2008 fullscreenShape.lineTo (0.0f, 0.0f);
2009 fullscreenShape.lineTo (100.0f, 0.0f);
2010 fullscreenShape.lineTo (100.0f, 45.0f);
2011 fullscreenShape.addRectangle (45.0f, 45.0f, 100.0f, 100.0f);
2012 PathStrokeType (30.0f).createStrokedPath (fullscreenShape, fullscreenShape);
2014 return new GlassWindowButton (
"maximise", Colour (0xff119911), shape, fullscreenShape);
2021void LookAndFeel_V2::positionDocumentWindowButtons (DocumentWindow&,
2022 int titleBarX,
int titleBarY,
2023 int titleBarW,
int titleBarH,
2024 Button* minimiseButton,
2025 Button* maximiseButton,
2026 Button* closeButton,
2027 bool positionTitleBarButtonsOnLeft)
2029 const int buttonW = titleBarH - titleBarH / 8;
2031 int x = positionTitleBarButtonsOnLeft ? titleBarX + 4
2032 : titleBarX + titleBarW - buttonW - buttonW / 4;
2034 if (closeButton !=
nullptr)
2036 closeButton->setBounds (x, titleBarY, buttonW, titleBarH);
2037 x += positionTitleBarButtonsOnLeft ? buttonW : -(buttonW + buttonW / 4);
2040 if (positionTitleBarButtonsOnLeft)
2041 std::swap (minimiseButton, maximiseButton);
2043 if (maximiseButton !=
nullptr)
2045 maximiseButton->setBounds (x, titleBarY, buttonW, titleBarH);
2046 x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
2049 if (minimiseButton !=
nullptr)
2050 minimiseButton->setBounds (x, titleBarY, buttonW, titleBarH);
2053int LookAndFeel_V2::getDefaultMenuBarHeight()
2066 struct WindowProperties final :
public FocusOutline::OutlineWindowProperties
2068 Rectangle<int> getOutlineBounds (Component& c)
override
2070 return c.getScreenBounds();
2073 void drawOutline (Graphics& g,
int width,
int height)
override
2075 g.setColour (Colours::yellow.withAlpha (0.6f));
2076 g.drawRoundedRectangle ({ (
float) width, (
float) height }, 3.0f, 3.0f);
2084void LookAndFeel_V2::drawStretchableLayoutResizerBar (Graphics& g,
int w,
int h,
2087 bool isMouseDragging)
2091 if (isMouseOver || isMouseDragging)
2093 g.fillAll (Colour (0x190000ff));
2097 auto cx = (
float) w * 0.5f;
2098 auto cy = (
float) h * 0.5f;
2101 g.setGradientFill (ColourGradient (Colours::white.withAlpha (alpha), cx + cr * 0.1f, cy + cr,
2102 Colours::black.withAlpha (alpha), cx, cy - cr * 4.0f,
2105 g.fillEllipse (cx - cr, cy - cr, cr * 2.0f, cr * 2.0f);
2109void LookAndFeel_V2::drawGroupComponentOutline (Graphics& g,
int width,
int height,
2110 const String& text,
const Justification& position,
2111 GroupComponent& group)
2113 const float textH = 15.0f;
2114 const float indent = 3.0f;
2115 const float textEdgeGap = 4.0f;
2122 auto y = f.getAscent() - 3.0f;
2123 auto w =
jmax (0.0f, (
float) width - x * 2.0f);
2124 auto h =
jmax (0.0f, (
float) height - y - indent);
2125 cs =
jmin (cs, w * 0.5f, h * 0.5f);
2126 auto cs2 = 2.0f * cs;
2128 auto textW = text.isEmpty() ? 0
2130 jmax (0.0f, w - cs2 - textEdgeGap * 2),
2131 (
float) f.getStringWidth (text) + textEdgeGap * 2.0f);
2132 auto textX = cs + textEdgeGap;
2135 textX = cs + (w - cs2 - textW) * 0.5f;
2137 textX = w - cs - textW - textEdgeGap;
2139 p.startNewSubPath (x + textX + textW, y);
2140 p.lineTo (x + w - cs, y);
2143 p.lineTo (x + w, y + h - cs);
2146 p.lineTo (x + cs, y + h);
2149 p.lineTo (x, y + cs);
2152 p.lineTo (x + textX, y);
2154 auto alpha = group.isEnabled() ? 1.0f : 0.5f;
2157 .withMultipliedAlpha (alpha));
2159 g.strokePath (p, PathStrokeType (2.0f));
2162 .withMultipliedAlpha (alpha));
2172int LookAndFeel_V2::getTabButtonOverlap (
int tabDepth)
2174 return 1 + tabDepth / 3;
2177int LookAndFeel_V2::getTabButtonSpaceAroundImage()
2182int LookAndFeel_V2::getTabButtonBestWidth (TabBarButton& button,
int tabDepth)
2184 int width = Font ((
float) tabDepth * 0.6f).getStringWidth (button.getButtonText().trim())
2185 + getTabButtonOverlap (tabDepth) * 2;
2187 if (
auto* extraComponent = button.getExtraComponent())
2188 width += button.getTabbedButtonBar().isVertical() ? extraComponent->getHeight()
2189 : extraComponent->getWidth();
2191 return jlimit (tabDepth * 2, tabDepth * 8, width);
2194Rectangle<int> LookAndFeel_V2::getTabButtonExtraComponentBounds (
const TabBarButton& button, Rectangle<int>& textArea, Component& comp)
2196 Rectangle<int> extraComp;
2198 auto orientation = button.getTabbedButtonBar().getOrientation();
2200 if (button.getExtraComponentPlacement() == TabBarButton::beforeText)
2202 switch (orientation)
2204 case TabbedButtonBar::TabsAtBottom:
2205 case TabbedButtonBar::TabsAtTop: extraComp = textArea.removeFromLeft (comp.getWidth());
break;
2206 case TabbedButtonBar::TabsAtLeft: extraComp = textArea.removeFromBottom (comp.getHeight());
break;
2207 case TabbedButtonBar::TabsAtRight: extraComp = textArea.removeFromTop (comp.getHeight());
break;
2213 switch (orientation)
2215 case TabbedButtonBar::TabsAtBottom:
2216 case TabbedButtonBar::TabsAtTop: extraComp = textArea.removeFromRight (comp.getWidth());
break;
2217 case TabbedButtonBar::TabsAtLeft: extraComp = textArea.removeFromTop (comp.getHeight());
break;
2218 case TabbedButtonBar::TabsAtRight: extraComp = textArea.removeFromBottom (comp.getHeight());
break;
2226void LookAndFeel_V2::createTabButtonShape (TabBarButton& button, Path& p,
bool ,
bool )
2228 auto activeArea = button.getActiveArea();
2229 auto w = (
float) activeArea.getWidth();
2230 auto h = (
float) activeArea.getHeight();
2235 if (button.getTabbedButtonBar().isVertical())
2238 const float indent = (
float) getTabButtonOverlap ((
int) depth);
2239 const float overhang = 4.0f;
2241 switch (button.getTabbedButtonBar().getOrientation())
2243 case TabbedButtonBar::TabsAtLeft:
2244 p.startNewSubPath (w, 0.0f);
2245 p.lineTo (0.0f, indent);
2246 p.lineTo (0.0f, h - indent);
2248 p.lineTo (w + overhang, h + overhang);
2249 p.lineTo (w + overhang, -overhang);
2252 case TabbedButtonBar::TabsAtRight:
2253 p.startNewSubPath (0.0f, 0.0f);
2254 p.lineTo (w, indent);
2255 p.lineTo (w, h - indent);
2257 p.lineTo (-overhang, h + overhang);
2258 p.lineTo (-overhang, -overhang);
2261 case TabbedButtonBar::TabsAtBottom:
2262 p.startNewSubPath (0.0f, 0.0f);
2263 p.lineTo (indent, h);
2264 p.lineTo (w - indent, h);
2266 p.lineTo (w + overhang, -overhang);
2267 p.lineTo (-overhang, -overhang);
2270 case TabbedButtonBar::TabsAtTop:
2272 p.startNewSubPath (0.0f, h);
2273 p.lineTo (indent, 0.0f);
2274 p.lineTo (w - indent, 0.0f);
2276 p.lineTo (w + overhang, h + overhang);
2277 p.lineTo (-overhang, h + overhang);
2283 p = p.createPathWithRoundedCorners (3.0f);
2286void LookAndFeel_V2::fillTabButtonShape (TabBarButton& button, Graphics& g,
const Path& path,
2289 auto tabBackground = button.getTabBackgroundColour();
2290 const bool isFrontTab = button.isFrontTab();
2292 g.setColour (isFrontTab ? tabBackground
2293 : tabBackground.withMultipliedAlpha (0.9f));
2298 : TabbedButtonBar::tabOutlineColourId, false)
2299 .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f));
2301 g.strokePath (path, PathStrokeType (isFrontTab ? 1.0f : 0.5f));
2304Font LookAndFeel_V2::getTabButtonFont (TabBarButton&,
float height)
2306 return { height * 0.6f };
2309void LookAndFeel_V2::drawTabButtonText (TabBarButton& button, Graphics& g,
bool isMouseOver,
bool isMouseDown)
2311 auto area = button.getTextArea().toFloat();
2313 auto length = area.getWidth();
2314 auto depth = area.getHeight();
2316 if (button.getTabbedButtonBar().isVertical())
2319 Font font (getTabButtonFont (button, depth));
2320 font.setUnderline (button.hasKeyboardFocus (
false));
2324 switch (button.getTabbedButtonBar().getOrientation())
2326 case TabbedButtonBar::TabsAtLeft: t = t.rotated (
MathConstants<float>::pi * -0.5f).translated (area.getX(), area.getBottom());
break;
2327 case TabbedButtonBar::TabsAtRight: t = t.rotated (
MathConstants<float>::pi * 0.5f).translated (area.getRight(), area.getY());
break;
2328 case TabbedButtonBar::TabsAtTop:
2329 case TabbedButtonBar::TabsAtBottom: t = t.translated (area.getX(), area.getY());
break;
2342 col = button.getTabBackgroundColour().contrasting();
2344 auto alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f;
2346 g.setColour (col.withMultipliedAlpha (alpha));
2350 g.drawFittedText (button.getButtonText().trim(),
2351 0, 0, (
int) length, (
int) depth,
2353 jmax (1, ((
int) depth) / 12));
2356void LookAndFeel_V2::drawTabButton (TabBarButton& button, Graphics& g,
bool isMouseOver,
bool isMouseDown)
2359 createTabButtonShape (button, tabShape, isMouseOver, isMouseDown);
2361 auto activeArea = button.getActiveArea();
2363 (
float) activeArea.getY()));
2365 DropShadow (Colours::black.withAlpha (0.5f), 2, Point<int> (0, 1)).drawForPath (g, tabShape);
2367 fillTabButtonShape (button, g, tabShape, isMouseOver, isMouseDown);
2368 drawTabButtonText (button, g, isMouseOver, isMouseDown);
2371void LookAndFeel_V2::drawTabbedButtonBarBackground (TabbedButtonBar&, Graphics&) {}
2373void LookAndFeel_V2::drawTabAreaBehindFrontButton (TabbedButtonBar& bar, Graphics& g,
const int w,
const int h)
2375 auto shadowSize = 0.2f;
2377 Rectangle<int> shadowRect, line;
2378 ColourGradient gradient (Colours::black.withAlpha (bar.isEnabled() ? 0.25f : 0.15f), 0, 0,
2379 Colours::transparentBlack, 0, 0, false);
2381 switch (bar.getOrientation())
2383 case TabbedButtonBar::TabsAtLeft:
2384 gradient.point1.x = (
float) w;
2385 gradient.point2.x = (
float) w * (1.0f - shadowSize);
2386 shadowRect.setBounds ((
int) gradient.point2.x, 0, w - (
int) gradient.point2.x, h);
2387 line.setBounds (w - 1, 0, 1, h);
2390 case TabbedButtonBar::TabsAtRight:
2391 gradient.point2.x = (
float) w * shadowSize;
2392 shadowRect.setBounds (0, 0, (
int) gradient.point2.x, h);
2393 line.setBounds (0, 0, 1, h);
2396 case TabbedButtonBar::TabsAtTop:
2397 gradient.point1.y = (
float) h;
2398 gradient.point2.y = (
float) h * (1.0f - shadowSize);
2399 shadowRect.setBounds (0, (
int) gradient.point2.y, w, h - (
int) gradient.point2.y);
2400 line.setBounds (0, h - 1, w, 1);
2403 case TabbedButtonBar::TabsAtBottom:
2404 gradient.point2.y = (
float) h * shadowSize;
2405 shadowRect.setBounds (0, 0, w, (
int) gradient.point2.y);
2406 line.setBounds (0, 0, w, 1);
2412 g.setGradientFill (gradient);
2413 g.fillRect (shadowRect.expanded (2, 2));
2415 g.setColour (Colour (0x80000000));
2419Button* LookAndFeel_V2::createTabBarExtrasButton()
2421 auto thickness = 7.0f;
2422 auto indent = 22.0f;
2425 p.addEllipse (-10.0f, -10.0f, 120.0f, 120.0f);
2427 DrawablePath ellipse;
2428 ellipse.setPath (p);
2429 ellipse.setFill (Colour (0x99ffffff));
2432 p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f);
2433 p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f);
2434 p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness);
2435 p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness);
2436 p.setUsingNonZeroWinding (
false);
2440 dp.setFill (Colour (0x59000000));
2442 DrawableComposite normalImage;
2443 normalImage.addAndMakeVisible (ellipse.createCopy().release());
2444 normalImage.addAndMakeVisible (dp.createCopy().release());
2446 dp.setFill (Colour (0xcc000000));
2448 DrawableComposite overImage;
2449 overImage.addAndMakeVisible (ellipse.createCopy().release());
2450 overImage.addAndMakeVisible (dp.createCopy().release());
2453 db->setImages (&normalImage, &overImage,
nullptr);
2459void LookAndFeel_V2::drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header)
2461 g.fillAll (Colours::white);
2463 auto area = header.getLocalBounds();
2464 area.removeFromTop (area.getHeight() / 2);
2468 g.setGradientFill (ColourGradient (backgroundColour,
2469 0.0f, (
float) area.getY(),
2470 backgroundColour.withMultipliedSaturation (.5f),
2471 0.0f, (
float) area.getBottom(),
2476 g.fillRect (area.removeFromBottom (1));
2478 for (
int i = header.getNumColumns (
true); --i >= 0;)
2479 g.fillRect (header.getColumnPosition (i).removeFromRight (1));
2482void LookAndFeel_V2::drawTableHeaderColumn (Graphics& g, TableHeaderComponent& header,
2483 const String& columnName,
int ,
2484 int width,
int height,
bool isMouseOver,
bool isMouseDown,
2490 g.fillAll (highlightColour);
2491 else if (isMouseOver)
2492 g.fillAll (highlightColour.withMultipliedAlpha (0.625f));
2494 Rectangle<int> area (width, height);
2500 sortArrow.addTriangle (0.0f, 0.0f,
2504 g.setColour (Colour (0x99000000));
2505 g.fillPath (sortArrow, sortArrow.getTransformToScaleToFit (area.removeFromRight (height / 2).reduced (2).toFloat(),
true));
2509 g.setFont (Font ((
float) height * 0.5f,
Font::bold));
2514void LookAndFeel_V2::drawLasso (Graphics& g, Component& lassoComp)
2516 const int outlineThickness = 1;
2518 g.fillAll (lassoComp.findColour (0x1000440 ));
2520 g.setColour (lassoComp.findColour (0x1000441 ));
2521 g.drawRect (lassoComp.getLocalBounds(), outlineThickness);
2525void LookAndFeel_V2::paintToolbarBackground (Graphics& g,
int w,
int h, Toolbar& toolbar)
2529 g.setGradientFill (ColourGradient (background, 0.0f, 0.0f,
2530 background.darker (0.1f),
2531 toolbar.isVertical() ? (
float) w - 1.0f : 0.0f,
2532 toolbar.isVertical() ? 0.0f : (
float) h - 1.0f,
2537Button* LookAndFeel_V2::createToolbarMissingItemsButton (Toolbar& )
2539 return createTabBarExtrasButton();
2542void LookAndFeel_V2::paintToolbarButtonBackground (Graphics& g,
int ,
int ,
2543 bool isMouseOver,
bool isMouseDown,
2544 ToolbarItemComponent& component)
2548 else if (isMouseOver)
2552void LookAndFeel_V2::paintToolbarButtonLabel (Graphics& g,
int x,
int y,
int width,
int height,
2553 const String& text, ToolbarItemComponent& component)
2556 .withAlpha (component.isEnabled() ? 1.0f : 0.25f));
2558 auto fontHeight =
jmin (14.0f, (
float) height * 0.85f);
2559 g.setFont (fontHeight);
2561 g.drawFittedText (text,
2562 x, y, width, height,
2564 jmax (1, height / (
int) fontHeight));
2568void LookAndFeel_V2::drawPropertyPanelSectionHeader (Graphics& g,
const String& name,
2569 bool isOpen,
int width,
int height)
2571 auto buttonSize = (
float) height * 0.75f;
2572 auto buttonIndent = ((
float) height - buttonSize) * 0.5f;
2574 drawTreeviewPlusMinusBox (g, Rectangle<float> (buttonIndent, buttonIndent, buttonSize, buttonSize), Colours::white, isOpen,
false);
2576 auto textX = (
int) (buttonIndent * 2.0f + buttonSize + 2.0f);
2578 g.setColour (Colours::black);
2579 g.setFont (Font ((
float) height * 0.7f,
Font::bold));
2583void LookAndFeel_V2::drawPropertyComponentBackground (Graphics& g,
int width,
int height, PropertyComponent& component)
2586 g.fillRect (0, 0, width, height - 1);
2589void LookAndFeel_V2::drawPropertyComponentLabel (Graphics& g,
int,
int height, PropertyComponent& component)
2592 .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f));
2594 g.setFont ((
float)
jmin (height, 24) * 0.65f);
2596 auto r = getPropertyComponentContentPosition (component);
2598 g.drawFittedText (component.getName(),
2599 3, r.getY(), r.getX() - 5, r.getHeight(),
2603Rectangle<int> LookAndFeel_V2::getPropertyComponentContentPosition (PropertyComponent& component)
2605 const int textW =
jmin (200, component.getWidth() / 3);
2606 return Rectangle<int> (textW, 1, component.getWidth() - textW - 1, component.getHeight() - 3);
2609int LookAndFeel_V2::getPropertyPanelSectionHeaderHeight (
const String& sectionTitle)
2611 return sectionTitle.isEmpty() ? 0 : 22;
2615void LookAndFeel_V2::drawCallOutBoxBackground (CallOutBox& box, Graphics& g,
2616 const Path& path, Image& cachedImage)
2618 if (cachedImage.isNull())
2620 cachedImage = Image (
Image::ARGB, box.getWidth(), box.getHeight(),
true);
2621 Graphics g2 (cachedImage);
2623 DropShadow (Colours::black.withAlpha (0.7f), 8, Point<int> (0, 2)).drawForPath (g2, path);
2626 g.setColour (Colours::black);
2627 g.drawImageAt (cachedImage, 0, 0);
2632 g.setColour (Colours::white.withAlpha (0.8f));
2633 g.strokePath (path, PathStrokeType (2.0f));
2636int LookAndFeel_V2::getCallOutBoxBorderSize (
const CallOutBox&)
2641float LookAndFeel_V2::getCallOutBoxCornerSize (
const CallOutBox&)
2647AttributedString LookAndFeel_V2::createFileChooserHeaderText (
const String& title,
2648 const String& instructions)
2654 s.append (title +
"\n\n", Font (17.0f,
Font::bold), colour);
2655 s.append (instructions, Font (14.0f), colour);
2660void LookAndFeel_V2::drawFileBrowserRow (Graphics& g,
int width,
int height,
2661 const File&,
const String& filename, Image* icon,
2662 const String& fileSizeDescription,
2663 const String& fileTimeDescription,
2664 bool isDirectory,
bool isItemSelected,
2665 int , DirectoryContentsDisplayComponent& dcc)
2667 auto fileListComp =
dynamic_cast<Component*
> (&dcc);
2674 g.setColour (Colours::black);
2676 if (icon !=
nullptr && icon->isValid())
2678 g.drawImageWithin (*icon, 2, 2, x - 4, height - 4,
2684 if (
auto* d = isDirectory ? getDefaultFolderImage()
2685 : getDefaultDocumentFileImage())
2686 d->drawWithin (g, Rectangle<float> (2.0f, 2.0f, x - 4.0f, (
float) height - 4.0f),
2697 g.setFont ((
float) height * 0.7f);
2699 if (width > 450 && ! isDirectory)
2701 auto sizeX =
roundToInt ((
float) width * 0.7f);
2702 auto dateX =
roundToInt ((
float) width * 0.8f);
2704 g.drawFittedText (filename,
2705 x, 0, sizeX - x, height,
2708 g.setFont ((
float) height * 0.5f);
2709 g.setColour (Colours::darkgrey);
2713 g.drawFittedText (fileSizeDescription,
2714 sizeX, 0, dateX - sizeX - 8, height,
2717 g.drawFittedText (fileTimeDescription,
2718 dateX, 0, width - 8 - dateX, height,
2724 g.drawFittedText (filename,
2725 x, 0, width - x, height,
2731Button* LookAndFeel_V2::createFileBrowserGoUpButton()
2736 arrowPath.addArrow ({ 50.0f, 100.0f, 50.0f, 0.0f }, 40.0f, 100.0f, 50.0f);
2738 DrawablePath arrowImage;
2739 arrowImage.setFill (Colours::black.withAlpha (0.4f));
2740 arrowImage.setPath (arrowPath);
2742 goUpButton->setImages (&arrowImage);
2747void LookAndFeel_V2::layoutFileBrowserComponent (FileBrowserComponent& browserComp,
2748 DirectoryContentsDisplayComponent* fileListComponent,
2749 FilePreviewComponent* previewComp,
2750 ComboBox* currentPathBox,
2751 TextEditor* filenameBox,
2755 auto w = browserComp.getWidth() - x - x;
2757 if (previewComp !=
nullptr)
2759 auto previewWidth = w / 3;
2760 previewComp->setBounds (x + w - previewWidth, 0, previewWidth, browserComp.getHeight());
2762 w -= previewWidth + 4;
2767 const int controlsHeight = 22;
2768 const int upButtonWidth = 50;
2769 auto bottomSectionHeight = controlsHeight + 8;
2771 currentPathBox->setBounds (x, y, w - upButtonWidth - 6, controlsHeight);
2772 goUpButton->setBounds (x + w - upButtonWidth, y, upButtonWidth, controlsHeight);
2774 y += controlsHeight + 4;
2776 if (
auto listAsComp =
dynamic_cast<Component*
> (fileListComponent))
2778 listAsComp->setBounds (x, y, w, browserComp.getHeight() - y - bottomSectionHeight);
2779 y = listAsComp->getBottom() + 4;
2782 filenameBox->setBounds (x + 50, y, w - 50, controlsHeight);
2793const Drawable* LookAndFeel_V2::getDefaultFolderImage()
2795 if (folderImage ==
nullptr)
2796 folderImage = createDrawableFromSVG (R
"svgdata(
2797<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="706" height="532">
2799 <linearGradient id="a">
2800 <stop stop-color="#adf" offset="0"/>
2801 <stop stop-color="#ecfaff" offset="1"/>
2803 <linearGradient id="b" x1=".6" x2="0" y1=".9" xlink:href="#a"/>
2804 <linearGradient id="c" x1=".6" x2=".1" y1=".9" y2=".3" xlink:href="#a"/>
2806 <g class="currentLayer">
2807 <path d="M112.1 104c-8.2 2.2-13.2 11.6-11.3 21l68.3 342.7c1.9 9.4 10.1 15.2 18.4 13l384.3-104.1c8.2-2.2 13.2-11.6 11.3-21l-48-266a15.8 15.8 0 0 0-18.4-12.8l-224.2 38s-20.3-41.3-28.3-39.3z" display="block" fill="url(#b)" stroke="#446c98" stroke-width="7"/>
2808 <path d="M608.6 136.8L235.2 208a22.7 22.7 0 0 0-16 19l-40.8 241c1.7 8.4 9.6 14.5 17.8 12.3l380-104c8-2.2 10.7-10.2 12.3-18.4l38-210.1c.4-15.4-10.4-11.8-18-11.1z" display="block" fill="url(#c)" opacity=".8" stroke="#446c98" stroke-width="7"/>
2813 return folderImage.get();
2816const Drawable* LookAndFeel_V2::getDefaultDocumentFileImage()
2818 if (documentImage ==
nullptr)
2819 documentImage = createDrawableFromSVG (R
"svgdata(
2820<svg version="1" viewBox="-10 -10 450 600" xmlns="http://www.w3.org/2000/svg">
2821 <path d="M17 0h290l120 132v426c0 10-8 19-17 19H17c-9 0-17-9-17-19V19C0 8 8 0 17 0z" fill="#e5e5e5" stroke="#888888" stroke-width="7"/>
2822 <path d="M427 132H324c-9 0-17-9-17-19V0l120 132z" fill="#ccc"/>
2826 return documentImage.get();
2830static Path createPathFromData (
float height,
const unsigned char* data,
size_t size)
2833 p.loadPathFromData (data, size);
2834 p.scaleToFit (0, 0, height * 2.0f, height,
true);
2840 static const unsigned char data[] =
2842 109,0,224,168,68,0,0,119,67,108,0,224,172,68,0,128,146,67,113,0,192,148,68,0,0,219,67,0,96,110,68,0,224,56,68,113,0,64,51,68,0,32,130,68,0,64,20,68,0,224,
2843 162,68,108,0,128,3,68,0,128,168,68,113,0,128,221,67,0,192,175,68,0,0,207,67,0,32,179,68,113,0,0,201,67,0,224,173,68,0,0,181,67,0,224,161,68,108,0,128,168,67,
2844 0,128,154,68,113,0,128,141,67,0,192,138,68,0,128,108,67,0,64,131,68,113,0,0,62,67,0,128,119,68,0,0,5,67,0,128,114,68,113,0,0,102,67,0,192,88,68,0,128,155,
2845 67,0,192,88,68,113,0,0,190,67,0,192,88,68,0,128,232,67,0,224,131,68,108,0,128,246,67,0,192,139,68,113,0,64,33,68,0,128,87,68,0,0,93,68,0,224,26,68,113,0,
2846 96,140,68,0,128,188,67,0,224,168,68,0,0,119,67,99,101
2849 return createPathFromData (height, data,
sizeof (data));
2854 static const unsigned char data[] =
2856 109,0,0,17,68,0,96,145,68,108,0,192,13,68,0,192,147,68,113,0,0,213,67,0,64,174,68,0,0,168,67,0,64,174,68,113,0,0,104,67,0,64,174,68,0,0,5,67,0,64,
2857 153,68,113,0,0,18,67,0,64,153,68,0,0,24,67,0,64,153,68,113,0,0,135,67,0,64,153,68,0,128,207,67,0,224,130,68,108,0,0,220,67,0,0,126,68,108,0,0,204,67,
2858 0,128,117,68,113,0,0,138,67,0,64,82,68,0,0,138,67,0,192,57,68,113,0,0,138,67,0,192,37,68,0,128,210,67,0,64,10,68,113,0,128,220,67,0,64,45,68,0,0,8,
2859 68,0,128,78,68,108,0,192,14,68,0,0,87,68,108,0,64,20,68,0,0,80,68,113,0,192,57,68,0,0,32,68,0,128,88,68,0,0,32,68,113,0,64,112,68,0,0,32,68,0,
2860 128,124,68,0,64,68,68,113,0,0,121,68,0,192,67,68,0,128,119,68,0,192,67,68,113,0,192,108,68,0,192,67,68,0,32,89,68,0,96,82,68,113,0,128,69,68,0,0,97,68,
2861 0,0,56,68,0,64,115,68,108,0,64,49,68,0,128,124,68,108,0,192,55,68,0,96,129,68,113,0,0,92,68,0,224,146,68,0,192,129,68,0,224,146,68,113,0,64,110,68,0,64,
2862 168,68,0,64,87,68,0,64,168,68,113,0,128,66,68,0,64,168,68,0,64,27,68,0,32,150,68,99,101
2865 return createPathFromData (height, data,
sizeof (data));
2869void LookAndFeel_V2::drawLevelMeter (Graphics& g,
int width,
int height,
float level)
2871 g.setColour (Colours::white.withAlpha (0.7f));
2872 g.fillRoundedRectangle (0.0f, 0.0f, (
float) width, (
float) height, 3.0f);
2873 g.setColour (Colours::black.withAlpha (0.2f));
2874 g.drawRoundedRectangle (1.0f, 1.0f, (
float) width - 2.0f, (
float) height - 2.0f, 3.0f, 1.0f);
2876 const int totalBlocks = 7;
2877 const int numBlocks =
roundToInt (totalBlocks * level);
2878 auto w = ((
float) width - 6.0f) / (
float) totalBlocks;
2880 for (
int i = 0; i < totalBlocks; ++i)
2883 g.setColour (Colours::lightblue.withAlpha (0.6f));
2885 g.setColour (i < totalBlocks - 1 ? Colours::blue.withAlpha (0.5f)
2888 g.fillRoundedRectangle (3.0f + (
float) i * w + w * 0.1f,
2891 (
float) height - 6.0f,
2897void LookAndFeel_V2::drawKeymapChangeButton (Graphics& g,
int width,
int height, Button& button,
const String& keyDescription)
2899 auto textColour = button.findColour (0x100ad01 ,
true);
2901 if (keyDescription.isNotEmpty())
2903 if (button.isEnabled())
2905 auto alpha = button.isDown() ? 0.3f : (button.isOver() ? 0.15f : 0.08f);
2906 g.fillAll (textColour.withAlpha (alpha));
2908 g.setOpacity (0.3f);
2912 g.setColour (textColour);
2913 g.setFont ((
float) height * 0.6f);
2914 g.drawFittedText (keyDescription,
2915 3, 0, width - 6, height,
2920 const float thickness = 7.0f;
2921 const float indent = 22.0f;
2924 p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f);
2925 p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f);
2926 p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness);
2927 p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness);
2928 p.setUsingNonZeroWinding (
false);
2930 g.setColour (textColour.withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f)));
2931 g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, (
float) width - 4.0f, (
float) height - 4.0f,
true));
2934 if (button.hasKeyboardFocus (
false))
2936 g.setColour (textColour.withAlpha (0.4f));
2937 g.drawRect (0, 0, width, height);
2942Font LookAndFeel_V2::getSidePanelTitleFont (SidePanel&)
2944 return Font (18.0f);
2947Justification LookAndFeel_V2::getSidePanelTitleJustification (SidePanel& panel)
2953Path LookAndFeel_V2::getSidePanelDismissButtonShape (SidePanel& panel)
2960 const int bevelThickness,
const Colour& topLeftColour,
const Colour& bottomRightColour,
2961 const bool useGradient,
const bool sharpEdgeOnOutside)
2963 if (g.clipRegionIntersects (Rectangle<int> (x, y, width, height)))
2965 auto& context = g.getInternalContext();
2966 Graphics::ScopedSaveState ss (g);
2968 for (
int i = bevelThickness; --i >= 0;)
2970 const float op = useGradient ? (
float) (sharpEdgeOnOutside ? bevelThickness - i : i) / (
float) bevelThickness
2973 context.setFill (topLeftColour.withMultipliedAlpha (op));
2974 context.fillRect (Rectangle<int> (x + i, y + i, width - i * 2, 1),
false);
2975 context.setFill (topLeftColour.withMultipliedAlpha (op * 0.75f));
2976 context.fillRect (Rectangle<int> (x + i, y + i + 1, 1, height - i * 2 - 2),
false);
2977 context.setFill (bottomRightColour.withMultipliedAlpha (op));
2978 context.fillRect (Rectangle<int> (x + i, y + height - i - 1, width - i * 2, 1),
false);
2979 context.setFill (bottomRightColour.withMultipliedAlpha (op * 0.75f));
2980 context.fillRect (Rectangle<int> (x + width - i - 1, y + i + 1, 1, height - i * 2 - 2),
false);
2986void LookAndFeel_V2::drawShinyButtonShape (Graphics& g,
float x,
float y,
float w,
float h,
2987 float maxCornerSize,
const Colour& baseColour,
float strokeWidth,
2988 bool flatOnLeft,
bool flatOnRight,
bool flatOnTop,
bool flatOnBottom)
noexcept
2990 if (w <= strokeWidth * 1.1f || h <= strokeWidth * 1.1f)
2993 auto cs =
jmin (maxCornerSize, w * 0.5f, h * 0.5f);
2996 outline.addRoundedRectangle (x, y, w, h, cs, cs,
2997 ! (flatOnLeft || flatOnTop),
2998 ! (flatOnRight || flatOnTop),
2999 ! (flatOnLeft || flatOnBottom),
3000 ! (flatOnRight || flatOnBottom));
3002 ColourGradient cg (baseColour, 0.0f, y,
3003 baseColour.overlaidWith (Colour (0x070000ff)), 0.0f, y + h,
3006 cg.addColour (0.5, baseColour.overlaidWith (Colour (0x33ffffff)));
3007 cg.addColour (0.51, baseColour.overlaidWith (Colour (0x110000ff)));
3009 g.setGradientFill (cg);
3010 g.fillPath (outline);
3012 g.setColour (Colour (0x80000000));
3013 g.strokePath (outline, PathStrokeType (strokeWidth));
3018 const float diameter,
const Colour& colour,
3019 const float outlineThickness)
noexcept
3021 if (diameter <= outlineThickness)
3025 p.addEllipse (x, y, diameter, diameter);
3028 ColourGradient cg (Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y,
3029 Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y + diameter,
false);
3031 cg.addColour (0.4, Colours::white.overlaidWith (colour));
3033 g.setGradientFill (cg);
3037 g.setGradientFill (ColourGradient (Colours::white, 0, y + diameter * 0.06f,
3038 Colours::transparentWhite, 0, y + diameter * 0.3f,
false));
3039 g.fillEllipse (x + diameter * 0.2f, y + diameter * 0.05f, diameter * 0.6f, diameter * 0.4f);
3041 ColourGradient cg (Colours::transparentBlack,
3042 x + diameter * 0.5f, y + diameter * 0.5f,
3043 Colours::black.withAlpha (0.5f * outlineThickness * colour.getFloatAlpha()),
3044 x, y + diameter * 0.5f,
true);
3046 cg.addColour (0.7, Colours::transparentBlack);
3047 cg.addColour (0.8, Colours::black.withAlpha (0.1f * outlineThickness));
3049 g.setGradientFill (cg);
3052 g.setColour (Colours::black.withAlpha (0.5f * colour.getFloatAlpha()));
3053 g.drawEllipse (x, y, diameter, diameter, outlineThickness);
3057void LookAndFeel_V2::drawGlassPointer (Graphics& g,
3058 const float x,
const float y,
const float diameter,
3059 const Colour& colour,
const float outlineThickness,
3060 const int direction)
noexcept
3062 if (diameter <= outlineThickness)
3066 p.startNewSubPath (x + diameter * 0.5f, y);
3067 p.lineTo (x + diameter, y + diameter * 0.6f);
3068 p.lineTo (x + diameter, y + diameter);
3069 p.lineTo (x, y + diameter);
3070 p.lineTo (x, y + diameter * 0.6f);
3074 x + diameter * 0.5f,
3075 y + diameter * 0.5f));
3078 ColourGradient cg (Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y,
3079 Colours::white.overlaidWith (colour.withMultipliedAlpha (0.3f)), 0, y + diameter,
false);
3081 cg.addColour (0.4, Colours::white.overlaidWith (colour));
3083 g.setGradientFill (cg);
3087 ColourGradient cg (Colours::transparentBlack,
3088 x + diameter * 0.5f, y + diameter * 0.5f,
3089 Colours::black.withAlpha (0.5f * outlineThickness * colour.getFloatAlpha()),
3090 x - diameter * 0.2f, y + diameter * 0.5f,
true);
3092 cg.addColour (0.5, Colours::transparentBlack);
3093 cg.addColour (0.7, Colours::black.withAlpha (0.07f * outlineThickness));
3095 g.setGradientFill (cg);
3098 g.setColour (Colours::black.withAlpha (0.5f * colour.getFloatAlpha()));
3099 g.strokePath (p, PathStrokeType (outlineThickness));
3104 float x,
float y,
float width,
float height,
3105 const Colour& colour,
float outlineThickness,
float cornerSize,
3106 bool flatOnLeft,
bool flatOnRight,
bool flatOnTop,
bool flatOnBottom)
noexcept
3108 if (width <= outlineThickness || height <= outlineThickness)
3111 auto intX = (
int) x;
3112 auto intY = (
int) y;
3113 auto intW = (
int) width;
3114 auto intH = (
int) height;
3116 auto cs = cornerSize < 0 ?
jmin (width * 0.5f, height * 0.5f) : cornerSize;
3117 auto edgeBlurRadius = height * 0.75f + (height - cs * 2.0f);
3118 auto intEdge = (
int) edgeBlurRadius;
3121 outline.addRoundedRectangle (x, y, width, height, cs, cs,
3122 ! (flatOnLeft || flatOnTop),
3123 ! (flatOnRight || flatOnTop),
3124 ! (flatOnLeft || flatOnBottom),
3125 ! (flatOnRight || flatOnBottom));
3128 ColourGradient cg (colour.darker (0.2f), 0, y,
3129 colour.darker (0.2f), 0, y + height,
false);
3131 cg.addColour (0.03, colour.withMultipliedAlpha (0.3f));
3132 cg.addColour (0.4, colour);
3133 cg.addColour (0.97, colour.withMultipliedAlpha (0.3f));
3135 g.setGradientFill (cg);
3136 g.fillPath (outline);
3139 ColourGradient cg (Colours::transparentBlack, x + edgeBlurRadius, y + height * 0.5f,
3140 colour.darker (0.2f), x, y + height * 0.5f,
true);
3142 cg.addColour (
jlimit (0.0, 1.0, 1.0 - (cs * 0.5f) / edgeBlurRadius), Colours::transparentBlack);
3143 cg.addColour (
jlimit (0.0, 1.0, 1.0 - (cs * 0.25f) / edgeBlurRadius), colour.darker (0.2f).withMultipliedAlpha (0.3f));
3145 if (! (flatOnLeft || flatOnTop || flatOnBottom))
3147 Graphics::ScopedSaveState ss (g);
3149 g.setGradientFill (cg);
3150 g.reduceClipRegion (intX, intY, intEdge, intH);
3151 g.fillPath (outline);
3154 if (! (flatOnRight || flatOnTop || flatOnBottom))
3156 cg.point1.setX (x + width - edgeBlurRadius);
3157 cg.point2.setX (x + width);
3159 Graphics::ScopedSaveState ss (g);
3161 g.setGradientFill (cg);
3162 g.reduceClipRegion (intX + intW - intEdge, intY, 2 + intEdge, intH);
3163 g.fillPath (outline);
3167 auto leftIndent = (flatOnTop || flatOnLeft) ? 0.0f : cs * 0.4f;
3168 auto rightIndent = (flatOnTop || flatOnRight) ? 0.0f : cs * 0.4f;
3171 highlight.addRoundedRectangle (x + leftIndent,
3173 width - (leftIndent + rightIndent),
3177 ! (flatOnLeft || flatOnTop),
3178 ! (flatOnRight || flatOnTop),
3179 ! (flatOnLeft || flatOnBottom),
3180 ! (flatOnRight || flatOnBottom));
3182 g.setGradientFill (ColourGradient (colour.brighter (10.0f), 0, y + height * 0.06f,
3183 Colours::transparentWhite, 0, y + height * 0.4f,
false));
3184 g.fillPath (highlight);
3187 g.setColour (colour.darker().withMultipliedAlpha (1.5f));
3188 g.strokePath (outline, PathStrokeType (outlineThickness));
@ textColourId
The colour for the text.
@ outlineColourId
An optional colour to use to draw a border around the window.
@ backgroundColourId
The background colour for the window.
@ backgroundColourId
The colour to fill the background of the button area.
@ outlineColourId
The colour to use to draw an outline around the text area.
Rectangle< ValueType > subtractedFrom(const Rectangle< ValueType > &original) const noexcept
Returns a rectangle with these borders removed from it.
@ outlineColourId
The colour to use for an outline around the bubble.
@ backgroundColourId
A background colour to fill the bubble with.
@ caretColourId
The colour with which to draw the caret.
static juce_wchar toLowerCase(juce_wchar character) noexcept
Converts a character to lower-case.
static ColourGradient horizontal(Colour colour1, float x1, Colour colour2, float x2)
Creates a horizontal linear gradient between two X coordinates.
static ColourGradient vertical(Colour colour1, float y1, Colour colour2, float y2)
Creates a vertical linear gradient between two Y coordinates.
static Colour greyLevel(float brightness) noexcept
Returns an opaque shade of grey.
Colour contrasting(float amount=1.0f) const noexcept
Returns a colour that will be clearly visible against this colour.
@ arrowColourId
The colour for the arrow shape that pops up the menu.
@ outlineColourId
The colour for an outline around the box.
@ focusedOutlineColourId
The colour that will be used to draw a box around the edge of the component when it has focus.
@ textColourId
The colour for the text in the box.
@ buttonColourId
The base colour for the button (a LookAndFeel class will probably use variations on this).
@ backgroundColourId
The background colour to fill the box with.
@ windowHasDropShadow
Indicates that the window should have a drop-shadow (this may not be possible on all platforms).
@ windowAppearsOnTaskbar
Indicates that the window should have a corresponding entry on the taskbar (ignored on MacOSX)
@ textColourId
The colour for the text.
@ highlightColourId
The colour to use to fill a highlighted row of the list.
@ highlightedTextColourId
The colour with which to draw the text in highlighted sections.
@ textColourId
The colour to draw any text with.
static std::unique_ptr< Drawable > createFromSVG(const XmlElement &svgDocument)
Attempts to parse an SVG (Scalable Vector Graphics) document, and to turn this into a Drawable tree.
void setShadowProperties(const DropShadow &newShadow)
Sets up parameters affecting the shadow's appearance.
@ currentPathBoxTextColourId
The colour to use for the text of the current path ComboBox.
@ filenameBoxBackgroundColourId
The colour to use to fill the background of the filename TextEditor.
@ currentPathBoxBackgroundColourId
The colour to use to fill the background of the current path ComboBox.
@ filenameBoxTextColourId
The colour to use for the text of the filename TextEditor.
@ currentPathBoxArrowColourId
The colour to use to draw the arrow of the current path ComboBox.
@ titleTextColourId
The colour to use to draw the box's title.
@ backgroundColourId
The background colour to fill the component with.
int getStringWidth(const String &text) const
Returns the total width of a string as it would be drawn using this font.
float getAscent() const
Returns the height of the font above its baseline, in pixels.
@ textColourId
The colour to use to draw the text label.
@ outlineColourId
The colour to use for drawing the line around the edge.
@ ARGB
< each pixel is a 4-byte ARGB premultiplied colour value.
@ centredRight
Indicates that the item should be centred vertically but placed on the right hand side.
@ centred
Indicates that the item should be centred vertically and horizontally.
@ centredLeft
Indicates that the item should be centred vertically but placed on the left hand side.
@ horizontallyCentred
Indicates that the item should be placed in the centre between the left and right sides of the availa...
@ right
Indicates that the item should be aligned against the right edge of the available space.
@ bottomLeft
Indicates that the item should be placed in the bottom-left corner.
static const int escapeKey
key-code for the escape key
static const int returnKey
key-code for the return key
@ outlineColourId
An optional colour to use to draw a border around the label.
@ backgroundColourId
The background colour to fill the label with.
@ textColourId
The colour for the text.
@ textColourId
The preferred colour to use for drawing text in the listbox.
@ backgroundColourId
The background colour to fill the list with.
@ outlineColourId
An optional colour to use to draw a border around the list.
void drawSpinningWaitAnimation(Graphics &, const Colour &colour, int x, int y, int w, int h) override
Draws a small image that spins to indicate that something's happening.
std::unique_ptr< DropShadower > createDropShadowerForComponent(Component &) override
Creates a drop-shadower for a given component, if required.
void setComponentEffectForBubbleComponent(BubbleComponent &bubbleComponent) override
Override this method to set effects, such as a drop-shadow, on a BubbleComponent.
void drawProgressBar(Graphics &, ProgressBar &, int width, int height, double progress, const String &textToShow) override
Draws a progress bar.
void drawPopupMenuBackgroundWithOptions(Graphics &, int width, int height, const PopupMenu::Options &) override
Fills the background of a popup menu component.
void drawToggleButton(Graphics &, ToggleButton &, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
Draws the contents of a standard ToggleButton.
void drawScrollbar(Graphics &, ScrollBar &, int x, int y, int width, int height, bool isScrollbarVertical, int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) override
Draws the thumb area of a scrollbar.
bool shouldPopupMenuScaleWithTargetComponent(const PopupMenu::Options &options) override
Return true if you want your popup menus to scale with the target component's AffineTransform or scal...
void drawPopupMenuColumnSeparatorWithOptions(Graphics &g, const Rectangle< int > &bounds, const PopupMenu::Options &) override
Implement this to draw some custom decoration between the columns of the popup menu.
static void drawGlassSphere(Graphics &, float x, float y, float diameter, const Colour &, float outlineThickness) noexcept
Utility function to draw a shiny, glassy circle (for round LED-type buttons).
void getIdealPopupMenuItemSize(const String &text, bool isSeparator, int standardMenuItemHeight, int &idealWidth, int &idealHeight) override
Finds the best size for an item in a popup menu.
void drawPopupMenuBackground(Graphics &, int width, int height) override
Fills the background of a popup menu component.
void drawScrollbarButton(Graphics &, ScrollBar &, int width, int height, int buttonDirection, bool isScrollbarVertical, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
Draws one of the buttons on a scrollbar.
std::unique_ptr< FocusOutline > createFocusOutlineForComponent(Component &) override
Creates a focus outline for a given component, if required.
void drawButtonText(Graphics &, TextButton &, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
Draws the text for a TextButton.
void getIdealPopupMenuItemSizeWithOptions(const String &text, bool isSeparator, int standardMenuItemHeight, int &idealWidth, int &idealHeight, const PopupMenu::Options &) override
Finds the best size for an item in a popup menu.
Rectangle< int > getTooltipBounds(const String &tipText, Point< int > screenPos, Rectangle< int > parentArea) override
returns the bounds for a tooltip at the given screen coordinate, constrained within the given desktop...
Font getAlertWindowMessageFont() override
Override this function to supply a custom font for the alert window message.
void drawBubble(Graphics &, BubbleComponent &, const Point< float > &tip, const Rectangle< float > &body) override
Override this method to draw a speech-bubble pointing at a specific location on the screen.
ProgressBar::Style getDefaultProgressBarStyle(const ProgressBar &) override
Returns the default style a progress bar should use if one hasn't been set.
int getScrollbarButtonSize(ScrollBar &) override
Returns the length in pixels to use for a scrollbar button.
int getPopupMenuColumnSeparatorWidthWithOptions(const PopupMenu::Options &) override
Return the amount of space that should be left between popup menu columns.
ImageEffectFilter * getScrollbarEffect() override
Returns the component effect to use for a scrollbar.
Path getCrossShape(float height) override
Returns a cross shape for use in yes/no boxes, etc.
static void drawBevel(Graphics &, int x, int y, int width, int height, int bevelThickness, const Colour &topLeftColour=Colours::white, const Colour &bottomRightColour=Colours::black, bool useGradient=true, bool sharpEdgeOnOutside=true)
Draws a 3D raised (or indented) bevel using two colours.
void drawPopupMenuItemWithOptions(Graphics &, const Rectangle< int > &area, bool isHighlighted, const PopupMenu::Item &item, const PopupMenu::Options &) override
Draws one of the items in a popup menu.
int getMinimumScrollbarThumbSize(ScrollBar &) override
Returns the minimum length in pixels to use for a scrollbar thumb.
int getDefaultScrollbarWidth() override
Returns the default thickness to use for a scrollbar.
Path getTickShape(float height) override
Returns a tick shape for use in yes/no boxes, etc.
Font getAlertWindowTitleFont() override
Override this function to supply a custom font for the alert window title.
void drawPopupMenuItem(Graphics &, const Rectangle< int > &area, bool isSeparator, bool isActive, bool isHighlighted, bool isTicked, bool hasSubMenu, const String &text, const String &shortcutKeyText, const Drawable *icon, const Colour *textColour) override
Draws one of the items in a popup menu.
static void drawGlassLozenge(Graphics &, float x, float y, float width, float height, const Colour &, float outlineThickness, float cornerSize, bool flatOnLeft, bool flatOnRight, bool flatOnTop, bool flatOnBottom) noexcept
Utility function to draw a shiny, glassy oblong (for text buttons).
Font getPopupMenuFont() override
Returns the size and style of font to use in popup menus.
bool isColourSpecified(int colourId) const noexcept
Returns true if the specified colour ID has been explicitly set using the setColour() method.
void setColour(int colourId, Colour colour) noexcept
Registers a colour to be used for a particular purpose.
Colour findColour(int colourId) const noexcept
Looks for a colour that has been registered with the given colour ID number.
@ backgroundColourId
The background colour, behind the bar.
@ foregroundColourId
The colour to use to draw the bar itself.
Style
The types of ProgressBar styles available.
@ linear
A linear progress bar.
@ labelTextColourId
The colour for the property's label text.
@ backgroundColourId
The background colour to fill the component with.
@ onlyReduceInSize
Indicates that the source rectangle can be reduced in size if required, but should never be made larg...
@ centred
A shorthand value that is equivalent to (xMid | yMid).
@ stretchToFit
If this flag is set, then the source rectangle will be resized to completely fill the destination rec...
@ backgroundColourId
A colour to use to fill the window's background.
SliderStyle
The types of slider available.
@ LinearBarVertical
A vertical bar slider with the text label drawn on top of it.
@ ThreeValueHorizontal
A horizontal slider that has three thumbs instead of one, so it can show a minimum and maximum value,...
@ TwoValueHorizontal
A horizontal slider that has two thumbs instead of one, so it can show a minimum and maximum value.
@ LinearBar
A horizontal bar slider with the text label drawn on top of it.
@ LinearHorizontal
A traditional horizontal slider.
@ LinearVertical
A traditional vertical slider.
@ ThreeValueVertical
A vertical slider that has three thumbs instead of one, so it can show a minimum and maximum value,...
@ TwoValueVertical
A vertical slider that has two thumbs instead of one, so it can show a minimum and maximum value.
@ textBoxBackgroundColourId
The background colour for the text-editor box.
@ textBoxTextColourId
The colour for the text in the text-editor box used for editing the value.
@ rotarySliderFillColourId
For rotary sliders, this colour fills the outer curve.
@ textBoxHighlightColourId
The text highlight colour for the text-editor box.
@ textBoxOutlineColourId
The colour to use for a border around the text-editor box.
@ trackColourId
The colour to draw the groove that the thumb moves along.
@ backgroundColourId
A colour to use to fill the slider's background.
@ rotarySliderOutlineColourId
For rotary sliders, this colour is used to draw the outer curve's outline.
@ thumbColourId
The colour to draw the thumb with.
@ TextBoxRight
Puts the text box to the right of the slider, vertically centred.
@ NoTextBox
Doesn't display a text box.
@ TextBoxAbove
Puts the text box above the slider, horizontally centred.
@ TextBoxBelow
Puts the text box below the slider, horizontally centred.
@ TextBoxLeft
Puts the text box to the left of the slider, vertically centred.
static String charToString(juce_wchar character)
Creates a string from a single character.
@ outlineColourId
The colour to use to draw an outline around the content.
@ backgroundColourId
The colour to fill the background behind the tabs.
@ textColourOnId
The colour to use for the button's text.when the button's toggle state is "on".
@ buttonColourId
The colour used to fill the button shape (when the button is toggled 'off').
@ buttonOnColourId
The colour used to fill the button shape (when the button is toggled 'on').
@ textColourOffId
The colour to use for the button's text when the button's toggle state is "off".
@ backgroundColourId
The colour to use for the text component's background - this can be transparent if necessary.
@ highlightColourId
The colour with which to fill the background of highlighted sections of the text - this can be transp...
@ textColourId
The colour that will be used when text is added to the editor.
@ outlineColourId
If this is non-transparent, it will be used to draw a box around the edge of the component.
@ highlightedTextColourId
The colour with which to draw the text in highlighted sections.
@ focusedOutlineColourId
If this is non-transparent, it will be used to draw a box around the edge of the component when it ha...
@ shadowColourId
If this is non-transparent, it'll be used to draw an inner shadow around the edge of the editor.
@ backgroundColourId
The colour to fill the background of the text area.
@ outlineColourId
The colour to use to draw an outline around the text area.
@ textColourId
The colour to use for the editable text.
static uint32 getMillisecondCounter() noexcept
Returns the number of millisecs since a fixed event (usually system startup).
@ dragAndDropIndicatorColourId
The colour to use for the drag-and-drop target position indicator.
@ oddItemsColourId
The colour to use to fill the background of the odd numbered items.
@ linesColourId
The colour to draw the lines with.
@ evenItemsColourId
The colour to use to fill the background of the even numbered items.
@ selectedItemBackgroundColourId
The colour to use to fill the background of any selected items.
@ backgroundColourId
A background colour to fill the component with.
#define TRANS(stringLiteral)
Uses the LocalisedStrings class to translate the given string literal.
wchar_t juce_wchar
A platform-independent 32-bit unicode character type.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
MessageBoxIconType
The type of icon to show in the dialog box.
@ WarningIcon
An exclamation mark to indicate that the dialog is a warning about something and shouldn't be ignored...
@ NoIcon
No icon will be shown on the dialog box.
@ InfoIcon
An icon that indicates that the dialog box is just giving the user some information,...
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
std::unique_ptr< XmlElement > parseXML(const String &textToParse)
Attempts to parse some XML text, returning a new XmlElement if it was valid.
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
unsigned char uint8
A platform-independent 8-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
constexpr int numElementsInArray(Type(&)[N]) noexcept
Handy function for getting the number of elements in a simple const C array.
static constexpr FloatType halfPi
A predefined value for Pi / 2.
static constexpr FloatType twoPi
A predefined value for 2 * Pi.
static constexpr FloatType pi
A predefined value for Pi.