Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1488 lines
68KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. Colour LookAndFeel_V4::ColourScheme::getUIColour (UIColour index) const noexcept
  21. {
  22. if (isPositiveAndBelow (index, numColours))
  23. return palette[index];
  24. jassertfalse;
  25. return {};
  26. }
  27. void LookAndFeel_V4::ColourScheme::setUIColour (UIColour index, Colour newColour) noexcept
  28. {
  29. if (isPositiveAndBelow (index, numColours))
  30. palette[index] = newColour;
  31. else
  32. jassertfalse;
  33. }
  34. bool LookAndFeel_V4::ColourScheme::operator== (const ColourScheme& other) const noexcept
  35. {
  36. for (auto i = 0; i < numColours; ++i)
  37. if (palette[i] != other.palette[i])
  38. return false;
  39. return true;
  40. }
  41. bool LookAndFeel_V4::ColourScheme::operator!= (const ColourScheme& other) const noexcept
  42. {
  43. return ! operator== (other);
  44. }
  45. //==============================================================================
  46. LookAndFeel_V4::LookAndFeel_V4() : currentColourScheme (getDarkColourScheme())
  47. {
  48. initialiseColours();
  49. }
  50. LookAndFeel_V4::LookAndFeel_V4 (ColourScheme scheme) : currentColourScheme (scheme)
  51. {
  52. initialiseColours();
  53. }
  54. LookAndFeel_V4::~LookAndFeel_V4() {}
  55. //==============================================================================
  56. void LookAndFeel_V4::setColourScheme (ColourScheme newColourScheme)
  57. {
  58. currentColourScheme = newColourScheme;
  59. initialiseColours();
  60. }
  61. LookAndFeel_V4::ColourScheme LookAndFeel_V4::getDarkColourScheme()
  62. {
  63. return { 0xff323e44, 0xff263238, 0xff323e44,
  64. 0xff8e989b, 0xffffffff, 0xff42a2c8,
  65. 0xffffffff, 0xff181f22, 0xffffffff };
  66. }
  67. LookAndFeel_V4::ColourScheme LookAndFeel_V4::getMidnightColourScheme()
  68. {
  69. return { 0xff2f2f3a, 0xff191926, 0xffd0d0d0,
  70. 0xff66667c, 0xc8ffffff, 0xffd8d8d8,
  71. 0xffffffff, 0xff606073, 0xff000000 };
  72. }
  73. LookAndFeel_V4::ColourScheme LookAndFeel_V4::getGreyColourScheme()
  74. {
  75. return { 0xff505050, 0xff424242, 0xff606060,
  76. 0xffa6a6a6, 0xffffffff, 0xff21ba90,
  77. 0xff000000, 0xffffffff, 0xffffffff };
  78. }
  79. LookAndFeel_V4::ColourScheme LookAndFeel_V4::getLightColourScheme()
  80. {
  81. return { 0xffefefef, 0xffffffff, 0xffffffff,
  82. 0xffdddddd, 0xff000000, 0xffa9a9a9,
  83. 0xffffffff, 0xff42a2c8, 0xff000000 };
  84. }
  85. //==============================================================================
  86. class LookAndFeel_V4_DocumentWindowButton : public Button
  87. {
  88. public:
  89. LookAndFeel_V4_DocumentWindowButton (const String& name, Colour c, const Path& normal, const Path& toggled)
  90. : Button (name), colour (c), normalShape (normal), toggledShape (toggled)
  91. {
  92. }
  93. void paintButton (Graphics& g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
  94. {
  95. auto background = Colours::grey;
  96. if (auto* rw = findParentComponentOfClass<ResizableWindow>())
  97. if (auto lf = dynamic_cast<LookAndFeel_V4*> (&rw->getLookAndFeel()))
  98. background = lf->getCurrentColourScheme().getUIColour (LookAndFeel_V4::ColourScheme::widgetBackground);
  99. g.fillAll (background);
  100. g.setColour ((! isEnabled() || shouldDrawButtonAsDown) ? colour.withAlpha (0.6f)
  101. : colour);
  102. if (shouldDrawButtonAsHighlighted)
  103. {
  104. g.fillAll();
  105. g.setColour (background);
  106. }
  107. auto& p = getToggleState() ? toggledShape : normalShape;
  108. auto reducedRect = Justification (Justification::centred)
  109. .appliedToRectangle (Rectangle<int> (getHeight(), getHeight()), getLocalBounds())
  110. .toFloat()
  111. .reduced ((float) getHeight() * 0.3f);
  112. g.fillPath (p, p.getTransformToScaleToFit (reducedRect, true));
  113. }
  114. private:
  115. Colour colour;
  116. Path normalShape, toggledShape;
  117. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V4_DocumentWindowButton)
  118. };
  119. Button* LookAndFeel_V4::createDocumentWindowButton (int buttonType)
  120. {
  121. Path shape;
  122. auto crossThickness = 0.15f;
  123. if (buttonType == DocumentWindow::closeButton)
  124. {
  125. shape.addLineSegment ({ 0.0f, 0.0f, 1.0f, 1.0f }, crossThickness);
  126. shape.addLineSegment ({ 1.0f, 0.0f, 0.0f, 1.0f }, crossThickness);
  127. return new LookAndFeel_V4_DocumentWindowButton ("close", Colour (0xff9A131D), shape, shape);
  128. }
  129. if (buttonType == DocumentWindow::minimiseButton)
  130. {
  131. shape.addLineSegment ({ 0.0f, 0.5f, 1.0f, 0.5f }, crossThickness);
  132. return new LookAndFeel_V4_DocumentWindowButton ("minimise", Colour (0xffaa8811), shape, shape);
  133. }
  134. if (buttonType == DocumentWindow::maximiseButton)
  135. {
  136. shape.addLineSegment ({ 0.5f, 0.0f, 0.5f, 1.0f }, crossThickness);
  137. shape.addLineSegment ({ 0.0f, 0.5f, 1.0f, 0.5f }, crossThickness);
  138. Path fullscreenShape;
  139. fullscreenShape.startNewSubPath (45.0f, 100.0f);
  140. fullscreenShape.lineTo (0.0f, 100.0f);
  141. fullscreenShape.lineTo (0.0f, 0.0f);
  142. fullscreenShape.lineTo (100.0f, 0.0f);
  143. fullscreenShape.lineTo (100.0f, 45.0f);
  144. fullscreenShape.addRectangle (45.0f, 45.0f, 100.0f, 100.0f);
  145. PathStrokeType (30.0f).createStrokedPath (fullscreenShape, fullscreenShape);
  146. return new LookAndFeel_V4_DocumentWindowButton ("maximise", Colour (0xff0A830A), shape, fullscreenShape);
  147. }
  148. jassertfalse;
  149. return nullptr;
  150. }
  151. void LookAndFeel_V4::positionDocumentWindowButtons (DocumentWindow&,
  152. int titleBarX, int titleBarY,
  153. int titleBarW, int titleBarH,
  154. Button* minimiseButton,
  155. Button* maximiseButton,
  156. Button* closeButton,
  157. bool positionTitleBarButtonsOnLeft)
  158. {
  159. titleBarH = jmin (titleBarH, titleBarH - titleBarY);
  160. auto buttonW = static_cast<int> (titleBarH * 1.2);
  161. auto x = positionTitleBarButtonsOnLeft ? titleBarX
  162. : titleBarX + titleBarW - buttonW;
  163. if (closeButton != nullptr)
  164. {
  165. closeButton->setBounds (x, titleBarY, buttonW, titleBarH);
  166. x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
  167. }
  168. if (positionTitleBarButtonsOnLeft)
  169. std::swap (minimiseButton, maximiseButton);
  170. if (maximiseButton != nullptr)
  171. {
  172. maximiseButton->setBounds (x, titleBarY, buttonW, titleBarH);
  173. x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
  174. }
  175. if (minimiseButton != nullptr)
  176. minimiseButton->setBounds (x, titleBarY, buttonW, titleBarH);
  177. }
  178. void LookAndFeel_V4::drawDocumentWindowTitleBar (DocumentWindow& window, Graphics& g,
  179. int w, int h, int titleSpaceX, int titleSpaceW,
  180. const Image* icon, bool drawTitleTextOnLeft)
  181. {
  182. if (w * h == 0)
  183. return;
  184. auto isActive = window.isActiveWindow();
  185. g.setColour (getCurrentColourScheme().getUIColour (ColourScheme::widgetBackground));
  186. g.fillAll();
  187. Font font ((float) h * 0.65f, Font::plain);
  188. g.setFont (font);
  189. auto textW = font.getStringWidth (window.getName());
  190. auto iconW = 0;
  191. auto iconH = 0;
  192. if (icon != nullptr)
  193. {
  194. iconH = static_cast<int> (font.getHeight());
  195. iconW = icon->getWidth() * iconH / icon->getHeight() + 4;
  196. }
  197. textW = jmin (titleSpaceW, textW + iconW);
  198. auto textX = drawTitleTextOnLeft ? titleSpaceX
  199. : jmax (titleSpaceX, (w - textW) / 2);
  200. if (textX + textW > titleSpaceX + titleSpaceW)
  201. textX = titleSpaceX + titleSpaceW - textW;
  202. if (icon != nullptr)
  203. {
  204. g.setOpacity (isActive ? 1.0f : 0.6f);
  205. g.drawImageWithin (*icon, textX, (h - iconH) / 2, iconW, iconH,
  206. RectanglePlacement::centred, false);
  207. textX += iconW;
  208. textW -= iconW;
  209. }
  210. if (window.isColourSpecified (DocumentWindow::textColourId) || isColourSpecified (DocumentWindow::textColourId))
  211. g.setColour (window.findColour (DocumentWindow::textColourId));
  212. else
  213. g.setColour (getCurrentColourScheme().getUIColour (ColourScheme::defaultText));
  214. g.drawText (window.getName(), textX, 0, textW, h, Justification::centredLeft, true);
  215. }
  216. //==============================================================================
  217. Font LookAndFeel_V4::getTextButtonFont (TextButton&, int buttonHeight)
  218. {
  219. return { jmin (16.0f, (float) buttonHeight * 0.6f) };
  220. }
  221. void LookAndFeel_V4::drawButtonBackground (Graphics& g,
  222. Button& button,
  223. const Colour& backgroundColour,
  224. bool shouldDrawButtonAsHighlighted,
  225. bool shouldDrawButtonAsDown)
  226. {
  227. auto cornerSize = 6.0f;
  228. auto bounds = button.getLocalBounds().toFloat().reduced (0.5f, 0.5f);
  229. auto baseColour = backgroundColour.withMultipliedSaturation (button.hasKeyboardFocus (true) ? 1.3f : 0.9f)
  230. .withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f);
  231. if (shouldDrawButtonAsDown || shouldDrawButtonAsHighlighted)
  232. baseColour = baseColour.contrasting (shouldDrawButtonAsDown ? 0.2f : 0.05f);
  233. g.setColour (baseColour);
  234. auto flatOnLeft = button.isConnectedOnLeft();
  235. auto flatOnRight = button.isConnectedOnRight();
  236. auto flatOnTop = button.isConnectedOnTop();
  237. auto flatOnBottom = button.isConnectedOnBottom();
  238. if (flatOnLeft || flatOnRight || flatOnTop || flatOnBottom)
  239. {
  240. Path path;
  241. path.addRoundedRectangle (bounds.getX(), bounds.getY(),
  242. bounds.getWidth(), bounds.getHeight(),
  243. cornerSize, cornerSize,
  244. ! (flatOnLeft || flatOnTop),
  245. ! (flatOnRight || flatOnTop),
  246. ! (flatOnLeft || flatOnBottom),
  247. ! (flatOnRight || flatOnBottom));
  248. g.fillPath (path);
  249. g.setColour (button.findColour (ComboBox::outlineColourId));
  250. g.strokePath (path, PathStrokeType (1.0f));
  251. }
  252. else
  253. {
  254. g.fillRoundedRectangle (bounds, cornerSize);
  255. g.setColour (button.findColour (ComboBox::outlineColourId));
  256. g.drawRoundedRectangle (bounds, cornerSize, 1.0f);
  257. }
  258. }
  259. void LookAndFeel_V4::drawToggleButton (Graphics& g, ToggleButton& button,
  260. bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
  261. {
  262. auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f);
  263. auto tickWidth = fontSize * 1.1f;
  264. drawTickBox (g, button, 4.0f, ((float) button.getHeight() - tickWidth) * 0.5f,
  265. tickWidth, tickWidth,
  266. button.getToggleState(),
  267. button.isEnabled(),
  268. shouldDrawButtonAsHighlighted,
  269. shouldDrawButtonAsDown);
  270. g.setColour (button.findColour (ToggleButton::textColourId));
  271. g.setFont (fontSize);
  272. if (! button.isEnabled())
  273. g.setOpacity (0.5f);
  274. g.drawFittedText (button.getButtonText(),
  275. button.getLocalBounds().withTrimmedLeft (roundToInt (tickWidth) + 10)
  276. .withTrimmedRight (2),
  277. Justification::centredLeft, 10);
  278. }
  279. void LookAndFeel_V4::drawTickBox (Graphics& g, Component& component,
  280. float x, float y, float w, float h,
  281. const bool ticked,
  282. const bool isEnabled,
  283. const bool shouldDrawButtonAsHighlighted,
  284. const bool shouldDrawButtonAsDown)
  285. {
  286. ignoreUnused (isEnabled, shouldDrawButtonAsHighlighted, shouldDrawButtonAsDown);
  287. Rectangle<float> tickBounds (x, y, w, h);
  288. g.setColour (component.findColour (ToggleButton::tickDisabledColourId));
  289. g.drawRoundedRectangle (tickBounds, 4.0f, 1.0f);
  290. if (ticked)
  291. {
  292. g.setColour (component.findColour (ToggleButton::tickColourId));
  293. auto tick = getTickShape (0.75f);
  294. g.fillPath (tick, tick.getTransformToScaleToFit (tickBounds.reduced (4, 5).toFloat(), false));
  295. }
  296. }
  297. void LookAndFeel_V4::changeToggleButtonWidthToFitText (ToggleButton& button)
  298. {
  299. auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f);
  300. auto tickWidth = fontSize * 1.1f;
  301. Font font (fontSize);
  302. button.setSize (font.getStringWidth (button.getButtonText()) + roundToInt (tickWidth) + 14, button.getHeight());
  303. }
  304. //==============================================================================
  305. AlertWindow* LookAndFeel_V4::createAlertWindow (const String& title, const String& message,
  306. const String& button1, const String& button2, const String& button3,
  307. AlertWindow::AlertIconType iconType,
  308. int numButtons, Component* associatedComponent)
  309. {
  310. auto boundsOffset = 50;
  311. auto* aw = LookAndFeel_V2::createAlertWindow (title, message, button1, button2, button3,
  312. iconType, numButtons, associatedComponent);
  313. auto bounds = aw->getBounds();
  314. bounds = bounds.withSizeKeepingCentre (bounds.getWidth() + boundsOffset, bounds.getHeight() + boundsOffset);
  315. aw->setBounds (bounds);
  316. for (auto* child : aw->getChildren())
  317. if (auto* button = dynamic_cast<TextButton*> (child))
  318. button->setBounds (button->getBounds() + Point<int> (25, 40));
  319. return aw;
  320. }
  321. void LookAndFeel_V4::drawAlertBox (Graphics& g, AlertWindow& alert,
  322. const Rectangle<int>& textArea, TextLayout& textLayout)
  323. {
  324. auto cornerSize = 4.0f;
  325. g.setColour (alert.findColour (AlertWindow::outlineColourId));
  326. g.drawRoundedRectangle (alert.getLocalBounds().toFloat(), cornerSize, 2.0f);
  327. auto bounds = alert.getLocalBounds().reduced (1);
  328. g.reduceClipRegion (bounds);
  329. g.setColour (alert.findColour (AlertWindow::backgroundColourId));
  330. g.fillRoundedRectangle (bounds.toFloat(), cornerSize);
  331. auto iconSpaceUsed = 0;
  332. auto iconWidth = 80;
  333. auto iconSize = jmin (iconWidth + 50, bounds.getHeight() + 20);
  334. if (alert.containsAnyExtraComponents() || alert.getNumButtons() > 2)
  335. iconSize = jmin (iconSize, textArea.getHeight() + 50);
  336. Rectangle<int> iconRect (iconSize / -10, iconSize / -10,
  337. iconSize, iconSize);
  338. if (alert.getAlertType() != AlertWindow::NoIcon)
  339. {
  340. Path icon;
  341. char character;
  342. uint32 colour;
  343. if (alert.getAlertType() == AlertWindow::WarningIcon)
  344. {
  345. character = '!';
  346. icon.addTriangle ((float) iconRect.getX() + (float) iconRect.getWidth() * 0.5f, (float) iconRect.getY(),
  347. static_cast<float> (iconRect.getRight()), static_cast<float> (iconRect.getBottom()),
  348. static_cast<float> (iconRect.getX()), static_cast<float> (iconRect.getBottom()));
  349. icon = icon.createPathWithRoundedCorners (5.0f);
  350. colour = 0x66ff2a00;
  351. }
  352. else
  353. {
  354. colour = Colour (0xff00b0b9).withAlpha (0.4f).getARGB();
  355. character = alert.getAlertType() == AlertWindow::InfoIcon ? 'i' : '?';
  356. icon.addEllipse (iconRect.toFloat());
  357. }
  358. GlyphArrangement ga;
  359. ga.addFittedText ({ (float) iconRect.getHeight() * 0.9f, Font::bold },
  360. String::charToString ((juce_wchar) (uint8) character),
  361. static_cast<float> (iconRect.getX()), static_cast<float> (iconRect.getY()),
  362. static_cast<float> (iconRect.getWidth()), static_cast<float> (iconRect.getHeight()),
  363. Justification::centred, false);
  364. ga.createPath (icon);
  365. icon.setUsingNonZeroWinding (false);
  366. g.setColour (Colour (colour));
  367. g.fillPath (icon);
  368. iconSpaceUsed = iconWidth;
  369. }
  370. g.setColour (alert.findColour (AlertWindow::textColourId));
  371. Rectangle<int> alertBounds (bounds.getX() + iconSpaceUsed, 30,
  372. bounds.getWidth(), bounds.getHeight() - getAlertWindowButtonHeight() - 20);
  373. textLayout.draw (g, alertBounds.toFloat());
  374. }
  375. int LookAndFeel_V4::getAlertWindowButtonHeight() { return 40; }
  376. Font LookAndFeel_V4::getAlertWindowTitleFont() { return { 18.0f, Font::bold }; }
  377. Font LookAndFeel_V4::getAlertWindowMessageFont() { return { 16.0f }; }
  378. Font LookAndFeel_V4::getAlertWindowFont() { return { 14.0f }; }
  379. //==============================================================================
  380. void LookAndFeel_V4::drawProgressBar (Graphics& g, ProgressBar& progressBar,
  381. int width, int height, double progress, const String& textToShow)
  382. {
  383. if (width == height)
  384. drawCircularProgressBar (g, progressBar, textToShow);
  385. else
  386. drawLinearProgressBar (g, progressBar, width, height, progress, textToShow);
  387. }
  388. void LookAndFeel_V4::drawLinearProgressBar (Graphics& g, ProgressBar& progressBar,
  389. int width, int height,
  390. double progress, const String& textToShow)
  391. {
  392. auto background = progressBar.findColour (ProgressBar::backgroundColourId);
  393. auto foreground = progressBar.findColour (ProgressBar::foregroundColourId);
  394. auto barBounds = progressBar.getLocalBounds().toFloat();
  395. g.setColour (background);
  396. g.fillRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f);
  397. if (progress >= 0.0f && progress <= 1.0f)
  398. {
  399. Path p;
  400. p.addRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f);
  401. g.reduceClipRegion (p);
  402. barBounds.setWidth (barBounds.getWidth() * (float) progress);
  403. g.setColour (foreground);
  404. g.fillRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f);
  405. }
  406. else
  407. {
  408. // spinning bar..
  409. g.setColour (background);
  410. auto stripeWidth = height * 2;
  411. auto position = static_cast<int> (Time::getMillisecondCounter() / 15) % stripeWidth;
  412. Path p;
  413. for (auto x = static_cast<float> (-position); x < (float) (width + stripeWidth); x += (float) stripeWidth)
  414. p.addQuadrilateral (x, 0.0f,
  415. x + (float) stripeWidth * 0.5f, 0.0f,
  416. x, static_cast<float> (height),
  417. x - (float) stripeWidth * 0.5f, static_cast<float> (height));
  418. Image im (Image::ARGB, width, height, true);
  419. {
  420. Graphics g2 (im);
  421. g2.setColour (foreground);
  422. g2.fillRoundedRectangle (barBounds, (float) progressBar.getHeight() * 0.5f);
  423. }
  424. g.setTiledImageFill (im, 0, 0, 0.85f);
  425. g.fillPath (p);
  426. }
  427. if (textToShow.isNotEmpty())
  428. {
  429. g.setColour (Colour::contrasting (background, foreground));
  430. g.setFont ((float) height * 0.6f);
  431. g.drawText (textToShow, 0, 0, width, height, Justification::centred, false);
  432. }
  433. }
  434. void LookAndFeel_V4::drawCircularProgressBar (Graphics& g, ProgressBar& progressBar, const String& progressText)
  435. {
  436. auto background = progressBar.findColour (ProgressBar::backgroundColourId);
  437. auto foreground = progressBar.findColour (ProgressBar::foregroundColourId);
  438. auto barBounds = progressBar.getLocalBounds().reduced (2, 2).toFloat();
  439. auto rotationInDegrees = static_cast<float> ((Time::getMillisecondCounter() / 10) % 360);
  440. auto normalisedRotation = rotationInDegrees / 360.0f;
  441. auto rotationOffset = 22.5f;
  442. auto maxRotation = 315.0f;
  443. auto startInDegrees = rotationInDegrees;
  444. auto endInDegrees = startInDegrees + rotationOffset;
  445. if (normalisedRotation >= 0.25f && normalisedRotation < 0.5f)
  446. {
  447. auto rescaledRotation = (normalisedRotation * 4.0f) - 1.0f;
  448. endInDegrees = startInDegrees + rotationOffset + (maxRotation * rescaledRotation);
  449. }
  450. else if (normalisedRotation >= 0.5f && normalisedRotation <= 1.0f)
  451. {
  452. endInDegrees = startInDegrees + rotationOffset + maxRotation;
  453. auto rescaledRotation = 1.0f - ((normalisedRotation * 2.0f) - 1.0f);
  454. startInDegrees = endInDegrees - rotationOffset - (maxRotation * rescaledRotation);
  455. }
  456. g.setColour (background);
  457. Path arcPath2;
  458. arcPath2.addCentredArc (barBounds.getCentreX(),
  459. barBounds.getCentreY(),
  460. barBounds.getWidth() * 0.5f,
  461. barBounds.getHeight() * 0.5f, 0.0f,
  462. 0.0f,
  463. MathConstants<float>::twoPi,
  464. true);
  465. g.strokePath (arcPath2, PathStrokeType (4.0f));
  466. g.setColour (foreground);
  467. Path arcPath;
  468. arcPath.addCentredArc (barBounds.getCentreX(),
  469. barBounds.getCentreY(),
  470. barBounds.getWidth() * 0.5f,
  471. barBounds.getHeight() * 0.5f,
  472. 0.0f,
  473. degreesToRadians (startInDegrees),
  474. degreesToRadians (endInDegrees),
  475. true);
  476. arcPath.applyTransform (AffineTransform::rotation (normalisedRotation * MathConstants<float>::pi * 2.25f, barBounds.getCentreX(), barBounds.getCentreY()));
  477. g.strokePath (arcPath, PathStrokeType (4.0f));
  478. if (progressText.isNotEmpty())
  479. {
  480. g.setColour (progressBar.findColour (TextButton::textColourOffId));
  481. g.setFont ({ 12.0f, Font::italic });
  482. g.drawText (progressText, barBounds, Justification::centred, false);
  483. }
  484. }
  485. //==============================================================================
  486. int LookAndFeel_V4::getDefaultScrollbarWidth()
  487. {
  488. return 8;
  489. }
  490. void LookAndFeel_V4::drawScrollbar (Graphics& g, ScrollBar& scrollbar, int x, int y, int width, int height,
  491. bool isScrollbarVertical, int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown)
  492. {
  493. ignoreUnused (isMouseDown);
  494. Rectangle<int> thumbBounds;
  495. if (isScrollbarVertical)
  496. thumbBounds = { x, thumbStartPosition, width, thumbSize };
  497. else
  498. thumbBounds = { thumbStartPosition, y, thumbSize, height };
  499. auto c = scrollbar.findColour (ScrollBar::ColourIds::thumbColourId);
  500. g.setColour (isMouseOver ? c.brighter (0.25f) : c);
  501. g.fillRoundedRectangle (thumbBounds.reduced (1).toFloat(), 4.0f);
  502. }
  503. //==============================================================================
  504. Path LookAndFeel_V4::getTickShape (float height)
  505. {
  506. static const unsigned char pathData[] = { 110,109,32,210,202,64,126,183,148,64,108,39,244,247,64,245,76,124,64,108,178,131,27,65,246,76,252,64,108,175,242,4,65,246,76,252,
  507. 64,108,236,5,68,65,0,0,160,180,108,240,150,90,65,21,136,52,63,108,48,59,16,65,0,0,32,65,108,32,210,202,64,126,183,148,64, 99,101,0,0 };
  508. Path path;
  509. path.loadPathFromData (pathData, sizeof (pathData));
  510. path.scaleToFit (0, 0, height * 2.0f, height, true);
  511. return path;
  512. }
  513. Path LookAndFeel_V4::getCrossShape (float height)
  514. {
  515. static const unsigned char pathData[] = { 110,109,51,51,255,66,0,0,0,0,108,205,204,13,67,51,51,99,65,108,0,0,170,66,205,204,141,66,108,51,179,13,67,52,51,255,66,108,0,0,255,
  516. 66,205,204,13,67,108,205,204,141,66,0,0,170,66,108,52,51,99,65,51,179,13,67,108,0,0,0,0,51,51,255,66,108,205,204,98,66, 204,204,141,66,108,0,0,0,0,51,51,99,65,108,51,51,
  517. 99,65,0,0,0,0,108,205,204,141,66,205,204,98,66,108,51,51,255,66,0,0,0,0,99,101,0,0 };
  518. Path path;
  519. path.loadPathFromData (pathData, sizeof (pathData));
  520. path.scaleToFit (0, 0, height * 2.0f, height, true);
  521. return path;
  522. }
  523. //==============================================================================
  524. void LookAndFeel_V4::fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor)
  525. {
  526. if (dynamic_cast<AlertWindow*> (textEditor.getParentComponent()) != nullptr)
  527. {
  528. g.setColour (textEditor.findColour (TextEditor::backgroundColourId));
  529. g.fillRect (0, 0, width, height);
  530. g.setColour (textEditor.findColour (TextEditor::outlineColourId));
  531. g.drawHorizontalLine (height - 1, 0.0f, static_cast<float> (width));
  532. }
  533. else
  534. {
  535. LookAndFeel_V2::fillTextEditorBackground (g, width, height, textEditor);
  536. }
  537. }
  538. void LookAndFeel_V4::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor)
  539. {
  540. if (dynamic_cast<AlertWindow*> (textEditor.getParentComponent()) == nullptr)
  541. {
  542. if (textEditor.isEnabled())
  543. {
  544. if (textEditor.hasKeyboardFocus (true) && ! textEditor.isReadOnly())
  545. {
  546. g.setColour (textEditor.findColour (TextEditor::focusedOutlineColourId));
  547. g.drawRect (0, 0, width, height, 2);
  548. }
  549. else
  550. {
  551. g.setColour (textEditor.findColour (TextEditor::outlineColourId));
  552. g.drawRect (0, 0, width, height);
  553. }
  554. }
  555. }
  556. }
  557. //==============================================================================
  558. Button* LookAndFeel_V4::createFileBrowserGoUpButton()
  559. {
  560. auto* goUpButton = new DrawableButton ("up", DrawableButton::ImageOnButtonBackground);
  561. Path arrowPath;
  562. arrowPath.addArrow ({ 50.0f, 100.0f, 50.0f, 0.0f }, 40.0f, 100.0f, 50.0f);
  563. DrawablePath arrowImage;
  564. arrowImage.setFill (goUpButton->findColour (TextButton::textColourOffId));
  565. arrowImage.setPath (arrowPath);
  566. goUpButton->setImages (&arrowImage);
  567. return goUpButton;
  568. }
  569. void LookAndFeel_V4::layoutFileBrowserComponent (FileBrowserComponent& browserComp,
  570. DirectoryContentsDisplayComponent* fileListComponent,
  571. FilePreviewComponent* previewComp,
  572. ComboBox* currentPathBox,
  573. TextEditor* filenameBox,
  574. Button* goUpButton)
  575. {
  576. auto sectionHeight = 22;
  577. auto buttonWidth = 50;
  578. auto b = browserComp.getLocalBounds().reduced (20, 5);
  579. auto topSlice = b.removeFromTop (sectionHeight);
  580. auto bottomSlice = b.removeFromBottom (sectionHeight);
  581. currentPathBox->setBounds (topSlice.removeFromLeft (topSlice.getWidth() - buttonWidth));
  582. topSlice.removeFromLeft (6);
  583. goUpButton->setBounds (topSlice);
  584. bottomSlice.removeFromLeft (20);
  585. filenameBox->setBounds (bottomSlice);
  586. if (previewComp != nullptr)
  587. previewComp->setBounds (b.removeFromRight (b.getWidth() / 3));
  588. if (auto* listAsComp = dynamic_cast<Component*> (fileListComponent))
  589. listAsComp->setBounds (b.reduced (0, 10));
  590. }
  591. void LookAndFeel_V4::drawFileBrowserRow (Graphics& g, int width, int height,
  592. const File& file, const String& filename, Image* icon,
  593. const String& fileSizeDescription,
  594. const String& fileTimeDescription,
  595. bool isDirectory, bool isItemSelected,
  596. int itemIndex, DirectoryContentsDisplayComponent& dcc)
  597. {
  598. LookAndFeel_V2::drawFileBrowserRow (g, width, height, file, filename, icon,
  599. fileSizeDescription, fileTimeDescription,
  600. isDirectory, isItemSelected, itemIndex, dcc);
  601. }
  602. //==============================================================================
  603. void LookAndFeel_V4::drawPopupMenuItem (Graphics& g, const Rectangle<int>& area,
  604. const bool isSeparator, const bool isActive,
  605. const bool isHighlighted, const bool isTicked,
  606. const bool hasSubMenu, const String& text,
  607. const String& shortcutKeyText,
  608. const Drawable* icon, const Colour* const textColourToUse)
  609. {
  610. if (isSeparator)
  611. {
  612. auto r = area.reduced (5, 0);
  613. r.removeFromTop (roundToInt (((float) r.getHeight() * 0.5f) - 0.5f));
  614. g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.3f));
  615. g.fillRect (r.removeFromTop (1));
  616. }
  617. else
  618. {
  619. auto textColour = (textColourToUse == nullptr ? findColour (PopupMenu::textColourId)
  620. : *textColourToUse);
  621. auto r = area.reduced (1);
  622. if (isHighlighted && isActive)
  623. {
  624. g.setColour (findColour (PopupMenu::highlightedBackgroundColourId));
  625. g.fillRect (r);
  626. g.setColour (findColour (PopupMenu::highlightedTextColourId));
  627. }
  628. else
  629. {
  630. g.setColour (textColour.withMultipliedAlpha (isActive ? 1.0f : 0.5f));
  631. }
  632. r.reduce (jmin (5, area.getWidth() / 20), 0);
  633. auto font = getPopupMenuFont();
  634. auto maxFontHeight = (float) r.getHeight() / 1.3f;
  635. if (font.getHeight() > maxFontHeight)
  636. font.setHeight (maxFontHeight);
  637. g.setFont (font);
  638. auto iconArea = r.removeFromLeft (roundToInt (maxFontHeight)).toFloat();
  639. if (icon != nullptr)
  640. {
  641. icon->drawWithin (g, iconArea, RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize, 1.0f);
  642. r.removeFromLeft (roundToInt (maxFontHeight * 0.5f));
  643. }
  644. else if (isTicked)
  645. {
  646. auto tick = getTickShape (1.0f);
  647. g.fillPath (tick, tick.getTransformToScaleToFit (iconArea.reduced (iconArea.getWidth() / 5, 0).toFloat(), true));
  648. }
  649. if (hasSubMenu)
  650. {
  651. auto arrowH = 0.6f * getPopupMenuFont().getAscent();
  652. auto x = static_cast<float> (r.removeFromRight ((int) arrowH).getX());
  653. auto halfH = static_cast<float> (r.getCentreY());
  654. Path path;
  655. path.startNewSubPath (x, halfH - arrowH * 0.5f);
  656. path.lineTo (x + arrowH * 0.6f, halfH);
  657. path.lineTo (x, halfH + arrowH * 0.5f);
  658. g.strokePath (path, PathStrokeType (2.0f));
  659. }
  660. r.removeFromRight (3);
  661. g.drawFittedText (text, r, Justification::centredLeft, 1);
  662. if (shortcutKeyText.isNotEmpty())
  663. {
  664. auto f2 = font;
  665. f2.setHeight (f2.getHeight() * 0.75f);
  666. f2.setHorizontalScale (0.95f);
  667. g.setFont (f2);
  668. g.drawText (shortcutKeyText, r, Justification::centredRight, true);
  669. }
  670. }
  671. }
  672. void LookAndFeel_V4::getIdealPopupMenuItemSize (const String& text, const bool isSeparator,
  673. int standardMenuItemHeight, int& idealWidth, int& idealHeight)
  674. {
  675. if (isSeparator)
  676. {
  677. idealWidth = 50;
  678. idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight / 10 : 10;
  679. }
  680. else
  681. {
  682. auto font = getPopupMenuFont();
  683. if (standardMenuItemHeight > 0 && font.getHeight() > (float) standardMenuItemHeight / 1.3f)
  684. font.setHeight ((float) standardMenuItemHeight / 1.3f);
  685. idealHeight = standardMenuItemHeight > 0 ? standardMenuItemHeight : roundToInt (font.getHeight() * 1.3f);
  686. idealWidth = font.getStringWidth (text) + idealHeight * 2;
  687. }
  688. }
  689. void LookAndFeel_V4::drawMenuBarBackground (Graphics& g, int width, int height,
  690. bool, MenuBarComponent& menuBar)
  691. {
  692. auto colour = menuBar.findColour (TextButton::buttonColourId).withAlpha (0.4f);
  693. Rectangle<int> r (width, height);
  694. g.setColour (colour.contrasting (0.15f));
  695. g.fillRect (r.removeFromTop (1));
  696. g.fillRect (r.removeFromBottom (1));
  697. g.setGradientFill (ColourGradient::vertical (colour, 0, colour.darker (0.2f), (float) height));
  698. g.fillRect (r);
  699. }
  700. void LookAndFeel_V4::drawMenuBarItem (Graphics& g, int width, int height,
  701. int itemIndex, const String& itemText,
  702. bool isMouseOverItem, bool isMenuOpen,
  703. bool /*isMouseOverBar*/, MenuBarComponent& menuBar)
  704. {
  705. if (! menuBar.isEnabled())
  706. {
  707. g.setColour (menuBar.findColour (TextButton::textColourOffId)
  708. .withMultipliedAlpha (0.5f));
  709. }
  710. else if (isMenuOpen || isMouseOverItem)
  711. {
  712. g.fillAll (menuBar.findColour (TextButton::buttonOnColourId));
  713. g.setColour (menuBar.findColour (TextButton::textColourOnId));
  714. }
  715. else
  716. {
  717. g.setColour (menuBar.findColour (TextButton::textColourOffId));
  718. }
  719. g.setFont (getMenuBarFont (menuBar, itemIndex, itemText));
  720. g.drawFittedText (itemText, 0, 0, width, height, Justification::centred, 1);
  721. }
  722. //==============================================================================
  723. void LookAndFeel_V4::drawComboBox (Graphics& g, int width, int height, bool,
  724. int, int, int, int, ComboBox& box)
  725. {
  726. auto cornerSize = box.findParentComponentOfClass<ChoicePropertyComponent>() != nullptr ? 0.0f : 3.0f;
  727. Rectangle<int> boxBounds (0, 0, width, height);
  728. g.setColour (box.findColour (ComboBox::backgroundColourId));
  729. g.fillRoundedRectangle (boxBounds.toFloat(), cornerSize);
  730. g.setColour (box.findColour (ComboBox::outlineColourId));
  731. g.drawRoundedRectangle (boxBounds.toFloat().reduced (0.5f, 0.5f), cornerSize, 1.0f);
  732. Rectangle<int> arrowZone (width - 30, 0, 20, height);
  733. Path path;
  734. path.startNewSubPath ((float) arrowZone.getX() + 3.0f, (float) arrowZone.getCentreY() - 2.0f);
  735. path.lineTo ((float) arrowZone.getCentreX(), (float) arrowZone.getCentreY() + 3.0f);
  736. path.lineTo ((float) arrowZone.getRight() - 3.0f, (float) arrowZone.getCentreY() - 2.0f);
  737. g.setColour (box.findColour (ComboBox::arrowColourId).withAlpha ((box.isEnabled() ? 0.9f : 0.2f)));
  738. g.strokePath (path, PathStrokeType (2.0f));
  739. }
  740. Font LookAndFeel_V4::getComboBoxFont (ComboBox& box)
  741. {
  742. return { jmin (16.0f, (float) box.getHeight() * 0.85f) };
  743. }
  744. void LookAndFeel_V4::positionComboBoxText (ComboBox& box, Label& label)
  745. {
  746. label.setBounds (1, 1,
  747. box.getWidth() - 30,
  748. box.getHeight() - 2);
  749. label.setFont (getComboBoxFont (box));
  750. }
  751. //==============================================================================
  752. int LookAndFeel_V4::getSliderThumbRadius (Slider& slider)
  753. {
  754. return jmin (12, slider.isHorizontal() ? static_cast<int> ((float) slider.getHeight() * 0.5f)
  755. : static_cast<int> ((float) slider.getWidth() * 0.5f));
  756. }
  757. void LookAndFeel_V4::drawLinearSlider (Graphics& g, int x, int y, int width, int height,
  758. float sliderPos,
  759. float minSliderPos,
  760. float maxSliderPos,
  761. const Slider::SliderStyle style, Slider& slider)
  762. {
  763. if (slider.isBar())
  764. {
  765. g.setColour (slider.findColour (Slider::trackColourId));
  766. g.fillRect (slider.isHorizontal() ? Rectangle<float> (static_cast<float> (x), (float) y + 0.5f, sliderPos - (float) x, (float) height - 1.0f)
  767. : Rectangle<float> ((float) x + 0.5f, sliderPos, (float) width - 1.0f, (float) y + ((float) height - sliderPos)));
  768. }
  769. else
  770. {
  771. auto isTwoVal = (style == Slider::SliderStyle::TwoValueVertical || style == Slider::SliderStyle::TwoValueHorizontal);
  772. auto isThreeVal = (style == Slider::SliderStyle::ThreeValueVertical || style == Slider::SliderStyle::ThreeValueHorizontal);
  773. auto trackWidth = jmin (6.0f, slider.isHorizontal() ? (float) height * 0.25f : (float) width * 0.25f);
  774. Point<float> startPoint (slider.isHorizontal() ? (float) x : (float) x + (float) width * 0.5f,
  775. slider.isHorizontal() ? (float) y + (float) height * 0.5f : (float) (height + y));
  776. Point<float> endPoint (slider.isHorizontal() ? (float) (width + x) : startPoint.x,
  777. slider.isHorizontal() ? startPoint.y : (float) y);
  778. Path backgroundTrack;
  779. backgroundTrack.startNewSubPath (startPoint);
  780. backgroundTrack.lineTo (endPoint);
  781. g.setColour (slider.findColour (Slider::backgroundColourId));
  782. g.strokePath (backgroundTrack, { trackWidth, PathStrokeType::curved, PathStrokeType::rounded });
  783. Path valueTrack;
  784. Point<float> minPoint, maxPoint, thumbPoint;
  785. if (isTwoVal || isThreeVal)
  786. {
  787. minPoint = { slider.isHorizontal() ? minSliderPos : (float) width * 0.5f,
  788. slider.isHorizontal() ? (float) height * 0.5f : minSliderPos };
  789. if (isThreeVal)
  790. thumbPoint = { slider.isHorizontal() ? sliderPos : (float) width * 0.5f,
  791. slider.isHorizontal() ? (float) height * 0.5f : sliderPos };
  792. maxPoint = { slider.isHorizontal() ? maxSliderPos : (float) width * 0.5f,
  793. slider.isHorizontal() ? (float) height * 0.5f : maxSliderPos };
  794. }
  795. else
  796. {
  797. auto kx = slider.isHorizontal() ? sliderPos : ((float) x + (float) width * 0.5f);
  798. auto ky = slider.isHorizontal() ? ((float) y + (float) height * 0.5f) : sliderPos;
  799. minPoint = startPoint;
  800. maxPoint = { kx, ky };
  801. }
  802. auto thumbWidth = getSliderThumbRadius (slider);
  803. valueTrack.startNewSubPath (minPoint);
  804. valueTrack.lineTo (isThreeVal ? thumbPoint : maxPoint);
  805. g.setColour (slider.findColour (Slider::trackColourId));
  806. g.strokePath (valueTrack, { trackWidth, PathStrokeType::curved, PathStrokeType::rounded });
  807. if (! isTwoVal)
  808. {
  809. g.setColour (slider.findColour (Slider::thumbColourId));
  810. g.fillEllipse (Rectangle<float> (static_cast<float> (thumbWidth), static_cast<float> (thumbWidth)).withCentre (isThreeVal ? thumbPoint : maxPoint));
  811. }
  812. if (isTwoVal || isThreeVal)
  813. {
  814. auto sr = jmin (trackWidth, (slider.isHorizontal() ? (float) height : (float) width) * 0.4f);
  815. auto pointerColour = slider.findColour (Slider::thumbColourId);
  816. if (slider.isHorizontal())
  817. {
  818. drawPointer (g, minSliderPos - sr,
  819. jmax (0.0f, (float) y + (float) height * 0.5f - trackWidth * 2.0f),
  820. trackWidth * 2.0f, pointerColour, 2);
  821. drawPointer (g, maxSliderPos - trackWidth,
  822. jmin ((float) (y + height) - trackWidth * 2.0f, (float) y + (float) height * 0.5f),
  823. trackWidth * 2.0f, pointerColour, 4);
  824. }
  825. else
  826. {
  827. drawPointer (g, jmax (0.0f, (float) x + (float) width * 0.5f - trackWidth * 2.0f),
  828. minSliderPos - trackWidth,
  829. trackWidth * 2.0f, pointerColour, 1);
  830. drawPointer (g, jmin ((float) (x + width) - trackWidth * 2.0f, (float) x + (float) width * 0.5f), maxSliderPos - sr,
  831. trackWidth * 2.0f, pointerColour, 3);
  832. }
  833. }
  834. }
  835. }
  836. void LookAndFeel_V4::drawRotarySlider (Graphics& g, int x, int y, int width, int height, float sliderPos,
  837. const float rotaryStartAngle, const float rotaryEndAngle, Slider& slider)
  838. {
  839. auto outline = slider.findColour (Slider::rotarySliderOutlineColourId);
  840. auto fill = slider.findColour (Slider::rotarySliderFillColourId);
  841. auto bounds = Rectangle<int> (x, y, width, height).toFloat().reduced (10);
  842. auto radius = jmin (bounds.getWidth(), bounds.getHeight()) / 2.0f;
  843. auto toAngle = rotaryStartAngle + sliderPos * (rotaryEndAngle - rotaryStartAngle);
  844. auto lineW = jmin (8.0f, radius * 0.5f);
  845. auto arcRadius = radius - lineW * 0.5f;
  846. Path backgroundArc;
  847. backgroundArc.addCentredArc (bounds.getCentreX(),
  848. bounds.getCentreY(),
  849. arcRadius,
  850. arcRadius,
  851. 0.0f,
  852. rotaryStartAngle,
  853. rotaryEndAngle,
  854. true);
  855. g.setColour (outline);
  856. g.strokePath (backgroundArc, PathStrokeType (lineW, PathStrokeType::curved, PathStrokeType::rounded));
  857. if (slider.isEnabled())
  858. {
  859. Path valueArc;
  860. valueArc.addCentredArc (bounds.getCentreX(),
  861. bounds.getCentreY(),
  862. arcRadius,
  863. arcRadius,
  864. 0.0f,
  865. rotaryStartAngle,
  866. toAngle,
  867. true);
  868. g.setColour (fill);
  869. g.strokePath (valueArc, PathStrokeType (lineW, PathStrokeType::curved, PathStrokeType::rounded));
  870. }
  871. auto thumbWidth = lineW * 2.0f;
  872. Point<float> thumbPoint (bounds.getCentreX() + arcRadius * std::cos (toAngle - MathConstants<float>::halfPi),
  873. bounds.getCentreY() + arcRadius * std::sin (toAngle - MathConstants<float>::halfPi));
  874. g.setColour (slider.findColour (Slider::thumbColourId));
  875. g.fillEllipse (Rectangle<float> (thumbWidth, thumbWidth).withCentre (thumbPoint));
  876. }
  877. void LookAndFeel_V4::drawPointer (Graphics& g, const float x, const float y, const float diameter,
  878. const Colour& colour, const int direction) noexcept
  879. {
  880. Path p;
  881. p.startNewSubPath (x + diameter * 0.5f, y);
  882. p.lineTo (x + diameter, y + diameter * 0.6f);
  883. p.lineTo (x + diameter, y + diameter);
  884. p.lineTo (x, y + diameter);
  885. p.lineTo (x, y + diameter * 0.6f);
  886. p.closeSubPath();
  887. p.applyTransform (AffineTransform::rotation ((float) direction * MathConstants<float>::halfPi,
  888. x + diameter * 0.5f, y + diameter * 0.5f));
  889. g.setColour (colour);
  890. g.fillPath (p);
  891. }
  892. Label* LookAndFeel_V4::createSliderTextBox (Slider& slider)
  893. {
  894. auto* l = LookAndFeel_V2::createSliderTextBox (slider);
  895. if (getCurrentColourScheme() == LookAndFeel_V4::getGreyColourScheme() && (slider.getSliderStyle() == Slider::LinearBar
  896. || slider.getSliderStyle() == Slider::LinearBarVertical))
  897. {
  898. l->setColour (Label::textColourId, Colours::black.withAlpha (0.7f));
  899. }
  900. return l;
  901. }
  902. //==============================================================================
  903. void LookAndFeel_V4::drawTooltip (Graphics& g, const String& text, int width, int height)
  904. {
  905. Rectangle<int> bounds (width, height);
  906. auto cornerSize = 5.0f;
  907. g.setColour (findColour (TooltipWindow::backgroundColourId));
  908. g.fillRoundedRectangle (bounds.toFloat(), cornerSize);
  909. g.setColour (findColour (TooltipWindow::outlineColourId));
  910. g.drawRoundedRectangle (bounds.toFloat().reduced (0.5f, 0.5f), cornerSize, 1.0f);
  911. LookAndFeelHelpers::layoutTooltipText (text, findColour (TooltipWindow::textColourId))
  912. .draw (g, { static_cast<float> (width), static_cast<float> (height) });
  913. }
  914. //==============================================================================
  915. void LookAndFeel_V4::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int>& area,
  916. bool isMouseOver, bool /*isMouseDown*/,
  917. ConcertinaPanel& concertina, Component& panel)
  918. {
  919. auto bounds = area.toFloat().reduced (0.5f);
  920. auto cornerSize = 4.0f;
  921. auto isTopPanel = (concertina.getPanel (0) == &panel);
  922. Path p;
  923. p.addRoundedRectangle (bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight(),
  924. cornerSize, cornerSize, isTopPanel, isTopPanel, false, false);
  925. g.setGradientFill (ColourGradient::vertical (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), static_cast<float> (area.getY()),
  926. Colours::darkgrey.withAlpha (0.1f), static_cast<float> (area.getBottom())));
  927. g.fillPath (p);
  928. }
  929. //==============================================================================
  930. void LookAndFeel_V4::drawLevelMeter (Graphics& g, int width, int height, float level)
  931. {
  932. auto outerCornerSize = 3.0f;
  933. auto outerBorderWidth = 2.0f;
  934. auto totalBlocks = 7;
  935. auto spacingFraction = 0.03f;
  936. g.setColour (findColour (ResizableWindow::backgroundColourId));
  937. g.fillRoundedRectangle (0.0f, 0.0f, static_cast<float> (width), static_cast<float> (height), outerCornerSize);
  938. auto doubleOuterBorderWidth = 2.0f * outerBorderWidth;
  939. auto numBlocks = roundToInt ((float) totalBlocks * level);
  940. auto blockWidth = ((float) width - doubleOuterBorderWidth) / static_cast<float> (totalBlocks);
  941. auto blockHeight = (float) height - doubleOuterBorderWidth;
  942. auto blockRectWidth = (1.0f - 2.0f * spacingFraction) * blockWidth;
  943. auto blockRectSpacing = spacingFraction * blockWidth;
  944. auto blockCornerSize = 0.1f * blockWidth;
  945. auto c = findColour (Slider::thumbColourId);
  946. for (auto i = 0; i < totalBlocks; ++i)
  947. {
  948. if (i >= numBlocks)
  949. g.setColour (c.withAlpha (0.5f));
  950. else
  951. g.setColour (i < totalBlocks - 1 ? c : Colours::red);
  952. g.fillRoundedRectangle (outerBorderWidth + ((float) i * blockWidth) + blockRectSpacing,
  953. outerBorderWidth,
  954. blockRectWidth,
  955. blockHeight,
  956. blockCornerSize);
  957. }
  958. }
  959. //==============================================================================
  960. void LookAndFeel_V4::paintToolbarBackground (Graphics& g, int w, int h, Toolbar& toolbar)
  961. {
  962. auto background = toolbar.findColour (Toolbar::backgroundColourId);
  963. g.setGradientFill ({ background, 0.0f, 0.0f,
  964. background.darker (0.2f),
  965. toolbar.isVertical() ? (float) w - 1.0f : 0.0f,
  966. toolbar.isVertical() ? 0.0f : (float) h - 1.0f,
  967. false });
  968. g.fillAll();
  969. }
  970. void LookAndFeel_V4::paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height,
  971. const String& text, ToolbarItemComponent& component)
  972. {
  973. auto baseTextColour = component.findParentComponentOfClass<PopupMenu::CustomComponent>() != nullptr
  974. ? component.findColour (PopupMenu::textColourId)
  975. : component.findColour (Toolbar::labelTextColourId);
  976. g.setColour (baseTextColour.withAlpha (component.isEnabled() ? 1.0f : 0.25f));
  977. auto fontHeight = jmin (14.0f, (float) height * 0.85f);
  978. g.setFont (fontHeight);
  979. g.drawFittedText (text,
  980. x, y, width, height,
  981. Justification::centred,
  982. jmax (1, height / (int) fontHeight));
  983. }
  984. //==============================================================================
  985. void LookAndFeel_V4::drawPropertyPanelSectionHeader (Graphics& g, const String& name,
  986. bool isOpen, int width, int height)
  987. {
  988. auto buttonSize = (float) height * 0.75f;
  989. auto buttonIndent = ((float) height - buttonSize) * 0.5f;
  990. drawTreeviewPlusMinusBox (g, { buttonIndent, buttonIndent, buttonSize, buttonSize },
  991. findColour (ResizableWindow::backgroundColourId), isOpen, false);
  992. auto textX = static_cast<int> ((buttonIndent * 2.0f + buttonSize + 2.0f));
  993. g.setColour (findColour (PropertyComponent::labelTextColourId));
  994. g.setFont ({ (float) height * 0.7f, Font::bold });
  995. g.drawText (name, textX, 0, width - textX - 4, height, Justification::centredLeft, true);
  996. }
  997. void LookAndFeel_V4::drawPropertyComponentBackground (Graphics& g, int width, int height, PropertyComponent& component)
  998. {
  999. g.setColour (component.findColour (PropertyComponent::backgroundColourId));
  1000. g.fillRect (0, 0, width, height - 1);
  1001. }
  1002. void LookAndFeel_V4::drawPropertyComponentLabel (Graphics& g, int width, int height, PropertyComponent& component)
  1003. {
  1004. ignoreUnused (width);
  1005. auto indent = getPropertyComponentIndent (component);
  1006. g.setColour (component.findColour (PropertyComponent::labelTextColourId)
  1007. .withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f));
  1008. g.setFont ((float) jmin (height, 24) * 0.65f);
  1009. auto r = getPropertyComponentContentPosition (component);
  1010. g.drawFittedText (component.getName(),
  1011. indent, r.getY(), r.getX() - 5, r.getHeight(),
  1012. Justification::centredLeft, 2);
  1013. }
  1014. int LookAndFeel_V4::getPropertyComponentIndent (PropertyComponent& component)
  1015. {
  1016. return jmin (10, component.getWidth() / 10);
  1017. }
  1018. Rectangle<int> LookAndFeel_V4::getPropertyComponentContentPosition (PropertyComponent& component)
  1019. {
  1020. auto textW = jmin (200, component.getWidth() / 2);
  1021. return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 };
  1022. }
  1023. //==============================================================================
  1024. void LookAndFeel_V4::drawCallOutBoxBackground (CallOutBox& box, Graphics& g,
  1025. const Path& path, Image& cachedImage)
  1026. {
  1027. if (cachedImage.isNull())
  1028. {
  1029. cachedImage = { Image::ARGB, box.getWidth(), box.getHeight(), true };
  1030. Graphics g2 (cachedImage);
  1031. DropShadow (Colours::black.withAlpha (0.7f), 8, { 0, 2 }).drawForPath (g2, path);
  1032. }
  1033. g.setColour (Colours::black);
  1034. g.drawImageAt (cachedImage, 0, 0);
  1035. g.setColour (currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.8f));
  1036. g.fillPath (path);
  1037. g.setColour (currentColourScheme.getUIColour (ColourScheme::UIColour::outline).withAlpha (0.8f));
  1038. g.strokePath (path, PathStrokeType (2.0f));
  1039. }
  1040. //==============================================================================
  1041. void LookAndFeel_V4::drawStretchableLayoutResizerBar (Graphics& g, int /*w*/, int /*h*/, bool /*isVerticalBar*/,
  1042. bool isMouseOver, bool isMouseDragging)
  1043. {
  1044. if (isMouseOver || isMouseDragging)
  1045. g.fillAll (currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).withAlpha (0.5f));
  1046. }
  1047. //==============================================================================
  1048. void LookAndFeel_V4::initialiseColours()
  1049. {
  1050. const uint32 transparent = 0x00000000;
  1051. const uint32 coloursToUse[] =
  1052. {
  1053. TextButton::buttonColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1054. TextButton::buttonOnColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1055. TextButton::textColourOnId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(),
  1056. TextButton::textColourOffId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1057. ToggleButton::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1058. ToggleButton::tickColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1059. ToggleButton::tickDisabledColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).withAlpha (0.5f).getARGB(),
  1060. TextEditor::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1061. TextEditor::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1062. TextEditor::highlightColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).withAlpha (0.4f).getARGB(),
  1063. TextEditor::highlightedTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(),
  1064. TextEditor::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1065. TextEditor::focusedOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1066. TextEditor::shadowColourId, transparent,
  1067. CaretComponent::caretColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(),
  1068. Label::backgroundColourId, transparent,
  1069. Label::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1070. Label::outlineColourId, transparent,
  1071. Label::textWhenEditingColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1072. ScrollBar::backgroundColourId, transparent,
  1073. ScrollBar::thumbColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(),
  1074. ScrollBar::trackColourId, transparent,
  1075. TreeView::linesColourId, transparent,
  1076. TreeView::backgroundColourId, transparent,
  1077. TreeView::dragAndDropIndicatorColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1078. TreeView::selectedItemBackgroundColourId, transparent,
  1079. TreeView::oddItemsColourId, transparent,
  1080. TreeView::evenItemsColourId, transparent,
  1081. PopupMenu::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground).getARGB(),
  1082. PopupMenu::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(),
  1083. PopupMenu::headerTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(),
  1084. PopupMenu::highlightedTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(),
  1085. PopupMenu::highlightedBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1086. ComboBox::buttonColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1087. ComboBox::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1088. ComboBox::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1089. ComboBox::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1090. ComboBox::arrowColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1091. ComboBox::focusedOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1092. PropertyComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1093. PropertyComponent::labelTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1094. TextPropertyComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1095. TextPropertyComponent::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1096. TextPropertyComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1097. BooleanPropertyComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1098. BooleanPropertyComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1099. ListBox::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1100. ListBox::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1101. ListBox::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1102. Slider::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1103. Slider::thumbColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(),
  1104. Slider::trackColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1105. Slider::rotarySliderFillColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1106. Slider::rotarySliderOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1107. Slider::textBoxTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1108. Slider::textBoxBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.0f).getARGB(),
  1109. Slider::textBoxHighlightColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).withAlpha (0.4f).getARGB(),
  1110. Slider::textBoxOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1111. ResizableWindow::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::windowBackground).getARGB(),
  1112. DocumentWindow::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1113. AlertWindow::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1114. AlertWindow::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1115. AlertWindow::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1116. ProgressBar::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1117. ProgressBar::foregroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1118. TooltipWindow::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1119. TooltipWindow::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(),
  1120. TooltipWindow::outlineColourId, transparent,
  1121. TabbedComponent::backgroundColourId, transparent,
  1122. TabbedComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1123. TabbedButtonBar::tabOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).withAlpha (0.5f).getARGB(),
  1124. TabbedButtonBar::frontOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1125. Toolbar::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.4f).getARGB(),
  1126. Toolbar::separatorColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1127. Toolbar::buttonMouseOverBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).contrasting (0.2f).getARGB(),
  1128. Toolbar::buttonMouseDownBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).contrasting (0.5f).getARGB(),
  1129. Toolbar::labelTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1130. Toolbar::editingModeOutlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1131. DrawableButton::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1132. DrawableButton::textColourOnId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(),
  1133. DrawableButton::backgroundColourId, transparent,
  1134. DrawableButton::backgroundOnColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1135. HyperlinkButton::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).interpolatedWith (Colours::blue, 0.4f).getARGB(),
  1136. GroupComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1137. GroupComponent::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1138. BubbleComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1139. BubbleComponent::outlineColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1140. DirectoryContentsDisplayComponent::highlightColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).getARGB(),
  1141. DirectoryContentsDisplayComponent::textColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(),
  1142. DirectoryContentsDisplayComponent::highlightedTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedText).getARGB(),
  1143. 0x1000440, /*LassoComponent::lassoFillColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(),
  1144. 0x1000441, /*LassoComponent::lassoOutlineColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::outline).getARGB(),
  1145. 0x1005000, /*MidiKeyboardComponent::whiteNoteColourId*/ 0xffffffff,
  1146. 0x1005001, /*MidiKeyboardComponent::blackNoteColourId*/ 0xff000000,
  1147. 0x1005002, /*MidiKeyboardComponent::keySeparatorLineColourId*/ 0x66000000,
  1148. 0x1005003, /*MidiKeyboardComponent::mouseOverKeyOverlayColourId*/ 0x80ffff00,
  1149. 0x1005004, /*MidiKeyboardComponent::keyDownOverlayColourId*/ 0xffb6b600,
  1150. 0x1005005, /*MidiKeyboardComponent::textLabelColourId*/ 0xff000000,
  1151. 0x1005006, /*MidiKeyboardComponent::upDownButtonBackgroundColourId*/ 0xffd3d3d3,
  1152. 0x1005007, /*MidiKeyboardComponent::upDownButtonArrowColourId*/ 0xff000000,
  1153. 0x1005008, /*MidiKeyboardComponent::shadowColourId*/ 0x4c000000,
  1154. 0x1004500, /*CodeEditorComponent::backgroundColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1155. 0x1004502, /*CodeEditorComponent::highlightColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).withAlpha (0.4f).getARGB(),
  1156. 0x1004503, /*CodeEditorComponent::defaultTextColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1157. 0x1004504, /*CodeEditorComponent::lineNumberBackgroundId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::highlightedFill).withAlpha (0.5f).getARGB(),
  1158. 0x1004505, /*CodeEditorComponent::lineNumberTextId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(),
  1159. 0x1007000, /*ColourSelector::backgroundColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1160. 0x1007001, /*ColourSelector::labelTextColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1161. 0x100ad00, /*KeyMappingEditorComponent::backgroundColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1162. 0x100ad01, /*KeyMappingEditorComponent::textColourId*/ currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1163. FileSearchPathListComponent::backgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground).getARGB(),
  1164. FileChooserDialogBox::titleTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1165. SidePanel::backgroundColour, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).getARGB(),
  1166. SidePanel::titleTextColour, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultText).getARGB(),
  1167. SidePanel::shadowBaseColour, currentColourScheme.getUIColour (ColourScheme::UIColour::widgetBackground).darker().getARGB(),
  1168. SidePanel::dismissButtonNormalColour, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).getARGB(),
  1169. SidePanel::dismissButtonOverColour, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).darker().getARGB(),
  1170. SidePanel::dismissButtonDownColour, currentColourScheme.getUIColour (ColourScheme::UIColour::defaultFill).brighter().getARGB(),
  1171. FileBrowserComponent::currentPathBoxBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground).getARGB(),
  1172. FileBrowserComponent::currentPathBoxTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(),
  1173. FileBrowserComponent::currentPathBoxArrowColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(),
  1174. FileBrowserComponent::filenameBoxBackgroundColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuBackground).getARGB(),
  1175. FileBrowserComponent::filenameBoxTextColourId, currentColourScheme.getUIColour (ColourScheme::UIColour::menuText).getARGB(),
  1176. };
  1177. for (int i = 0; i < numElementsInArray (coloursToUse); i += 2)
  1178. setColour ((int) coloursToUse [i], Colour ((uint32) coloursToUse [i + 1]));
  1179. }
  1180. } // namespace juce