Show disabled eye/padlock in Timeline when parent is deactivated

We've added a new "disabled" style state to do this.
This commit is contained in:
David Capello 2016-06-15 12:00:31 -03:00
parent 81c4043127
commit a2a06965db
9 changed files with 116 additions and 34 deletions

View File

@ -529,12 +529,18 @@
<style id="timeline_open_eye:active">
<icon part="timeline_open_eye_active" />
</style>
<style id="timeline_open_eye:disabled">
<icon color="disabled" />
</style>
<style id="timeline_closed_eye" base="timeline_box">
<icon part="timeline_closed_eye_normal" align="center" valign="middle" />
</style>
<style id="timeline_closed_eye:active">
<icon part="timeline_closed_eye_active" />
</style>
<style id="timeline_closed_eye:disabled">
<icon color="disabled" />
</style>
<!-- timeline_padlock -->
<style id="timeline_open_padlock" base="timeline_box">
@ -543,12 +549,18 @@
<style id="timeline_open_padlock:active">
<icon part="timeline_open_padlock_active" />
</style>
<style id="timeline_open_padlock:disabled">
<icon color="disabled" />
</style>
<style id="timeline_closed_padlock" base="timeline_box">
<icon part="timeline_closed_padlock_normal" align="center" valign="middle" />
</style>
<style id="timeline_closed_padlock:active">
<icon part="timeline_closed_padlock_active" />
</style>
<style id="timeline_closed_padlock:disabled">
<icon color="disabled" />
</style>
<!-- timeline_continuous -->
<style id="timeline_continuous" base="timeline_box">

View File

@ -459,10 +459,10 @@ void SkinTheme::loadXml(const std::string& skinId)
else if (ruleName == "icon") {
if (align) (*style)[StyleSheet::iconAlignRule()] = css::Value(align);
if (part_id) (*style)[StyleSheet::iconPartRule()] = css::Value(part_id);
if (color_id) (*style)[StyleSheet::iconColorRule()] = value_or_none(color_id);
const char* x = xmlRule->Attribute("x");
const char* y = xmlRule->Attribute("y");
if (x) (*style)[StyleSheet::iconXRule()] = css::Value(strtol(x, NULL, 10));
if (y) (*style)[StyleSheet::iconYRule()] = css::Value(strtol(y, NULL, 10));
}

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -23,6 +23,7 @@ namespace skin {
css::State Style::m_hoverState("hover");
css::State Style::m_activeState("active");
css::State Style::m_clickedState("clicked");
css::State Style::m_disabledState("disabled");
Rule::~Rule()
{
@ -110,7 +111,10 @@ void IconRule::onPaint(ui::Graphics* g, const gfx::Rect& bounds, const char* tex
x += m_x;
y += m_y;
g->drawRgbaSurface(bmp, x, y);
if (m_color == gfx::ColorNone)
g->drawRgbaSurface(bmp, x, y);
else
g->drawColoredRgbaSurface(bmp, m_color, x, y);
}
Rules::Rules(const css::Query& query) :
@ -125,6 +129,7 @@ Rules::Rules(const css::Query& query) :
css::Value iconPart = query[StyleSheet::iconPartRule()];
css::Value iconX = query[StyleSheet::iconXRule()];
css::Value iconY = query[StyleSheet::iconYRule()];
css::Value iconColor = query[StyleSheet::iconColorRule()];
css::Value textAlign = query[StyleSheet::textAlignRule()];
css::Value textColor = query[StyleSheet::textColorRule()];
css::Value paddingLeft = query[StyleSheet::paddingLeftRule()];
@ -145,12 +150,14 @@ Rules::Rules(const css::Query& query) :
if (iconAlign != none
|| iconPart != none
|| iconX != none
|| iconY != none) {
|| iconY != none
|| iconColor != none) {
m_icon = new IconRule();
m_icon->setAlign((int)iconAlign.number());
m_icon->setPart(StyleSheet::convertPart(iconPart));
m_icon->setX((int)iconX.number()*ui::guiscale());
m_icon->setY((int)iconY.number()*ui::guiscale());
m_icon->setColor(StyleSheet::convertColor(iconColor));
}
if (textAlign != none

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -84,12 +84,14 @@ namespace app {
class IconRule : public Rule {
public:
explicit IconRule() : m_align(0) { }
explicit IconRule() : m_align(0),
m_color(gfx::ColorNone) { }
void setAlign(int align) { m_align = align; }
void setPart(const SkinPartPtr& part) { m_part = part; }
void setX(int x) { m_x = x; }
void setY(int y) { m_y = y; }
void setColor(gfx::Color color) { m_color = color; }
SkinPartPtr getPart() { return m_part; }
@ -100,6 +102,7 @@ namespace app {
int m_align;
SkinPartPtr m_part;
int m_x, m_y;
gfx::Color m_color;
};
class Rules {
@ -128,6 +131,7 @@ namespace app {
static const css::State& hover() { return m_hoverState; }
static const css::State& active() { return m_activeState; }
static const css::State& clicked() { return m_clickedState; }
static const css::State& disabled() { return m_disabledState; }
Style(css::Sheet& sheet, const std::string& id);
~Style();
@ -156,6 +160,7 @@ namespace app {
static css::State m_hoverState;
static css::State m_activeState;
static css::State m_clickedState;
static css::State m_disabledState;
};
} // namespace skin

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -28,6 +28,7 @@ css::Rule StyleSheet::m_iconAlignRule("icon-align");
css::Rule StyleSheet::m_iconPartRule("icon-part");
css::Rule StyleSheet::m_iconXRule("icon-x");
css::Rule StyleSheet::m_iconYRule("icon-y");
css::Rule StyleSheet::m_iconColorRule("icon-color");
css::Rule StyleSheet::m_textAlignRule("text-align");
css::Rule StyleSheet::m_textColorRule("text-color");
css::Rule StyleSheet::m_paddingLeftRule("padding-left");
@ -45,6 +46,7 @@ StyleSheet::StyleSheet()
m_sheet->addRule(&m_iconPartRule);
m_sheet->addRule(&m_iconXRule);
m_sheet->addRule(&m_iconYRule);
m_sheet->addRule(&m_iconColorRule);
m_sheet->addRule(&m_textAlignRule);
m_sheet->addRule(&m_textColorRule);
m_sheet->addRule(&m_paddingLeftRule);

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2001-2015 David Capello
// Copyright (C) 2001-2016 David Capello
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
@ -43,6 +43,7 @@ namespace app {
static css::Rule& iconPartRule() { return m_iconPartRule; }
static css::Rule& iconXRule() { return m_iconXRule; }
static css::Rule& iconYRule() { return m_iconYRule; }
static css::Rule& iconColorRule() { return m_iconColorRule; }
static css::Rule& textAlignRule() { return m_textAlignRule; }
static css::Rule& textColorRule() { return m_textColorRule; }
static css::Rule& paddingLeftRule() { return m_paddingLeftRule; }
@ -69,6 +70,7 @@ namespace app {
static css::Rule m_iconPartRule;
static css::Rule m_iconXRule;
static css::Rule m_iconYRule;
static css::Rule m_iconColorRule;
static css::Rule m_textAlignRule;
static css::Rule m_textColorRule;
static css::Rule m_paddingLeftRule;

View File

@ -121,12 +121,27 @@ struct Timeline::DrawCelData {
namespace {
template<typename Pred>
void for_each_expanded_layer(LayerGroup* group, Pred&& pred, int level = 0) {
void for_each_expanded_layer(LayerGroup* group,
Pred&& pred,
int level = 0,
LayerFlags flags =
LayerFlags(int(LayerFlags::Visible) |
int(LayerFlags::Editable))) {
if (!group->isVisible())
flags = static_cast<LayerFlags>(int(flags) & ~int(LayerFlags::Visible));
if (!group->isEditable())
flags = static_cast<LayerFlags>(int(flags) & ~int(LayerFlags::Editable));
for (Layer* child : group->layers()) {
if (child->isGroup() && !child->isCollapsed())
for_each_expanded_layer<Pred>(static_cast<LayerGroup*>(child),
std::forward<Pred>(pred), level+1);
pred(child, level);
for_each_expanded_layer<Pred>(
static_cast<LayerGroup*>(child),
std::forward<Pred>(pred),
level+1,
flags);
pred(child, level, flags);
}
}
@ -592,6 +607,8 @@ bool Timeline::onProcessMessage(Message* msg)
return true;
}
bool regenLayers = false;
switch (m_hot.part) {
case PART_NOTHING:
@ -602,8 +619,11 @@ bool Timeline::onProcessMessage(Message* msg)
case PART_HEADER_EYE: {
bool newVisibleState = !allLayersVisible();
for (size_t i=0; i<m_layers.size(); i++)
for (size_t i=0; i<m_layers.size(); i++) {
m_layers[i].layer->setVisible(newVisibleState);
if (m_layers[i].layer->isGroup())
regenLayers = true;
}
// Redraw all views.
m_document->notifyGeneralUpdate();
@ -612,8 +632,11 @@ bool Timeline::onProcessMessage(Message* msg)
case PART_HEADER_PADLOCK: {
bool newEditableState = !allLayersUnlocked();
for (size_t i=0; i<m_layers.size(); i++)
for (size_t i=0; i<m_layers.size(); i++) {
m_layers[i].layer->setEditable(newEditableState);
if (m_layers[i].layer->isGroup())
regenLayers = true;
}
break;
}
@ -680,9 +703,12 @@ bool Timeline::onProcessMessage(Message* msg)
// Hide/show layer.
if (m_hot.layer == m_clk.layer && validLayer(m_hot.layer)) {
Layer* layer = m_layers[m_clk.layer].layer;
ASSERT(layer != NULL);
ASSERT(layer);
layer->setVisible(!layer->isVisible());
if (layer->isGroup())
regenLayers = true;
// Redraw all views.
m_document->notifyGeneralUpdate();
}
@ -692,8 +718,10 @@ bool Timeline::onProcessMessage(Message* msg)
// Lock/unlock layer.
if (m_hot.layer == m_clk.layer && validLayer(m_hot.layer)) {
Layer* layer = m_layers[m_clk.layer].layer;
ASSERT(layer != NULL);
ASSERT(layer);
layer->setEditable(!layer->isEditable());
if (layer->isGroup())
regenLayers = true;
}
break;
@ -763,6 +791,11 @@ bool Timeline::onProcessMessage(Message* msg)
}
if (regenLayers) {
regenerateLayers();
invalidate();
}
if (mouseMsg->left() &&
m_state == STATE_MOVING_RANGE &&
m_dropRange.type() != Range::kNone) {
@ -1282,8 +1315,11 @@ void Timeline::getDrawableFrames(ui::Graphics* g, frame_t* first_frame, frame_t*
}
void Timeline::drawPart(ui::Graphics* g, const gfx::Rect& bounds,
const char* text, Style* style,
bool is_active, bool is_hover, bool is_clicked)
const char* text, Style* style,
bool is_active,
bool is_hover,
bool is_clicked,
bool is_disabled)
{
IntersectClip clip(g, bounds);
if (!clip)
@ -1293,6 +1329,7 @@ void Timeline::drawPart(ui::Graphics* g, const gfx::Rect& bounds,
if (is_active) state += Style::active();
if (is_hover) state += Style::hover();
if (is_clicked) state += Style::clicked();
if (is_disabled) state += Style::disabled();
style->paint(g, bounds, text, state);
}
@ -1391,6 +1428,8 @@ void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
{
SkinTheme::Styles& styles = skinTheme()->styles;
Layer* layer = m_layers[layerIdx].layer;
bool parentVisible = ((int(m_layers[layerIdx].inheritedFlags) & int(LayerFlags::Visible)) != 0);
bool parentEditable = ((int(m_layers[layerIdx].inheritedFlags) & int(LayerFlags::Editable)) != 0);
bool is_active = isLayerActive(layerIdx);
bool hotlayer = (m_hot.layer == layerIdx);
bool clklayer = (m_clk.layer == layerIdx);
@ -1401,32 +1440,40 @@ void Timeline::drawLayer(ui::Graphics* g, LayerIndex layerIdx)
// Draw the eye (visible flag).
bounds = getPartBounds(Hit(PART_LAYER_EYE_ICON, layerIdx));
drawPart(g, bounds, NULL,
layer->isVisible() ? styles.timelineOpenEye(): styles.timelineClosedEye(),
drawPart(
g, bounds, nullptr,
(layer->isVisible() ? styles.timelineOpenEye():
styles.timelineClosedEye()),
is_active,
(hotlayer && m_hot.part == PART_LAYER_EYE_ICON),
(clklayer && m_clk.part == PART_LAYER_EYE_ICON));
(clklayer && m_clk.part == PART_LAYER_EYE_ICON),
!parentVisible);
// Draw the padlock (editable flag).
bounds = getPartBounds(Hit(PART_LAYER_PADLOCK_ICON, layerIdx));
drawPart(g, bounds, NULL,
layer->isEditable() ? styles.timelineOpenPadlock(): styles.timelineClosedPadlock(),
drawPart(
g, bounds, nullptr,
(layer->isEditable() ? styles.timelineOpenPadlock():
styles.timelineClosedPadlock()),
is_active,
(hotlayer && m_hot.part == PART_LAYER_PADLOCK_ICON),
(clklayer && m_clk.part == PART_LAYER_PADLOCK_ICON));
(clklayer && m_clk.part == PART_LAYER_PADLOCK_ICON),
!parentEditable);
// Draw the continuous flag/group icon.
bounds = getPartBounds(Hit(PART_LAYER_CONTINUOUS_ICON, layerIdx));
if (layer->isImage()) {
drawPart(g, bounds, NULL,
layer->isContinuous() ? styles.timelineContinuous(): styles.timelineDiscontinuous(),
layer->isContinuous() ? styles.timelineContinuous():
styles.timelineDiscontinuous(),
is_active,
(hotlayer && m_hot.part == PART_LAYER_CONTINUOUS_ICON),
(clklayer && m_clk.part == PART_LAYER_CONTINUOUS_ICON));
}
else if (layer->isGroup()) {
drawPart(g, bounds, NULL,
layer->isCollapsed() ? styles.timelineClosedGroup(): styles.timelineOpenGroup(),
layer->isCollapsed() ? styles.timelineClosedGroup():
styles.timelineOpenGroup(),
is_active,
(hotlayer && m_hot.part == PART_LAYER_CONTINUOUS_ICON),
(clklayer && m_clk.part == PART_LAYER_CONTINUOUS_ICON));
@ -1963,7 +2010,7 @@ void Timeline::regenerateLayers()
size_t nlayers = 0;
for_each_expanded_layer(
m_sprite->root(),
[&nlayers](Layer* layer, int level){
[&nlayers](Layer* layer, int level, LayerFlags flags) {
++nlayers;
});
@ -1977,8 +2024,8 @@ void Timeline::regenerateLayers()
size_t i = 0;
for_each_expanded_layer(
m_sprite->root(),
[&i, this](Layer* layer, int level){
m_layers[i++] = LayerInfo(layer, level);
[&i, this](Layer* layer, int level, LayerFlags flags) {
m_layers[i++] = LayerInfo(layer, level, flags);
});
updateScrollBars();

View File

@ -200,8 +200,9 @@ namespace app {
void getDrawableLayers(ui::Graphics* g, LayerIndex* first_layer, LayerIndex* last_layer);
void getDrawableFrames(ui::Graphics* g, frame_t* first_frame, frame_t* 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);
const char* text, skin::Style* style,
bool is_active = false, bool is_hover = false,
bool is_clicked = false, bool is_disabled = false);
void drawTop(ui::Graphics* g);
void drawHeader(ui::Graphics* g);
void drawHeaderFrame(ui::Graphics* g, frame_t frame);
@ -262,13 +263,18 @@ namespace app {
struct LayerInfo {
Layer* layer;
int level;
LayerFlags inheritedFlags;
LayerInfo()
: layer(nullptr), level(0) {
: layer(nullptr),
level(0),
inheritedFlags(LayerFlags::None) {
}
LayerInfo(Layer* layer, int level)
: layer(layer), level(level) {
LayerInfo(Layer* layer, int level, LayerFlags inheritedFlags)
: layer(layer),
level(level),
inheritedFlags(inheritedFlags) {
}
};

View File

@ -30,6 +30,7 @@ namespace doc {
// Layer class
enum class LayerFlags {
None = 0,
Visible = 1, // Can be read
Editable = 2, // Can be written
LockMove = 4, // Cannot be moved