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.

230 lines
6.8KB

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