The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

226 lines
6.5KB

  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. #include "../Application/jucer_Headers.h"
  19. #include "../Application/jucer_Application.h"
  20. #include "jucer_AppearanceSettings.h"
  21. //==============================================================================
  22. AppearanceSettings::AppearanceSettings (bool updateAppWhenChanged)
  23. : settings ("COLOUR_SCHEME")
  24. {
  25. if (! ProjucerApplication::getApp().isRunningCommandLine)
  26. {
  27. ProjucerLookAndFeel lf;
  28. CodeDocument doc;
  29. CPlusPlusCodeTokeniser tokeniser;
  30. CodeEditorComponent editor (doc, &tokeniser);
  31. CodeEditorComponent::ColourScheme cs (editor.getColourScheme());
  32. for (int i = cs.types.size(); --i >= 0;)
  33. {
  34. auto& t = cs.types.getReference(i);
  35. getColourValue (t.name) = t.colour.toString();
  36. }
  37. getCodeFontValue() = getDefaultCodeFont().toString();
  38. if (updateAppWhenChanged)
  39. settings.addListener (this);
  40. }
  41. }
  42. File AppearanceSettings::getSchemesFolder()
  43. {
  44. File f (getGlobalProperties().getFile().getSiblingFile ("Schemes"));
  45. f.createDirectory();
  46. return f;
  47. }
  48. void AppearanceSettings::writeDefaultSchemeFile (const String& xmlString, const String& name)
  49. {
  50. auto file = getSchemesFolder().getChildFile (name).withFileExtension (getSchemeFileSuffix());
  51. AppearanceSettings settings (false);
  52. if (auto xml = parseXML (xmlString))
  53. settings.readFromXML (*xml);
  54. settings.writeToFile (file);
  55. }
  56. void AppearanceSettings::refreshPresetSchemeList()
  57. {
  58. writeDefaultSchemeFile (BinaryData::colourscheme_dark_xml, "Default (Dark)");
  59. writeDefaultSchemeFile (BinaryData::colourscheme_light_xml, "Default (Light)");
  60. auto newSchemes = getSchemesFolder().findChildFiles (File::findFiles, false, String ("*") + getSchemeFileSuffix());
  61. if (newSchemes != presetSchemeFiles)
  62. {
  63. presetSchemeFiles.swapWith (newSchemes);
  64. ProjucerApplication::getCommandManager().commandStatusChanged();
  65. }
  66. }
  67. StringArray AppearanceSettings::getPresetSchemes()
  68. {
  69. StringArray s;
  70. for (int i = 0; i < presetSchemeFiles.size(); ++i)
  71. s.add (presetSchemeFiles.getReference(i).getFileNameWithoutExtension());
  72. return s;
  73. }
  74. void AppearanceSettings::selectPresetScheme (int index)
  75. {
  76. readFromFile (presetSchemeFiles [index]);
  77. }
  78. bool AppearanceSettings::readFromXML (const XmlElement& xml)
  79. {
  80. if (xml.hasTagName (settings.getType().toString()))
  81. {
  82. const ValueTree newSettings (ValueTree::fromXml (xml));
  83. // we'll manually copy across the new properties to the existing tree so that
  84. // any open editors will be kept up to date..
  85. settings.copyPropertiesFrom (newSettings, nullptr);
  86. for (int i = settings.getNumChildren(); --i >= 0;)
  87. {
  88. ValueTree c (settings.getChild (i));
  89. const ValueTree newValue (newSettings.getChildWithProperty (Ids::name, c.getProperty (Ids::name)));
  90. if (newValue.isValid())
  91. c.copyPropertiesFrom (newValue, nullptr);
  92. }
  93. return true;
  94. }
  95. return false;
  96. }
  97. bool AppearanceSettings::readFromFile (const File& file)
  98. {
  99. if (auto xml = parseXML (file))
  100. return readFromXML (*xml);
  101. return false;
  102. }
  103. bool AppearanceSettings::writeToFile (const File& file) const
  104. {
  105. if (auto xml = settings.createXml())
  106. return xml->writeTo (file, {});
  107. return false;
  108. }
  109. Font AppearanceSettings::getDefaultCodeFont()
  110. {
  111. return Font (Font::getDefaultMonospacedFontName(), Font::getDefaultStyle(), 13.0f);
  112. }
  113. StringArray AppearanceSettings::getColourNames() const
  114. {
  115. StringArray s;
  116. for (auto c : settings)
  117. if (c.hasType ("COLOUR"))
  118. s.add (c[Ids::name]);
  119. return s;
  120. }
  121. void AppearanceSettings::updateColourScheme()
  122. {
  123. ProjucerApplication::getApp().mainWindowList.sendLookAndFeelChange();
  124. }
  125. void AppearanceSettings::applyToCodeEditor (CodeEditorComponent& editor) const
  126. {
  127. CodeEditorComponent::ColourScheme cs (editor.getColourScheme());
  128. for (int i = cs.types.size(); --i >= 0;)
  129. {
  130. CodeEditorComponent::ColourScheme::TokenType& t = cs.types.getReference(i);
  131. getColour (t.name, t.colour);
  132. }
  133. editor.setColourScheme (cs);
  134. editor.setFont (getCodeFont());
  135. editor.setColour (ScrollBar::thumbColourId, editor.findColour (CodeEditorComponent::backgroundColourId)
  136. .contrasting()
  137. .withAlpha (0.13f));
  138. }
  139. Font AppearanceSettings::getCodeFont() const
  140. {
  141. const String fontString (settings [Ids::font].toString());
  142. if (fontString.isEmpty())
  143. return getDefaultCodeFont();
  144. return Font::fromString (fontString);
  145. }
  146. Value AppearanceSettings::getCodeFontValue()
  147. {
  148. return settings.getPropertyAsValue (Ids::font, nullptr);
  149. }
  150. Value AppearanceSettings::getColourValue (const String& colourName)
  151. {
  152. ValueTree c (settings.getChildWithProperty (Ids::name, colourName));
  153. if (! c.isValid())
  154. {
  155. c = ValueTree ("COLOUR");
  156. c.setProperty (Ids::name, colourName, nullptr);
  157. settings.appendChild (c, nullptr);
  158. }
  159. return c.getPropertyAsValue (Ids::colour, nullptr);
  160. }
  161. bool AppearanceSettings::getColour (const String& name, Colour& result) const
  162. {
  163. const ValueTree colour (settings.getChildWithProperty (Ids::name, name));
  164. if (colour.isValid())
  165. {
  166. result = Colour::fromString (colour [Ids::colour].toString());
  167. return true;
  168. }
  169. return false;
  170. }