1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
#include "ColourSchemeManager.h"
#include "iregistry.h"
#include "itextstream.h"
#include "ieclasscolours.h"
#include "module/StaticModule.h"
namespace colours
{
const char* const COLOURSCHEME_VERSION = "1.0";
void ColourSchemeManager::foreachScheme(const std::function<void(const std::string&, IColourScheme&)>& functor)
{
for (auto& pair : _colourSchemes)
{
functor(pair.first, pair.second);
}
}
/* returns true, if the scheme called <name> exists
*/
bool ColourSchemeManager::schemeExists(const std::string& name)
{
return _colourSchemes.find(name) != _colourSchemes.end();
}
ColourScheme& ColourSchemeManager::getActiveScheme()
{
return _colourSchemes[_activeScheme];
}
ColourScheme& ColourSchemeManager::getColourScheme(const std::string& name)
{
return _colourSchemes[name];
}
bool ColourSchemeManager::isActive(const std::string& name)
{
return schemeExists(name) && name == _activeScheme;
}
void ColourSchemeManager::setActive(const std::string& name)
{
if (schemeExists(name))
{
_activeScheme = name;
}
}
void ColourSchemeManager::restoreColourSchemes()
{
// Clear the whole colourScheme map and reload it from the registry
_colourSchemes.clear();
loadColourSchemes();
emitEclassOverrides();
}
void ColourSchemeManager::deleteScheme(const std::string& name)
{
if (schemeExists(name))
{
// Delete the scheme from the map
_colourSchemes.erase(name);
// Choose a new theme from the list, if the active scheme was deleted
if (_activeScheme == name && !_colourSchemes.empty())
{
_activeScheme = _colourSchemes.begin()->second.getName();
}
}
}
void ColourSchemeManager::saveScheme(const std::string& name)
{
std::string basePath = "user/ui/colourschemes";
// Re-create the schemeNode
xml::Node schemeNode = GlobalRegistry().createKeyWithName(basePath, "colourscheme", name);
schemeNode.setAttributeValue("version", COLOURSCHEME_VERSION);
// Set the readonly attribute if necessary
if (_colourSchemes[name].isReadOnly())
{
schemeNode.setAttributeValue("readonly", "1");
}
// Set the active attribute, if this is the active scheme
if (name == _activeScheme)
{
schemeNode.setAttributeValue("active", "1");
}
// This will be the path where all the <colour> nodes are added to
std::string schemePath = basePath + "/colourscheme[@name='" + name + "']";
// Retrieve the list with all the ColourItems of this scheme
auto& scheme = _colourSchemes[name];
// Cycle through all the ColourItems and save them into the registry
scheme.foreachColour([&](const std::string& name, colours::IColourItem& item)
{
auto colourNode = GlobalRegistry().createKeyWithName(schemePath, "colour", name);
colourNode.setAttributeValue("value", string::to_string(item.getColour()));
});
}
void ColourSchemeManager::saveColourSchemes()
{
// Delete all existing schemes from the registry
GlobalRegistry().deleteXPath("user/ui/colourschemes//colourscheme");
// Save all schemes that are stored in memory
for (auto it = _colourSchemes.begin(); it != _colourSchemes.end(); ++it)
{
if (!it->first.empty())
{
// Save the scheme whose name is stored in it->first
saveScheme(it->first);
}
}
// Flush the whole colour scheme structure and re-load it from the registry.
// This is to remove any remaining artifacts.
restoreColourSchemes();
}
void ColourSchemeManager::loadColourSchemes()
{
// load from XMLRegistry
rMessage() << "ColourSchemeManager: Loading colour schemes..." << std::endl;
// Find all <scheme> nodes
auto schemeNodes = GlobalRegistry().findXPath(
"user/ui/colourschemes/colourscheme[@version='" + std::string(COLOURSCHEME_VERSION) + "']"
);
if (schemeNodes.empty())
{
rMessage() << "ColourSchemeManager: No schemes found..." << std::endl;
return;
}
std::string schemeName = "";
_activeScheme = "";
// Cycle through all found scheme nodes
for (const auto& node : schemeNodes)
{
schemeName = node.getAttributeValue("name");
// If the scheme is already in the list, skip it
if (!schemeExists(schemeName))
{
// Construct the ColourScheme class from the xml::node
_colourSchemes[schemeName] = ColourScheme(node);
// Check, if this is the currently active scheme
if (_activeScheme.empty() && node.getAttributeValue("active") == "1")
{
_activeScheme = schemeName;
}
}
else if (node.getAttributeValue("readonly") == "1")
{
// 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);
}
}
// If there isn't any active scheme yet, take the last one as active scheme
if (_activeScheme.empty() && !schemeNodes.empty())
{
_activeScheme = schemeName;
}
}
void ColourSchemeManager::copyScheme(const std::string& fromName, const std::string& toName)
{
if (schemeExists(fromName))
{
// Copy the actual entry
_colourSchemes[toName] = _colourSchemes[fromName];
_colourSchemes[toName].setReadOnly(false);
}
else
{
rMessage() << "ColourSchemeManager: Scheme " << fromName << " does not exist!" << std::endl;
}
}
Vector3 ColourSchemeManager::getColour(const std::string& colourName)
{
return _colourSchemes[_activeScheme].getColour(colourName).getColour();
}
const std::string& ColourSchemeManager::getName() const
{
static std::string _name(MODULE_COLOURSCHEME_MANAGER);
return _name;
}
const StringSet& ColourSchemeManager::getDependencies() const
{
static StringSet _dependencies;
if (_dependencies.empty())
{
_dependencies.insert(MODULE_XMLREGISTRY);
_dependencies.insert(MODULE_ECLASS_COLOUR_MANAGER);
}
return _dependencies;
}
void ColourSchemeManager::initialiseModule(const IApplicationContext& ctx)
{
loadColourSchemes();
emitEclassOverrides();
}
void ColourSchemeManager::emitEclassOverrides()
{
auto& colourManager = GlobalEclassColourManager();
colourManager.clearOverrideColours();
// Apply the overrides for the known entity classes
auto& activeScheme = getActiveScheme();
colourManager.addOverrideColour("worldspawn", activeScheme.getColour("default_brush").getColour());
colourManager.addOverrideColour("light", activeScheme.getColour("light_volumes").getColour());
}
module::StaticModuleRegistration<ColourSchemeManager> colourSchemeManagerModule;
} // namespace ui
|