Add styles to the Timeline widget

- Added support for styles to SkinTheme and skin.xml.
- Added app::skin::Style/Rule/BackgroundRule/IconRule/TextRule classes.
- Added app::skin::SkinPart class to refer to one part (BITMAP) of
  the skin sheet.
- Renamed app::skin::SkinPart to SkinParts as now SkinPart is a class.
This commit is contained in:
David Capello 2013-12-11 00:34:16 -03:00
parent 11335fd5f3
commit 4bd4aac429
15 changed files with 1456 additions and 688 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -63,6 +63,17 @@
<color id="filelist_selected_row_face" value="#2c4c91" />
<color id="filelist_disabled_row_text" value="#ffc8c8" />
<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>
<cursors>
@ -80,14 +91,14 @@
<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_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_t" x="240" y="112" 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="144" 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_bl" x="240" y="176" 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_br" x="240" y="208" 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_tr" x="256" y="160" 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_r" x="256" y="176" 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_b" x="256" 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="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" />
</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="transformation_handle" x="208" y="144" w="5" h="5" />
<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>
<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" />
</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>

View File

@ -177,9 +177,12 @@ add_library(app-library
ui/palette_view.cpp
ui/popup_window_pin.cpp
ui/skin/button_icon_impl.cpp
ui/skin/skin_part.cpp
ui/skin/skin_property.cpp
ui/skin/skin_slider_property.cpp
ui/skin/skin_theme.cpp
ui/skin/style.cpp
ui/skin/style_sheet.cpp
ui/status_bar.cpp
ui/tabs.cpp
ui/timeline.cpp

View File

@ -31,9 +31,9 @@ namespace app {
template<typename Base = ui::Button>
class SkinButton : public Base {
public:
SkinButton(SkinPart partNormal,
SkinPart partHot,
SkinPart partSelected)
SkinButton(SkinParts partNormal,
SkinParts partHot,
SkinParts partSelected)
: Base("")
, m_partNormal(partNormal)
, m_partHot(partHot)
@ -41,9 +41,9 @@ namespace app {
{
}
void setParts(SkinPart partNormal,
SkinPart partHot,
SkinPart partSelected) {
void setParts(SkinParts partNormal,
SkinParts partHot,
SkinParts partSelected) {
m_partNormal = partNormal;
m_partHot = partHot;
m_partSelected = partSelected;
@ -55,7 +55,7 @@ namespace app {
gfx::Rect bounds(Base::getClientBounds());
ui::Graphics* g = ev.getGraphics();
SkinTheme* theme = static_cast<SkinTheme*>(Base::getTheme());
SkinPart part;
SkinParts part;
if (Base::isSelected())
part = m_partSelected;
@ -68,9 +68,9 @@ namespace app {
}
private:
SkinPart m_partNormal;
SkinPart m_partHot;
SkinPart m_partSelected;
SkinParts m_partNormal;
SkinParts m_partHot;
SkinParts m_partSelected;
};
} // namespace skin

View 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

View 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

View File

@ -33,7 +33,9 @@ namespace app {
name##_W
// Available parts in the skin sheet
enum SkinPart {
enum SkinParts {
PART_NONE,
PART_RADIO_NORMAL,
PART_RADIO_SELECTED,

View File

@ -29,11 +29,14 @@
#include "app/ui/skin/skin_property.h"
#include "app/ui/skin/skin_slider_property.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_exception.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/shared_ptr.h"
#include "css/sheet.h"
#include "gfx/border.h"
#include "gfx/point.h"
#include "gfx/rect.h"
@ -145,8 +148,7 @@ SkinTheme::SkinTheme()
// Initialize all graphics in NULL (these bitmaps are loaded from the skin)
m_sheet_bmp = NULL;
for (int c=0; c<PARTS; ++c)
m_part[c] = NULL;
m_part.resize(PARTS, NULL);
sheet_mapping["radio_normal"] = PART_RADIO_NORMAL;
sheet_mapping["radio_selected"] = PART_RADIO_SELECTED;
@ -348,8 +350,8 @@ SkinTheme::~SkinTheme()
for (size_t c=0; c<m_cursors.size(); ++c)
delete m_cursors[c];
for (int c=0; c<PARTS; ++c)
destroy_bitmap(m_part[c]);
m_part.clear();
m_parts_by_id.clear();
for (std::map<std::string, BITMAP*>::iterator
it = m_toolicon.begin(); it != m_toolicon.end(); ++it) {
@ -364,7 +366,7 @@ SkinTheme::~SkinTheme()
destroy_font(m_minifont);
}
// Call ji_regen_theme after this
// Call Theme::regenerate() after this.
void SkinTheme::reload_skin()
{
if (m_sheet_bmp) {
@ -417,150 +419,229 @@ void SkinTheme::onRegenerate()
{
scrollbar_size = 12 * jguiscale();
m_part.clear();
m_part.resize(PARTS, NULL);
// Load the skin XML
std::string xml_filename = "skins/" + m_selected_skin + "/skin.xml";
ResourceFinder rf;
rf.findInDataDir(xml_filename.c_str());
while (const char* path = rf.next()) {
if (!base::file_exists(path))
continue;
const char* path;
while ((path = rf.next()) &&
!base::file_exists(path)) {
}
if (!path) // not found
return;
XmlDocumentRef doc = open_xml(path);
TiXmlHandle handle(doc);
XmlDocumentRef doc = open_xml(path);
TiXmlHandle handle(doc);
// Load colors
{
TiXmlElement* xmlColor = handle
.FirstChild("skin")
.FirstChild("colors")
.FirstChild("color").ToElement();
while (xmlColor) {
std::string id = xmlColor->Attribute("id");
uint32_t value = strtol(xmlColor->Attribute("value")+1, NULL, 16);
// Load colors
{
TiXmlElement* xmlColor = handle
.FirstChild("skin")
.FirstChild("colors")
.FirstChild("color").ToElement();
while (xmlColor) {
std::string id = xmlColor->Attribute("id");
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 =
color_mapping.find(id);
if (it != color_mapping.end()) {
m_colors[it->second] = ui::rgba((value & 0xff0000) >> 16,
(value & 0xff00) >> 8,
(value & 0xff));
}
PRINTF("Loading color '%s'...\n", id.c_str());
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
{
TiXmlElement* xmlCursor = handle
.FirstChild("skin")
.FirstChild("cursors")
.FirstChild("cursor").ToElement();
while (xmlCursor) {
std::string id = xmlCursor->Attribute("id");
int x = strtol(xmlCursor->Attribute("x"), NULL, 10);
int y = strtol(xmlCursor->Attribute("y"), NULL, 10);
int w = strtol(xmlCursor->Attribute("w"), NULL, 10);
int h = strtol(xmlCursor->Attribute("h"), NULL, 10);
int focusx = strtol(xmlCursor->Attribute("focusx"), NULL, 10);
int focusy = strtol(xmlCursor->Attribute("focusy"), NULL, 10);
int c;
// Load cursors
{
TiXmlElement* xmlCursor = handle
.FirstChild("skin")
.FirstChild("cursors")
.FirstChild("cursor").ToElement();
while (xmlCursor) {
std::string id = xmlCursor->Attribute("id");
int x = strtol(xmlCursor->Attribute("x"), NULL, 10);
int y = strtol(xmlCursor->Attribute("y"), NULL, 10);
int w = strtol(xmlCursor->Attribute("w"), NULL, 10);
int h = strtol(xmlCursor->Attribute("h"), NULL, 10);
int focusx = strtol(xmlCursor->Attribute("focusx"), NULL, 10);
int focusy = strtol(xmlCursor->Attribute("focusy"), NULL, 10);
int c;
for (c=0; c<kCursorTypes; ++c) {
if (id != cursor_names[c])
continue;
PRINTF("Loading cursor '%s'...\n", id.c_str());
delete m_cursors[c];
m_cursors[c] = NULL;
for (c=0; c<kCursorTypes; ++c) {
if (id != cursor_names[c])
continue;
BITMAP* bmp = cropPartFromSheet(NULL, x, y, w, h);
she::Surface* surface =
she::Instance()->createSurfaceFromNativeHandle(reinterpret_cast<void*>(bmp));
delete m_cursors[c];
m_cursors[c] = NULL;
m_cursors[c] = new Cursor(surface, gfx::Point(focusx*jguiscale(),
focusy*jguiscale()));
break;
}
BITMAP* bmp = cropPartFromSheet(NULL, x, y, w, h);
she::Surface* surface =
she::Instance()->createSurfaceFromNativeHandle(reinterpret_cast<void*>(bmp));
if (c == kCursorTypes) {
throw base::Exception("Unknown cursor specified in '%s':\n"
"<cursor id='%s' ... />\n", xml_filename.c_str(), id.c_str());
}
xmlCursor = xmlCursor->NextSiblingElement();
m_cursors[c] = new Cursor(surface, gfx::Point(focusx*jguiscale(),
focusy*jguiscale()));
break;
}
}
// Load tool icons
{
TiXmlElement* xmlIcon = handle
.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();
if (c == kCursorTypes) {
throw base::Exception("Unknown cursor specified in '%s':\n"
"<cursor id='%s' ... />\n", xml_filename.c_str(), id.c_str());
}
xmlCursor = xmlCursor->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;
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);
}
// Load tool icons
{
TiXmlElement* xmlIcon = handle
.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);
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;
if (w > 0 && h > 0) {
// 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();
for (size_t i=0; i<part->size(); ++i)
m_part[c+i] = part->getBitmap(i);
}
}
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);
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);
}
xmlRule = xmlRule->NextSiblingElement();
}
xmlStyle = xmlStyle->NextSiblingElement();
}
}
}
@ -2023,53 +2104,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,
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;
// 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,
rc.w-m_part[nw]->w-m_part[ne]->w, rc.h))) {
for (x = rc.x+m_part[nw]->w;
x < rc.x+rc.w-m_part[ne]->w;
x += m_part[n]->w) {
g->drawAlphaBitmap(m_part[n], x, rc.y);
if (IntersectClip clip = IntersectClip(g, Rect(rc.x+nw->w, rc.y,
rc.w-nw->w-ne->w, rc.h))) {
for (x = rc.x+nw->w;
x < rc.x+rc.w-ne->w;
x += n->w) {
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
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,
rc.w-m_part[sw]->w-m_part[se]->w, rc.h))) {
for (x = rc.x+m_part[sw]->w;
x < rc.x+rc.w-m_part[se]->w;
x += m_part[s]->w) {
g->drawAlphaBitmap(m_part[s], x, rc.y+rc.h-m_part[s]->h);
if (IntersectClip clip = IntersectClip(g, Rect(rc.x+sw->w, rc.y,
rc.w-sw->w-se->w, rc.h))) {
for (x = rc.x+sw->w;
x < rc.x+rc.w-se->w;
x += s->w) {
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,
rc.w, rc.h-m_part[nw]->h-m_part[sw]->h))) {
if (IntersectClip clip = IntersectClip(g, Rect(rc.x, rc.y+nw->h,
rc.w, rc.h-nw->h-sw->h))) {
// Left
for (y = rc.y+m_part[nw]->h;
y < rc.y+rc.h-m_part[sw]->h;
y += m_part[w]->h) {
g->drawAlphaBitmap(m_part[w], rc.x, y);
for (y = rc.y+nw->h;
y < rc.y+rc.h-sw->h;
y += w->h) {
g->drawAlphaBitmap(w, rc.x, y);
}
// Right
for (y = rc.y+m_part[ne]->h;
y < rc.y+rc.h-m_part[se]->h;
y += m_part[e]->h) {
g->drawAlphaBitmap(m_part[e], rc.x+rc.w-m_part[e]->w, y);
for (y = rc.y+ne->h;
y < rc.y+rc.h-se->h;
y += e->h) {
g->drawAlphaBitmap(e, rc.x+rc.w-e->w, y);
}
}
}
@ -2124,6 +2234,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)
{
Rect rc2(rc.x, rc.y, x_mid-rc.x+1, rc.h);

View File

@ -19,9 +19,13 @@
#ifndef 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/style_sheet.h"
#include "base/compiler_specific.h"
#include "gfx/fwd.h"
#include "ui/color.h"
#include "ui/manager.h"
#include "ui/system.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_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, 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_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);
@ -177,14 +182,31 @@ namespace app {
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:
void onRegenerate();
void onRegenerate() OVERRIDE;
private:
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);
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);
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);
ui::Color getWidgetBgColor(ui::Widget* widget);
@ -202,13 +224,28 @@ namespace app {
std::string m_selected_skin;
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, ui::Color> m_colors_by_id;
std::vector<ui::Cursor*> m_cursors;
std::vector<ui::Color> m_colors;
StyleSheet m_stylesheet;
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 app

190
src/app/ui/skin/style.cpp Normal file
View File

@ -0,0 +1,190 @@
/* 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,
bounds, 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 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) {
m_text = new TextRule();
m_text->setAlign((int)textAlign.number());
m_text->setColor(StyleSheet::convertColor(textColor));
}
}
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

151
src/app/ui/skin/style.h Normal file
View File

@ -0,0 +1,151 @@
/* 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/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; }
protected:
void onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* text) OVERRIDE;
private:
int m_align;
ui::Color m_color;
};
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

View File

@ -0,0 +1,108 @@
/* 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");
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);
}
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

View File

@ -0,0 +1,79 @@
/* 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; }
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;
css::Sheet* m_sheet;
StyleMap m_styles;
};
} // namespace skin
} // namespace app
#endif

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include "app/context_observer.h"
#include "app/document_observer.h"
#include "app/ui/editor/editor_observer.h"
#include "app/ui/skin/style.h"
#include "base/compiler_specific.h"
#include "raster/frame_number.h"
#include "ui/widget.h"
@ -34,6 +35,10 @@ namespace raster {
class Sprite;
}
namespace ui {
class Graphics;
}
namespace app {
using namespace raster;
@ -74,6 +79,7 @@ namespace app {
protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE;
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
void onPaint(ui::PaintEvent& ev) OVERRIDE;
// DocumentObserver impl.
void onAddLayer(DocumentEvent& ev) OVERRIDE;
@ -95,18 +101,19 @@ namespace app {
private:
void detachDocument();
void setCursor(int x, int y);
void getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer);
void getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame);
void drawHeader(const gfx::Rect& clip);
void drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame);
void drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
bool is_hot, bool is_clk,
const char* text, int text_align);
void drawSeparator(const gfx::Rect& clip);
void drawLayer(const gfx::Rect& clip, int layer_index);
void drawLayerPadding();
void drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel);
bool drawPart(int part, int layer, FrameNumber frame);
void getDrawableLayers(ui::Graphics* g, int* first_layer, int* last_layer);
void getDrawableFrames(ui::Graphics* g, FrameNumber* first_frame, FrameNumber* last_frame);
void drawPart(ui::Graphics* g, const gfx::Rect& bounds,
const char* text, skin::Style* style,
bool is_active = false, bool is_hover = false, bool is_clicked = false);
void drawHeader(ui::Graphics* g);
void drawHeaderFrame(ui::Graphics* g, FrameNumber frame);
void drawLayer(ui::Graphics* g, int layer_index);
void drawCel(ui::Graphics* g, int layer_index, FrameNumber frame, Cel* cel);
void drawPaddings(ui::Graphics* g);
bool drawPart(ui::Graphics* g, 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 hotThis(int hot_part, int hot_layer, FrameNumber hotFrame);
void centerCel(int layer, FrameNumber frame);
@ -116,6 +123,20 @@ namespace app {
void setScroll(int x, int y, bool use_refresh_region);
int getLayerIndex(const Layer* layer);
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;
Editor* m_editor;
Document* m_document;