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.

221 lines
6.3KB

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