Skip to content

Commit

Permalink
Improve handling of overlapping frame tags in the Timeline (fix asepr…
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Mar 27, 2017
1 parent 2c2f29b commit 27bc151
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 9 deletions.
Binary file modified data/themes/default/sheet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion data/themes/default/theme.xml
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@
<text color="button_hot_text" state="mouse" />
<text color="button_selected_text" state="selected" />
<text color="background" x="1" y="1" state="disabled" />
<newlayer />
<newlayer />
<text color="disabled" state="disabled" />
</style>
<style id="check_box" border="2">
Expand Down
86 changes: 79 additions & 7 deletions src/app/ui/timeline/timeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1136,9 +1136,11 @@ void Timeline::onResize(ui::ResizeEvent& ev)

gfx::Size sz = m_aniControls.sizeHint();
m_aniControls.setBounds(
gfx::Rect(rc.x, rc.y, MIN(sz.w, m_separator_x),
font()->height() +
skinTheme()->dimensions.timelineTagsAreaHeight()));
gfx::Rect(
rc.x,
rc.y+MAX(0, m_tagBands-1)*oneTagHeight(),
MIN(sz.w, m_separator_x),
oneTagHeight()));

updateScrollBars();
}
Expand Down Expand Up @@ -2010,11 +2012,15 @@ void Timeline::drawFrameTags(ui::Graphics* g)
clientBounds().w,
theme->dimensions.timelineTagsAreaHeight()));

std::vector<unsigned char> tagsPerFrame(m_sprite->totalFrames(), 0);

for (FrameTag* frameTag : m_sprite->frameTags()) {
gfx::Rect bounds1 = getPartBounds(Hit(PART_HEADER_FRAME, firstLayer(), frameTag->fromFrame()));
gfx::Rect bounds2 = getPartBounds(Hit(PART_HEADER_FRAME, firstLayer(), frameTag->toFrame()));
gfx::Rect bounds = bounds1.createUnion(bounds2);
bounds.y -= theme->dimensions.timelineTagsAreaHeight();
gfx::Rect frameTagBounds = getPartBounds(Hit(PART_FRAME_TAG, 0, 0, frameTag->id()));
bounds.h = bounds.y2() - frameTagBounds.y2();
bounds.y = frameTagBounds.y2();

{
IntersectClip clip(g, bounds);
Expand All @@ -2023,7 +2029,7 @@ void Timeline::drawFrameTags(ui::Graphics* g)
}

{
bounds = getPartBounds(Hit(PART_FRAME_TAG, 0, 0, frameTag->id()));
bounds = frameTagBounds;

gfx::Color bg = frameTag->color();
if (m_clk.part == PART_FRAME_TAG && m_clk.frameTag == frameTag->id()) {
Expand All @@ -2049,6 +2055,11 @@ void Timeline::drawFrameTags(ui::Graphics* g)
gfx::ColorNone,
bounds.origin());
}

for (frame_t f=frameTag->fromFrame(); f<=frameTag->toFrame(); ++f) {
if (tagsPerFrame[f] < 255)
++tagsPerFrame[f];
}
}
}

Expand Down Expand Up @@ -2335,6 +2346,13 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
bounds.x += 3*ui::guiscale();
bounds.w = font()->textLength(frameTag->name().c_str()) + 4*ui::guiscale();
bounds.h = font()->height() + 2*ui::guiscale();

auto it = m_tagBand.find(frameTag);
if (it != m_tagBand.end()) {
int dy = (m_tagBands-it->second-1)*oneTagHeight();
bounds.y -= dy;
}

return bounds;
}
break;
Expand Down Expand Up @@ -2405,9 +2423,46 @@ void Timeline::regenerateLayers()
m_layers[i++] = LayerInfo(layer, level, flags);
});

regenerateTagBands();
updateScrollBars();
}

void Timeline::regenerateTagBands()
{
// TODO improve this implementation
std::vector<unsigned char> tagsPerFrame(m_sprite->totalFrames(), 0);
std::vector<FrameTag*> bands(4, nullptr);
m_tagBand.clear();
for (FrameTag* frameTag : m_sprite->frameTags()) {
frame_t f = frameTag->fromFrame();

int b=0;
for (; b<int(bands.size()); ++b) {
if (!bands[b] ||
frameTag->fromFrame() > calcTagVisibleToFrame(bands[b])) {
bands[b] = frameTag;
m_tagBand[frameTag] = b;
break;
}
}
if (b == int(bands.size()))
m_tagBand[frameTag] = tagsPerFrame[f];

frame_t toFrame = calcTagVisibleToFrame(frameTag);
for (; f<=toFrame; ++f) {
if (tagsPerFrame[f] < 255)
++tagsPerFrame[f];
}
}
int oldBands = m_tagBands;
m_tagBands = 0;
for (int i : tagsPerFrame)
m_tagBands = MAX(m_tagBands, i);

if (oldBands != m_tagBands)
layout();
}

void Timeline::updateScrollBars()
{
gfx::Rect rc = bounds();
Expand Down Expand Up @@ -3108,13 +3163,30 @@ int Timeline::outlineWidth() const
return skinTheme()->dimensions.timelineOutlineWidth();
}

int Timeline::oneTagHeight() const
{
return
font()->height() +
2*ui::guiscale() +
skinTheme()->dimensions.timelineTagsAreaHeight();
}

// Returns the last frame where the frame tag (or frame tag label)
// is visible in the timeline.
int Timeline::calcTagVisibleToFrame(FrameTag* frameTag) const
{
return
MAX(frameTag->toFrame(),
frameTag->fromFrame() +
font()->textLength(frameTag->name())/frameBoxWidth());
}

int Timeline::topHeight() const
{
int h = 0;
if (m_document && m_sprite) {
h += skinTheme()->dimensions.timelineTopBorder();
h += font()->height();
h += skinTheme()->dimensions.timelineTagsAreaHeight();
h += oneTagHeight() * MAX(1, m_tagBands);
}
return h;
}
Expand Down
10 changes: 10 additions & 0 deletions src/app/ui/timeline/timeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ namespace app {
gfx::Rect getRangeBounds(const Range& range) const;
void invalidateHit(const Hit& hit);
void regenerateLayers();
void regenerateTagBands();
void updateScrollBars();
void updateByMousePos(ui::Message* msg, const gfx::Point& mousePos);
Hit hitTest(ui::Message* msg, const gfx::Point& mousePos);
Expand Down Expand Up @@ -308,6 +309,8 @@ namespace app {
int layerBoxHeight() const;
int frameBoxWidth() const;
int outlineWidth() const;
int oneTagHeight() const;
int calcTagVisibleToFrame(FrameTag* frameTag) const;

void updateCelOverlayBounds(const Hit& hit);
void drawCelOverlay(ui::Graphics* g);
Expand All @@ -329,7 +332,14 @@ namespace app {
Range m_startRange;
Range m_dropRange;
State m_state;

// Data used to display each layer
std::vector<LayerInfo> m_layers;

// Data used to display frame tags
int m_tagBands = 0;
std::map<FrameTag*, int> m_tagBand;

int m_separator_x;
int m_separator_w;
int m_origFrames;
Expand Down
4 changes: 3 additions & 1 deletion src/doc/frame_tags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ void FrameTags::add(FrameTag* tag)
{
auto it = begin(), end = this->end();
for (; it != end; ++it) {
if ((*it)->fromFrame() > tag->fromFrame())
if ((*it)->fromFrame() > tag->fromFrame() ||
((*it)->fromFrame() == tag->fromFrame() &&
(*it)->toFrame() < tag->toFrame()))
break;
}
m_tags.insert(it, tag);
Expand Down

0 comments on commit 27bc151

Please sign in to comment.