mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-01 01:20:25 +00:00
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:
parent
61d5693727
commit
8e81fb808d
@ -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})
|
||||
|
@ -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
10
src/css/CMakeLists.txt
Normal 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
20
src/css/LICENSE.txt
Normal 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
4
src/css/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Aseprite CSS Library
|
||||
*Copyright (C) 2013 David Capello*
|
||||
|
||||
> Distributed under [MIT license](LICENSE.txt)
|
69
src/css/compound_style.cpp
Normal file
69
src/css/compound_style.cpp
Normal 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
42
src/css/compound_style.h
Normal 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
19
src/css/css.h
Normal 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
220
src/css/css_unittest.cpp
Normal 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
57
src/css/map.h
Normal 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
28
src/css/query.cpp
Normal 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
40
src/css/query.h
Normal 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
20
src/css/rule.cpp
Normal 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
32
src/css/rule.h
Normal 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
80
src/css/sheet.cpp
Normal 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
42
src/css/sheet.h
Normal 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
71
src/css/state.h
Normal 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
73
src/css/stateful_style.h
Normal 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
20
src/css/style.cpp
Normal 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
50
src/css/style.h
Normal 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
98
src/css/value.cpp
Normal 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
50
src/css/value.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user