Improve the generation of css::Query instances (see Sheet::query() member function)

This commit is contained in:
David Capello 2013-12-09 23:07:48 -03:00
parent 20fb1317a3
commit 11335fd5f3
11 changed files with 124 additions and 45 deletions

View File

@ -25,7 +25,7 @@ void CompoundStyle::update()
{ {
deleteQueries(); deleteQueries();
Style* style = m_sheet->getStyle(m_name); const Style* style = m_sheet->getStyle(m_name);
if (style) if (style)
m_normal = m_sheet->query(*style); m_normal = m_sheet->query(*style);
} }
@ -56,7 +56,7 @@ const Query& CompoundStyle::operator[](const States& states) const
if (it != m_queries.end()) if (it != m_queries.end())
return *it->second; return *it->second;
else { else {
Style* style = m_sheet->getStyle(m_name); const Style* style = m_sheet->getStyle(m_name);
if (style == NULL) if (style == NULL)
return m_normal; return m_normal;

View File

@ -174,6 +174,9 @@ TEST(Css, CompoundStyles)
Style baseFocus("base:focus"); Style baseFocus("base:focus");
Style sub("sub", &base); Style sub("sub", &base);
Style subFocus("sub:focus", &base); Style subFocus("sub:focus", &base);
Style sub2("sub2", &sub);
Style sub3("sub3", &sub2);
Style sub3FocusHover("sub3:focus:hover", &sub2);
base[bg] = Value(1); base[bg] = Value(1);
base[fg] = Value(2); base[fg] = Value(2);
@ -183,6 +186,9 @@ TEST(Css, CompoundStyles)
sub[bg] = Value(5); sub[bg] = Value(5);
subFocus[fg] = Value(6); subFocus[fg] = Value(6);
sub3[bg] = Value(7);
sub3FocusHover[fg] = Value(8);
Sheet sheet; Sheet sheet;
sheet.addRule(&bg); sheet.addRule(&bg);
sheet.addRule(&fg); sheet.addRule(&fg);
@ -191,6 +197,9 @@ TEST(Css, CompoundStyles)
sheet.addStyle(&baseFocus); sheet.addStyle(&baseFocus);
sheet.addStyle(&sub); sheet.addStyle(&sub);
sheet.addStyle(&subFocus); sheet.addStyle(&subFocus);
sheet.addStyle(&sub2);
sheet.addStyle(&sub3);
sheet.addStyle(&sub3FocusHover);
CompoundStyle compoundBase = sheet.compoundStyle("base"); CompoundStyle compoundBase = sheet.compoundStyle("base");
EXPECT_EQ(Value(1), compoundBase[bg]); EXPECT_EQ(Value(1), compoundBase[bg]);
@ -211,6 +220,27 @@ TEST(Css, CompoundStyles)
EXPECT_EQ(Value(6), compoundSub[focus][fg]); EXPECT_EQ(Value(6), compoundSub[focus][fg]);
EXPECT_EQ(Value(4), compoundSub[hover+focus][bg]); EXPECT_EQ(Value(4), compoundSub[hover+focus][bg]);
EXPECT_EQ(Value(6), compoundSub[hover+focus][fg]); EXPECT_EQ(Value(6), compoundSub[hover+focus][fg]);
CompoundStyle compoundSub2 = sheet.compoundStyle("sub2");
EXPECT_EQ(Value(5), compoundSub2[bg]);
EXPECT_EQ(Value(2), compoundSub2[fg]);
EXPECT_EQ(Value(5), compoundSub2[hover][bg]);
EXPECT_EQ(Value(3), compoundSub2[hover][fg]);
EXPECT_EQ(Value(4), compoundSub2[focus][bg]);
EXPECT_EQ(Value(6), compoundSub2[focus][fg]);
EXPECT_EQ(Value(4), compoundSub2[hover+focus][bg]);
EXPECT_EQ(Value(6), compoundSub2[hover+focus][fg]);
CompoundStyle compoundSub3 = sheet.compoundStyle("sub3");
EXPECT_EQ(Value(7), compoundSub3[bg]);
EXPECT_EQ(Value(2), compoundSub3[fg]);
EXPECT_EQ(Value(7), compoundSub3[hover][bg]);
EXPECT_EQ(Value(3), compoundSub3[hover][fg]);
EXPECT_EQ(Value(4), compoundSub3[focus][bg]);
EXPECT_EQ(Value(6), compoundSub3[focus][fg]);
EXPECT_EQ(Value(4), compoundSub3[hover+focus][bg]);
EXPECT_EQ(Value(6), compoundSub3[hover+focus][fg]);
EXPECT_EQ(Value(8), compoundSub3[focus+hover][fg]);
} }
int main(int argc, char** argv) int main(int argc, char** argv)

View File

@ -47,6 +47,10 @@ namespace css {
m_map[name] = value; m_map[name] = value;
} }
bool exists(const std::string& name) const {
return (m_map.find(name) != m_map.end());
}
private: private:
map m_map; map m_map;
T m_default; T m_default;

View File

@ -12,17 +12,18 @@
namespace css { namespace css {
void Query::addRuleValue(const std::string& ruleName, Style* style) void Query::addFromStyle(const Style* style)
{ {
m_ruleValue.add(ruleName, style); for (Style::const_iterator it = style->begin(), end = style->end();
}
void Query::addFromStyle(Style* style)
{
for (Style::iterator it = style->begin(), end = style->end();
it != end; ++it) { it != end; ++it) {
addRuleValue(it->first, style); addRuleValue(it->first, style);
} }
} }
void Query::addRuleValue(const std::string& ruleName, const Style* style)
{
if (!m_ruleValue.exists(ruleName))
m_ruleValue.add(ruleName, style);
}
} // namespace css } // namespace css

View File

@ -19,11 +19,12 @@ namespace css {
public: public:
Query() { } Query() { }
void addRuleValue(const std::string& ruleName, Style* style); // Adds more rules from the given style only if the query doesn't
void addFromStyle(Style* style); // contain those rules already.
void addFromStyle(const Style* style);
const Value& operator[](const Rule& rule) const { const Value& operator[](const Rule& rule) const {
Style* style = m_ruleValue[rule.name()]; const Style* style = m_ruleValue[rule.name()];
if (style) if (style)
return (*style)[rule.name()]; return (*style)[rule.name()];
else else
@ -31,6 +32,8 @@ namespace css {
} }
private: private:
void addRuleValue(const std::string& ruleName, const Style* style);
Styles m_ruleValue; Styles m_ruleValue;
Value m_none; Value m_none;
}; };

View File

@ -14,6 +14,8 @@
#include "css/query.h" #include "css/query.h"
#include "css/stateful_style.h" #include "css/stateful_style.h"
#include <stdio.h>
namespace css { namespace css {
Sheet::Sheet() Sheet::Sheet()
@ -30,43 +32,71 @@ void Sheet::addStyle(Style* style)
m_styles.add(style->name(), style); m_styles.add(style->name(), style);
} }
Style* Sheet::getStyle(const std::string& name) const Style* Sheet::getStyle(const std::string& name)
{ {
return m_styles[name]; return m_styles[name];
} }
Query Sheet::query(const StatefulStyle& compound) Query Sheet::query(const StatefulStyle& compound)
{ {
const Style* firstStyle = &compound.style();
const Style* style;
Query query; Query query;
std::string name;
std::string name = compound.style().name(); // We create a string with all states. This is the style with
Style* style = m_styles[name]; // highest priority.
Style* base = NULL; std::string states;
if (style) { for (States::const_iterator
base = style->base(); state_it = compound.states().begin(),
if (base) state_end = compound.states().end(); state_it != state_end; ++state_it) {
query.addFromStyle(base); states += StatefulStyle::kSeparator;
states += (*state_it)->name();
query.addFromStyle(style);
} }
for (States::const_iterator it = compound.states().begin(), // Query by priority for the following styles:
end = compound.states().end(); it != end; ++it) { // style:state1:state2:...
if (base) { // ...
name = base->name(); // base1:state1:state2:...
name += StatefulStyle::kSeparator; // base0:state1:state2:...
name += (*it)->name(); for (style=firstStyle; style != NULL; style=style->base()) {
style = m_styles[name]; name = style->name();
if (style) name += states;
query.addFromStyle(style);
}
name = compound.style().name(); const Style* style2 = m_styles[name];
name += StatefulStyle::kSeparator; if (style2)
name += (*it)->name(); query.addFromStyle(style2);
style = m_styles[name]; }
if (style)
query.addFromStyle(style); // Query for:
// style:state2
// style:state1
// ...
// base1:state2
// base1:state1
// base0:state2
// base0:state1
for (States::const_reverse_iterator
state_it = compound.states().rbegin(),
state_end = compound.states().rend(); state_it != state_end; ++state_it) {
for (style=firstStyle; style != NULL; style=style->base()) {
name = style->name();
name += StatefulStyle::kSeparator;
name += (*state_it)->name();
const Style* style2 = m_styles[name];
if (style2)
query.addFromStyle(style2);
}
}
// Query for:
// style
// ...
// base1
// base0
for (style=firstStyle; style != NULL; style=style->base()) {
query.addFromStyle(style);
} }
return query; return query;

View File

@ -27,7 +27,7 @@ namespace css {
void addRule(Rule* rule); void addRule(Rule* rule);
void addStyle(Style* style); void addStyle(Style* style);
Style* getStyle(const std::string& name); const Style* getStyle(const std::string& name);
Query query(const StatefulStyle& stateful); Query query(const StatefulStyle& stateful);
CompoundStyle compoundStyle(const std::string& name); CompoundStyle compoundStyle(const std::string& name);

View File

@ -28,6 +28,8 @@ namespace css {
typedef std::vector<const State*> List; typedef std::vector<const State*> List;
typedef List::iterator iterator; typedef List::iterator iterator;
typedef List::const_iterator const_iterator; typedef List::const_iterator const_iterator;
typedef List::reverse_iterator reverse_iterator;
typedef List::const_reverse_iterator const_reverse_iterator;
States() { } States() { }
States(const State& state) { States(const State& state) {
@ -36,9 +38,12 @@ namespace css {
iterator begin() { return m_list.begin(); } iterator begin() { return m_list.begin(); }
iterator end() { return m_list.end(); } iterator end() { return m_list.end(); }
const_iterator begin() const { return m_list.begin(); } const_iterator begin() const { return m_list.begin(); }
const_iterator end() const { return m_list.end(); } const_iterator end() const { return m_list.end(); }
reverse_iterator rbegin() { return m_list.rbegin(); }
reverse_iterator rend() { return m_list.rend(); }
const_reverse_iterator rbegin() const { return m_list.rbegin(); }
const_reverse_iterator rend() const { return m_list.rend(); }
States& operator+=(const State& other) { States& operator+=(const State& other) {
m_list.push_back(&other); m_list.push_back(&other);

View File

@ -12,7 +12,7 @@
namespace css { namespace css {
Style::Style(const std::string& name, Style* base) : Style::Style(const std::string& name, const Style* base) :
m_name(name), m_name(name),
m_base(base) { m_base(base) {
} }

View File

@ -19,12 +19,13 @@ namespace css {
class Style { class Style {
public: public:
typedef Values::iterator iterator; typedef Values::iterator iterator;
typedef Values::const_iterator const_iterator;
Style() { } Style() { }
Style(const std::string& name, Style* base = NULL); Style(const std::string& name, const Style* base = NULL);
const std::string& name() const { return m_name; } const std::string& name() const { return m_name; }
Style* base() const { return m_base; } const Style* base() const { return m_base; }
const Value& operator[](const Rule& rule) const { const Value& operator[](const Rule& rule) const {
return m_values[rule.name()]; return m_values[rule.name()];
@ -36,14 +37,16 @@ namespace css {
iterator begin() { return m_values.begin(); } iterator begin() { return m_values.begin(); }
iterator end() { return m_values.end(); } iterator end() { return m_values.end(); }
const_iterator begin() const { return m_values.begin(); }
const_iterator end() const { return m_values.end(); }
private: private:
std::string m_name; std::string m_name;
Style* m_base; const Style* m_base;
Values m_values; Values m_values;
}; };
typedef Map<Style*> Styles; typedef Map<const Style*> Styles;
} // namespace css } // namespace css

View File

@ -36,6 +36,9 @@ namespace css {
void setUnit(const std::string& unit = ""); void setUnit(const std::string& unit = "");
bool operator==(const Value& other) const; bool operator==(const Value& other) const;
bool operator!=(const Value& other) const {
return !operator==(other);
}
private: private:
Type m_type; Type m_type;