Add css library

This is a base library that will be used by SkinTheme to draw parts
with CSS styles (or something similar).
This commit is contained in:
David Capello 2013-12-03 19:31:36 -03:00
parent 61d5693727
commit 8e81fb808d
22 changed files with 1051 additions and 4 deletions

View File

@ -1,4 +1,4 @@
# ASEPRITE
# Aseprite
# Copyright (C) 2001-2013 David Capello
add_definitions(-DHAVE_CONFIG_H)
@ -11,9 +11,8 @@ if(MSVC)
endif(MSVC)
# Libraries in this directory
set(aseprite_libraries app-library raster-lib
scripting-lib undo-lib filters-lib ui-lib
she gfx-lib base-lib)
set(aseprite_libraries app-library css-lib raster-lib scripting-lib
undo-lib filters-lib ui-lib she gfx-lib base-lib)
# Directories where .h files can be found
include_directories(. .. ../third_party)
@ -150,6 +149,7 @@ endif()
add_subdirectory(base)
add_subdirectory(filters)
add_subdirectory(gfx)
add_subdirectory(css)
add_subdirectory(raster)
add_subdirectory(scripting)
add_subdirectory(she)
@ -244,6 +244,7 @@ endfunction()
find_unittests(base base-lib ${sys_libs})
find_unittests(gfx gfx-lib base-lib ${sys_libs})
find_unittests(raster raster-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_unittests(css css-lib gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_unittests(ui ui-lib she gfx-lib base-lib ${libs3rdparty} ${sys_libs})
find_unittests(file ${all_libs})
find_unittests(app ${all_libs})

View File

@ -15,6 +15,7 @@ because they don't depend on any other component.
* [allegro](allegro/): Modified version of [Allegro](http://alleg.sourceforge.net/) library, used for keyboard/mouse input, and drawing 2D graphics on screen.
* [base](base/): Core/basic stuff, multithreading, utf8, sha1, file system, memory, etc.
* [css](css/): Style sheet library.
* [gfx](gfx/): Abstract graphics structures like point, size, rectangle, region, color, etc.
* [scripting](scripting/): JavaScript engine ([V8](https://code.google.com/p/v8/)).
* [undo](undo/): Generic library to manage undo history of undoable actions.

10
src/css/CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
# Aseprite CSS Library
# Copyright (C) 2013 David Capello
add_library(css-lib
compound_style.cpp
query.cpp
rule.cpp
sheet.cpp
style.cpp
value.cpp)

20
src/css/LICENSE.txt Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2001-2013 David Capello
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

4
src/css/README.md Normal file
View File

@ -0,0 +1,4 @@
# Aseprite CSS Library
*Copyright (C) 2013 David Capello*
> Distributed under [MIT license](LICENSE.txt)

View File

@ -0,0 +1,69 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "css/compound_style.h"
#include "css/sheet.h"
namespace css {
CompoundStyle::CompoundStyle(Sheet* sheet, const std::string& name) :
m_sheet(sheet),
m_name(name)
{
update();
}
void CompoundStyle::update()
{
deleteQueries();
Style* style = m_sheet->getStyle(m_name);
if (style)
m_normal = m_sheet->query(*style);
}
CompoundStyle::~CompoundStyle()
{
deleteQueries();
}
void CompoundStyle::deleteQueries()
{
for (QueriesMap::iterator it = m_queries.begin(), end = m_queries.end();
it != end; ++it) {
delete it->second;
}
m_queries.clear();
}
const Value& CompoundStyle::operator[](const Rule& rule) const
{
return m_normal[rule];
}
const Query& CompoundStyle::operator[](const States& states) const
{
QueriesMap::const_iterator it = m_queries.find(states);
if (it != m_queries.end())
return *it->second;
else {
Style* style = m_sheet->getStyle(m_name);
if (style == NULL)
return m_normal;
Query* newQuery = new Query(m_sheet->query(StatefulStyle(*style, states)));
m_queries[states] = newQuery;
return *newQuery;
}
}
} // namespace css

42
src/css/compound_style.h Normal file
View File

@ -0,0 +1,42 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_COMPOUND_STYLE_H_INCLUDED
#define CSS_COMPOUND_STYLE_H_INCLUDED
#include "css/query.h"
#include "css/rule.h"
#include "css/state.h"
#include "css/stateful_style.h"
namespace css {
class Sheet;
class CompoundStyle {
public:
CompoundStyle(Sheet* sheet, const std::string& name);
~CompoundStyle();
void update();
const Value& operator[](const Rule& rule) const;
const Query& operator[](const States& states) const;
private:
typedef std::map<States, Query*> QueriesMap;
void deleteQueries();
Sheet* m_sheet;
std::string m_name;
Query m_normal;
mutable QueriesMap m_queries;
};
} // namespace css
#endif

19
src/css/css.h Normal file
View File

@ -0,0 +1,19 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_CSS_H_INCLUDED
#define CSS_CSS_H_INCLUDED
#include "css/compound_style.h"
#include "css/query.h"
#include "css/rule.h"
#include "css/sheet.h"
#include "css/state.h"
#include "css/stateful_style.h"
#include "css/style.h"
#include "css/value.h"
#endif

220
src/css/css_unittest.cpp Normal file
View File

@ -0,0 +1,220 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#include <gtest/gtest.h>
#include "css/css.h"
using namespace css;
using namespace std;
ostream& operator<<(ostream& os, const Value& value)
{
os << "(" << value.type();
if (value.type() == Value::Number)
os << ", " << value.number() << " [" << value.unit() << "]";
else if (value.type() == Value::String)
os << ", " << value.string();
os << ")";
return os;
}
TEST(Css, Style)
{
Rule background("background");
Rule text("text");
Rule border("border");
Style style("style");
style[background] = Value("image.png");
style[text] = Value("hi");
style[border] = Value(12.0, "px");
EXPECT_EQ(Value("image.png"), style[background]);
EXPECT_EQ(Value("hi"), style[text]);
EXPECT_EQ(Value(12.0, "px"), style[border]);
style[border].setNumber(13.0);
EXPECT_EQ(Value(13.0, "px"), style[border]);
Style style2("style2", &style);
EXPECT_EQ(&style, style2.base());
EXPECT_EQ(Value(), style2[background]);
EXPECT_EQ(Value(), style2[text]);
EXPECT_EQ(Value(), style2[border]);
}
TEST(Css, QueryIsInSyncWithStyleSheet)
{
Rule background("background");
Sheet sheet;
sheet.addRule(&background);
Style style("style");
style[background] = Value("a.png");
sheet.addStyle(&style);
Query query = sheet.query(style);
EXPECT_EQ(Value("a.png"), query[background]);
style[background] = Value("b.png");
EXPECT_EQ(Value("b.png"), query[background]);
}
TEST(Css, StatefulStyles)
{
Rule background("background");
Rule text("text");
Rule border("border");
State hover("hover");
State focus("focus");
State active("active");
Style base("base");
Style baseHover("base:hover");
Style baseFocus("base:focus");
Style baseActive("base:active");
base[background] = Value("image.png");
base[text] = Value("textnormal");
baseHover[text] = Value("texthover");
baseFocus[border] = Value(12.0);
baseActive[border] = Value(24.0);
Sheet sheet;
sheet.addRule(&background);
sheet.addRule(&text);
sheet.addRule(&border);
sheet.addStyle(&base);
sheet.addStyle(&baseHover);
sheet.addStyle(&baseFocus);
sheet.addStyle(&baseActive);
Query query = sheet.query(base);
EXPECT_EQ(Value("image.png"), query[background]);
EXPECT_EQ(Value("textnormal"), query[text]);
query = sheet.query(base + hover);
EXPECT_EQ(Value("image.png"), query[background]);
EXPECT_EQ(Value("texthover"), query[text]);
query = sheet.query(base + focus);
EXPECT_EQ(Value("image.png"), query[background]);
EXPECT_EQ(Value("textnormal"), query[text]);
EXPECT_EQ(Value(12.0), query[border]);
query = sheet.query(base + focus + hover);
EXPECT_EQ(Value("image.png"), query[background]);
EXPECT_EQ(Value("texthover"), query[text]);
EXPECT_EQ(Value(12.0), query[border]);
query = sheet.query(base + focus + hover + active);
EXPECT_EQ(Value("image.png"), query[background]);
EXPECT_EQ(Value("texthover"), query[text]);
EXPECT_EQ(Value(24.0), query[border]);
query = sheet.query(base + active + focus + hover); // Different order
EXPECT_EQ(Value("image.png"), query[background]);
EXPECT_EQ(Value("texthover"), query[text]);
EXPECT_EQ(Value(12.0), query[border]);
}
TEST(Css, StyleHierarchy)
{
Rule bg("bg");
Rule fg("fg");
State hover("hover");
State focus("focus");
Style base("base");
Style stylea("stylea", &base);
Style styleb("styleb", &stylea);
Style stylec("stylec", &styleb);
base[bg] = Value(1);
base[fg] = Value(2);
stylea[bg] = Value(3);
styleb[bg] = Value(4);
styleb[fg] = Value(5);
stylec[bg] = Value(6);
Sheet sheet;
sheet.addRule(&bg);
sheet.addRule(&fg);
sheet.addStyle(&base);
sheet.addStyle(&stylea);
sheet.addStyle(&styleb);
sheet.addStyle(&stylec);
Query query = sheet.query(base);
EXPECT_EQ(Value(1), query[bg]);
EXPECT_EQ(Value(2), query[fg]);
query = sheet.query(stylea);
EXPECT_EQ(Value(3), query[bg]);
EXPECT_EQ(Value(2), query[fg]);
query = sheet.query(styleb);
EXPECT_EQ(Value(4), query[bg]);
EXPECT_EQ(Value(5), query[fg]);
query = sheet.query(stylec);
EXPECT_EQ(Value(6), query[bg]);
EXPECT_EQ(Value(5), query[fg]);
}
TEST(Css, CompoundStyles)
{
Rule bg("bg");
Rule fg("fg");
State hover("hover");
State focus("focus");
Style base("base");
Style baseHover("base:hover");
Style baseFocus("base:focus");
Style sub("sub", &base);
Style subFocus("sub:focus", &base);
base[bg] = Value(1);
base[fg] = Value(2);
baseHover[fg] = Value(3);
baseFocus[bg] = Value(4);
sub[bg] = Value(5);
subFocus[fg] = Value(6);
Sheet sheet;
sheet.addRule(&bg);
sheet.addRule(&fg);
sheet.addStyle(&base);
sheet.addStyle(&baseHover);
sheet.addStyle(&baseFocus);
sheet.addStyle(&sub);
sheet.addStyle(&subFocus);
CompoundStyle compoundBase = sheet.compoundStyle("base");
EXPECT_EQ(Value(1), compoundBase[bg]);
EXPECT_EQ(Value(2), compoundBase[fg]);
EXPECT_EQ(Value(1), compoundBase[hover][bg]);
EXPECT_EQ(Value(3), compoundBase[hover][fg]);
EXPECT_EQ(Value(4), compoundBase[focus][bg]);
EXPECT_EQ(Value(2), compoundBase[focus][fg]);
EXPECT_EQ(Value(4), compoundBase[hover+focus][bg]);
EXPECT_EQ(Value(3), compoundBase[hover+focus][fg]);
CompoundStyle compoundSub = sheet.compoundStyle("sub");
EXPECT_EQ(Value(5), compoundSub[bg]);
EXPECT_EQ(Value(2), compoundSub[fg]);
EXPECT_EQ(Value(5), compoundSub[hover][bg]);
EXPECT_EQ(Value(3), compoundSub[hover][fg]);
EXPECT_EQ(Value(4), compoundSub[focus][bg]);
EXPECT_EQ(Value(6), compoundSub[focus][fg]);
EXPECT_EQ(Value(4), compoundSub[hover+focus][bg]);
EXPECT_EQ(Value(6), compoundSub[hover+focus][fg]);
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

57
src/css/map.h Normal file
View File

@ -0,0 +1,57 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_MAP_H_INCLUDED
#define CSS_MAP_H_INCLUDED
#include <map>
#include <string>
namespace css {
template<typename T>
class Map {
public:
typedef std::map<std::string, T> map;
typedef typename map::iterator iterator;
typedef typename map::const_iterator const_iterator;
Map() : m_default() { }
iterator begin() { return m_map.begin(); }
iterator end() { return m_map.end(); }
const_iterator begin() const { return m_map.begin(); }
const_iterator end() const { return m_map.end(); }
const T& operator[](const std::string& name) const {
const_iterator it = m_map.find(name);
if (it != m_map.end())
return it->second;
else
return m_default;
}
T& operator[](const std::string& name) {
iterator it = m_map.find(name);
if (it != m_map.end())
return it->second;
else
return m_map[name] = T();
}
void add(const std::string& name, T value) {
m_map[name] = value;
}
private:
map m_map;
T m_default;
};
} // namespace css
#endif

28
src/css/query.cpp Normal file
View File

@ -0,0 +1,28 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "css/query.h"
namespace css {
void Query::addRuleValue(const std::string& ruleName, Style* style)
{
m_ruleValue.add(ruleName, style);
}
void Query::addFromStyle(Style* style)
{
for (Style::iterator it = style->begin(), end = style->end();
it != end; ++it) {
addRuleValue(it->first, style);
}
}
} // namespace css

40
src/css/query.h Normal file
View File

@ -0,0 +1,40 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_QUERY_H_INCLUDED
#define CSS_QUERY_H_INCLUDED
#include "css/rule.h"
#include "css/style.h"
#include "css/value.h"
#include <map>
namespace css {
class Query {
public:
Query() { }
void addRuleValue(const std::string& ruleName, Style* style);
void addFromStyle(Style* style);
const Value& operator[](const Rule& rule) const {
Style* style = m_ruleValue[rule.name()];
if (style)
return (*style)[rule.name()];
else
return m_none;
}
private:
Styles m_ruleValue;
Value m_none;
};
} // namespace css
#endif

20
src/css/rule.cpp Normal file
View File

@ -0,0 +1,20 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "css/rule.h"
namespace css {
Rule::Rule(const std::string& name) :
m_name(name)
{
}
} // namespace css

32
src/css/rule.h Normal file
View File

@ -0,0 +1,32 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_RULE_H_INCLUDED
#define CSS_RULE_H_INCLUDED
#include "css/map.h"
#include <map>
#include <string>
namespace css {
class Rule {
public:
Rule() { }
Rule(const std::string& name);
const std::string& name() const { return m_name; }
private:
std::string m_name;
};
typedef Map<Rule*> Rules;
} // namespace css
#endif

80
src/css/sheet.cpp Normal file
View File

@ -0,0 +1,80 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "css/sheet.h"
#include "css/compound_style.h"
#include "css/query.h"
#include "css/stateful_style.h"
namespace css {
Sheet::Sheet()
{
}
void Sheet::addRule(Rule* rule)
{
m_rules.add(rule->name(), rule);
}
void Sheet::addStyle(Style* style)
{
m_styles.add(style->name(), style);
}
Style* Sheet::getStyle(const std::string& name)
{
return m_styles[name];
}
Query Sheet::query(const StatefulStyle& compound)
{
Query query;
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);
}
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);
}
name = compound.style().name();
name += StatefulStyle::kSeparator;
name += (*it)->name();
style = m_styles[name];
if (style)
query.addFromStyle(style);
}
return query;
}
CompoundStyle Sheet::compoundStyle(const std::string& name)
{
return CompoundStyle(this, name);
}
} // namespace css

42
src/css/sheet.h Normal file
View File

@ -0,0 +1,42 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_SHEET_H_INCLUDED
#define CSS_SHEET_H_INCLUDED
#include "css/rule.h"
#include "css/style.h"
#include "css/value.h"
#include <map>
#include <string>
namespace css {
class CompoundStyle;
class Query;
class StatefulStyle;
class Sheet {
public:
Sheet();
void addRule(Rule* rule);
void addStyle(Style* style);
Style* getStyle(const std::string& name);
Query query(const StatefulStyle& stateful);
CompoundStyle compoundStyle(const std::string& name);
private:
Rules m_rules;
Styles m_styles;
};
} // namespace css
#endif

71
src/css/state.h Normal file
View File

@ -0,0 +1,71 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_STATE_H_INCLUDED
#define CSS_STATE_H_INCLUDED
#include <string>
#include <vector>
namespace css {
class State {
public:
State() { }
State(const std::string& name) : m_name(name) { }
const std::string& name() const { return m_name; }
private:
std::string m_name;
};
class States {
public:
typedef std::vector<const State*> List;
typedef List::iterator iterator;
typedef List::const_iterator const_iterator;
States() { }
States(const State& state) {
operator+=(state);
}
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(); }
States& operator+=(const State& other) {
m_list.push_back(&other);
return *this;
}
States& operator+=(const States& others) {
for (const_iterator it=others.begin(), end=others.end(); it != end; ++it)
operator+=(*(*it));
return *this;
}
bool operator<(const States& other) const {
return m_list < other.m_list;
}
private:
List m_list;
};
inline States operator+(const State& a, const State& b) {
States states;
states += a;
states += b;
return states;
}
} // namespace css
#endif

73
src/css/stateful_style.h Normal file
View File

@ -0,0 +1,73 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_STATEFUL_STYLE_H_INCLUDED
#define CSS_STATEFUL_STYLE_H_INCLUDED
#include "css/rule.h"
#include "css/state.h"
#include "css/style.h"
#include "css/value.h"
namespace css {
class StatefulStyle {
public:
static const char kSeparator = ':';
StatefulStyle() : m_style(NULL) { }
StatefulStyle(const Style& style) : m_style(&style) { }
StatefulStyle(const State& state) {
operator+=(state);
}
StatefulStyle(const Style& style, const States& states) :
m_style(&style) {
operator+=(states);
}
const Style& style() const { return *m_style; }
const States& states() const { return m_states; }
StatefulStyle& setStyle(const Style& style) {
m_style = &style;
return *this;
}
StatefulStyle& operator+=(const State& state) {
m_states += state;
return *this;
}
StatefulStyle& operator+=(const States& states) {
m_states += states;
return *this;
}
private:
const Style* m_style;
States m_states;
};
inline StatefulStyle operator+(const Style& style, const State& state) {
StatefulStyle styleState;
styleState.setStyle(style);
styleState += state;
return styleState;
}
inline StatefulStyle operator+(StatefulStyle& styleState, const State& state) {
StatefulStyle styleState2 = styleState;
styleState2 += state;
return styleState2;
}
inline StatefulStyle operator+(StatefulStyle& styleState, const States& states) {
StatefulStyle styleState2 = styleState;
styleState2 += states;
return styleState2;
}
} // namespace css
#endif

20
src/css/style.cpp Normal file
View File

@ -0,0 +1,20 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "css/style.h"
namespace css {
Style::Style(const std::string& name, Style* base) :
m_name(name),
m_base(base) {
}
} // namespace css

50
src/css/style.h Normal file
View File

@ -0,0 +1,50 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_STYLE_H_INCLUDED
#define CSS_STYLE_H_INCLUDED
#include <map>
#include <string>
#include "css/map.h"
#include "css/rule.h"
#include "css/value.h"
namespace css {
class Style {
public:
typedef Values::iterator iterator;
Style() { }
Style(const std::string& name, Style* base = NULL);
const std::string& name() const { return m_name; }
Style* base() const { return m_base; }
const Value& operator[](const Rule& rule) const {
return m_values[rule.name()];
}
Value& operator[](const Rule& rule) {
return m_values[rule.name()];
}
iterator begin() { return m_values.begin(); }
iterator end() { return m_values.end(); }
private:
std::string m_name;
Style* m_base;
Values m_values;
};
typedef Map<Style*> Styles;
} // namespace css
#endif

98
src/css/value.cpp Normal file
View File

@ -0,0 +1,98 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "css/value.h"
namespace css {
Value::Value() :
m_type(None)
{
}
Value::Value(double value, const std::string& unit) :
m_type(Number),
m_number(value),
m_string(unit)
{
}
Value::Value(const std::string& value) :
m_type(String),
m_string(value)
{
}
double Value::number() const
{
if (m_type == Number)
return m_number;
else
return 0.0;
}
std::string Value::string() const
{
if (m_type == String)
return m_string;
else
return std::string();
}
std::string Value::unit() const
{
if (m_type == Number)
return m_string;
else
return std::string();
}
void Value::setNumber(double value)
{
if (m_type != Number) {
m_type = Number;
m_string = "";
}
m_number = value;
}
void Value::setString(const std::string& value)
{
m_type = String;
m_string = value;
}
void Value::setUnit(const std::string& unit)
{
if (m_type != Number) {
m_type = Number;
m_number = 0.0;
}
m_string = unit;
}
bool Value::operator==(const Value& other) const
{
if (m_type != other.m_type)
return false;
switch (m_type) {
case None:
return true;
case Number:
return m_number == other.m_number && m_string == other.m_string;
case String:
return m_string == other.m_string;
default:
return false;
}
}
} // namespace css

50
src/css/value.h Normal file
View File

@ -0,0 +1,50 @@
// Aseprite CSS Library
// Copyright (C) 2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef CSS_VALUE_H_INCLUDED
#define CSS_VALUE_H_INCLUDED
#include "css/map.h"
#include <string>
namespace css {
class Value {
public:
enum Type {
None,
Number,
String
};
Value();
explicit Value(double value, const std::string& unit = "");
explicit Value(const std::string& value);
Type type() const { return m_type; }
double number() const;
std::string string() const;
std::string unit() const;
void setNumber(double value);
void setString(const std::string& value);
void setUnit(const std::string& unit = "");
bool operator==(const Value& other) const;
private:
Type m_type;
double m_number;
std::string m_string;
};
typedef Map<Value> Values;
} // namespace css
#endif