add way for adding/removing classes

This commit is contained in:
Konstantin Käfer
2014-06-27 19:11:57 +02:00
parent 48019ae85c
commit a41f0db7dd
2 changed files with 95 additions and 0 deletions

View File

@@ -5,11 +5,13 @@
#include <llmr/style/class_properties.hpp>
#include <llmr/style/style_properties.hpp>
#include <llmr/style/rasterize_properties.hpp>
#include <llmr/style/applied_class_properties.hpp>
#include <vector>
#include <memory>
#include <string>
#include <map>
#include <set>
namespace llmr {
@@ -33,6 +35,15 @@ public:
bool isBackground() const;
// Sets the list of classes and creates transitions to the currently applied values.
void setClasses(const std::vector<std::string> &class_names, timestamp now,
const ClassPropertyTransition &defaultTransition);
private:
// Applies all properties from a class, if they haven't been applied already.
void applyClassProperties(ClassID class_id, std::set<PropertyKey> &already_applied,
timestamp now, const ClassPropertyTransition &defaultTransition);
public:
// The name of this layer.
const std::string id;
@@ -44,6 +55,12 @@ public:
// Contains all style classes that can be applied to this layer.
const std::map<ClassID, ClassProperties> styles;
private:
// For every property, stores a list of applied property values, with
// optional transition times.
std::map<PropertyKey, AppliedClassProperties> appliedStyle;
public:
// Stores the evaluated, and cascaded styling information, specific to this
// layer's type.
StyleProperties style;

View File

@@ -1,4 +1,5 @@
#include <llmr/style/style_layer.hpp>
#include <llmr/style/property_fallback.hpp>
namespace llmr {
@@ -10,4 +11,81 @@ bool StyleLayer::isBackground() const {
return id == "background";
}
void StyleLayer::setClasses(const std::vector<std::string> &class_names, const timestamp now,
const ClassPropertyTransition &defaultTransition) {
// Stores all keys that we have already added transitions for.
std::set<PropertyKey> already_applied;
// Reverse iterate through all class names and apply them last to first.
for (auto it = class_names.rbegin(); it != class_names.rend(); it++) {
const std::string &class_name = *it;
// From here on, we're only dealing with IDs to avoid comparing strings all the time.
const ClassID class_id = ClassDictionary::Lookup(class_name);
applyClassProperties(class_id, already_applied, now, defaultTransition);
}
// As the last class, apply the default class.
applyClassProperties(ClassID::Default, already_applied, now, defaultTransition);
// Make sure that we also transition to the fallback value for keys that aren't changed by
// any applied classes.
for (std::pair<const PropertyKey, AppliedClassProperties> &property_pair : appliedStyle) {
const PropertyKey key = property_pair.first;
if (already_applied.find(key) != already_applied.end()) {
// This property has already been set by a previous class, so we don't need to
// transition to the fallback.
continue;
}
AppliedClassProperties &appliedProperties = property_pair.second;
// Make sure that we don't do double transitions to the fallback value.
if (appliedProperties.mostRecent() != ClassID::Fallback) {
// This property key hasn't been set by a previous class, so we need to add a transition
// to the fallback value for that key.
const timestamp begin = now + defaultTransition.delay;
const timestamp end = begin + defaultTransition.duration;
const PropertyValue &value = PropertyFallbackValue::Get(key);
appliedProperties.add(ClassID::Fallback, begin, end, value);
}
}
}
// Helper function for applying all properties of a a single class that haven't been applied yet.
void StyleLayer::applyClassProperties(const ClassID class_id,
std::set<PropertyKey> &already_applied, timestamp now,
const ClassPropertyTransition &defaultTransition) {
auto style_it = styles.find(class_id);
if (style_it == styles.end()) {
// There is no class in this layer with this class_name.
return;
}
// Loop through all the properties in this style, and add transitions to them, if they're
// not already the most recent transition.
const ClassProperties &properties = style_it->second;
for (const std::pair<PropertyKey, PropertyValue> &property_pair : properties) {
PropertyKey key = property_pair.first;
if (already_applied.find(key) != already_applied.end()) {
// This property has already been set by a previous class.
continue;
}
// Mark this property as written by a previous class, so that subsequent
// classes won't override this.
already_applied.insert(key);
// If the most recent transition is not the one with the highest priority, create
// a transition.
AppliedClassProperties &appliedProperties = appliedStyle[key];
if (appliedProperties.mostRecent() != class_id) {
const ClassPropertyTransition &transition =
properties.getTransition(key, defaultTransition);
const timestamp begin = now + transition.delay;
const timestamp end = begin + transition.duration;
const PropertyValue &value = property_pair.second;
appliedProperties.add(class_id, begin, end, value);
}
}
}
}