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

View File

@ -174,6 +174,9 @@ TEST(Css, CompoundStyles)
Style baseFocus("base:focus");
Style sub("sub", &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[fg] = Value(2);
@ -183,6 +186,9 @@ TEST(Css, CompoundStyles)
sub[bg] = Value(5);
subFocus[fg] = Value(6);
sub3[bg] = Value(7);
sub3FocusHover[fg] = Value(8);
Sheet sheet;
sheet.addRule(&bg);
sheet.addRule(&fg);
@ -191,6 +197,9 @@ TEST(Css, CompoundStyles)
sheet.addStyle(&baseFocus);
sheet.addStyle(&sub);
sheet.addStyle(&subFocus);
sheet.addStyle(&sub2);
sheet.addStyle(&sub3);
sheet.addStyle(&sub3FocusHover);
CompoundStyle compoundBase = sheet.compoundStyle("base");
EXPECT_EQ(Value(1), compoundBase[bg]);
@ -211,6 +220,27 @@ TEST(Css, CompoundStyles)
EXPECT_EQ(Value(6), compoundSub[focus][fg]);
EXPECT_EQ(Value(4), compoundSub[hover+focus][bg]);
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)

View File

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

View File

@ -12,17 +12,18 @@
namespace css {
void Query::addRuleValue(const std::string& ruleName, Style* style)
void Query::addFromStyle(const Style* style)
{
m_ruleValue.add(ruleName, style);
}
void Query::addFromStyle(Style* style)
{
for (Style::iterator it = style->begin(), end = style->end();
for (Style::const_iterator it = style->begin(), end = style->end();
it != end; ++it) {
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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