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.

219 lines
6.2KB

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