From dc42f6f66b1f892cf857492dadb12276904cbe46 Mon Sep 17 00:00:00 2001 From: codereader Date: Thu, 22 Dec 2016 19:00:06 +0100 Subject: [PATCH] Resolve #4444: Make selected group item colour customisable. And make sure newly added colour scheme items get added to existing ones defined in the user's settings folder. --- install/colours.xml | 10 ++- .../uimanager/colourscheme/ColourScheme.cpp | 80 +++++++++++++----- plugins/uimanager/colourscheme/ColourScheme.h | 84 +++++++++---------- .../colourscheme/ColourSchemeManager.cpp | 51 ++++++----- radiant/render/backend/OpenGLShader.cpp | 2 +- 5 files changed, 136 insertions(+), 91 deletions(-) diff --git a/install/colours.xml b/install/colours.xml index 4884dec18b..f012b9becf 100644 --- a/install/colours.xml +++ b/install/colours.xml @@ -11,6 +11,7 @@ + @@ -43,6 +44,7 @@ + @@ -75,6 +77,7 @@ + @@ -107,6 +110,7 @@ + @@ -154,6 +158,7 @@ + @@ -170,8 +175,9 @@ - - + + + diff --git a/plugins/uimanager/colourscheme/ColourScheme.cpp b/plugins/uimanager/colourscheme/ColourScheme.cpp index 7179d4e9ae..e64dfbe68a 100644 --- a/plugins/uimanager/colourscheme/ColourScheme.cpp +++ b/plugins/uimanager/colourscheme/ColourScheme.cpp @@ -2,44 +2,84 @@ #include "itextstream.h" -namespace ui { +namespace ui +{ + +ColourScheme::ColourScheme() +{} /* ColourScheme Constructor * Builds the colourscheme structure and passes the found tags to the ColourItem constructor * All the found items are stored in a vector of ColourItems */ -ColourScheme::ColourScheme(xml::Node& schemeNode) { +ColourScheme::ColourScheme(const xml::Node& schemeNode) +{ _readOnly = (schemeNode.getAttributeValue("readonly") == "1"); // Select all nodes from the tree xml::NodeList colourNodes = schemeNode.getNamedChildren("colour"); - if (colourNodes.size() > 0) { - // Assign the name of this scheme - _name = schemeNode.getAttributeValue("name"); + if (colourNodes.empty()) + { + rMessage() << "ColourScheme: No scheme items found." << std::endl; + return; + } - // Cycle through all found colour tags and add them to this scheme - for (unsigned int i = 0; i < colourNodes.size(); i++) { - std::string colourName = colourNodes[i].getAttributeValue("name"); - _colours[colourName] = ColourItem(colourNodes[i]); - } + // Assign the name of this scheme + _name = schemeNode.getAttributeValue("name"); - } - else { - rMessage() << "ColourScheme: No scheme items found.\n"; + // Cycle through all found colour tags and add them to this scheme + for (const xml::Node& colourNode : colourNodes) + { + std::string colourName = colourNode.getAttributeValue("name"); + + _colours[colourName] = ColourItem(colourNode); } } -/* Returns the specified colour object - */ -ColourItem& ColourScheme::getColour(const std::string& colourName) { +ColourItemMap& ColourScheme::getColourMap() +{ + return _colours; +} + +ColourItem& ColourScheme::getColour(const std::string& colourName) +{ ColourItemMap::iterator it = _colours.find(colourName); - if (it != _colours.end()) { + + if (it != _colours.end()) + { return it->second; } - else { - rMessage() << "ColourScheme: Colour " << colourName.c_str() << " doesn't exist!\n"; - return _emptyColour; + + rMessage() << "ColourScheme: Colour " << colourName << " doesn't exist!" << std::endl; + + return _emptyColour; +} + +const std::string& ColourScheme::getName() const +{ + return _name; +} + +bool ColourScheme::isReadOnly() const +{ + return _readOnly; +} + +void ColourScheme::setReadOnly(bool isReadOnly) +{ + _readOnly = isReadOnly; +} + +void ColourScheme::mergeMissingItemsFromScheme(const ColourScheme& other) +{ + for (const ColourItemMap::value_type& otherPair : other._colours) + { + // Insert any ColourItems from the other mapping into this scheme + if (_colours.find(otherPair.first) == _colours.end()) + { + _colours.insert(otherPair); + } } } diff --git a/plugins/uimanager/colourscheme/ColourScheme.h b/plugins/uimanager/colourscheme/ColourScheme.h index 85c918bb47..0ec3d6fcc2 100644 --- a/plugins/uimanager/colourscheme/ColourScheme.h +++ b/plugins/uimanager/colourscheme/ColourScheme.h @@ -5,84 +5,76 @@ #include "string/convert.h" #include "xmlutil/Node.h" -namespace ui { +namespace ui +{ /* The ColourItem represents a single colour. This ia a simple derivative of * Vector3 which provides an additional constructor to extract the colour information * from an XML node. */ -class ColourItem -: public Vector3 +class ColourItem : + public Vector3 { public: /** Default constructor. Creates a black colour. */ - ColourItem() - : Vector3(0, 0, 0) + ColourItem() : + Vector3(0, 0, 0) {} /** Construct a ColourItem from an XML Node. */ - ColourItem(xml::Node& colourNode) - : Vector3(string::convert(colourNode.getAttributeValue("value"))) + ColourItem(const xml::Node& colourNode) : + Vector3(string::convert(colourNode.getAttributeValue("value"))) {} - }; typedef std::map ColourItemMap; /* A colourscheme is basically a collection of ColourItems */ -class ColourScheme { - - private: - // The name of this scheme - std::string _name; +class ColourScheme +{ +private: + // The name of this scheme + std::string _name; - // The ColourItems Map - ColourItemMap _colours; + // The ColourItems Map + ColourItemMap _colours; - // True if the scheme must not be edited - bool _readOnly; + // True if the scheme must not be edited + bool _readOnly; - /* Empty Colour, this serves as return value for - non-existing, but requested colours */ - ColourItem _emptyColour; + /* Empty Colour, this serves as return value for + non-existing, but requested colours */ + ColourItem _emptyColour; - public: - // Constructors - ColourScheme() {}; - // Constructs a ColourScheme from a given xml::node - ColourScheme(xml::Node& schemeNode); +public: + // Constructors + ColourScheme(); - // Returns the list of ColourItems - ColourItemMap& getColourMap() { - return _colours; - } + // Constructs a ColourScheme from a given xml::node + ColourScheme(const xml::Node& schemeNode); - // Returns the requested colour object - ColourItem& getColour(const std::string& colourName); + // Returns the list of ColourItems + ColourItemMap& getColourMap(); - // returns the name of this colour scheme - std::string getName() const { - return _name; - } + // Returns the requested colour object + ColourItem& getColour(const std::string& colourName); - // returns true if the scheme is read-only - bool isReadOnly() const { - return _readOnly; - } + // returns the name of this colour scheme + const std::string& getName() const; - // set the read-only status of this scheme - void setReadOnly(const bool isReadOnly) { - _readOnly = isReadOnly; - } + // returns true if the scheme is read-only + bool isReadOnly() const; - // Destructor - ~ColourScheme() {}; + // set the read-only status of this scheme + void setReadOnly(bool isReadOnly); -}; // class ColourScheme + // Tries to add any missing items from the given scheme into this one + void mergeMissingItemsFromScheme(const ColourScheme& other); +}; } // namespace ui diff --git a/plugins/uimanager/colourscheme/ColourSchemeManager.cpp b/plugins/uimanager/colourscheme/ColourSchemeManager.cpp index 391ab0a9e4..fcb466f818 100644 --- a/plugins/uimanager/colourscheme/ColourSchemeManager.cpp +++ b/plugins/uimanager/colourscheme/ColourSchemeManager.cpp @@ -146,8 +146,6 @@ void ColourSchemeManager::saveColourSchemes() void ColourSchemeManager::loadColourSchemes() { - std::string schemeName = ""; - // load from XMLRegistry rMessage() << "ColourSchemeManager: Loading colour schemes..." << std::endl; @@ -156,36 +154,45 @@ void ColourSchemeManager::loadColourSchemes() "user/ui/colourschemes/colourscheme[@version='" + COLOURSCHEME_VERSION + "']" ); - if (!schemeNodes.empty()) + if (schemeNodes.empty()) { - // Cycle through all found scheme nodes - for (std::size_t i = 0; i < schemeNodes.size(); i++) + rMessage() << "ColourSchemeManager: No schemes found..." << std::endl; + return; + } + + std::string schemeName = ""; + + // Cycle through all found scheme nodes + for (const xml::Node& node : schemeNodes) + { + schemeName = node.getAttributeValue("name"); + + // If the scheme is already in the list, skip it + if (!schemeExists(schemeName)) { - schemeName = schemeNodes[i].getAttributeValue("name"); + // Construct the ColourScheme class from the xml::node + _colourSchemes[schemeName] = ColourScheme(node); - // If the scheme is already in the list, skip it - if (!schemeExists(schemeName)) + // Check, if this is the currently active scheme + if (node.getAttributeValue("active") == "1") { - // Construct the ColourScheme class from the xml::node - _colourSchemes[schemeName] = ColourScheme(schemeNodes[i]); - - // Check, if this is the currently active scheme - if (schemeNodes[i].getAttributeValue("active") == "1") - { - _activeScheme = schemeName; - } + _activeScheme = schemeName; } } - - // If there isn't any active scheme yet, take the last one as active scheme - if (_activeScheme.empty() && !schemeNodes.empty()) + else if (node.getAttributeValue("readonly") == "1") { - _activeScheme = schemeName; + // Scheme exists, but we have a factory-defined scheme + // try to merge any missing items into the existing scheme + ColourScheme readOnlyScheme(node); + + _colourSchemes[schemeName].mergeMissingItemsFromScheme(readOnlyScheme); } } - else + + // If there isn't any active scheme yet, take the last one as active scheme + if (_activeScheme.empty() && !schemeNodes.empty()) { - rMessage() << "ColourSchemeManager: No schemes found..." << std::endl; + _activeScheme = schemeName; } } diff --git a/radiant/render/backend/OpenGLShader.cpp b/radiant/render/backend/OpenGLShader.cpp index 1cfb04b140..c52aa6f4c5 100644 --- a/radiant/render/backend/OpenGLShader.cpp +++ b/radiant/render/backend/OpenGLShader.cpp @@ -785,7 +785,7 @@ void OpenGLShader::construct(const std::string& name) } else if (name == "$XY_OVERLAY_GROUP") { - Vector3 colorSelBrushes(0, 0.4, 0.8); + Vector3 colorSelBrushes = ColourSchemes().getColour("selected_group_items"); state.setColour(colorSelBrushes[0], colorSelBrushes[1], colorSelBrushes[2],