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.

juce_LookAndFeel_V4.cpp 66KB

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