mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-10 12:44:53 +00:00
TimeLine: add range outline and hot state
This is the first step to improve the copy/move of ranges in the timeline.
This commit is contained in:
parent
875301cb82
commit
7ea7521f6a
@ -492,6 +492,16 @@
|
|||||||
<background color="timeline_normal" part="timeline_padding_br" />
|
<background color="timeline_normal" part="timeline_padding_br" />
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<!-- timeline_range_outline -->
|
||||||
|
<style id="timeline_range_outline">
|
||||||
|
</style>
|
||||||
|
<style id="timeline_range_outline:active">
|
||||||
|
<background part="colorbar_border_hotfg" />
|
||||||
|
</style>
|
||||||
|
<style id="timeline_range_outline:hover">
|
||||||
|
<background part="colorbar_border_fg" />
|
||||||
|
</style>
|
||||||
|
|
||||||
</stylesheet>
|
</stylesheet>
|
||||||
|
|
||||||
</skin>
|
</skin>
|
||||||
|
@ -102,6 +102,7 @@ static const char* kTimelinePaddingTr = "timeline_padding_tr";
|
|||||||
static const char* kTimelinePaddingBl = "timeline_padding_bl";
|
static const char* kTimelinePaddingBl = "timeline_padding_bl";
|
||||||
static const char* kTimelinePaddingBr = "timeline_padding_br";
|
static const char* kTimelinePaddingBr = "timeline_padding_br";
|
||||||
static const char* kTimelineSelectedCelStyle = "timeline_selected_cel";
|
static const char* kTimelineSelectedCelStyle = "timeline_selected_cel";
|
||||||
|
static const char* kTimelineRangeOutlineStyle = "timeline_range_outline";
|
||||||
|
|
||||||
static const char* kTimelineActiveColor = "timeline_active";
|
static const char* kTimelineActiveColor = "timeline_active";
|
||||||
|
|
||||||
@ -118,7 +119,8 @@ enum {
|
|||||||
A_PART_LAYER_EYE_ICON,
|
A_PART_LAYER_EYE_ICON,
|
||||||
A_PART_LAYER_PADLOCK_ICON,
|
A_PART_LAYER_PADLOCK_ICON,
|
||||||
A_PART_LAYER_TEXT,
|
A_PART_LAYER_TEXT,
|
||||||
A_PART_CEL
|
A_PART_CEL,
|
||||||
|
A_PART_RANGE_OUTLINE
|
||||||
};
|
};
|
||||||
|
|
||||||
Timeline::Timeline()
|
Timeline::Timeline()
|
||||||
@ -143,6 +145,7 @@ Timeline::Timeline()
|
|||||||
, m_timelinePaddingBlStyle(get_style(kTimelinePaddingBl))
|
, m_timelinePaddingBlStyle(get_style(kTimelinePaddingBl))
|
||||||
, m_timelinePaddingBrStyle(get_style(kTimelinePaddingBr))
|
, m_timelinePaddingBrStyle(get_style(kTimelinePaddingBr))
|
||||||
, m_timelineSelectedCelStyle(get_style(kTimelineSelectedCelStyle))
|
, m_timelineSelectedCelStyle(get_style(kTimelineSelectedCelStyle))
|
||||||
|
, m_timelineRangeOutlineStyle(get_style(kTimelineRangeOutlineStyle))
|
||||||
, m_context(UIContext::instance())
|
, m_context(UIContext::instance())
|
||||||
, m_editor(NULL)
|
, m_editor(NULL)
|
||||||
, m_document(NULL)
|
, m_document(NULL)
|
||||||
@ -312,7 +315,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
m_state = STATE_MOVING_FRAME;
|
m_state = STATE_MOVING_FRAME;
|
||||||
else {
|
else {
|
||||||
m_state = STATE_SELECTING_FRAMES;
|
m_state = STATE_SELECTING_FRAMES;
|
||||||
m_range.startRange(getLayerIndex(m_layer), m_clk_frame);
|
m_range.startRange(getLayerIndex(m_layer), m_clk_frame, Range::Frames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -349,7 +352,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (startRange)
|
if (startRange)
|
||||||
m_range.startRange(m_clk_layer, m_frame);
|
m_range.startRange(m_clk_layer, m_frame, Range::Layers);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -382,7 +385,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
else {
|
else {
|
||||||
m_state = STATE_SELECTING_CELS;
|
m_state = STATE_SELECTING_CELS;
|
||||||
if (selectCel)
|
if (selectCel)
|
||||||
m_range.startRange(m_clk_layer, m_clk_frame);
|
m_range.startRange(m_clk_layer, m_clk_frame, Range::Cels);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -521,6 +524,12 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
else {
|
else {
|
||||||
if (hot_layer >= (int)m_layers.size()) hot_layer = -1;
|
if (hot_layer >= (int)m_layers.size()) hot_layer = -1;
|
||||||
if (hot_frame > m_sprite->getLastFrame()) hot_frame = FrameNumber(-1);
|
if (hot_frame > m_sprite->getLastFrame()) hot_frame = FrameNumber(-1);
|
||||||
|
|
||||||
|
gfx::Rect outline = getPartBounds(A_PART_RANGE_OUTLINE);
|
||||||
|
if (outline.contains(mousePos) &&
|
||||||
|
!gfx::Rect(outline).shrink(4*jguiscale()).contains(mousePos)) {
|
||||||
|
hot_part = A_PART_RANGE_OUTLINE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the new 'hot' thing.
|
// Set the new 'hot' thing.
|
||||||
@ -669,7 +678,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
regenerateLayers();
|
regenerateLayers();
|
||||||
|
|
||||||
m_range.startRange(getLayerIndex(firstLayer), m_frame);
|
m_range.startRange(getLayerIndex(firstLayer), m_frame, m_range.type());
|
||||||
m_range.endRange(getLayerIndex(lastLayer), m_frame);
|
m_range.endRange(getLayerIndex(lastLayer), m_frame);
|
||||||
}
|
}
|
||||||
catch (LockedDocumentException& e) {
|
catch (LockedDocumentException& e) {
|
||||||
@ -748,11 +757,6 @@ bool Timeline::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable range if we selected only one cel.
|
|
||||||
if (m_range.layerBegin() == m_range.layerEnd() &&
|
|
||||||
m_range.frameBegin() == m_range.frameEnd())
|
|
||||||
m_range.disableRange();
|
|
||||||
|
|
||||||
// Clean the clicked-part & redraw the hot-part.
|
// Clean the clicked-part & redraw the hot-part.
|
||||||
cleanClk();
|
cleanClk();
|
||||||
|
|
||||||
@ -942,6 +946,7 @@ void Timeline::onPaint(ui::PaintEvent& ev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
drawPaddings(g);
|
drawPaddings(g);
|
||||||
|
drawRangeOutline(g);
|
||||||
}
|
}
|
||||||
catch (const LockedDocumentException&) {
|
catch (const LockedDocumentException&) {
|
||||||
noDoc = true;
|
noDoc = true;
|
||||||
@ -1099,6 +1104,9 @@ void Timeline::setCursor(int x, int y)
|
|||||||
|| m_state == STATE_MOVING_ONIONSKIN_RANGE_RIGHT) {
|
|| m_state == STATE_MOVING_ONIONSKIN_RANGE_RIGHT) {
|
||||||
jmouse_set_cursor(kSizeRCursor);
|
jmouse_set_cursor(kSizeRCursor);
|
||||||
}
|
}
|
||||||
|
else if (m_hot_part == A_PART_RANGE_OUTLINE) {
|
||||||
|
jmouse_set_cursor(kMoveCursor);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
jmouse_set_cursor(kArrowCursor);
|
jmouse_set_cursor(kArrowCursor);
|
||||||
}
|
}
|
||||||
@ -1270,6 +1278,17 @@ void Timeline::drawCel(ui::Graphics* g, int layer_index, FrameNumber frame, Cel*
|
|||||||
drawPart(g, bounds, NULL, style, is_active, is_hover);
|
drawPart(g, bounds, NULL, style, is_active, is_hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Timeline::drawRangeOutline(ui::Graphics* g)
|
||||||
|
{
|
||||||
|
gfx::Rect bounds = getPartBounds(A_PART_RANGE_OUTLINE);
|
||||||
|
|
||||||
|
Style::State state;
|
||||||
|
if (m_range.enabled()) state += Style::active();
|
||||||
|
if (m_hot_part == A_PART_RANGE_OUTLINE) state += Style::hover();
|
||||||
|
|
||||||
|
m_timelineRangeOutlineStyle->paint(g, bounds, NULL, state);
|
||||||
|
}
|
||||||
|
|
||||||
void Timeline::drawPaddings(ui::Graphics* g)
|
void Timeline::drawPaddings(ui::Graphics* g)
|
||||||
{
|
{
|
||||||
gfx::Rect client = getClientBounds();
|
gfx::Rect client = getClientBounds();
|
||||||
@ -1425,6 +1444,24 @@ gfx::Rect Timeline::getPartBounds(int part, int layer, FrameNumber frame) const
|
|||||||
LAYSIZE);
|
LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case A_PART_RANGE_OUTLINE:
|
||||||
|
switch (m_range.type()) {
|
||||||
|
case Range::None: break; // Return empty rectangle
|
||||||
|
case Range::Cels:
|
||||||
|
return
|
||||||
|
getPartBounds(A_PART_CEL, m_range.layerBegin(), m_range.frameBegin()).createUnion(
|
||||||
|
getPartBounds(A_PART_CEL, m_range.layerEnd(), m_range.frameEnd())).enlarge(2*jguiscale());
|
||||||
|
case Range::Frames:
|
||||||
|
return
|
||||||
|
getPartBounds(A_PART_HEADER_FRAME, 0, m_range.frameBegin()).createUnion(
|
||||||
|
getPartBounds(A_PART_HEADER_FRAME, 0, m_range.frameEnd()));
|
||||||
|
case Range::Layers:
|
||||||
|
return
|
||||||
|
getPartBounds(A_PART_LAYER, m_range.layerBegin()).createUnion(
|
||||||
|
getPartBounds(A_PART_LAYER, m_range.layerEnd()));
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return gfx::Rect();
|
return gfx::Rect();
|
||||||
@ -1658,28 +1695,28 @@ bool Timeline::isFrameActive(FrameNumber frame) const
|
|||||||
return m_range.inRange(frame);
|
return m_range.inRange(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::Range::startRange(int layer, FrameNumber frame)
|
void Timeline::Range::startRange(int layer, FrameNumber frame, Type type)
|
||||||
{
|
{
|
||||||
m_enabled = true;
|
m_type = type;
|
||||||
m_layerBegin = m_layerEnd = layer;
|
m_layerBegin = m_layerEnd = layer;
|
||||||
m_frameBegin = m_frameEnd = frame;
|
m_frameBegin = m_frameEnd = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::Range::endRange(int layer, FrameNumber frame)
|
void Timeline::Range::endRange(int layer, FrameNumber frame)
|
||||||
{
|
{
|
||||||
ASSERT(m_enabled);
|
ASSERT(enabled());
|
||||||
m_layerEnd = layer;
|
m_layerEnd = layer;
|
||||||
m_frameEnd = frame;
|
m_frameEnd = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::Range::disableRange()
|
void Timeline::Range::disableRange()
|
||||||
{
|
{
|
||||||
m_enabled = false;
|
m_type = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Timeline::Range::inRange(int layer) const
|
bool Timeline::Range::inRange(int layer) const
|
||||||
{
|
{
|
||||||
if (m_enabled)
|
if (enabled())
|
||||||
return (layer >= layerBegin() && layer <= layerEnd());
|
return (layer >= layerBegin() && layer <= layerEnd());
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
@ -1687,7 +1724,7 @@ bool Timeline::Range::inRange(int layer) const
|
|||||||
|
|
||||||
bool Timeline::Range::inRange(FrameNumber frame) const
|
bool Timeline::Range::inRange(FrameNumber frame) const
|
||||||
{
|
{
|
||||||
if (m_enabled)
|
if (enabled())
|
||||||
return (frame >= frameBegin() && frame <= frameEnd());
|
return (frame >= frameBegin() && frame <= frameEnd());
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -67,9 +67,12 @@ namespace app {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Range {
|
struct Range {
|
||||||
Range() : m_enabled(false) { }
|
enum Type { None, Cels, Frames, Layers };
|
||||||
|
|
||||||
bool enabled() const { return m_enabled; }
|
Range() : m_type(None) { }
|
||||||
|
|
||||||
|
Type type() const { return m_type; }
|
||||||
|
bool enabled() const { return m_type != None; }
|
||||||
int layerBegin() const { return MIN(m_layerBegin, m_layerEnd); }
|
int layerBegin() const { return MIN(m_layerBegin, m_layerEnd); }
|
||||||
int layerEnd() const { return MAX(m_layerBegin, m_layerEnd); }
|
int layerEnd() const { return MAX(m_layerBegin, m_layerEnd); }
|
||||||
FrameNumber frameBegin() const { return MIN(m_frameBegin, m_frameEnd); }
|
FrameNumber frameBegin() const { return MIN(m_frameBegin, m_frameEnd); }
|
||||||
@ -79,12 +82,12 @@ namespace app {
|
|||||||
bool inRange(FrameNumber frame) const;
|
bool inRange(FrameNumber frame) const;
|
||||||
bool inRange(int layer, FrameNumber frame) const;
|
bool inRange(int layer, FrameNumber frame) const;
|
||||||
|
|
||||||
void startRange(int layer, FrameNumber frame);
|
void startRange(int layer, FrameNumber frame, Type type);
|
||||||
void endRange(int layer, FrameNumber frame);
|
void endRange(int layer, FrameNumber frame);
|
||||||
void disableRange();
|
void disableRange();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_enabled;
|
Type m_type;
|
||||||
int m_layerBegin;
|
int m_layerBegin;
|
||||||
int m_layerEnd;
|
int m_layerEnd;
|
||||||
FrameNumber m_frameBegin;
|
FrameNumber m_frameBegin;
|
||||||
@ -142,6 +145,7 @@ namespace app {
|
|||||||
void drawHeaderFrame(ui::Graphics* g, FrameNumber frame);
|
void drawHeaderFrame(ui::Graphics* g, FrameNumber frame);
|
||||||
void drawLayer(ui::Graphics* g, int layer_index);
|
void drawLayer(ui::Graphics* g, int layer_index);
|
||||||
void drawCel(ui::Graphics* g, int layer_index, FrameNumber frame, Cel* cel);
|
void drawCel(ui::Graphics* g, int layer_index, FrameNumber frame, Cel* cel);
|
||||||
|
void drawRangeOutline(ui::Graphics* g);
|
||||||
void drawPaddings(ui::Graphics* g);
|
void drawPaddings(ui::Graphics* g);
|
||||||
bool drawPart(ui::Graphics* g, int part, int layer, FrameNumber frame);
|
bool drawPart(ui::Graphics* g, int part, int layer, FrameNumber frame);
|
||||||
gfx::Rect getLayerHeadersBounds() const;
|
gfx::Rect getLayerHeadersBounds() const;
|
||||||
@ -182,6 +186,7 @@ namespace app {
|
|||||||
skin::Style* m_timelinePaddingBlStyle;
|
skin::Style* m_timelinePaddingBlStyle;
|
||||||
skin::Style* m_timelinePaddingBrStyle;
|
skin::Style* m_timelinePaddingBrStyle;
|
||||||
skin::Style* m_timelineSelectedCelStyle;
|
skin::Style* m_timelineSelectedCelStyle;
|
||||||
|
skin::Style* m_timelineRangeOutlineStyle;
|
||||||
Context* m_context;
|
Context* m_context;
|
||||||
Editor* m_editor;
|
Editor* m_editor;
|
||||||
Document* m_document;
|
Document* m_document;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user