/* ============================================================================== This file is part of the JUCE 6 technical preview. Copyright (c) 2017 - ROLI Ltd. You may use this code under the terms of the GPL v3 (see www.gnu.org/licenses). For this technical preview, this file is not subject to commercial licensing. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE DISCLAIMED. ============================================================================== */ #include "../Application/jucer_Headers.h" #include "../Application/jucer_Application.h" #include "jucer_AppearanceSettings.h" //============================================================================== AppearanceSettings::AppearanceSettings (bool updateAppWhenChanged) : settings ("COLOUR_SCHEME") { if (! ProjucerApplication::getApp().isRunningCommandLine) { ProjucerLookAndFeel lf; CodeDocument doc; CPlusPlusCodeTokeniser tokeniser; CodeEditorComponent editor (doc, &tokeniser); CodeEditorComponent::ColourScheme cs (editor.getColourScheme()); for (int i = cs.types.size(); --i >= 0;) { auto& t = cs.types.getReference(i); getColourValue (t.name) = t.colour.toString(); } getCodeFontValue() = getDefaultCodeFont().toString(); if (updateAppWhenChanged) settings.addListener (this); } } File AppearanceSettings::getSchemesFolder() { File f (getGlobalProperties().getFile().getSiblingFile ("Schemes")); f.createDirectory(); return f; } void AppearanceSettings::writeDefaultSchemeFile (const String& xmlString, const String& name) { auto file = getSchemesFolder().getChildFile (name).withFileExtension (getSchemeFileSuffix()); AppearanceSettings settings (false); if (auto xml = parseXML (xmlString)) settings.readFromXML (*xml); settings.writeToFile (file); } void AppearanceSettings::refreshPresetSchemeList() { writeDefaultSchemeFile (BinaryData::colourscheme_dark_xml, "Default (Dark)"); writeDefaultSchemeFile (BinaryData::colourscheme_light_xml, "Default (Light)"); auto newSchemes = getSchemesFolder().findChildFiles (File::findFiles, false, String ("*") + getSchemeFileSuffix()); if (newSchemes != presetSchemeFiles) { presetSchemeFiles.swapWith (newSchemes); ProjucerApplication::getCommandManager().commandStatusChanged(); } } StringArray AppearanceSettings::getPresetSchemes() { StringArray s; for (int i = 0; i < presetSchemeFiles.size(); ++i) s.add (presetSchemeFiles.getReference(i).getFileNameWithoutExtension()); return s; } void AppearanceSettings::selectPresetScheme (int index) { readFromFile (presetSchemeFiles [index]); } bool AppearanceSettings::readFromXML (const XmlElement& xml) { if (xml.hasTagName (settings.getType().toString())) { const ValueTree newSettings (ValueTree::fromXml (xml)); // we'll manually copy across the new properties to the existing tree so that // any open editors will be kept up to date.. settings.copyPropertiesFrom (newSettings, nullptr); for (int i = settings.getNumChildren(); --i >= 0;) { ValueTree c (settings.getChild (i)); const ValueTree newValue (newSettings.getChildWithProperty (Ids::name, c.getProperty (Ids::name))); if (newValue.isValid()) c.copyPropertiesFrom (newValue, nullptr); } return true; } return false; } bool AppearanceSettings::readFromFile (const File& file) { if (auto xml = parseXML (file)) return readFromXML (*xml); return false; } bool AppearanceSettings::writeToFile (const File& file) const { if (auto xml = settings.createXml()) return xml->writeTo (file, {}); return false; } Font AppearanceSettings::getDefaultCodeFont() { return Font (Font::getDefaultMonospacedFontName(), Font::getDefaultStyle(), 13.0f); } StringArray AppearanceSettings::getColourNames() const { StringArray s; for (auto c : settings) if (c.hasType ("COLOUR")) s.add (c[Ids::name]); return s; } void AppearanceSettings::updateColourScheme() { ProjucerApplication::getApp().mainWindowList.sendLookAndFeelChange(); } void AppearanceSettings::applyToCodeEditor (CodeEditorComponent& editor) const { CodeEditorComponent::ColourScheme cs (editor.getColourScheme()); for (int i = cs.types.size(); --i >= 0;) { CodeEditorComponent::ColourScheme::TokenType& t = cs.types.getReference(i); getColour (t.name, t.colour); } editor.setColourScheme (cs); editor.setFont (getCodeFont()); editor.setColour (ScrollBar::thumbColourId, editor.findColour (CodeEditorComponent::backgroundColourId) .contrasting() .withAlpha (0.13f)); } Font AppearanceSettings::getCodeFont() const { const String fontString (settings [Ids::font].toString()); if (fontString.isEmpty()) return getDefaultCodeFont(); return Font::fromString (fontString); } Value AppearanceSettings::getCodeFontValue() { return settings.getPropertyAsValue (Ids::font, nullptr); } Value AppearanceSettings::getColourValue (const String& colourName) { ValueTree c (settings.getChildWithProperty (Ids::name, colourName)); if (! c.isValid()) { c = ValueTree ("COLOUR"); c.setProperty (Ids::name, colourName, nullptr); settings.appendChild (c, nullptr); } return c.getPropertyAsValue (Ids::colour, nullptr); } bool AppearanceSettings::getColour (const String& name, Colour& result) const { const ValueTree colour (settings.getChildWithProperty (Ids::name, name)); if (colour.isValid()) { result = Colour::fromString (colour [Ids::colour].toString()); return true; } return false; }