mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-10 03:44:16 +00:00
Merge branch 'timeline' into dev
This commit is contained in:
commit
b5ea9fd7e7
Binary file not shown.
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 11 KiB |
@ -63,6 +63,17 @@
|
|||||||
<color id="filelist_selected_row_face" value="#2c4c91" />
|
<color id="filelist_selected_row_face" value="#2c4c91" />
|
||||||
<color id="filelist_disabled_row_text" value="#ffc8c8" />
|
<color id="filelist_disabled_row_text" value="#ffc8c8" />
|
||||||
<color id="workspace" value="#7d929e" />
|
<color id="workspace" value="#7d929e" />
|
||||||
|
<color id="timeline_normal" value="#c6c6c6" />
|
||||||
|
<color id="timeline_normal_text" value="#000000" />
|
||||||
|
<color id="timeline_hover" value="#d9d9d9" />
|
||||||
|
<color id="timeline_hover_text" value="#000000" />
|
||||||
|
<color id="timeline_active" value="#7d929e" />
|
||||||
|
<color id="timeline_active_text" value="#ffffff" />
|
||||||
|
<color id="timeline_active_hover" value="#99b3c2" />
|
||||||
|
<color id="timeline_active_hover_text" value="#ffffff" />
|
||||||
|
<color id="timeline_clicked" value="#536069" />
|
||||||
|
<color id="timeline_clicked_text" value="#ffffff" />
|
||||||
|
<color id="timeline_padding" value="#7d929e" />
|
||||||
</colors>
|
</colors>
|
||||||
|
|
||||||
<cursors>
|
<cursors>
|
||||||
@ -80,14 +91,14 @@
|
|||||||
<cursor id="size_bl" x="80" y="176" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="size_bl" x="80" y="176" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="size_b" x="80" y="192" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="size_b" x="80" y="192" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="size_br" x="80" y="208" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="size_br" x="80" y="208" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_tl" x="240" y="96" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_tl" x="240" y="160" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_t" x="240" y="112" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_tr" x="256" y="160" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_tr" x="240" y="128" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_l" x="240" y="176" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_l" x="240" y="144" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_r" x="256" y="176" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_r" x="240" y="160" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_t" x="240" y="192" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_bl" x="240" y="176" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_b" x="256" y="192" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_b" x="240" y="192" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_bl" x="240" y="208" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="rotate_br" x="240" y="208" w="16" h="16" focusx="8" focusy="8" />
|
<cursor id="rotate_br" x="256" y="208" w="16" h="16" focusx="8" focusy="8" />
|
||||||
<cursor id="eyedropper" x="80" y="224" w="16" h="16" focusx="0" focusy="15" />
|
<cursor id="eyedropper" x="80" y="224" w="16" h="16" focusx="0" focusy="15" />
|
||||||
</cursors>
|
</cursors>
|
||||||
|
|
||||||
@ -259,6 +270,133 @@
|
|||||||
<part id="drop_down_button_right_selected" x="71" y="48" w1="2" w2="2" w3="3" h1="4" h2="6" h3="6" />
|
<part id="drop_down_button_right_selected" x="71" y="48" w1="2" w2="2" w3="3" h1="4" h2="6" h3="6" />
|
||||||
<part id="transformation_handle" x="208" y="144" w="5" h="5" />
|
<part id="transformation_handle" x="208" y="144" w="5" h="5" />
|
||||||
<part id="pivot_handle" x="224" y="144" w="9" h="9" />
|
<part id="pivot_handle" x="224" y="144" w="9" h="9" />
|
||||||
|
<part id="timeline_normal" x="240" y="0" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_active" x="252" y="0" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_hover" x="264" y="0" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_active_hover" x="276" y="0" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_clicked" x="288" y="0" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_open_eye_normal" x="240" y="12" w="12" h="12" />
|
||||||
|
<part id="timeline_open_eye_active" x="252" y="12" w="12" h="12" />
|
||||||
|
<part id="timeline_closed_eye_normal" x="240" y="24" w="12" h="12" />
|
||||||
|
<part id="timeline_closed_eye_active" x="252" y="24" w="12" h="12" />
|
||||||
|
<part id="timeline_open_padlock_normal" x="240" y="36" w="12" h="12" />
|
||||||
|
<part id="timeline_open_padlock_active" x="252" y="36" w="12" h="12" />
|
||||||
|
<part id="timeline_closed_padlock_normal" x="240" y="48" w="12" h="12" />
|
||||||
|
<part id="timeline_closed_padlock_active" x="252" y="48" w="12" h="12" />
|
||||||
|
<part id="timeline_empty_frame_normal" x="240" y="60" w="12" h="12" />
|
||||||
|
<part id="timeline_empty_frame_active" x="252" y="60" w="12" h="12" />
|
||||||
|
<part id="timeline_keyframe_normal" x="240" y="72" w="12" h="12" />
|
||||||
|
<part id="timeline_keyframe_active" x="252" y="72" w="12" h="12" />
|
||||||
|
<part id="timeline_fromleft_normal" x="240" y="84" w="12" h="12" />
|
||||||
|
<part id="timeline_fromleft_active" x="252" y="84" w="12" h="12" />
|
||||||
|
<part id="timeline_fromright_normal" x="240" y="96" w="12" h="12" />
|
||||||
|
<part id="timeline_fromright_active" x="252" y="96" w="12" h="12" />
|
||||||
|
<part id="timeline_fromboth_normal" x="240" y="108" w="12" h="12" />
|
||||||
|
<part id="timeline_fromboth_active" x="252" y="108" w="12" h="12" />
|
||||||
|
<part id="timeline_gear" x="264" y="12" w="12" h="12" />
|
||||||
|
<part id="timeline_padding" x="276" y="12" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_padding_tr" x="288" y="12" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_padding_bl" x="276" y="24" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
|
<part id="timeline_padding_br" x="288" y="24" w1="2" w2="8" w3="2" h1="2" h2="8" h3="2" />
|
||||||
</parts>
|
</parts>
|
||||||
|
|
||||||
|
<stylesheet>
|
||||||
|
|
||||||
|
<!-- timeline -->
|
||||||
|
<style id="timeline">
|
||||||
|
<background color="timeline_normal" part="timeline_normal" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_box -->
|
||||||
|
<style id="timeline_box">
|
||||||
|
<background color="timeline_normal" part="timeline_normal" />
|
||||||
|
<text color="timeline_normal_text" align="center" valign="middle" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_box:hover">
|
||||||
|
<background color="timeline_hover" part="timeline_hover" />
|
||||||
|
<text color="timeline_hover_text" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_box:active">
|
||||||
|
<background color="timeline_active" part="timeline_active" />
|
||||||
|
<text color="timeline_active_text" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_box:active:hover">
|
||||||
|
<background color="timeline_active_hover" part="timeline_active_hover" />
|
||||||
|
<text color="timeline_active_hover_text" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_box:clicked">
|
||||||
|
<background color="timeline_clicked" part="timeline_clicked" />
|
||||||
|
<text color="timeline_clicked_text" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_eye -->
|
||||||
|
<style id="timeline_open_eye" base="timeline_box">
|
||||||
|
<icon part="timeline_open_eye_normal" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_open_eye:active">
|
||||||
|
<icon part="timeline_open_eye_active" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_closed_eye" base="timeline_box">
|
||||||
|
<icon part="timeline_closed_eye_normal" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_closed_eye:active">
|
||||||
|
<icon part="timeline_closed_eye_active" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_padlock -->
|
||||||
|
<style id="timeline_open_padlock" base="timeline_box">
|
||||||
|
<icon part="timeline_open_padlock_normal" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_open_padlock:active">
|
||||||
|
<icon part="timeline_open_padlock_active" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_closed_padlock" base="timeline_box">
|
||||||
|
<icon part="timeline_closed_padlock_normal" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_closed_padlock:active">
|
||||||
|
<icon part="timeline_closed_padlock_active" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_layer -->
|
||||||
|
<style id="timeline_layer" base="timeline_box">
|
||||||
|
<text align="left" valign="middle" padding-left="4" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_empty_frame -->
|
||||||
|
<style id="timeline_empty_frame" base="timeline_box">
|
||||||
|
<icon part="timeline_empty_frame_normal" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_empty_frame:active">
|
||||||
|
<icon part="timeline_empty_frame_active" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!--timeline_keyframe-->
|
||||||
|
<style id="timeline_keyframe" base="timeline_box">
|
||||||
|
<icon part="timeline_keyframe_normal" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_keyframe:active">
|
||||||
|
<icon part="timeline_keyframe_active" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_cel -->
|
||||||
|
<style id="timeline_gear" base="timeline_box">
|
||||||
|
<icon part="timeline_gear" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- paddings -->
|
||||||
|
<style id="timeline_padding">
|
||||||
|
<background color="timeline_normal" part="timeline_padding" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_padding_tr">
|
||||||
|
<background color="timeline_normal" part="timeline_padding_tr" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_padding_bl">
|
||||||
|
<background color="timeline_normal" part="timeline_padding_bl" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_padding_br">
|
||||||
|
<background color="timeline_normal" part="timeline_padding_br" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</stylesheet>
|
||||||
|
|
||||||
</skin>
|
</skin>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# ASEPRITE
|
# Aseprite
|
||||||
# Copyright (C) 2001-2013 David Capello
|
# Copyright (C) 2001-2013 David Capello
|
||||||
|
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
add_definitions(-DHAVE_CONFIG_H)
|
||||||
@ -11,9 +11,8 @@ if(MSVC)
|
|||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
# Libraries in this directory
|
# Libraries in this directory
|
||||||
set(aseprite_libraries app-library raster-lib
|
set(aseprite_libraries app-library css-lib raster-lib scripting-lib
|
||||||
scripting-lib undo-lib filters-lib ui-lib
|
undo-lib filters-lib ui-lib she gfx-lib base-lib)
|
||||||
she gfx-lib base-lib)
|
|
||||||
|
|
||||||
# Directories where .h files can be found
|
# Directories where .h files can be found
|
||||||
include_directories(. .. ../third_party)
|
include_directories(. .. ../third_party)
|
||||||
@ -150,6 +149,7 @@ endif()
|
|||||||
add_subdirectory(base)
|
add_subdirectory(base)
|
||||||
add_subdirectory(filters)
|
add_subdirectory(filters)
|
||||||
add_subdirectory(gfx)
|
add_subdirectory(gfx)
|
||||||
|
add_subdirectory(css)
|
||||||
add_subdirectory(raster)
|
add_subdirectory(raster)
|
||||||
add_subdirectory(scripting)
|
add_subdirectory(scripting)
|
||||||
add_subdirectory(she)
|
add_subdirectory(she)
|
||||||
@ -244,6 +244,7 @@ endfunction()
|
|||||||
find_unittests(base base-lib ${sys_libs})
|
find_unittests(base base-lib ${sys_libs})
|
||||||
find_unittests(gfx gfx-lib 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(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(ui ui-lib she gfx-lib base-lib ${libs3rdparty} ${sys_libs})
|
||||||
find_unittests(file ${all_libs})
|
find_unittests(file ${all_libs})
|
||||||
find_unittests(app ${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.
|
* [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.
|
* [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.
|
* [gfx](gfx/): Abstract graphics structures like point, size, rectangle, region, color, etc.
|
||||||
* [scripting](scripting/): JavaScript engine ([V8](https://code.google.com/p/v8/)).
|
* [scripting](scripting/): JavaScript engine ([V8](https://code.google.com/p/v8/)).
|
||||||
* [undo](undo/): Generic library to manage undo history of undoable actions.
|
* [undo](undo/): Generic library to manage undo history of undoable actions.
|
||||||
|
@ -177,9 +177,12 @@ add_library(app-library
|
|||||||
ui/palette_view.cpp
|
ui/palette_view.cpp
|
||||||
ui/popup_window_pin.cpp
|
ui/popup_window_pin.cpp
|
||||||
ui/skin/button_icon_impl.cpp
|
ui/skin/button_icon_impl.cpp
|
||||||
|
ui/skin/skin_part.cpp
|
||||||
ui/skin/skin_property.cpp
|
ui/skin/skin_property.cpp
|
||||||
ui/skin/skin_slider_property.cpp
|
ui/skin/skin_slider_property.cpp
|
||||||
ui/skin/skin_theme.cpp
|
ui/skin/skin_theme.cpp
|
||||||
|
ui/skin/style.cpp
|
||||||
|
ui/skin/style_sheet.cpp
|
||||||
ui/status_bar.cpp
|
ui/status_bar.cpp
|
||||||
ui/tabs.cpp
|
ui/tabs.cpp
|
||||||
ui/timeline.cpp
|
ui/timeline.cpp
|
||||||
|
@ -404,30 +404,17 @@ void setup_mini_look(Widget* widget)
|
|||||||
|
|
||||||
void setup_look(Widget* widget, LookType lookType)
|
void setup_look(Widget* widget, LookType lookType)
|
||||||
{
|
{
|
||||||
SharedPtr<SkinProperty> skinProp;
|
SkinPropertyPtr skinProp = get_skin_property(widget);
|
||||||
|
|
||||||
skinProp = widget->getProperty(SkinProperty::SkinPropertyName);
|
|
||||||
if (skinProp == NULL)
|
|
||||||
skinProp.reset(new SkinProperty);
|
|
||||||
|
|
||||||
skinProp->setLook(lookType);
|
skinProp->setLook(lookType);
|
||||||
widget->setProperty(skinProp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4)
|
void setup_bevels(Widget* widget, int b1, int b2, int b3, int b4)
|
||||||
{
|
{
|
||||||
SharedPtr<SkinProperty> skinProp;
|
SkinPropertyPtr skinProp = get_skin_property(widget);
|
||||||
|
|
||||||
skinProp = widget->getProperty(SkinProperty::SkinPropertyName);
|
|
||||||
if (skinProp == NULL)
|
|
||||||
skinProp.reset(new SkinProperty);
|
|
||||||
|
|
||||||
skinProp->setUpperLeft(b1);
|
skinProp->setUpperLeft(b1);
|
||||||
skinProp->setUpperRight(b2);
|
skinProp->setUpperRight(b2);
|
||||||
skinProp->setLowerLeft(b3);
|
skinProp->setLowerLeft(b3);
|
||||||
skinProp->setLowerRight(b4);
|
skinProp->setLowerRight(b4);
|
||||||
|
|
||||||
widget->setProperty(skinProp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the IconInterface pointer interface of the button to show the
|
// Sets the IconInterface pointer interface of the button to show the
|
||||||
|
@ -128,7 +128,7 @@ void ColorSliders::addSlider(Channel channel, const char* labelText, int min, in
|
|||||||
m_entry.push_back(entry);
|
m_entry.push_back(entry);
|
||||||
m_channel.push_back(channel);
|
m_channel.push_back(channel);
|
||||||
|
|
||||||
slider->setProperty(PropertyPtr(new SkinSliderProperty(new ColorSliderBgPainter(channel))));
|
slider->setProperty(SkinSliderPropertyPtr(new SkinSliderProperty(new ColorSliderBgPainter(channel))));
|
||||||
slider->setDoubleBuffered(true);
|
slider->setDoubleBuffered(true);
|
||||||
|
|
||||||
slider->Change.connect(Bind<void>(&ColorSliders::onSliderChange, this, m_slider.size()-1));
|
slider->Change.connect(Bind<void>(&ColorSliders::onSliderChange, this, m_slider.size()-1));
|
||||||
@ -201,7 +201,7 @@ void ColorSliders::updateSlidersBgColor(const app::Color& color)
|
|||||||
|
|
||||||
void ColorSliders::updateSliderBgColor(Slider* slider, const app::Color& color)
|
void ColorSliders::updateSliderBgColor(Slider* slider, const app::Color& color)
|
||||||
{
|
{
|
||||||
SharedPtr<SkinSliderProperty> sliderProperty(slider->getProperty("SkinProperty"));
|
SkinSliderPropertyPtr sliderProperty(slider->getProperty(SkinSliderProperty::Name));
|
||||||
|
|
||||||
static_cast<ColorSliderBgPainter*>(sliderProperty->getBgPainter())->setColor(color);
|
static_cast<ColorSliderBgPainter*>(sliderProperty->getBgPainter())->setColor(color);
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ namespace app {
|
|||||||
template<typename Base = ui::Button>
|
template<typename Base = ui::Button>
|
||||||
class SkinButton : public Base {
|
class SkinButton : public Base {
|
||||||
public:
|
public:
|
||||||
SkinButton(SkinPart partNormal,
|
SkinButton(SkinParts partNormal,
|
||||||
SkinPart partHot,
|
SkinParts partHot,
|
||||||
SkinPart partSelected)
|
SkinParts partSelected)
|
||||||
: Base("")
|
: Base("")
|
||||||
, m_partNormal(partNormal)
|
, m_partNormal(partNormal)
|
||||||
, m_partHot(partHot)
|
, m_partHot(partHot)
|
||||||
@ -41,9 +41,9 @@ namespace app {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void setParts(SkinPart partNormal,
|
void setParts(SkinParts partNormal,
|
||||||
SkinPart partHot,
|
SkinParts partHot,
|
||||||
SkinPart partSelected) {
|
SkinParts partSelected) {
|
||||||
m_partNormal = partNormal;
|
m_partNormal = partNormal;
|
||||||
m_partHot = partHot;
|
m_partHot = partHot;
|
||||||
m_partSelected = partSelected;
|
m_partSelected = partSelected;
|
||||||
@ -55,7 +55,7 @@ namespace app {
|
|||||||
gfx::Rect bounds(Base::getClientBounds());
|
gfx::Rect bounds(Base::getClientBounds());
|
||||||
ui::Graphics* g = ev.getGraphics();
|
ui::Graphics* g = ev.getGraphics();
|
||||||
SkinTheme* theme = static_cast<SkinTheme*>(Base::getTheme());
|
SkinTheme* theme = static_cast<SkinTheme*>(Base::getTheme());
|
||||||
SkinPart part;
|
SkinParts part;
|
||||||
|
|
||||||
if (Base::isSelected())
|
if (Base::isSelected())
|
||||||
part = m_partSelected;
|
part = m_partSelected;
|
||||||
@ -68,9 +68,9 @@ namespace app {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkinPart m_partNormal;
|
SkinParts m_partNormal;
|
||||||
SkinPart m_partHot;
|
SkinParts m_partHot;
|
||||||
SkinPart m_partSelected;
|
SkinParts m_partSelected;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace skin
|
} // namespace skin
|
||||||
|
63
src/app/ui/skin/skin_part.cpp
Normal file
63
src/app/ui/skin/skin_part.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/ui/skin/skin_part.h"
|
||||||
|
|
||||||
|
#include <allegro.h>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace skin {
|
||||||
|
|
||||||
|
SkinPart::SkinPart()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SkinPart::~SkinPart()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinPart::clear()
|
||||||
|
{
|
||||||
|
for (Bitmaps::iterator it = m_bitmaps.begin(), end = m_bitmaps.end();
|
||||||
|
it != end; ++it) {
|
||||||
|
destroy_bitmap(*it);
|
||||||
|
*it = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinPart::setBitmap(size_t index, BITMAP* bitmap)
|
||||||
|
{
|
||||||
|
if (index >= m_bitmaps.size())
|
||||||
|
m_bitmaps.resize(index+1, NULL);
|
||||||
|
|
||||||
|
if (m_bitmaps[index] == bitmap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_bitmaps[index])
|
||||||
|
destroy_bitmap(m_bitmaps[index]);
|
||||||
|
|
||||||
|
m_bitmaps[index] = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace skin
|
||||||
|
} // namespace app
|
54
src/app/ui/skin/skin_part.h
Normal file
54
src/app/ui/skin/skin_part.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APP_UI_SKIN_SKIN_PART_H_INCLUDED
|
||||||
|
#define APP_UI_SKIN_SKIN_PART_H_INCLUDED
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "base/shared_ptr.h"
|
||||||
|
|
||||||
|
struct BITMAP;
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace skin {
|
||||||
|
|
||||||
|
class SkinPart {
|
||||||
|
public:
|
||||||
|
typedef std::vector<BITMAP*> Bitmaps;
|
||||||
|
|
||||||
|
SkinPart();
|
||||||
|
~SkinPart();
|
||||||
|
|
||||||
|
size_t size() const { return m_bitmaps.size(); }
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void setBitmap(size_t index, BITMAP* bitmap);
|
||||||
|
BITMAP* getBitmap(size_t index) const {
|
||||||
|
return (index < m_bitmaps.size() ? m_bitmaps[index]: NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Bitmaps m_bitmaps;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SharedPtr<SkinPart> SkinPartPtr;
|
||||||
|
|
||||||
|
} // namespace skin
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
@ -33,7 +33,9 @@ namespace app {
|
|||||||
name##_W
|
name##_W
|
||||||
|
|
||||||
// Available parts in the skin sheet
|
// Available parts in the skin sheet
|
||||||
enum SkinPart {
|
enum SkinParts {
|
||||||
|
|
||||||
|
PART_NONE,
|
||||||
|
|
||||||
PART_RADIO_NORMAL,
|
PART_RADIO_NORMAL,
|
||||||
PART_RADIO_SELECTED,
|
PART_RADIO_SELECTED,
|
||||||
|
@ -22,13 +22,15 @@
|
|||||||
|
|
||||||
#include "app/ui/skin/skin_property.h"
|
#include "app/ui/skin/skin_property.h"
|
||||||
|
|
||||||
|
#include "ui/widget.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace skin {
|
namespace skin {
|
||||||
|
|
||||||
const char* SkinProperty::SkinPropertyName = "SkinProperty";
|
const char* SkinProperty::Name = "SkinProperty";
|
||||||
|
|
||||||
SkinProperty::SkinProperty()
|
SkinProperty::SkinProperty()
|
||||||
: Property(SkinPropertyName)
|
: Property(Name)
|
||||||
{
|
{
|
||||||
m_look = NormalLook;
|
m_look = NormalLook;
|
||||||
m_upperLeft = 0;
|
m_upperLeft = 0;
|
||||||
@ -41,5 +43,18 @@ SkinProperty::~SkinProperty()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SkinPropertyPtr get_skin_property(ui::Widget* widget)
|
||||||
|
{
|
||||||
|
SkinPropertyPtr skinProp;
|
||||||
|
|
||||||
|
skinProp = widget->getProperty(SkinProperty::Name);
|
||||||
|
if (skinProp == NULL) {
|
||||||
|
skinProp.reset(new SkinProperty);
|
||||||
|
widget->setProperty(skinProp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return skinProp;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace skin
|
} // namespace skin
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -19,8 +19,13 @@
|
|||||||
#ifndef APP_UI_SKIN_SKIN_PROPERTY_H_INCLUDED
|
#ifndef APP_UI_SKIN_SKIN_PROPERTY_H_INCLUDED
|
||||||
#define APP_UI_SKIN_SKIN_PROPERTY_H_INCLUDED
|
#define APP_UI_SKIN_SKIN_PROPERTY_H_INCLUDED
|
||||||
|
|
||||||
|
#include "base/shared_ptr.h"
|
||||||
#include "ui/property.h"
|
#include "ui/property.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class Widget;
|
||||||
|
}
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace skin {
|
namespace skin {
|
||||||
|
|
||||||
@ -35,7 +40,7 @@ namespace app {
|
|||||||
// Property to show widgets with a special look (e.g.: buttons or sliders with mini-borders)
|
// Property to show widgets with a special look (e.g.: buttons or sliders with mini-borders)
|
||||||
class SkinProperty : public ui::Property {
|
class SkinProperty : public ui::Property {
|
||||||
public:
|
public:
|
||||||
static const char* SkinPropertyName;
|
static const char* Name;
|
||||||
|
|
||||||
SkinProperty();
|
SkinProperty();
|
||||||
~SkinProperty();
|
~SkinProperty();
|
||||||
@ -61,6 +66,10 @@ namespace app {
|
|||||||
int m_lowerRight;
|
int m_lowerRight;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef SharedPtr<SkinProperty> SkinPropertyPtr;
|
||||||
|
|
||||||
|
SkinPropertyPtr get_skin_property(ui::Widget* widget);
|
||||||
|
|
||||||
} // namespace skin
|
} // namespace skin
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
||||||
|
@ -25,8 +25,11 @@
|
|||||||
namespace app {
|
namespace app {
|
||||||
namespace skin {
|
namespace skin {
|
||||||
|
|
||||||
|
const char* SkinSliderProperty::Name = "SkinSliderProperty";
|
||||||
|
|
||||||
SkinSliderProperty::SkinSliderProperty(ISliderBgPainter* painter)
|
SkinSliderProperty::SkinSliderProperty(ISliderBgPainter* painter)
|
||||||
: m_painter(painter)
|
: Property(Name)
|
||||||
|
, m_painter(painter)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
#ifndef APP_UI_SKIN_SKIN_SLIDER_PROPERTY_H_INCLUDED
|
#ifndef APP_UI_SKIN_SKIN_SLIDER_PROPERTY_H_INCLUDED
|
||||||
#define APP_UI_SKIN_SKIN_SLIDER_PROPERTY_H_INCLUDED
|
#define APP_UI_SKIN_SKIN_SLIDER_PROPERTY_H_INCLUDED
|
||||||
|
|
||||||
#include "gfx/rect.h"
|
|
||||||
#include "app/ui/skin/skin_property.h"
|
#include "app/ui/skin/skin_property.h"
|
||||||
|
#include "base/shared_ptr.h"
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
class Slider;
|
class Slider;
|
||||||
@ -35,8 +36,10 @@ namespace app {
|
|||||||
virtual void paint(ui::Slider* slider, ui::Graphics* graphics, const gfx::Rect& rc) = 0;
|
virtual void paint(ui::Slider* slider, ui::Graphics* graphics, const gfx::Rect& rc) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkinSliderProperty : public SkinProperty {
|
class SkinSliderProperty : public ui::Property {
|
||||||
public:
|
public:
|
||||||
|
static const char* Name;
|
||||||
|
|
||||||
// The given painter is deleted automatically when this
|
// The given painter is deleted automatically when this
|
||||||
// property the destroyed.
|
// property the destroyed.
|
||||||
SkinSliderProperty(ISliderBgPainter* painter);
|
SkinSliderProperty(ISliderBgPainter* painter);
|
||||||
@ -48,6 +51,8 @@ namespace app {
|
|||||||
ISliderBgPainter* m_painter;
|
ISliderBgPainter* m_painter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef SharedPtr<SkinSliderProperty> SkinSliderPropertyPtr;
|
||||||
|
|
||||||
} // namespace skin
|
} // namespace skin
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
||||||
|
@ -29,11 +29,14 @@
|
|||||||
#include "app/ui/skin/skin_property.h"
|
#include "app/ui/skin/skin_property.h"
|
||||||
#include "app/ui/skin/skin_slider_property.h"
|
#include "app/ui/skin/skin_slider_property.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
|
#include "app/ui/skin/style.h"
|
||||||
|
#include "app/ui/skin/style_sheet.h"
|
||||||
#include "app/xml_document.h"
|
#include "app/xml_document.h"
|
||||||
#include "app/xml_exception.h"
|
#include "app/xml_exception.h"
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
#include "base/shared_ptr.h"
|
#include "base/shared_ptr.h"
|
||||||
|
#include "css/sheet.h"
|
||||||
#include "gfx/border.h"
|
#include "gfx/border.h"
|
||||||
#include "gfx/point.h"
|
#include "gfx/point.h"
|
||||||
#include "gfx/rect.h"
|
#include "gfx/rect.h"
|
||||||
@ -145,8 +148,7 @@ SkinTheme::SkinTheme()
|
|||||||
|
|
||||||
// Initialize all graphics in NULL (these bitmaps are loaded from the skin)
|
// Initialize all graphics in NULL (these bitmaps are loaded from the skin)
|
||||||
m_sheet_bmp = NULL;
|
m_sheet_bmp = NULL;
|
||||||
for (int c=0; c<PARTS; ++c)
|
m_part.resize(PARTS, NULL);
|
||||||
m_part[c] = NULL;
|
|
||||||
|
|
||||||
sheet_mapping["radio_normal"] = PART_RADIO_NORMAL;
|
sheet_mapping["radio_normal"] = PART_RADIO_NORMAL;
|
||||||
sheet_mapping["radio_selected"] = PART_RADIO_SELECTED;
|
sheet_mapping["radio_selected"] = PART_RADIO_SELECTED;
|
||||||
@ -348,8 +350,8 @@ SkinTheme::~SkinTheme()
|
|||||||
for (size_t c=0; c<m_cursors.size(); ++c)
|
for (size_t c=0; c<m_cursors.size(); ++c)
|
||||||
delete m_cursors[c];
|
delete m_cursors[c];
|
||||||
|
|
||||||
for (int c=0; c<PARTS; ++c)
|
m_part.clear();
|
||||||
destroy_bitmap(m_part[c]);
|
m_parts_by_id.clear();
|
||||||
|
|
||||||
for (std::map<std::string, BITMAP*>::iterator
|
for (std::map<std::string, BITMAP*>::iterator
|
||||||
it = m_toolicon.begin(); it != m_toolicon.end(); ++it) {
|
it = m_toolicon.begin(); it != m_toolicon.end(); ++it) {
|
||||||
@ -364,7 +366,7 @@ SkinTheme::~SkinTheme()
|
|||||||
destroy_font(m_minifont);
|
destroy_font(m_minifont);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call ji_regen_theme after this
|
// Call Theme::regenerate() after this.
|
||||||
void SkinTheme::reload_skin()
|
void SkinTheme::reload_skin()
|
||||||
{
|
{
|
||||||
if (m_sheet_bmp) {
|
if (m_sheet_bmp) {
|
||||||
@ -417,150 +419,241 @@ void SkinTheme::onRegenerate()
|
|||||||
{
|
{
|
||||||
scrollbar_size = 12 * jguiscale();
|
scrollbar_size = 12 * jguiscale();
|
||||||
|
|
||||||
|
m_part.clear();
|
||||||
|
m_part.resize(PARTS, NULL);
|
||||||
|
|
||||||
// Load the skin XML
|
// Load the skin XML
|
||||||
std::string xml_filename = "skins/" + m_selected_skin + "/skin.xml";
|
std::string xml_filename = "skins/" + m_selected_skin + "/skin.xml";
|
||||||
ResourceFinder rf;
|
ResourceFinder rf;
|
||||||
rf.findInDataDir(xml_filename.c_str());
|
rf.findInDataDir(xml_filename.c_str());
|
||||||
|
|
||||||
while (const char* path = rf.next()) {
|
const char* path;
|
||||||
if (!base::file_exists(path))
|
while ((path = rf.next()) &&
|
||||||
continue;
|
!base::file_exists(path)) {
|
||||||
|
}
|
||||||
|
if (!path) // not found
|
||||||
|
return;
|
||||||
|
|
||||||
XmlDocumentRef doc = open_xml(path);
|
XmlDocumentRef doc = open_xml(path);
|
||||||
TiXmlHandle handle(doc);
|
TiXmlHandle handle(doc);
|
||||||
|
|
||||||
// Load colors
|
// Load colors
|
||||||
{
|
{
|
||||||
TiXmlElement* xmlColor = handle
|
TiXmlElement* xmlColor = handle
|
||||||
.FirstChild("skin")
|
.FirstChild("skin")
|
||||||
.FirstChild("colors")
|
.FirstChild("colors")
|
||||||
.FirstChild("color").ToElement();
|
.FirstChild("color").ToElement();
|
||||||
while (xmlColor) {
|
while (xmlColor) {
|
||||||
std::string id = xmlColor->Attribute("id");
|
std::string id = xmlColor->Attribute("id");
|
||||||
uint32_t value = strtol(xmlColor->Attribute("value")+1, NULL, 16);
|
uint32_t value = strtol(xmlColor->Attribute("value")+1, NULL, 16);
|
||||||
|
ui::Color color = ui::rgba((value & 0xff0000) >> 16,
|
||||||
|
(value & 0xff00) >> 8,
|
||||||
|
(value & 0xff));
|
||||||
|
|
||||||
std::map<std::string, ThemeColor::Type>::iterator it =
|
PRINTF("Loading color '%s'...\n", id.c_str());
|
||||||
color_mapping.find(id);
|
|
||||||
if (it != color_mapping.end()) {
|
|
||||||
m_colors[it->second] = ui::rgba((value & 0xff0000) >> 16,
|
|
||||||
(value & 0xff00) >> 8,
|
|
||||||
(value & 0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlColor = xmlColor->NextSiblingElement();
|
m_colors_by_id[id] = color;
|
||||||
|
|
||||||
|
std::map<std::string, ThemeColor::Type>::iterator it = color_mapping.find(id);
|
||||||
|
if (it != color_mapping.end()) {
|
||||||
|
m_colors[it->second] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlColor = xmlColor->NextSiblingElement();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load cursors
|
// Load cursors
|
||||||
{
|
{
|
||||||
TiXmlElement* xmlCursor = handle
|
TiXmlElement* xmlCursor = handle
|
||||||
.FirstChild("skin")
|
.FirstChild("skin")
|
||||||
.FirstChild("cursors")
|
.FirstChild("cursors")
|
||||||
.FirstChild("cursor").ToElement();
|
.FirstChild("cursor").ToElement();
|
||||||
while (xmlCursor) {
|
while (xmlCursor) {
|
||||||
std::string id = xmlCursor->Attribute("id");
|
std::string id = xmlCursor->Attribute("id");
|
||||||
int x = strtol(xmlCursor->Attribute("x"), NULL, 10);
|
int x = strtol(xmlCursor->Attribute("x"), NULL, 10);
|
||||||
int y = strtol(xmlCursor->Attribute("y"), NULL, 10);
|
int y = strtol(xmlCursor->Attribute("y"), NULL, 10);
|
||||||
int w = strtol(xmlCursor->Attribute("w"), NULL, 10);
|
int w = strtol(xmlCursor->Attribute("w"), NULL, 10);
|
||||||
int h = strtol(xmlCursor->Attribute("h"), NULL, 10);
|
int h = strtol(xmlCursor->Attribute("h"), NULL, 10);
|
||||||
int focusx = strtol(xmlCursor->Attribute("focusx"), NULL, 10);
|
int focusx = strtol(xmlCursor->Attribute("focusx"), NULL, 10);
|
||||||
int focusy = strtol(xmlCursor->Attribute("focusy"), NULL, 10);
|
int focusy = strtol(xmlCursor->Attribute("focusy"), NULL, 10);
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
for (c=0; c<kCursorTypes; ++c) {
|
PRINTF("Loading cursor '%s'...\n", id.c_str());
|
||||||
if (id != cursor_names[c])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
delete m_cursors[c];
|
for (c=0; c<kCursorTypes; ++c) {
|
||||||
m_cursors[c] = NULL;
|
if (id != cursor_names[c])
|
||||||
|
continue;
|
||||||
|
|
||||||
BITMAP* bmp = cropPartFromSheet(NULL, x, y, w, h);
|
delete m_cursors[c];
|
||||||
she::Surface* surface =
|
m_cursors[c] = NULL;
|
||||||
she::Instance()->createSurfaceFromNativeHandle(reinterpret_cast<void*>(bmp));
|
|
||||||
|
|
||||||
m_cursors[c] = new Cursor(surface, gfx::Point(focusx*jguiscale(),
|
BITMAP* bmp = cropPartFromSheet(NULL, x, y, w, h);
|
||||||
focusy*jguiscale()));
|
she::Surface* surface =
|
||||||
break;
|
she::Instance()->createSurfaceFromNativeHandle(reinterpret_cast<void*>(bmp));
|
||||||
}
|
|
||||||
|
|
||||||
if (c == kCursorTypes) {
|
m_cursors[c] = new Cursor(surface, gfx::Point(focusx*jguiscale(),
|
||||||
throw base::Exception("Unknown cursor specified in '%s':\n"
|
focusy*jguiscale()));
|
||||||
"<cursor id='%s' ... />\n", xml_filename.c_str(), id.c_str());
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
xmlCursor = xmlCursor->NextSiblingElement();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Load tool icons
|
if (c == kCursorTypes) {
|
||||||
{
|
throw base::Exception("Unknown cursor specified in '%s':\n"
|
||||||
TiXmlElement* xmlIcon = handle
|
"<cursor id='%s' ... />\n", xml_filename.c_str(), id.c_str());
|
||||||
.FirstChild("skin")
|
|
||||||
.FirstChild("tools")
|
|
||||||
.FirstChild("tool").ToElement();
|
|
||||||
while (xmlIcon) {
|
|
||||||
// Get the tool-icon rectangle
|
|
||||||
const char* tool_id = xmlIcon->Attribute("id");
|
|
||||||
int x = strtol(xmlIcon->Attribute("x"), NULL, 10);
|
|
||||||
int y = strtol(xmlIcon->Attribute("y"), NULL, 10);
|
|
||||||
int w = strtol(xmlIcon->Attribute("w"), NULL, 10);
|
|
||||||
int h = strtol(xmlIcon->Attribute("h"), NULL, 10);
|
|
||||||
|
|
||||||
// Crop the tool-icon from the sheet
|
|
||||||
m_toolicon[tool_id] = cropPartFromSheet(m_toolicon[tool_id], x, y, w, h);
|
|
||||||
|
|
||||||
xmlIcon = xmlIcon->NextSiblingElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xmlCursor = xmlCursor->NextSiblingElement();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load parts
|
// Load tool icons
|
||||||
{
|
{
|
||||||
TiXmlElement* xmlPart = handle
|
TiXmlElement* xmlIcon = handle
|
||||||
.FirstChild("skin")
|
.FirstChild("skin")
|
||||||
.FirstChild("parts")
|
.FirstChild("tools")
|
||||||
.FirstChild("part").ToElement();
|
.FirstChild("tool").ToElement();
|
||||||
while (xmlPart) {
|
while (xmlIcon) {
|
||||||
// Get the tool-icon rectangle
|
// Get the tool-icon rectangle
|
||||||
const char* part_id = xmlPart->Attribute("id");
|
const char* tool_id = xmlIcon->Attribute("id");
|
||||||
int x = strtol(xmlPart->Attribute("x"), NULL, 10);
|
int x = strtol(xmlIcon->Attribute("x"), NULL, 10);
|
||||||
int y = strtol(xmlPart->Attribute("y"), NULL, 10);
|
int y = strtol(xmlIcon->Attribute("y"), NULL, 10);
|
||||||
int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0;
|
int w = strtol(xmlIcon->Attribute("w"), NULL, 10);
|
||||||
int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0;
|
int h = strtol(xmlIcon->Attribute("h"), NULL, 10);
|
||||||
std::map<std::string, int>::iterator it = sheet_mapping.find(part_id);
|
|
||||||
if (it == sheet_mapping.end()) {
|
|
||||||
throw base::Exception("Unknown part specified in '%s':\n"
|
|
||||||
"<part id='%s' ... />\n", xml_filename.c_str(), part_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
PRINTF("Loading tool icon '%s'...\n", tool_id);
|
||||||
|
|
||||||
|
// Crop the tool-icon from the sheet
|
||||||
|
m_toolicon[tool_id] = cropPartFromSheet(m_toolicon[tool_id], x, y, w, h);
|
||||||
|
|
||||||
|
xmlIcon = xmlIcon->NextSiblingElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load parts
|
||||||
|
{
|
||||||
|
TiXmlElement* xmlPart = handle
|
||||||
|
.FirstChild("skin")
|
||||||
|
.FirstChild("parts")
|
||||||
|
.FirstChild("part").ToElement();
|
||||||
|
while (xmlPart) {
|
||||||
|
// Get the tool-icon rectangle
|
||||||
|
const char* part_id = xmlPart->Attribute("id");
|
||||||
|
int x = strtol(xmlPart->Attribute("x"), NULL, 10);
|
||||||
|
int y = strtol(xmlPart->Attribute("y"), NULL, 10);
|
||||||
|
int w = xmlPart->Attribute("w") ? strtol(xmlPart->Attribute("w"), NULL, 10): 0;
|
||||||
|
int h = xmlPart->Attribute("h") ? strtol(xmlPart->Attribute("h"), NULL, 10): 0;
|
||||||
|
|
||||||
|
PRINTF("Loading part '%s'...\n", part_id);
|
||||||
|
|
||||||
|
SkinPartPtr part = m_parts_by_id[part_id];
|
||||||
|
if (part == NULL)
|
||||||
|
part = m_parts_by_id[part_id] = SkinPartPtr(new SkinPart);
|
||||||
|
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
|
part->setBitmap(0, cropPartFromSheet(part->getBitmap(0), x, y, w, h));
|
||||||
|
}
|
||||||
|
else if (xmlPart->Attribute("w1")) { // 3x3-1 part (NW, N, NE, E, SE, S, SW, W)
|
||||||
|
int w1 = strtol(xmlPart->Attribute("w1"), NULL, 10);
|
||||||
|
int w2 = strtol(xmlPart->Attribute("w2"), NULL, 10);
|
||||||
|
int w3 = strtol(xmlPart->Attribute("w3"), NULL, 10);
|
||||||
|
int h1 = strtol(xmlPart->Attribute("h1"), NULL, 10);
|
||||||
|
int h2 = strtol(xmlPart->Attribute("h2"), NULL, 10);
|
||||||
|
int h3 = strtol(xmlPart->Attribute("h3"), NULL, 10);
|
||||||
|
|
||||||
|
part->setBitmap(0, cropPartFromSheet(part->getBitmap(0), x, y, w1, h1)); // NW
|
||||||
|
part->setBitmap(1, cropPartFromSheet(part->getBitmap(1), x+w1, y, w2, h1)); // N
|
||||||
|
part->setBitmap(2, cropPartFromSheet(part->getBitmap(2), x+w1+w2, y, w3, h1)); // NE
|
||||||
|
part->setBitmap(3, cropPartFromSheet(part->getBitmap(3), x+w1+w2, y+h1, w3, h2)); // E
|
||||||
|
part->setBitmap(4, cropPartFromSheet(part->getBitmap(4), x+w1+w2, y+h1+h2, w3, h3)); // SE
|
||||||
|
part->setBitmap(5, cropPartFromSheet(part->getBitmap(5), x+w1, y+h1+h2, w2, h3)); // S
|
||||||
|
part->setBitmap(6, cropPartFromSheet(part->getBitmap(6), x, y+h1+h2, w1, h3)); // SW
|
||||||
|
part->setBitmap(7, cropPartFromSheet(part->getBitmap(7), x, y+h1, w1, h2)); // W
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the m_part vector (which is used for backward
|
||||||
|
// compatibility for widgets that doesn't use SkinStyle).
|
||||||
|
std::map<std::string, int>::iterator it = sheet_mapping.find(part_id);
|
||||||
|
if (it != sheet_mapping.end()) {
|
||||||
int c = it->second;
|
int c = it->second;
|
||||||
|
for (size_t i=0; i<part->size(); ++i)
|
||||||
if (w > 0 && h > 0) {
|
m_part[c+i] = part->getBitmap(i);
|
||||||
// Crop the part from the sheet
|
|
||||||
m_part[c] = cropPartFromSheet(m_part[c], x, y, w, h);
|
|
||||||
}
|
|
||||||
else if (xmlPart->Attribute("w1")) { // 3x3-1 part (NW, N, NE, E, SE, S, SW, W)
|
|
||||||
int w1 = strtol(xmlPart->Attribute("w1"), NULL, 10);
|
|
||||||
int w2 = strtol(xmlPart->Attribute("w2"), NULL, 10);
|
|
||||||
int w3 = strtol(xmlPart->Attribute("w3"), NULL, 10);
|
|
||||||
int h1 = strtol(xmlPart->Attribute("h1"), NULL, 10);
|
|
||||||
int h2 = strtol(xmlPart->Attribute("h2"), NULL, 10);
|
|
||||||
int h3 = strtol(xmlPart->Attribute("h3"), NULL, 10);
|
|
||||||
|
|
||||||
m_part[c ] = cropPartFromSheet(m_part[c ], x, y, w1, h1); // NW
|
|
||||||
m_part[c+1] = cropPartFromSheet(m_part[c+1], x+w1, y, w2, h1); // N
|
|
||||||
m_part[c+2] = cropPartFromSheet(m_part[c+2], x+w1+w2, y, w3, h1); // NE
|
|
||||||
m_part[c+3] = cropPartFromSheet(m_part[c+3], x+w1+w2, y+h1, w3, h2); // E
|
|
||||||
m_part[c+4] = cropPartFromSheet(m_part[c+4], x+w1+w2, y+h1+h2, w3, h3); // SE
|
|
||||||
m_part[c+5] = cropPartFromSheet(m_part[c+5], x+w1, y+h1+h2, w2, h3); // S
|
|
||||||
m_part[c+6] = cropPartFromSheet(m_part[c+6], x, y+h1+h2, w1, h3); // SW
|
|
||||||
m_part[c+7] = cropPartFromSheet(m_part[c+7], x, y+h1, w1, h2); // W
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlPart = xmlPart->NextSiblingElement();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
xmlPart = xmlPart->NextSiblingElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load styles
|
||||||
|
{
|
||||||
|
TiXmlElement* xmlStyle = handle
|
||||||
|
.FirstChild("skin")
|
||||||
|
.FirstChild("stylesheet")
|
||||||
|
.FirstChild("style").ToElement();
|
||||||
|
while (xmlStyle) {
|
||||||
|
const char* style_id = xmlStyle->Attribute("id");
|
||||||
|
const char* base_id = xmlStyle->Attribute("base");
|
||||||
|
const css::Style* base = NULL;
|
||||||
|
|
||||||
|
if (base_id)
|
||||||
|
base = m_stylesheet.sheet().getStyle(base_id);
|
||||||
|
|
||||||
|
css::Style* style = new css::Style(style_id, base);
|
||||||
|
m_stylesheet.sheet().addStyle(style);
|
||||||
|
|
||||||
|
TiXmlElement* xmlRule = xmlStyle->FirstChildElement();
|
||||||
|
while (xmlRule) {
|
||||||
|
const std::string ruleName = xmlRule->Value();
|
||||||
|
|
||||||
|
PRINTF("- Rule '%s' for '%s'\n", ruleName.c_str(), style_id);
|
||||||
|
|
||||||
|
// TODO This code design to read styles could be improved.
|
||||||
|
|
||||||
|
const char* part_id = xmlRule->Attribute("part");
|
||||||
|
const char* color_id = xmlRule->Attribute("color");
|
||||||
|
|
||||||
|
// Style align
|
||||||
|
int align = 0;
|
||||||
|
const char* halign = xmlRule->Attribute("align");
|
||||||
|
const char* valign = xmlRule->Attribute("valign");
|
||||||
|
if (halign) {
|
||||||
|
if (strcmp(halign, "left") == 0) align |= JI_LEFT;
|
||||||
|
else if (strcmp(halign, "right") == 0) align |= JI_RIGHT;
|
||||||
|
else if (strcmp(halign, "center") == 0) align |= JI_CENTER;
|
||||||
|
}
|
||||||
|
if (valign) {
|
||||||
|
if (strcmp(valign, "top") == 0) align |= JI_TOP;
|
||||||
|
else if (strcmp(valign, "bottom") == 0) align |= JI_BOTTOM;
|
||||||
|
else if (strcmp(valign, "middle") == 0) align |= JI_MIDDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ruleName == "background") {
|
||||||
|
if (color_id) (*style)[StyleSheet::backgroundColorRule()] = css::Value(color_id);
|
||||||
|
if (part_id) (*style)[StyleSheet::backgroundPartRule()] = css::Value(part_id);
|
||||||
|
}
|
||||||
|
else if (ruleName == "icon") {
|
||||||
|
if (align) (*style)[StyleSheet::iconAlignRule()] = css::Value(align);
|
||||||
|
if (part_id) (*style)[StyleSheet::iconPartRule()] = css::Value(part_id);
|
||||||
|
}
|
||||||
|
else if (ruleName == "text") {
|
||||||
|
if (color_id) (*style)[StyleSheet::textColorRule()] = css::Value(color_id);
|
||||||
|
if (align) (*style)[StyleSheet::textAlignRule()] = css::Value(align);
|
||||||
|
|
||||||
|
const char* padding_left = xmlRule->Attribute("padding-left");
|
||||||
|
const char* padding_top = xmlRule->Attribute("padding-top");
|
||||||
|
const char* padding_right = xmlRule->Attribute("padding-right");
|
||||||
|
const char* padding_bottom = xmlRule->Attribute("padding-bottom");
|
||||||
|
|
||||||
|
if (padding_left) (*style)[StyleSheet::paddingLeftRule()] = css::Value(strtol(padding_left, NULL, 10));
|
||||||
|
if (padding_top) (*style)[StyleSheet::paddingTopRule()] = css::Value(strtol(padding_top, NULL, 10));
|
||||||
|
if (padding_right) (*style)[StyleSheet::paddingRightRule()] = css::Value(strtol(padding_right, NULL, 10));
|
||||||
|
if (padding_bottom) (*style)[StyleSheet::paddingBottomRule()] = css::Value(strtol(padding_bottom, NULL, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlRule = xmlRule->NextSiblingElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlStyle = xmlStyle->NextSiblingElement();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -851,7 +944,7 @@ void SkinTheme::paintButton(PaintEvent& ev)
|
|||||||
|
|
||||||
// Tool buttons are smaller
|
// Tool buttons are smaller
|
||||||
LookType look = NormalLook;
|
LookType look = NormalLook;
|
||||||
SharedPtr<SkinProperty> skinPropery = widget->getProperty(SkinProperty::SkinPropertyName);
|
SkinPropertyPtr skinPropery = widget->getProperty(SkinProperty::Name);
|
||||||
if (skinPropery != NULL)
|
if (skinPropery != NULL)
|
||||||
look = skinPropery->getLook();
|
look = skinPropery->getLook();
|
||||||
|
|
||||||
@ -926,7 +1019,7 @@ void SkinTheme::paintCheckBox(PaintEvent& ev)
|
|||||||
|
|
||||||
// Check box look
|
// Check box look
|
||||||
LookType look = NormalLook;
|
LookType look = NormalLook;
|
||||||
SharedPtr<SkinProperty> skinPropery = widget->getProperty(SkinProperty::SkinPropertyName);
|
SkinPropertyPtr skinPropery = widget->getProperty(SkinProperty::Name);
|
||||||
if (skinPropery != NULL)
|
if (skinPropery != NULL)
|
||||||
look = skinPropery->getLook();
|
look = skinPropery->getLook();
|
||||||
|
|
||||||
@ -990,7 +1083,7 @@ void SkinTheme::paintEntry(PaintEvent& ev)
|
|||||||
y2 = widget->getBounds().y2()-1;
|
y2 = widget->getBounds().y2()-1;
|
||||||
|
|
||||||
bool isMiniLook = false;
|
bool isMiniLook = false;
|
||||||
SharedPtr<SkinProperty> skinPropery = widget->getProperty(SkinProperty::SkinPropertyName);
|
SkinPropertyPtr skinPropery = widget->getProperty(SkinProperty::Name);
|
||||||
if (skinPropery != NULL)
|
if (skinPropery != NULL)
|
||||||
isMiniLook = (skinPropery->getLook() == MiniLook);
|
isMiniLook = (skinPropery->getLook() == MiniLook);
|
||||||
|
|
||||||
@ -1404,12 +1497,13 @@ void SkinTheme::paintSlider(PaintEvent& ev)
|
|||||||
// customized background (e.g. RGB sliders)
|
// customized background (e.g. RGB sliders)
|
||||||
ISliderBgPainter* bgPainter = NULL;
|
ISliderBgPainter* bgPainter = NULL;
|
||||||
|
|
||||||
SharedPtr<SkinProperty> skinPropery = widget->getProperty(SkinProperty::SkinPropertyName);
|
SkinPropertyPtr skinPropery = widget->getProperty(SkinProperty::Name);
|
||||||
if (skinPropery != NULL)
|
if (skinPropery != NULL)
|
||||||
isMiniLook = (skinPropery->getLook() == MiniLook);
|
isMiniLook = (skinPropery->getLook() == MiniLook);
|
||||||
|
|
||||||
if (SkinSliderProperty* sliderProperty = dynamic_cast<SkinSliderProperty*>(skinPropery.get()))
|
SkinSliderPropertyPtr skinSliderPropery = widget->getProperty(SkinSliderProperty::Name);
|
||||||
bgPainter = sliderProperty->getBgPainter();
|
if (skinSliderPropery != NULL)
|
||||||
|
bgPainter = skinSliderPropery->getBgPainter();
|
||||||
|
|
||||||
// Draw customized background
|
// Draw customized background
|
||||||
if (bgPainter) {
|
if (bgPainter) {
|
||||||
@ -2022,53 +2116,82 @@ void SkinTheme::draw_bounds_template(BITMAP* bmp, int x1, int y1, int x2, int y2
|
|||||||
|
|
||||||
void SkinTheme::draw_bounds_template(Graphics* g, const Rect& rc,
|
void SkinTheme::draw_bounds_template(Graphics* g, const Rect& rc,
|
||||||
int nw, int n, int ne, int e, int se, int s, int sw, int w)
|
int nw, int n, int ne, int e, int se, int s, int sw, int w)
|
||||||
|
{
|
||||||
|
draw_bounds_template(g, rc,
|
||||||
|
m_part[nw],
|
||||||
|
m_part[n],
|
||||||
|
m_part[ne],
|
||||||
|
m_part[e],
|
||||||
|
m_part[se],
|
||||||
|
m_part[s],
|
||||||
|
m_part[sw],
|
||||||
|
m_part[w]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinTheme::draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr& skinPart)
|
||||||
|
{
|
||||||
|
draw_bounds_template(g, rc,
|
||||||
|
skinPart->getBitmap(0),
|
||||||
|
skinPart->getBitmap(1),
|
||||||
|
skinPart->getBitmap(2),
|
||||||
|
skinPart->getBitmap(3),
|
||||||
|
skinPart->getBitmap(4),
|
||||||
|
skinPart->getBitmap(5),
|
||||||
|
skinPart->getBitmap(6),
|
||||||
|
skinPart->getBitmap(7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinTheme::draw_bounds_template(Graphics* g, const Rect& rc,
|
||||||
|
BITMAP* nw, BITMAP* n, BITMAP* ne,
|
||||||
|
BITMAP* e, BITMAP* se, BITMAP* s,
|
||||||
|
BITMAP* sw, BITMAP* w)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
// Top
|
// Top
|
||||||
|
|
||||||
g->drawAlphaBitmap(m_part[nw], rc.x, rc.y);
|
g->drawAlphaBitmap(nw, rc.x, rc.y);
|
||||||
|
|
||||||
if (IntersectClip clip = IntersectClip(g, Rect(rc.x+m_part[nw]->w, rc.y,
|
if (IntersectClip clip = IntersectClip(g, Rect(rc.x+nw->w, rc.y,
|
||||||
rc.w-m_part[nw]->w-m_part[ne]->w, rc.h))) {
|
rc.w-nw->w-ne->w, rc.h))) {
|
||||||
for (x = rc.x+m_part[nw]->w;
|
for (x = rc.x+nw->w;
|
||||||
x < rc.x+rc.w-m_part[ne]->w;
|
x < rc.x+rc.w-ne->w;
|
||||||
x += m_part[n]->w) {
|
x += n->w) {
|
||||||
g->drawAlphaBitmap(m_part[n], x, rc.y);
|
g->drawAlphaBitmap(n, x, rc.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g->drawAlphaBitmap(m_part[ne], rc.x+rc.w-m_part[ne]->w, rc.y);
|
g->drawAlphaBitmap(ne, rc.x+rc.w-ne->w, rc.y);
|
||||||
|
|
||||||
// Bottom
|
// Bottom
|
||||||
|
|
||||||
g->drawAlphaBitmap(m_part[sw], rc.x, rc.y+rc.h-m_part[sw]->h);
|
g->drawAlphaBitmap(sw, rc.x, rc.y+rc.h-sw->h);
|
||||||
|
|
||||||
if (IntersectClip clip = IntersectClip(g, Rect(rc.x+m_part[sw]->w, rc.y,
|
if (IntersectClip clip = IntersectClip(g, Rect(rc.x+sw->w, rc.y,
|
||||||
rc.w-m_part[sw]->w-m_part[se]->w, rc.h))) {
|
rc.w-sw->w-se->w, rc.h))) {
|
||||||
for (x = rc.x+m_part[sw]->w;
|
for (x = rc.x+sw->w;
|
||||||
x < rc.x+rc.w-m_part[se]->w;
|
x < rc.x+rc.w-se->w;
|
||||||
x += m_part[s]->w) {
|
x += s->w) {
|
||||||
g->drawAlphaBitmap(m_part[s], x, rc.y+rc.h-m_part[s]->h);
|
g->drawAlphaBitmap(s, x, rc.y+rc.h-s->h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g->drawAlphaBitmap(m_part[se], rc.x+rc.w-m_part[se]->w, rc.y+rc.h-m_part[se]->h);
|
g->drawAlphaBitmap(se, rc.x+rc.w-se->w, rc.y+rc.h-se->h);
|
||||||
|
|
||||||
if (IntersectClip clip = IntersectClip(g, Rect(rc.x, rc.y+m_part[nw]->h,
|
if (IntersectClip clip = IntersectClip(g, Rect(rc.x, rc.y+nw->h,
|
||||||
rc.w, rc.h-m_part[nw]->h-m_part[sw]->h))) {
|
rc.w, rc.h-nw->h-sw->h))) {
|
||||||
// Left
|
// Left
|
||||||
for (y = rc.y+m_part[nw]->h;
|
for (y = rc.y+nw->h;
|
||||||
y < rc.y+rc.h-m_part[sw]->h;
|
y < rc.y+rc.h-sw->h;
|
||||||
y += m_part[w]->h) {
|
y += w->h) {
|
||||||
g->drawAlphaBitmap(m_part[w], rc.x, y);
|
g->drawAlphaBitmap(w, rc.x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right
|
// Right
|
||||||
for (y = rc.y+m_part[ne]->h;
|
for (y = rc.y+ne->h;
|
||||||
y < rc.y+rc.h-m_part[se]->h;
|
y < rc.y+rc.h-se->h;
|
||||||
y += m_part[e]->h) {
|
y += e->h) {
|
||||||
g->drawAlphaBitmap(m_part[e], rc.x+rc.w-m_part[e]->w, y);
|
g->drawAlphaBitmap(e, rc.x+rc.w-e->w, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2123,6 +2246,19 @@ void SkinTheme::draw_bounds_nw(Graphics* g, const Rect& rc, int nw, ui::Color bg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SkinTheme::draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr skinPart, ui::Color bg)
|
||||||
|
{
|
||||||
|
draw_bounds_template(g, rc, skinPart);
|
||||||
|
|
||||||
|
// Center
|
||||||
|
if (!is_transparent(bg)) {
|
||||||
|
g->fillRect(bg, Rect(rc).shrink(Border(skinPart->getBitmap(7)->w,
|
||||||
|
skinPart->getBitmap(1)->h,
|
||||||
|
skinPart->getBitmap(3)->w,
|
||||||
|
skinPart->getBitmap(5)->h)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SkinTheme::draw_bounds_nw2(Graphics* g, const Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2)
|
void SkinTheme::draw_bounds_nw2(Graphics* g, const Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2)
|
||||||
{
|
{
|
||||||
Rect rc2(rc.x, rc.y, x_mid-rc.x+1, rc.h);
|
Rect rc2(rc.x, rc.y, x_mid-rc.x+1, rc.h);
|
||||||
|
@ -19,9 +19,13 @@
|
|||||||
#ifndef APP_UI_SKIN_SKIN_THEME_H_INCLUDED
|
#ifndef APP_UI_SKIN_SKIN_THEME_H_INCLUDED
|
||||||
#define APP_UI_SKIN_SKIN_THEME_H_INCLUDED
|
#define APP_UI_SKIN_SKIN_THEME_H_INCLUDED
|
||||||
|
|
||||||
#include "gfx/fwd.h"
|
#include "app/ui/skin/skin_part.h"
|
||||||
#include "app/ui/skin/skin_parts.h"
|
#include "app/ui/skin/skin_parts.h"
|
||||||
|
#include "app/ui/skin/style_sheet.h"
|
||||||
|
#include "base/compiler_specific.h"
|
||||||
|
#include "gfx/fwd.h"
|
||||||
#include "ui/color.h"
|
#include "ui/color.h"
|
||||||
|
#include "ui/manager.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/theme.h"
|
#include "ui/theme.h"
|
||||||
|
|
||||||
@ -164,6 +168,7 @@ namespace app {
|
|||||||
void draw_bounds_array(BITMAP* bmp, int x1, int y1, int x2, int y2, int parts[8]);
|
void draw_bounds_array(BITMAP* bmp, int x1, int y1, int x2, int y2, int parts[8]);
|
||||||
void draw_bounds_nw(BITMAP* bmp, int x1, int y1, int x2, int y2, int nw, ui::Color bg = ui::ColorNone);
|
void draw_bounds_nw(BITMAP* bmp, int x1, int y1, int x2, int y2, int nw, ui::Color bg = ui::ColorNone);
|
||||||
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, int nw, ui::Color bg = ui::ColorNone);
|
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, int nw, ui::Color bg = ui::ColorNone);
|
||||||
|
void draw_bounds_nw(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr skinPart, ui::Color bg = ui::ColorNone);
|
||||||
void draw_bounds_nw2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2);
|
void draw_bounds_nw2(ui::Graphics* g, const gfx::Rect& rc, int x_mid, int nw1, int nw2, ui::Color bg1, ui::Color bg2);
|
||||||
void draw_part_as_hline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part);
|
void draw_part_as_hline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part);
|
||||||
void draw_part_as_vline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part);
|
void draw_part_as_vline(BITMAP* bmp, int x1, int y1, int x2, int y2, int part);
|
||||||
@ -177,14 +182,31 @@ namespace app {
|
|||||||
|
|
||||||
void drawProgressBar(BITMAP* bmp, int x1, int y1, int x2, int y2, float progress);
|
void drawProgressBar(BITMAP* bmp, int x1, int y1, int x2, int y2, float progress);
|
||||||
|
|
||||||
|
Style* getStyle(const std::string& id) {
|
||||||
|
return m_stylesheet.getStyle(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
SkinPartPtr getPartById(const std::string& id) {
|
||||||
|
return m_parts_by_id[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::Color getColorById(const std::string& id) {
|
||||||
|
return m_colors_by_id[id];
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onRegenerate();
|
void onRegenerate() OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void draw_bounds_template(BITMAP* bmp, int x1, int y1, int x2, int y2,
|
void draw_bounds_template(BITMAP* bmp, int x1, int y1, int x2, int y2,
|
||||||
int nw, int n, int ne, int e, int se, int s, int sw, int w);
|
int nw, int n, int ne, int e, int se, int s, int sw, int w);
|
||||||
void draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc,
|
void draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc,
|
||||||
int nw, int n, int ne, int e, int se, int s, int sw, int w);
|
int nw, int n, int ne, int e, int se, int s, int sw, int w);
|
||||||
|
void draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc, const SkinPartPtr& skinPart);
|
||||||
|
void draw_bounds_template(ui::Graphics* g, const gfx::Rect& rc,
|
||||||
|
BITMAP* nw, BITMAP* n, BITMAP* ne,
|
||||||
|
BITMAP* e, BITMAP* se, BITMAP* s,
|
||||||
|
BITMAP* sw, BITMAP* w);
|
||||||
|
|
||||||
BITMAP* cropPartFromSheet(BITMAP* bmp, int x, int y, int w, int h);
|
BITMAP* cropPartFromSheet(BITMAP* bmp, int x, int y, int w, int h);
|
||||||
ui::Color getWidgetBgColor(ui::Widget* widget);
|
ui::Color getWidgetBgColor(ui::Widget* widget);
|
||||||
@ -202,13 +224,28 @@ namespace app {
|
|||||||
|
|
||||||
std::string m_selected_skin;
|
std::string m_selected_skin;
|
||||||
BITMAP* m_sheet_bmp;
|
BITMAP* m_sheet_bmp;
|
||||||
BITMAP* m_part[PARTS];
|
std::vector<BITMAP*> m_part;
|
||||||
|
std::map<std::string, SkinPartPtr> m_parts_by_id;
|
||||||
std::map<std::string, BITMAP*> m_toolicon;
|
std::map<std::string, BITMAP*> m_toolicon;
|
||||||
|
std::map<std::string, ui::Color> m_colors_by_id;
|
||||||
std::vector<ui::Cursor*> m_cursors;
|
std::vector<ui::Cursor*> m_cursors;
|
||||||
std::vector<ui::Color> m_colors;
|
std::vector<ui::Color> m_colors;
|
||||||
|
StyleSheet m_stylesheet;
|
||||||
FONT* m_minifont;
|
FONT* m_minifont;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Style* get_style(const std::string& id) {
|
||||||
|
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getStyle(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline SkinPartPtr get_part_by_id(const std::string& id) {
|
||||||
|
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getPartById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ui::Color get_color_by_id(const std::string& id) {
|
||||||
|
return static_cast<SkinTheme*>(ui::Manager::getDefault()->getTheme())->getColorById(id);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace skin
|
} // namespace skin
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
||||||
|
202
src/app/ui/skin/style.cpp
Normal file
202
src/app/ui/skin/style.cpp
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/ui/skin/style.h"
|
||||||
|
|
||||||
|
#include "app/ui/skin/skin_theme.h"
|
||||||
|
#include "css/sheet.h"
|
||||||
|
#include "ui/graphics.h"
|
||||||
|
#include "ui/theme.h"
|
||||||
|
|
||||||
|
#include <allegro.h>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace skin {
|
||||||
|
|
||||||
|
css::State Style::m_hoverState("hover");
|
||||||
|
css::State Style::m_activeState("active");
|
||||||
|
css::State Style::m_clickedState("clicked");
|
||||||
|
|
||||||
|
Rule::~Rule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rule::paint(ui::Graphics* g,
|
||||||
|
const gfx::Rect& bounds,
|
||||||
|
const char* text)
|
||||||
|
{
|
||||||
|
onPaint(g, bounds, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text)
|
||||||
|
{
|
||||||
|
SkinTheme* theme = static_cast<SkinTheme*>(ui::CurrentTheme::get());
|
||||||
|
|
||||||
|
if (m_part != NULL && m_part->size() > 0) {
|
||||||
|
if (m_part->size() == 1) {
|
||||||
|
if (!ui::is_transparent(m_color))
|
||||||
|
g->fillRect(m_color, bounds);
|
||||||
|
|
||||||
|
g->drawAlphaBitmap(m_part->getBitmap(0), bounds.x, bounds.y);
|
||||||
|
}
|
||||||
|
else if (m_part->size() == 8) {
|
||||||
|
theme->draw_bounds_nw(g, bounds, m_part, m_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!ui::is_transparent(m_color)) {
|
||||||
|
g->fillRect(m_color, bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text)
|
||||||
|
{
|
||||||
|
SkinTheme* theme = static_cast<SkinTheme*>(ui::CurrentTheme::get());
|
||||||
|
|
||||||
|
if (text) {
|
||||||
|
g->drawString(text,
|
||||||
|
(ui::is_transparent(m_color) ?
|
||||||
|
theme->getColor(ThemeColor::Text):
|
||||||
|
m_color),
|
||||||
|
ui::ColorNone,
|
||||||
|
gfx::Rect(bounds).shrink(m_padding), m_align);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IconRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text)
|
||||||
|
{
|
||||||
|
BITMAP* bmp = m_part->getBitmap(0);
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
if (m_align & JI_RIGHT)
|
||||||
|
x = bounds.x2() - bmp->w;
|
||||||
|
else if (m_align & JI_CENTER)
|
||||||
|
x = bounds.x + bounds.w/2 - bmp->w/2;
|
||||||
|
else
|
||||||
|
x = bounds.x;
|
||||||
|
|
||||||
|
if (m_align & JI_BOTTOM)
|
||||||
|
y = bounds.y2() - bmp->h;
|
||||||
|
else if (m_align & JI_MIDDLE)
|
||||||
|
y = bounds.y + bounds.h/2 - bmp->h/2;
|
||||||
|
else
|
||||||
|
y = bounds.y;
|
||||||
|
|
||||||
|
g->drawAlphaBitmap(bmp, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rules::Rules(const css::Query& query) :
|
||||||
|
m_background(NULL),
|
||||||
|
m_text(NULL),
|
||||||
|
m_icon(NULL)
|
||||||
|
{
|
||||||
|
css::Value backgroundColor = query[StyleSheet::backgroundColorRule()];
|
||||||
|
css::Value backgroundPart = query[StyleSheet::backgroundPartRule()];
|
||||||
|
css::Value iconAlign = query[StyleSheet::iconAlignRule()];
|
||||||
|
css::Value iconPart = query[StyleSheet::iconPartRule()];
|
||||||
|
css::Value textAlign = query[StyleSheet::textAlignRule()];
|
||||||
|
css::Value textColor = query[StyleSheet::textColorRule()];
|
||||||
|
css::Value paddingLeft = query[StyleSheet::paddingLeftRule()];
|
||||||
|
css::Value paddingTop = query[StyleSheet::paddingTopRule()];
|
||||||
|
css::Value paddingRight = query[StyleSheet::paddingRightRule()];
|
||||||
|
css::Value paddingBottom = query[StyleSheet::paddingBottomRule()];
|
||||||
|
css::Value none;
|
||||||
|
|
||||||
|
if (backgroundColor != none
|
||||||
|
|| backgroundPart != none) {
|
||||||
|
m_background = new BackgroundRule();
|
||||||
|
m_background->setColor(StyleSheet::convertColor(backgroundColor));
|
||||||
|
m_background->setPart(StyleSheet::convertPart(backgroundPart));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconAlign != none
|
||||||
|
|| iconPart != none) {
|
||||||
|
m_icon = new IconRule();
|
||||||
|
m_icon->setAlign((int)iconAlign.number());
|
||||||
|
m_icon->setPart(StyleSheet::convertPart(iconPart));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textAlign != none
|
||||||
|
|| textColor != none
|
||||||
|
|| paddingLeft != none
|
||||||
|
|| paddingTop != none
|
||||||
|
|| paddingRight != none
|
||||||
|
|| paddingBottom != none) {
|
||||||
|
m_text = new TextRule();
|
||||||
|
m_text->setAlign((int)textAlign.number());
|
||||||
|
m_text->setColor(StyleSheet::convertColor(textColor));
|
||||||
|
m_text->setPadding(gfx::Border(
|
||||||
|
paddingLeft.number(), paddingTop.number(),
|
||||||
|
paddingRight.number(), paddingBottom.number())*ui::jguiscale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rules::~Rules()
|
||||||
|
{
|
||||||
|
delete m_background;
|
||||||
|
delete m_text;
|
||||||
|
delete m_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rules::paint(ui::Graphics* g,
|
||||||
|
const gfx::Rect& bounds,
|
||||||
|
const char* text)
|
||||||
|
{
|
||||||
|
if (m_background) m_background->paint(g, bounds, text);
|
||||||
|
if (m_icon) m_icon->paint(g, bounds, text);
|
||||||
|
if (m_text) m_text->paint(g, bounds, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
Style::Style(css::Sheet& sheet, const std::string& id)
|
||||||
|
: m_id(id)
|
||||||
|
, m_compoundStyle(sheet.compoundStyle(id))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Style::~Style()
|
||||||
|
{
|
||||||
|
for (RulesMap::iterator it = m_rules.begin(), end = m_rules.end();
|
||||||
|
it != end; ++it) {
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Style::paint(ui::Graphics* g,
|
||||||
|
const gfx::Rect& bounds,
|
||||||
|
const char* text,
|
||||||
|
const State& state)
|
||||||
|
{
|
||||||
|
Rules* rules = NULL;
|
||||||
|
|
||||||
|
RulesMap::iterator it = m_rules.find(state);
|
||||||
|
if (it != m_rules.end()) {
|
||||||
|
rules = it->second;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rules = new Rules(m_compoundStyle[state]);
|
||||||
|
m_rules[state] = rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
rules->paint(g, bounds, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace skin
|
||||||
|
} // namespace app
|
154
src/app/ui/skin/style.h
Normal file
154
src/app/ui/skin/style.h
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APP_UI_SKIN_STYLE_H_INCLUDED
|
||||||
|
#define APP_UI_SKIN_STYLE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "app/ui/skin/skin_part.h"
|
||||||
|
#include "base/compiler_specific.h"
|
||||||
|
#include "base/disable_copying.h"
|
||||||
|
#include "css/compound_style.h"
|
||||||
|
#include "css/state.h"
|
||||||
|
#include "css/stateful_style.h"
|
||||||
|
#include "gfx/border.h"
|
||||||
|
#include "gfx/fwd.h"
|
||||||
|
#include "ui/color.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class Graphics;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace skin {
|
||||||
|
|
||||||
|
class Rule {
|
||||||
|
public:
|
||||||
|
Rule() { }
|
||||||
|
virtual ~Rule();
|
||||||
|
|
||||||
|
void paint(ui::Graphics* g,
|
||||||
|
const gfx::Rect& bounds,
|
||||||
|
const char* text);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BackgroundRule : public Rule {
|
||||||
|
public:
|
||||||
|
BackgroundRule() : m_color(ui::ColorNone) { }
|
||||||
|
|
||||||
|
void setColor(ui::Color color) { m_color = color; }
|
||||||
|
void setPart(const SkinPartPtr& part) { m_part = part; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ui::Color m_color;
|
||||||
|
SkinPartPtr m_part;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextRule : public Rule {
|
||||||
|
public:
|
||||||
|
explicit TextRule() : m_align(0),
|
||||||
|
m_color(ui::ColorNone) { }
|
||||||
|
|
||||||
|
void setAlign(int align) { m_align = align; }
|
||||||
|
void setColor(ui::Color color) { m_color = color; }
|
||||||
|
void setPadding(const gfx::Border& padding) { m_padding = padding; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_align;
|
||||||
|
ui::Color m_color;
|
||||||
|
gfx::Border m_padding;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IconRule : public Rule {
|
||||||
|
public:
|
||||||
|
explicit IconRule() : m_align(0) { }
|
||||||
|
|
||||||
|
void setAlign(int align) { m_align = align; }
|
||||||
|
void setPart(const SkinPartPtr& part) { m_part = part; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_align;
|
||||||
|
SkinPartPtr m_part;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Rules {
|
||||||
|
public:
|
||||||
|
Rules(const css::Query& query);
|
||||||
|
~Rules();
|
||||||
|
|
||||||
|
void paint(ui::Graphics* g,
|
||||||
|
const gfx::Rect& bounds,
|
||||||
|
const char* text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BackgroundRule* m_background;
|
||||||
|
TextRule* m_text;
|
||||||
|
IconRule* m_icon;
|
||||||
|
|
||||||
|
DISABLE_COPYING(Rules);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Style {
|
||||||
|
public:
|
||||||
|
typedef css::States State;
|
||||||
|
|
||||||
|
static const css::State& hover() { return m_hoverState; }
|
||||||
|
static const css::State& active() { return m_activeState; }
|
||||||
|
static const css::State& clicked() { return m_clickedState; }
|
||||||
|
|
||||||
|
Style(css::Sheet& sheet, const std::string& id);
|
||||||
|
~Style();
|
||||||
|
|
||||||
|
void paint(ui::Graphics* g,
|
||||||
|
const gfx::Rect& bounds,
|
||||||
|
const char* text,
|
||||||
|
const State& state);
|
||||||
|
|
||||||
|
const std::string& id() const { return m_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<State, Rules*> RulesMap;
|
||||||
|
|
||||||
|
std::string m_id;
|
||||||
|
css::CompoundStyle m_compoundStyle;
|
||||||
|
RulesMap m_rules;
|
||||||
|
|
||||||
|
static css::State m_hoverState;
|
||||||
|
static css::State m_activeState;
|
||||||
|
static css::State m_clickedState;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace skin
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
116
src/app/ui/skin/style_sheet.cpp
Normal file
116
src/app/ui/skin/style_sheet.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "app/ui/skin/style_sheet.h"
|
||||||
|
|
||||||
|
#include "app/ui/skin/skin_theme.h"
|
||||||
|
#include "app/ui/skin/style.h"
|
||||||
|
#include "base/exception.h"
|
||||||
|
#include "css/sheet.h"
|
||||||
|
|
||||||
|
#include "tinyxml.h"
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace skin {
|
||||||
|
|
||||||
|
css::Rule StyleSheet::m_backgroundColorRule("background-color");
|
||||||
|
css::Rule StyleSheet::m_backgroundPartRule("background-part");
|
||||||
|
css::Rule StyleSheet::m_iconAlignRule("icon-align");
|
||||||
|
css::Rule StyleSheet::m_iconPartRule("icon-part");
|
||||||
|
css::Rule StyleSheet::m_textAlignRule("text-align");
|
||||||
|
css::Rule StyleSheet::m_textColorRule("text-color");
|
||||||
|
css::Rule StyleSheet::m_paddingLeftRule("padding-left");
|
||||||
|
css::Rule StyleSheet::m_paddingTopRule("padding-top");
|
||||||
|
css::Rule StyleSheet::m_paddingRightRule("padding-right");
|
||||||
|
css::Rule StyleSheet::m_paddingBottomRule("padding-bottom");
|
||||||
|
|
||||||
|
StyleSheet::StyleSheet()
|
||||||
|
{
|
||||||
|
m_sheet = new css::Sheet;
|
||||||
|
m_sheet->addRule(&m_backgroundColorRule);
|
||||||
|
m_sheet->addRule(&m_backgroundPartRule);
|
||||||
|
m_sheet->addRule(&m_iconAlignRule);
|
||||||
|
m_sheet->addRule(&m_iconPartRule);
|
||||||
|
m_sheet->addRule(&m_textAlignRule);
|
||||||
|
m_sheet->addRule(&m_textColorRule);
|
||||||
|
m_sheet->addRule(&m_paddingLeftRule);
|
||||||
|
m_sheet->addRule(&m_paddingTopRule);
|
||||||
|
m_sheet->addRule(&m_paddingRightRule);
|
||||||
|
m_sheet->addRule(&m_paddingBottomRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleSheet::~StyleSheet()
|
||||||
|
{
|
||||||
|
destroyAllStyles();
|
||||||
|
delete m_sheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleSheet::destroyAllStyles()
|
||||||
|
{
|
||||||
|
for (StyleMap::iterator it = m_styles.begin(), end = m_styles.end();
|
||||||
|
it != end; ++it)
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
Style* StyleSheet::getStyle(const std::string& id)
|
||||||
|
{
|
||||||
|
Style* style = NULL;
|
||||||
|
|
||||||
|
StyleMap::iterator it = m_styles.find(id);
|
||||||
|
if (it != m_styles.end())
|
||||||
|
style = it->second;
|
||||||
|
else {
|
||||||
|
style = new Style(*m_sheet, id);
|
||||||
|
m_styles[id] = style;
|
||||||
|
}
|
||||||
|
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
SkinPartPtr StyleSheet::convertPart(const css::Value& value)
|
||||||
|
{
|
||||||
|
SkinPartPtr part;
|
||||||
|
if (value.type() == css::Value::String) {
|
||||||
|
const std::string& part_id = value.string();
|
||||||
|
part = get_part_by_id(part_id);
|
||||||
|
if (part == NULL)
|
||||||
|
throw base::Exception("Unknown part '%s'\n", part_id.c_str());
|
||||||
|
}
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
ui::Color StyleSheet::convertColor(const css::Value& value)
|
||||||
|
{
|
||||||
|
ui::Color color;
|
||||||
|
if (value.type() == css::Value::String) {
|
||||||
|
const std::string& color_id = value.string();
|
||||||
|
color = get_color_by_id(color_id);
|
||||||
|
if (color == ui::ColorNone)
|
||||||
|
throw base::Exception("Unknown color '%s'\n", color_id.c_str());
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace skin
|
||||||
|
} // namespace app
|
88
src/app/ui/skin/style_sheet.h
Normal file
88
src/app/ui/skin/style_sheet.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* Aseprite
|
||||||
|
* Copyright (C) 2001-2013 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef APP_UI_SKIN_STYLE_SHEET_H_INCLUDED
|
||||||
|
#define APP_UI_SKIN_STYLE_SHEET_H_INCLUDED
|
||||||
|
|
||||||
|
#include "app/ui/skin/skin_part.h"
|
||||||
|
#include "css/rule.h"
|
||||||
|
#include "css/state.h"
|
||||||
|
#include "ui/color.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class TiXmlElement;
|
||||||
|
|
||||||
|
namespace css {
|
||||||
|
class Sheet;
|
||||||
|
class Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
namespace skin {
|
||||||
|
|
||||||
|
class Style;
|
||||||
|
|
||||||
|
class StyleSheet {
|
||||||
|
public:
|
||||||
|
StyleSheet();
|
||||||
|
~StyleSheet();
|
||||||
|
|
||||||
|
static css::Rule& backgroundColorRule() { return m_backgroundColorRule; }
|
||||||
|
static css::Rule& backgroundPartRule() { return m_backgroundPartRule; }
|
||||||
|
static css::Rule& iconAlignRule() { return m_iconAlignRule; }
|
||||||
|
static css::Rule& iconPartRule() { return m_iconPartRule; }
|
||||||
|
static css::Rule& textAlignRule() { return m_textAlignRule; }
|
||||||
|
static css::Rule& textColorRule() { return m_textColorRule; }
|
||||||
|
static css::Rule& paddingLeftRule() { return m_paddingLeftRule; }
|
||||||
|
static css::Rule& paddingTopRule() { return m_paddingTopRule; }
|
||||||
|
static css::Rule& paddingRightRule() { return m_paddingRightRule; }
|
||||||
|
static css::Rule& paddingBottomRule() { return m_paddingBottomRule; }
|
||||||
|
|
||||||
|
css::Sheet& sheet() { return *m_sheet; }
|
||||||
|
|
||||||
|
Style* getStyle(const std::string& id);
|
||||||
|
|
||||||
|
static SkinPartPtr convertPart(const css::Value& value);
|
||||||
|
static ui::Color convertColor(const css::Value& value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef std::map<std::string, Style*> StyleMap;
|
||||||
|
|
||||||
|
void destroyAllStyles();
|
||||||
|
|
||||||
|
static css::Rule m_backgroundColorRule;
|
||||||
|
static css::Rule m_backgroundPartRule;
|
||||||
|
static css::Rule m_iconAlignRule;
|
||||||
|
static css::Rule m_iconPartRule;
|
||||||
|
static css::Rule m_textAlignRule;
|
||||||
|
static css::Rule m_textColorRule;
|
||||||
|
static css::Rule m_paddingLeftRule;
|
||||||
|
static css::Rule m_paddingTopRule;
|
||||||
|
static css::Rule m_paddingRightRule;
|
||||||
|
static css::Rule m_paddingBottomRule;
|
||||||
|
|
||||||
|
css::Sheet* m_sheet;
|
||||||
|
StyleMap m_styles;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace skin
|
||||||
|
} // namespace app
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
|||||||
#include "app/context_observer.h"
|
#include "app/context_observer.h"
|
||||||
#include "app/document_observer.h"
|
#include "app/document_observer.h"
|
||||||
#include "app/ui/editor/editor_observer.h"
|
#include "app/ui/editor/editor_observer.h"
|
||||||
|
#include "app/ui/skin/style.h"
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "raster/frame_number.h"
|
#include "raster/frame_number.h"
|
||||||
#include "ui/widget.h"
|
#include "ui/widget.h"
|
||||||
@ -34,6 +35,10 @@ namespace raster {
|
|||||||
class Sprite;
|
class Sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
class Graphics;
|
||||||
|
}
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
using namespace raster;
|
using namespace raster;
|
||||||
|
|
||||||
@ -49,6 +54,7 @@ namespace app {
|
|||||||
enum State {
|
enum State {
|
||||||
STATE_STANDBY,
|
STATE_STANDBY,
|
||||||
STATE_SCROLLING,
|
STATE_SCROLLING,
|
||||||
|
STATE_SELECTING_FRAME,
|
||||||
STATE_MOVING_SEPARATOR,
|
STATE_MOVING_SEPARATOR,
|
||||||
STATE_MOVING_LAYER,
|
STATE_MOVING_LAYER,
|
||||||
STATE_MOVING_CEL,
|
STATE_MOVING_CEL,
|
||||||
@ -74,6 +80,7 @@ namespace app {
|
|||||||
protected:
|
protected:
|
||||||
bool onProcessMessage(ui::Message* msg) OVERRIDE;
|
bool onProcessMessage(ui::Message* msg) OVERRIDE;
|
||||||
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
|
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
|
||||||
|
void onPaint(ui::PaintEvent& ev) OVERRIDE;
|
||||||
|
|
||||||
// DocumentObserver impl.
|
// DocumentObserver impl.
|
||||||
void onAddLayer(DocumentEvent& ev) OVERRIDE;
|
void onAddLayer(DocumentEvent& ev) OVERRIDE;
|
||||||
@ -95,18 +102,19 @@ namespace app {
|
|||||||
private:
|
private:
|
||||||
void detachDocument();
|
void detachDocument();
|
||||||
void setCursor(int x, int y);
|
void setCursor(int x, int y);
|
||||||
void getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer);
|
void getDrawableLayers(ui::Graphics* g, int* first_layer, int* last_layer);
|
||||||
void getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame);
|
void getDrawableFrames(ui::Graphics* g, FrameNumber* first_frame, FrameNumber* last_frame);
|
||||||
void drawHeader(const gfx::Rect& clip);
|
void drawPart(ui::Graphics* g, const gfx::Rect& bounds,
|
||||||
void drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame);
|
const char* text, skin::Style* style,
|
||||||
void drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
|
bool is_active = false, bool is_hover = false, bool is_clicked = false);
|
||||||
bool is_hot, bool is_clk,
|
void drawHeader(ui::Graphics* g);
|
||||||
const char* text, int text_align);
|
void drawHeaderFrame(ui::Graphics* g, FrameNumber frame);
|
||||||
void drawSeparator(const gfx::Rect& clip);
|
void drawLayer(ui::Graphics* g, int layer_index);
|
||||||
void drawLayer(const gfx::Rect& clip, int layer_index);
|
void drawCel(ui::Graphics* g, int layer_index, FrameNumber frame, Cel* cel);
|
||||||
void drawLayerPadding();
|
void drawPaddings(ui::Graphics* g);
|
||||||
void drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel);
|
bool drawPart(ui::Graphics* g, int part, int layer, FrameNumber frame);
|
||||||
bool drawPart(int part, int layer, FrameNumber frame);
|
gfx::Rect getPartBounds(int part, int layer = 0, FrameNumber frame = FrameNumber(0)) const;
|
||||||
|
void invalidatePart(int part, int layer, FrameNumber frame);
|
||||||
void regenerateLayers();
|
void regenerateLayers();
|
||||||
void hotThis(int hot_part, int hot_layer, FrameNumber hotFrame);
|
void hotThis(int hot_part, int hot_layer, FrameNumber hotFrame);
|
||||||
void centerCel(int layer, FrameNumber frame);
|
void centerCel(int layer, FrameNumber frame);
|
||||||
@ -114,14 +122,32 @@ namespace app {
|
|||||||
void showCurrentCel();
|
void showCurrentCel();
|
||||||
void cleanClk();
|
void cleanClk();
|
||||||
void setScroll(int x, int y, bool use_refresh_region);
|
void setScroll(int x, int y, bool use_refresh_region);
|
||||||
int getLayerIndex(const Layer* layer);
|
int getLayerIndex(const Layer* layer) const;
|
||||||
|
bool isLayerActive(const Layer* layer) const;
|
||||||
|
bool isFrameActive(FrameNumber frame) const;
|
||||||
|
|
||||||
|
skin::Style* m_timelineStyle;
|
||||||
|
skin::Style* m_timelineBoxStyle;
|
||||||
|
skin::Style* m_timelineOpenEyeStyle;
|
||||||
|
skin::Style* m_timelineClosedEyeStyle;
|
||||||
|
skin::Style* m_timelineOpenPadlockStyle;
|
||||||
|
skin::Style* m_timelineClosedPadlockStyle;
|
||||||
|
skin::Style* m_timelineLayerStyle;
|
||||||
|
skin::Style* m_timelineEmptyFrameStyle;
|
||||||
|
skin::Style* m_timelineKeyframeStyle;
|
||||||
|
skin::Style* m_timelineGearStyle;
|
||||||
|
skin::Style* m_timelinePaddingStyle;
|
||||||
|
skin::Style* m_timelinePaddingTrStyle;
|
||||||
|
skin::Style* m_timelinePaddingBlStyle;
|
||||||
|
skin::Style* m_timelinePaddingBrStyle;
|
||||||
Context* m_context;
|
Context* m_context;
|
||||||
Editor* m_editor;
|
Editor* m_editor;
|
||||||
Document* m_document;
|
Document* m_document;
|
||||||
Sprite* m_sprite;
|
Sprite* m_sprite;
|
||||||
Layer* m_layer;
|
Layer* m_layer;
|
||||||
FrameNumber m_frame;
|
FrameNumber m_frame;
|
||||||
|
FrameNumber m_frameBegin;
|
||||||
|
FrameNumber m_frameEnd;
|
||||||
State m_state;
|
State m_state;
|
||||||
std::vector<Layer*> m_layers;
|
std::vector<Layer*> m_layers;
|
||||||
int m_scroll_x;
|
int m_scroll_x;
|
||||||
|
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();
|
||||||
|
|
||||||
|
const 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 {
|
||||||
|
const 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
|
250
src/css/css_unittest.cpp
Normal file
250
src/css/css_unittest.cpp
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
// 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);
|
||||||
|
Style sub2("sub2", &sub);
|
||||||
|
Style sub3("sub3", &sub2);
|
||||||
|
Style sub3FocusHover("sub3:focus:hover", &sub2);
|
||||||
|
|
||||||
|
base[bg] = Value(1);
|
||||||
|
base[fg] = Value(2);
|
||||||
|
baseHover[fg] = Value(3);
|
||||||
|
baseFocus[bg] = Value(4);
|
||||||
|
|
||||||
|
sub[bg] = Value(5);
|
||||||
|
subFocus[fg] = Value(6);
|
||||||
|
|
||||||
|
sub3[bg] = Value(7);
|
||||||
|
sub3FocusHover[fg] = Value(8);
|
||||||
|
|
||||||
|
Sheet sheet;
|
||||||
|
sheet.addRule(&bg);
|
||||||
|
sheet.addRule(&fg);
|
||||||
|
sheet.addStyle(&base);
|
||||||
|
sheet.addStyle(&baseHover);
|
||||||
|
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]);
|
||||||
|
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]);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
61
src/css/map.h
Normal file
61
src/css/map.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exists(const std::string& name) const {
|
||||||
|
return (m_map.find(name) != m_map.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
map m_map;
|
||||||
|
T m_default;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace css
|
||||||
|
|
||||||
|
#endif
|
29
src/css/query.cpp
Normal file
29
src/css/query.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// 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::addFromStyle(const Style* style)
|
||||||
|
{
|
||||||
|
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
|
43
src/css/query.h
Normal file
43
src/css/query.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// 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() { }
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
const Style* style = m_ruleValue[rule.name()];
|
||||||
|
if (style)
|
||||||
|
return (*style)[rule.name()];
|
||||||
|
else
|
||||||
|
return m_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addRuleValue(const std::string& ruleName, const Style* style);
|
||||||
|
|
||||||
|
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
|
110
src/css/sheet.cpp
Normal file
110
src/css/sheet.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
#include <stdio.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
const 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
|
76
src/css/state.h
Normal file
76
src/css/state.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
// 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;
|
||||||
|
typedef List::reverse_iterator reverse_iterator;
|
||||||
|
typedef List::const_reverse_iterator const_reverse_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(); }
|
||||||
|
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);
|
||||||
|
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, const Style* base) :
|
||||||
|
m_name(name),
|
||||||
|
m_base(base) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace css
|
53
src/css/style.h
Normal file
53
src/css/style.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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;
|
||||||
|
typedef Values::const_iterator const_iterator;
|
||||||
|
|
||||||
|
Style() { }
|
||||||
|
Style(const std::string& name, const Style* base = NULL);
|
||||||
|
|
||||||
|
const std::string& name() const { return m_name; }
|
||||||
|
const 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(); }
|
||||||
|
const_iterator begin() const { return m_values.begin(); }
|
||||||
|
const_iterator end() const { return m_values.end(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_name;
|
||||||
|
const Style* m_base;
|
||||||
|
Values m_values;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Map<const 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
|
53
src/css/value.h
Normal file
53
src/css/value.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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;
|
||||||
|
bool operator!=(const Value& other) const {
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type;
|
||||||
|
double m_number;
|
||||||
|
std::string m_string;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef Map<Value> Values;
|
||||||
|
|
||||||
|
} // namespace css
|
||||||
|
|
||||||
|
#endif
|
@ -145,13 +145,21 @@ gfx::Size Graphics::fitString(const std::string& str, int maxWidth, int align)
|
|||||||
|
|
||||||
gfx::Size Graphics::drawStringAlgorithm(const std::string& str, Color fg, Color bg, const gfx::Rect& rc, int align, bool draw)
|
gfx::Size Graphics::drawStringAlgorithm(const std::string& str, Color fg, Color bg, const gfx::Rect& rc, int align, bool draw)
|
||||||
{
|
{
|
||||||
|
gfx::Point pt(0, rc.y);
|
||||||
|
|
||||||
|
if ((align & (JI_MIDDLE | JI_BOTTOM)) != 0) {
|
||||||
|
gfx::Size preSize = drawStringAlgorithm(str, ColorNone, ColorNone, rc, 0, false);
|
||||||
|
if (align & JI_MIDDLE)
|
||||||
|
pt.y = rc.y + rc.h/2 - preSize.h/2;
|
||||||
|
else if (align & JI_BOTTOM)
|
||||||
|
pt.y = rc.y + rc.h - preSize.h;
|
||||||
|
}
|
||||||
|
|
||||||
gfx::Size calculatedSize(0, 0);
|
gfx::Size calculatedSize(0, 0);
|
||||||
size_t beg, end, new_word_beg, old_end;
|
size_t beg, end, new_word_beg, old_end;
|
||||||
std::string line;
|
std::string line;
|
||||||
gfx::Point pt;
|
|
||||||
|
|
||||||
// Draw line-by-line
|
// Draw line-by-line
|
||||||
pt.y = rc.y;
|
|
||||||
for (beg=end=0; end != std::string::npos; ) {
|
for (beg=end=0; end != std::string::npos; ) {
|
||||||
pt.x = rc.x;
|
pt.x = rc.x;
|
||||||
|
|
||||||
@ -209,19 +217,19 @@ gfx::Size Graphics::drawStringAlgorithm(const std::string& str, Color fg, Color
|
|||||||
ji_font_set_aa_mode(m_currentFont, to_system(bg));
|
ji_font_set_aa_mode(m_currentFont, to_system(bg));
|
||||||
textout_ex(m_bmp, m_currentFont, line.c_str(), m_dx+xout, m_dy+pt.y, to_system(fg), to_system(bg));
|
textout_ex(m_bmp, m_currentFont, line.c_str(), m_dx+xout, m_dy+pt.y, to_system(fg), to_system(bg));
|
||||||
|
|
||||||
jrectexclude(m_bmp,
|
if (!is_transparent(bg))
|
||||||
m_dx+rc.x, m_dy+pt.y, m_dx+rc.x+rc.w-1, m_dy+pt.y+lineSize.h-1,
|
jrectexclude(m_bmp,
|
||||||
m_dx+xout, m_dy+pt.y, m_dx+xout+lineSize.w-1, m_dy+pt.y+lineSize.h-1, bg);
|
m_dx+rc.x, m_dy+pt.y, m_dx+rc.x+rc.w-1, m_dy+pt.y+lineSize.h-1,
|
||||||
|
m_dx+xout, m_dy+pt.y, m_dx+xout+lineSize.w-1, m_dy+pt.y+lineSize.h-1, bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pt.y += lineSize.h;
|
pt.y += lineSize.h;
|
||||||
|
calculatedSize.h += lineSize.h;
|
||||||
beg = end+1;
|
beg = end+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
calculatedSize.h += pt.y;
|
|
||||||
|
|
||||||
// Fill bottom area
|
// Fill bottom area
|
||||||
if (draw) {
|
if (draw && !is_transparent(bg)) {
|
||||||
if (pt.y < rc.y+rc.h)
|
if (pt.y < rc.y+rc.h)
|
||||||
fillRect(bg, gfx::Rect(rc.x, pt.y, rc.w, rc.y+rc.h-pt.y));
|
fillRect(bg, gfx::Rect(rc.x, pt.y, rc.w, rc.y+rc.h-pt.y));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user