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.

214 lines
6.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE 7 technical preview.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. You may use this code under the terms of the GPL v3
  6. (see www.gnu.org/licenses).
  7. For the technical preview this file cannot be licensed commercially.
  8. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  9. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  10. DISCLAIMED.
  11. ==============================================================================
  12. */
  13. #include "../Application/jucer_Headers.h"
  14. #include "../Application/jucer_Application.h"
  15. #include "jucer_AppearanceSettings.h"
  16. //==============================================================================
  17. AppearanceSettings::AppearanceSettings (bool updateAppWhenChanged)
  18. : settings ("COLOUR_SCHEME")
  19. {
  20. CodeDocument doc;
  21. CPlusPlusCodeTokeniser tokeniser;
  22. CodeEditorComponent editor (doc, &tokeniser);
  23. CodeEditorComponent::ColourScheme cs (editor.getColourScheme());
  24. for (int i = cs.types.size(); --i >= 0;)
  25. {
  26. auto& t = cs.types.getReference(i);
  27. getColourValue (t.name) = t.colour.toString();
  28. }
  29. getCodeFontValue() = getDefaultCodeFont().toString();
  30. if (updateAppWhenChanged)
  31. settings.addListener (this);
  32. }
  33. File AppearanceSettings::getSchemesFolder()
  34. {
  35. File f (getGlobalProperties().getFile().getSiblingFile ("Schemes"));
  36. f.createDirectory();
  37. return f;
  38. }
  39. void AppearanceSettings::writeDefaultSchemeFile (const String& xmlString, const String& name)
  40. {
  41. auto file = getSchemesFolder().getChildFile (name).withFileExtension (getSchemeFileSuffix());
  42. AppearanceSettings settings (false);
  43. if (auto xml = parseXML (xmlString))
  44. settings.readFromXML (*xml);
  45. settings.writeToFile (file);
  46. }
  47. void AppearanceSettings::refreshPresetSchemeList()
  48. {
  49. writeDefaultSchemeFile (BinaryData::colourscheme_dark_xml, "Default (Dark)");
  50. writeDefaultSchemeFile (BinaryData::colourscheme_light_xml, "Default (Light)");
  51. auto newSchemes = getSchemesFolder().findChildFiles (File::findFiles, false, String ("*") + getSchemeFileSuffix());
  52. if (newSchemes != presetSchemeFiles)
  53. {
  54. presetSchemeFiles.swapWith (newSchemes);
  55. ProjucerApplication::getCommandManager().commandStatusChanged();
  56. }
  57. }
  58. StringArray AppearanceSettings::getPresetSchemes()
  59. {
  60. StringArray s;
  61. for (int i = 0; i < presetSchemeFiles.size(); ++i)
  62. s.add (presetSchemeFiles.getReference(i).getFileNameWithoutExtension());
  63. return s;
  64. }
  65. void AppearanceSettings::selectPresetScheme (int index)
  66. {
  67. readFromFile (presetSchemeFiles [index]);
  68. }
  69. bool AppearanceSettings::readFromXML (const XmlElement& xml)
  70. {
  71. if (xml.hasTagName (settings.getType().toString()))
  72. {
  73. const ValueTree newSettings (ValueTree::fromXml (xml));
  74. // we'll manually copy across the new properties to the existing tree so that
  75. // any open editors will be kept up to date..
  76. settings.copyPropertiesFrom (newSettings, nullptr);
  77. for (int i = settings.getNumChildren(); --i >= 0;)
  78. {
  79. ValueTree c (settings.getChild (i));
  80. const ValueTree newValue (newSettings.getChildWithProperty (Ids::name, c.getProperty (Ids::name)));
  81. if (newValue.isValid())
  82. c.copyPropertiesFrom (newValue, nullptr);
  83. }
  84. return true;
  85. }
  86. return false;
  87. }
  88. bool AppearanceSettings::readFromFile (const File& file)
  89. {
  90. if (auto xml = parseXML (file))
  91. return readFromXML (*xml);
  92. return false;
  93. }
  94. bool AppearanceSettings::writeToFile (const File& file) const
  95. {
  96. if (auto xml = settings.createXml())
  97. return xml->writeTo (file, {});
  98. return false;
  99. }
  100. Font AppearanceSettings::getDefaultCodeFont()
  101. {
  102. return Font (Font::getDefaultMonospacedFontName(), Font::getDefaultStyle(), 13.0f);
  103. }
  104. StringArray AppearanceSettings::getColourNames() const
  105. {
  106. StringArray s;
  107. for (auto c : settings)
  108. if (c.hasType ("COLOUR"))
  109. s.add (c[Ids::name]);
  110. return s;
  111. }
  112. void AppearanceSettings::updateColourScheme()
  113. {
  114. ProjucerApplication::getApp().mainWindowList.sendLookAndFeelChange();
  115. }
  116. void AppearanceSettings::applyToCodeEditor (CodeEditorComponent& editor) const
  117. {
  118. CodeEditorComponent::ColourScheme cs (editor.getColourScheme());
  119. for (int i = cs.types.size(); --i >= 0;)
  120. {
  121. CodeEditorComponent::ColourScheme::TokenType& t = cs.types.getReference(i);
  122. getColour (t.name, t.colour);
  123. }
  124. editor.setColourScheme (cs);
  125. editor.setFont (getCodeFont());
  126. editor.setColour (ScrollBar::thumbColourId, editor.findColour (CodeEditorComponent::backgroundColourId)
  127. .contrasting()
  128. .withAlpha (0.13f));
  129. }
  130. Font AppearanceSettings::getCodeFont() const
  131. {
  132. const String fontString (settings [Ids::font].toString());
  133. if (fontString.isEmpty())
  134. return getDefaultCodeFont();
  135. return Font::fromString (fontString);
  136. }
  137. Value AppearanceSettings::getCodeFontValue()
  138. {
  139. return settings.getPropertyAsValue (Ids::font, nullptr);
  140. }
  141. Value AppearanceSettings::getColourValue (const String& colourName)
  142. {
  143. ValueTree c (settings.getChildWithProperty (Ids::name, colourName));
  144. if (! c.isValid())
  145. {
  146. c = ValueTree ("COLOUR");
  147. c.setProperty (Ids::name, colourName, nullptr);
  148. settings.appendChild (c, nullptr);
  149. }
  150. return c.getPropertyAsValue (Ids::colour, nullptr);
  151. }
  152. bool AppearanceSettings::getColour (const String& name, Colour& result) const
  153. {
  154. const ValueTree colour (settings.getChildWithProperty (Ids::name, name));
  155. if (colour.isValid())
  156. {
  157. result = Colour::fromString (colour [Ids::colour].toString());
  158. return true;
  159. }
  160. return false;
  161. }