mirror of https://github.com/aseprite/aseprite.git
Add scroll bars to Timeline widget (fix #732)
Changes: - Added ui::ScrollableViewDelegate so ui::ScrollBar can be child of a non-ui::View widget. - Added a generic ui::setup_scrollbars() utility to locate horizontal/vertical scrollbars depending on the scrollable area and the available viewport area. - Replaced Timeline::m_scroll_x/y ints with m_hbar/m_vbar widgets. - Added transparent scrollbar look & feel. - Added a "hover" state to mini-scrollbars used in sprite editors.
This commit is contained in:
parent
4ff5f79035
commit
9772f99303
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
|
@ -260,7 +260,13 @@
|
||||||
<part id="scrollbar_bg" x="64" y="144" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
<part id="scrollbar_bg" x="64" y="144" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
||||||
<part id="scrollbar_thumb" x="64" y="160" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
<part id="scrollbar_thumb" x="64" y="160" w1="5" w2="6" w3="5" h1="5" h2="6" h3="5" />
|
||||||
<part id="mini_scrollbar_bg" x="64" y="176" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
<part id="mini_scrollbar_bg" x="64" y="176" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
<part id="mini_scrollbar_thumb" x="64" y="192" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
<part id="mini_scrollbar_thumb" x="72" y="176" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
|
<part id="mini_scrollbar_bg_hot" x="64" y="184" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
|
<part id="mini_scrollbar_thumb_hot" x="72" y="184" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
|
<part id="transparent_scrollbar_bg" x="64" y="192" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
|
<part id="transparent_scrollbar_thumb" x="72" y="192" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
|
<part id="transparent_scrollbar_bg_hot" x="64" y="200" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
|
<part id="transparent_scrollbar_thumb_hot" x="72" y="200" w1="3" w2="2" w3="3" h1="3" h2="2" h3="3" />
|
||||||
<part id="tooltip" x="112" y="64" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
<part id="tooltip" x="112" y="64" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||||
<part id="tooltip_arrow" x="128" y="64" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
<part id="tooltip_arrow" x="128" y="64" w1="5" w2="6" w3="5" h1="5" h2="5" h3="6" />
|
||||||
<part id="ani_first" x="144" y="192" w="5" h="5" />
|
<part id="ani_first" x="144" y="192" w="5" h="5" />
|
||||||
|
@ -451,9 +457,29 @@
|
||||||
<style id="mini_scrollbar">
|
<style id="mini_scrollbar">
|
||||||
<background part="mini_scrollbar_bg" />
|
<background part="mini_scrollbar_bg" />
|
||||||
</style>
|
</style>
|
||||||
|
<style id="mini_scrollbar:hover">
|
||||||
|
<background part="mini_scrollbar_bg_hot" />
|
||||||
|
</style>
|
||||||
<style id="mini_scrollbar_thumb">
|
<style id="mini_scrollbar_thumb">
|
||||||
<background part="mini_scrollbar_thumb" />
|
<background part="mini_scrollbar_thumb" />
|
||||||
</style>
|
</style>
|
||||||
|
<style id="mini_scrollbar_thumb:hover">
|
||||||
|
<background part="mini_scrollbar_thumb_hot" />
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- transparent_scrollbar -->
|
||||||
|
<style id="transparent_scrollbar">
|
||||||
|
<background part="transparent_scrollbar_bg" />
|
||||||
|
</style>
|
||||||
|
<style id="transparent_scrollbar:hover">
|
||||||
|
<background part="transparent_scrollbar_bg_hot" />
|
||||||
|
</style>
|
||||||
|
<style id="transparent_scrollbar_thumb">
|
||||||
|
<background part="transparent_scrollbar_thumb" />
|
||||||
|
</style>
|
||||||
|
<style id="transparent_scrollbar_thumb:hover">
|
||||||
|
<background part="transparent_scrollbar_thumb_hot" />
|
||||||
|
</style>
|
||||||
|
|
||||||
<!-- timeline -->
|
<!-- timeline -->
|
||||||
<style id="timeline">
|
<style id="timeline">
|
||||||
|
|
|
@ -1506,19 +1506,29 @@ void SkinTheme::paintViewScrollbar(PaintEvent& ev)
|
||||||
if (skinPropery)
|
if (skinPropery)
|
||||||
isMiniLook = (skinPropery->getLook() == MiniLook);
|
isMiniLook = (skinPropery->getLook() == MiniLook);
|
||||||
|
|
||||||
skin::Style* bgStyle = (isMiniLook ?
|
skin::Style* bgStyle;
|
||||||
styles.miniScrollbar():
|
skin::Style* thumbStyle;
|
||||||
styles.scrollbar());
|
|
||||||
|
|
||||||
skin::Style* thumbStyle = (isMiniLook ?
|
if (widget->isTransparent()) {
|
||||||
styles.miniScrollbarThumb():
|
bgStyle = styles.transparentScrollbar();
|
||||||
styles.scrollbarThumb());
|
thumbStyle = styles.transparentScrollbarThumb();
|
||||||
|
}
|
||||||
|
else if (isMiniLook) {
|
||||||
|
bgStyle = styles.miniScrollbar();
|
||||||
|
thumbStyle = styles.miniScrollbarThumb();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bgStyle = styles.scrollbar();
|
||||||
|
thumbStyle = styles.scrollbarThumb();
|
||||||
|
}
|
||||||
|
|
||||||
widget->getScrollBarThemeInfo(&pos, &len);
|
widget->getScrollBarThemeInfo(&pos, &len);
|
||||||
|
|
||||||
gfx::Rect rc = widget->getClientBounds();
|
Style::State state;
|
||||||
|
if (widget->hasMouse()) state += Style::hover();
|
||||||
|
|
||||||
bgStyle->paint(g, rc, NULL, Style::State());
|
gfx::Rect rc = widget->getClientBounds();
|
||||||
|
bgStyle->paint(g, rc, NULL, state);
|
||||||
|
|
||||||
// Horizontal bar
|
// Horizontal bar
|
||||||
if (widget->getAlign() & HORIZONTAL) {
|
if (widget->getAlign() & HORIZONTAL) {
|
||||||
|
@ -1531,7 +1541,7 @@ void SkinTheme::paintViewScrollbar(PaintEvent& ev)
|
||||||
rc.h = len;
|
rc.h = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
thumbStyle->paint(g, rc, NULL, Style::State());
|
thumbStyle->paint(g, rc, NULL, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkinTheme::paintViewViewport(PaintEvent& ev)
|
void SkinTheme::paintViewViewport(PaintEvent& ev)
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "gfx/point.h"
|
#include "gfx/point.h"
|
||||||
#include "gfx/rect.h"
|
#include "gfx/rect.h"
|
||||||
#include "she/font.h"
|
#include "she/font.h"
|
||||||
|
#include "ui/scroll_helper.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -118,12 +119,12 @@ struct Timeline::DrawCelData {
|
||||||
|
|
||||||
Timeline::Timeline()
|
Timeline::Timeline()
|
||||||
: Widget(kGenericWidget)
|
: Widget(kGenericWidget)
|
||||||
|
, m_hbar(HORIZONTAL, this)
|
||||||
|
, m_vbar(VERTICAL, this)
|
||||||
, m_context(UIContext::instance())
|
, m_context(UIContext::instance())
|
||||||
, m_editor(NULL)
|
, m_editor(NULL)
|
||||||
, m_document(NULL)
|
, m_document(NULL)
|
||||||
, m_sprite(NULL)
|
, m_sprite(NULL)
|
||||||
, m_scroll_x(0)
|
|
||||||
, m_scroll_y(0)
|
|
||||||
, m_separator_x(100 * guiscale())
|
, m_separator_x(100 * guiscale())
|
||||||
, m_separator_w(1)
|
, m_separator_w(1)
|
||||||
, m_confPopup(NULL)
|
, m_confPopup(NULL)
|
||||||
|
@ -137,6 +138,16 @@ Timeline::Timeline()
|
||||||
|
|
||||||
setDoubleBuffered(true);
|
setDoubleBuffered(true);
|
||||||
addChild(&m_aniControls);
|
addChild(&m_aniControls);
|
||||||
|
addChild(&m_hbar);
|
||||||
|
addChild(&m_vbar);
|
||||||
|
|
||||||
|
int barsize = skinTheme()->dimensions.miniScrollbarSize();
|
||||||
|
m_hbar.setBarWidth(barsize);
|
||||||
|
m_vbar.setBarWidth(barsize);
|
||||||
|
m_hbar.setBgColor(gfx::rgba(0, 0, 0, 128));
|
||||||
|
m_vbar.setBgColor(gfx::rgba(0, 0, 0, 128));
|
||||||
|
m_hbar.setTransparent(true);
|
||||||
|
m_vbar.setTransparent(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline::~Timeline()
|
Timeline::~Timeline()
|
||||||
|
@ -192,9 +203,7 @@ void Timeline::updateUsingEditor(Editor* editor)
|
||||||
|
|
||||||
setFocusStop(true);
|
setFocusStop(true);
|
||||||
regenerateLayers();
|
regenerateLayers();
|
||||||
setScroll(
|
setViewScroll(getViewScroll());
|
||||||
m_scroll_x,
|
|
||||||
m_scroll_y);
|
|
||||||
showCurrentCel();
|
showCurrentCel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,9 +463,10 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||||
|
|
||||||
case STATE_SCROLLING: {
|
case STATE_SCROLLING: {
|
||||||
gfx::Point absMousePos = static_cast<MouseMessage*>(msg)->position();
|
gfx::Point absMousePos = static_cast<MouseMessage*>(msg)->position();
|
||||||
setScroll(
|
setViewScroll(
|
||||||
m_scroll_x - (absMousePos.x - m_oldPos.x),
|
getViewScroll() - gfx::Point(
|
||||||
m_scroll_y - (absMousePos.y - m_oldPos.y));
|
(absMousePos.x - m_oldPos.x),
|
||||||
|
(absMousePos.y - m_oldPos.y)));
|
||||||
|
|
||||||
m_oldPos = absMousePos;
|
m_oldPos = absMousePos;
|
||||||
return true;
|
return true;
|
||||||
|
@ -827,8 +837,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||||
dy *= 3;
|
dy *= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
setScroll(m_scroll_x+dx,
|
setViewScroll(getViewScroll() + gfx::Point(dx, dy));
|
||||||
m_scroll_y+dy);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -859,6 +868,8 @@ void Timeline::onResize(ui::ResizeEvent& ev)
|
||||||
gfx::Rect(rc.x, rc.y, MIN(sz.w, m_separator_x),
|
gfx::Rect(rc.x, rc.y, MIN(sz.w, m_separator_x),
|
||||||
getFont()->height() +
|
getFont()->height() +
|
||||||
skinTheme()->dimensions.timelineTagsAreaHeight()));
|
skinTheme()->dimensions.timelineTagsAreaHeight()));
|
||||||
|
|
||||||
|
updateScrollBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::onPaint(ui::PaintEvent& ev)
|
void Timeline::onPaint(ui::PaintEvent& ev)
|
||||||
|
@ -1170,7 +1181,7 @@ void Timeline::setCursor(ui::Message* msg, const Hit& hit)
|
||||||
void Timeline::getDrawableLayers(ui::Graphics* g, LayerIndex* first_layer, LayerIndex* last_layer)
|
void Timeline::getDrawableLayers(ui::Graphics* g, LayerIndex* first_layer, LayerIndex* last_layer)
|
||||||
{
|
{
|
||||||
int hpx = (getClientBounds().h - HDRSIZE - topHeight());
|
int hpx = (getClientBounds().h - HDRSIZE - topHeight());
|
||||||
LayerIndex i = lastLayer() - LayerIndex((m_scroll_y+hpx) / LAYSIZE);
|
LayerIndex i = lastLayer() - LayerIndex((getViewScroll().y+hpx) / LAYSIZE);
|
||||||
i = MID(firstLayer(), i, lastLayer());
|
i = MID(firstLayer(), i, lastLayer());
|
||||||
|
|
||||||
LayerIndex j = i + LayerIndex(hpx / LAYSIZE + 1);
|
LayerIndex j = i + LayerIndex(hpx / LAYSIZE + 1);
|
||||||
|
@ -1185,7 +1196,7 @@ void Timeline::getDrawableLayers(ui::Graphics* g, LayerIndex* first_layer, Layer
|
||||||
|
|
||||||
void Timeline::getDrawableFrames(ui::Graphics* g, frame_t* first_frame, frame_t* last_frame)
|
void Timeline::getDrawableFrames(ui::Graphics* g, frame_t* first_frame, frame_t* last_frame)
|
||||||
{
|
{
|
||||||
*first_frame = frame_t((m_separator_w + m_scroll_x) / FRMSIZE);
|
*first_frame = frame_t((m_separator_w + getViewScroll().x) / FRMSIZE);
|
||||||
*last_frame = *first_frame
|
*last_frame = *first_frame
|
||||||
+ frame_t((getClientBounds().w - m_separator_w) / FRMSIZE);
|
+ frame_t((getClientBounds().w - m_separator_w) / FRMSIZE);
|
||||||
}
|
}
|
||||||
|
@ -1649,7 +1660,7 @@ gfx::Rect Timeline::getCelsBounds() const
|
||||||
rc.x += m_separator_x;
|
rc.x += m_separator_x;
|
||||||
rc.w -= m_separator_x;
|
rc.w -= m_separator_x;
|
||||||
rc.y += HDRSIZE + topHeight();
|
rc.y += HDRSIZE + topHeight();
|
||||||
rc.h -= HDRSIZE - topHeight();
|
rc.h -= HDRSIZE + topHeight();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1691,7 +1702,8 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
|
|
||||||
case PART_HEADER_FRAME:
|
case PART_HEADER_FRAME:
|
||||||
return gfx::Rect(
|
return gfx::Rect(
|
||||||
bounds.x + m_separator_x + m_separator_w - 1 + FRMSIZE*MAX(firstFrame(), hit.frame) - m_scroll_x,
|
bounds.x + m_separator_x + m_separator_w - 1
|
||||||
|
+ FRMSIZE*MAX(firstFrame(), hit.frame) - getViewScroll().x,
|
||||||
bounds.y + y, FRMSIZE, HDRSIZE);
|
bounds.y + y, FRMSIZE, HDRSIZE);
|
||||||
|
|
||||||
case PART_HEADER_FRAME_TAGS:
|
case PART_HEADER_FRAME_TAGS:
|
||||||
|
@ -1703,7 +1715,7 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
case PART_LAYER:
|
case PART_LAYER:
|
||||||
if (validLayer(hit.layer)) {
|
if (validLayer(hit.layer)) {
|
||||||
return gfx::Rect(bounds.x,
|
return gfx::Rect(bounds.x,
|
||||||
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - m_scroll_y,
|
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - getViewScroll().y,
|
||||||
m_separator_x, LAYSIZE);
|
m_separator_x, LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1711,7 +1723,7 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
case PART_LAYER_EYE_ICON:
|
case PART_LAYER_EYE_ICON:
|
||||||
if (validLayer(hit.layer)) {
|
if (validLayer(hit.layer)) {
|
||||||
return gfx::Rect(bounds.x,
|
return gfx::Rect(bounds.x,
|
||||||
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - m_scroll_y,
|
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - getViewScroll().y,
|
||||||
FRMSIZE, LAYSIZE);
|
FRMSIZE, LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1719,7 +1731,7 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
case PART_LAYER_PADLOCK_ICON:
|
case PART_LAYER_PADLOCK_ICON:
|
||||||
if (validLayer(hit.layer)) {
|
if (validLayer(hit.layer)) {
|
||||||
return gfx::Rect(bounds.x + FRMSIZE,
|
return gfx::Rect(bounds.x + FRMSIZE,
|
||||||
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - m_scroll_y,
|
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - getViewScroll().y,
|
||||||
FRMSIZE, LAYSIZE);
|
FRMSIZE, LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1727,7 +1739,7 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
case PART_LAYER_CONTINUOUS_ICON:
|
case PART_LAYER_CONTINUOUS_ICON:
|
||||||
if (validLayer(hit.layer)) {
|
if (validLayer(hit.layer)) {
|
||||||
return gfx::Rect(bounds.x + 2*FRMSIZE,
|
return gfx::Rect(bounds.x + 2*FRMSIZE,
|
||||||
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - m_scroll_y,
|
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - getViewScroll().y,
|
||||||
FRMSIZE, LAYSIZE);
|
FRMSIZE, LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1736,7 +1748,7 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
if (validLayer(hit.layer)) {
|
if (validLayer(hit.layer)) {
|
||||||
int x = FRMSIZE*3;
|
int x = FRMSIZE*3;
|
||||||
return gfx::Rect(bounds.x + x,
|
return gfx::Rect(bounds.x + x,
|
||||||
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - m_scroll_y,
|
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - getViewScroll().y,
|
||||||
m_separator_x - x, LAYSIZE);
|
m_separator_x - x, LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1744,8 +1756,8 @@ gfx::Rect Timeline::getPartBounds(const Hit& hit) const
|
||||||
case PART_CEL:
|
case PART_CEL:
|
||||||
if (validLayer(hit.layer) && hit.frame >= frame_t(0)) {
|
if (validLayer(hit.layer) && hit.frame >= frame_t(0)) {
|
||||||
return gfx::Rect(
|
return gfx::Rect(
|
||||||
bounds.x + m_separator_x + m_separator_w - 1 + FRMSIZE*hit.frame - m_scroll_x,
|
bounds.x + m_separator_x + m_separator_w - 1 + FRMSIZE*hit.frame - getViewScroll().x,
|
||||||
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - m_scroll_y,
|
bounds.y + y + HDRSIZE + LAYSIZE*(lastLayer()-hit.layer) - getViewScroll().y,
|
||||||
FRMSIZE, LAYSIZE);
|
FRMSIZE, LAYSIZE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1823,6 +1835,18 @@ void Timeline::regenerateLayers()
|
||||||
|
|
||||||
for (size_t c=0; c<nlayers; c++)
|
for (size_t c=0; c<nlayers; c++)
|
||||||
m_layers[c] = m_sprite->indexToLayer(LayerIndex(c));
|
m_layers[c] = m_sprite->indexToLayer(LayerIndex(c));
|
||||||
|
|
||||||
|
updateScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timeline::updateScrollBars()
|
||||||
|
{
|
||||||
|
gfx::Rect rc = getBounds();
|
||||||
|
m_viewportArea = getCelsBounds().offset(rc.getOrigin());
|
||||||
|
ui::setup_scrollbars(getScrollableSize(),
|
||||||
|
m_viewportArea, *this,
|
||||||
|
m_hbar,
|
||||||
|
m_vbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::updateByMousePos(ui::Message* msg, const gfx::Point& mousePos)
|
void Timeline::updateByMousePos(ui::Message* msg, const gfx::Point& mousePos)
|
||||||
|
@ -1847,18 +1871,19 @@ Timeline::Hit Timeline::hitTest(ui::Message* msg, const gfx::Point& mousePos)
|
||||||
hit.part = PART_SEPARATOR;
|
hit.part = PART_SEPARATOR;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
gfx::Point scroll = getViewScroll();
|
||||||
int top = topHeight();
|
int top = topHeight();
|
||||||
|
|
||||||
hit.layer = lastLayer() - LayerIndex(
|
hit.layer = lastLayer() - LayerIndex(
|
||||||
(mousePos.y
|
(mousePos.y
|
||||||
- top
|
- top
|
||||||
- HDRSIZE
|
- HDRSIZE
|
||||||
+ m_scroll_y) / LAYSIZE);
|
+ scroll.y) / LAYSIZE);
|
||||||
|
|
||||||
hit.frame = frame_t((mousePos.x
|
hit.frame = frame_t((mousePos.x
|
||||||
- m_separator_x
|
- m_separator_x
|
||||||
- m_separator_w
|
- m_separator_w
|
||||||
+ m_scroll_x) / FRMSIZE);
|
+ scroll.x) / FRMSIZE);
|
||||||
|
|
||||||
if (hasCapture()) {
|
if (hasCapture()) {
|
||||||
hit.layer = MID(firstLayer(), hit.layer, lastLayer());
|
hit.layer = MID(firstLayer(), hit.layer, lastLayer());
|
||||||
|
@ -1962,18 +1987,19 @@ Timeline::Hit Timeline::hitTestCel(const gfx::Point& mousePos)
|
||||||
if (!m_document)
|
if (!m_document)
|
||||||
return hit;
|
return hit;
|
||||||
|
|
||||||
|
gfx::Point scroll = getViewScroll();
|
||||||
int top = topHeight();
|
int top = topHeight();
|
||||||
|
|
||||||
hit.layer = lastLayer() - LayerIndex(
|
hit.layer = lastLayer() - LayerIndex(
|
||||||
(mousePos.y
|
(mousePos.y
|
||||||
- top
|
- top
|
||||||
- HDRSIZE
|
- HDRSIZE
|
||||||
+ m_scroll_y) / LAYSIZE);
|
+ scroll.y) / LAYSIZE);
|
||||||
|
|
||||||
hit.frame = frame_t((mousePos.x
|
hit.frame = frame_t((mousePos.x
|
||||||
- m_separator_x
|
- m_separator_x
|
||||||
- m_separator_w
|
- m_separator_w
|
||||||
+ m_scroll_x) / FRMSIZE);
|
+ scroll.x) / FRMSIZE);
|
||||||
|
|
||||||
hit.layer = MID(firstLayer(), hit.layer, lastLayer());
|
hit.layer = MID(firstLayer(), hit.layer, lastLayer());
|
||||||
hit.frame = MAX(firstFrame(), hit.frame);
|
hit.frame = MAX(firstFrame(), hit.frame);
|
||||||
|
@ -2138,36 +2164,31 @@ void Timeline::updateStatusBar(ui::Message* msg)
|
||||||
|
|
||||||
void Timeline::showCel(LayerIndex layer, frame_t frame)
|
void Timeline::showCel(LayerIndex layer, frame_t frame)
|
||||||
{
|
{
|
||||||
int scroll_x, scroll_y;
|
gfx::Point scroll = getViewScroll();
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
int left = getBounds().x + m_separator_x + m_separator_w;
|
int left = m_viewportArea.x;
|
||||||
int top = getBounds().y + topHeight() + HDRSIZE;
|
int top = m_viewportArea.y;
|
||||||
|
|
||||||
x1 = left + FRMSIZE*frame - m_scroll_x;
|
x1 = left + FRMSIZE*frame - scroll.x;
|
||||||
y1 = top + LAYSIZE*(lastLayer() - layer) - m_scroll_y;
|
y1 = top + LAYSIZE*(lastLayer() - layer) - scroll.y;
|
||||||
x2 = x1 + FRMSIZE - 1;
|
x2 = x1 + FRMSIZE - 1;
|
||||||
y2 = y1 + LAYSIZE - 1;
|
y2 = y1 + LAYSIZE - 1;
|
||||||
|
|
||||||
scroll_x = m_scroll_x;
|
|
||||||
scroll_y = m_scroll_y;
|
|
||||||
|
|
||||||
if (x1 < left) {
|
if (x1 < left) {
|
||||||
scroll_x -= left - (x1);
|
scroll.x -= left - (x1);
|
||||||
}
|
}
|
||||||
else if (x2 > getBounds().x2()-1) {
|
else if (x2 > m_viewportArea.x2()-1) {
|
||||||
scroll_x += (x2) - (getBounds().x2()-1);
|
scroll.x += (x2) - (m_viewportArea.x2()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y1 < top) {
|
if (y1 < top) {
|
||||||
scroll_y -= top - (y1);
|
scroll.y -= top - (y1);
|
||||||
}
|
}
|
||||||
else if (y2 > getBounds().y2()-1) {
|
else if (y2 > m_viewportArea.y2()-1) {
|
||||||
scroll_y += (y2) - (getBounds().y2()-1);
|
scroll.y += (y2) - (m_viewportArea.y2()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scroll_x != m_scroll_x ||
|
setViewScroll(scroll);
|
||||||
scroll_y != m_scroll_y)
|
|
||||||
setScroll(scroll_x, scroll_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::showCurrentCel()
|
void Timeline::showCurrentCel()
|
||||||
|
@ -2183,17 +2204,29 @@ void Timeline::cleanClk()
|
||||||
m_clk = Hit(PART_NOTHING);
|
m_clk = Hit(PART_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timeline::setScroll(int x, int y)
|
gfx::Size Timeline::getScrollableSize() const
|
||||||
{
|
{
|
||||||
int max_scroll_x = m_sprite->totalFrames() * FRMSIZE - getBounds().w/2;
|
if (m_sprite) {
|
||||||
int max_scroll_y = m_layers.size() * LAYSIZE - getBounds().h/2;
|
return gfx::Size(
|
||||||
max_scroll_x = MAX(0, max_scroll_x);
|
m_sprite->totalFrames() * FRMSIZE + getBounds().w/2,
|
||||||
max_scroll_y = MAX(0, max_scroll_y);
|
m_layers.size() * LAYSIZE + getBounds().h/2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return gfx::Size(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
m_scroll_x = MID(0, x, max_scroll_x);
|
gfx::Point Timeline::getMaxScrollablePos() const
|
||||||
m_scroll_y = MID(0, y, max_scroll_y);
|
{
|
||||||
|
if (m_sprite) {
|
||||||
invalidate();
|
gfx::Size size = getScrollableSize();
|
||||||
|
int max_scroll_x = size.w - getBounds().w/2;
|
||||||
|
int max_scroll_y = size.h - getBounds().h/2;
|
||||||
|
max_scroll_x = MAX(0, max_scroll_x);
|
||||||
|
max_scroll_y = MAX(0, max_scroll_y);
|
||||||
|
return gfx::Point(max_scroll_x, max_scroll_y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return gfx::Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Timeline::allLayersVisible()
|
bool Timeline::allLayersVisible()
|
||||||
|
@ -2314,6 +2347,32 @@ void Timeline::dropRange(DropOp op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::Size Timeline::getVisibleSize() const
|
||||||
|
{
|
||||||
|
return getCelsBounds().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::Point Timeline::getViewScroll() const
|
||||||
|
{
|
||||||
|
return gfx::Point(m_hbar.getPos(), m_vbar.getPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timeline::setViewScroll(const gfx::Point& pt)
|
||||||
|
{
|
||||||
|
const gfx::Point oldScroll = getViewScroll();
|
||||||
|
const gfx::Point maxPos = getMaxScrollablePos();
|
||||||
|
gfx::Point newScroll = pt;
|
||||||
|
newScroll.x = MID(0, newScroll.x, maxPos.x);
|
||||||
|
newScroll.y = MID(0, newScroll.y, maxPos.y);
|
||||||
|
|
||||||
|
if (newScroll == oldScroll)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_hbar.setPos(newScroll.x);
|
||||||
|
m_vbar.setPos(newScroll.y);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
void Timeline::updateDropRange(const gfx::Point& pt)
|
void Timeline::updateDropRange(const gfx::Point& pt)
|
||||||
{
|
{
|
||||||
DropTarget::HHit oldHHit = m_dropTarget.hhit;
|
DropTarget::HHit oldHHit = m_dropTarget.hhit;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "doc/frame.h"
|
#include "doc/frame.h"
|
||||||
#include "doc/layer_index.h"
|
#include "doc/layer_index.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
|
#include "ui/scroll_bar.h"
|
||||||
#include "ui/timer.h"
|
#include "ui/timer.h"
|
||||||
#include "ui/widget.h"
|
#include "ui/widget.h"
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ namespace app {
|
||||||
class Editor;
|
class Editor;
|
||||||
|
|
||||||
class Timeline : public ui::Widget
|
class Timeline : public ui::Widget
|
||||||
|
, public ui::ScrollableViewDelegate
|
||||||
, public doc::DocumentsObserver
|
, public doc::DocumentsObserver
|
||||||
, public doc::DocumentObserver
|
, public doc::DocumentObserver
|
||||||
, public app::EditorObserver
|
, public app::EditorObserver
|
||||||
|
@ -99,6 +101,11 @@ namespace app {
|
||||||
// called from popup menus.
|
// called from popup menus.
|
||||||
void dropRange(DropOp op);
|
void dropRange(DropOp op);
|
||||||
|
|
||||||
|
// ScrollableViewDelegate impl
|
||||||
|
gfx::Size getVisibleSize() const override;
|
||||||
|
gfx::Point getViewScroll() const override;
|
||||||
|
void setViewScroll(const gfx::Point& pt) override;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -212,6 +219,7 @@ namespace app {
|
||||||
gfx::Rect getRangeBounds(const Range& range) const;
|
gfx::Rect getRangeBounds(const Range& range) const;
|
||||||
void invalidateHit(const Hit& hit);
|
void invalidateHit(const Hit& hit);
|
||||||
void regenerateLayers();
|
void regenerateLayers();
|
||||||
|
void updateScrollBars();
|
||||||
void updateByMousePos(ui::Message* msg, const gfx::Point& mousePos);
|
void updateByMousePos(ui::Message* msg, const gfx::Point& mousePos);
|
||||||
Hit hitTest(ui::Message* msg, const gfx::Point& mousePos);
|
Hit hitTest(ui::Message* msg, const gfx::Point& mousePos);
|
||||||
Hit hitTestCel(const gfx::Point& mousePos);
|
Hit hitTestCel(const gfx::Point& mousePos);
|
||||||
|
@ -219,7 +227,8 @@ namespace app {
|
||||||
void showCel(LayerIndex layer, frame_t frame);
|
void showCel(LayerIndex layer, frame_t frame);
|
||||||
void showCurrentCel();
|
void showCurrentCel();
|
||||||
void cleanClk();
|
void cleanClk();
|
||||||
void setScroll(int x, int y);
|
gfx::Size getScrollableSize() const;
|
||||||
|
gfx::Point getMaxScrollablePos() const;
|
||||||
LayerIndex getLayerIndex(const Layer* layer) const;
|
LayerIndex getLayerIndex(const Layer* layer) const;
|
||||||
bool isLayerActive(LayerIndex layerIdx) const;
|
bool isLayerActive(LayerIndex layerIdx) const;
|
||||||
bool isFrameActive(frame_t frame) const;
|
bool isFrameActive(frame_t frame) const;
|
||||||
|
@ -246,6 +255,9 @@ namespace app {
|
||||||
DocumentPreferences& docPref() const;
|
DocumentPreferences& docPref() const;
|
||||||
skin::SkinTheme* skinTheme() const;
|
skin::SkinTheme* skinTheme() const;
|
||||||
|
|
||||||
|
ui::ScrollBar m_hbar;
|
||||||
|
ui::ScrollBar m_vbar;
|
||||||
|
gfx::Rect m_viewportArea;
|
||||||
Context* m_context;
|
Context* m_context;
|
||||||
Editor* m_editor;
|
Editor* m_editor;
|
||||||
Document* m_document;
|
Document* m_document;
|
||||||
|
@ -256,8 +268,6 @@ namespace app {
|
||||||
Range m_dropRange;
|
Range m_dropRange;
|
||||||
State m_state;
|
State m_state;
|
||||||
std::vector<Layer*> m_layers;
|
std::vector<Layer*> m_layers;
|
||||||
int m_scroll_x;
|
|
||||||
int m_scroll_y;
|
|
||||||
int m_separator_x;
|
int m_separator_x;
|
||||||
int m_separator_w;
|
int m_separator_w;
|
||||||
int m_origFrames;
|
int m_origFrames;
|
||||||
|
|
|
@ -37,6 +37,7 @@ add_library(ui-lib
|
||||||
register_message.cpp
|
register_message.cpp
|
||||||
resize_event.cpp
|
resize_event.cpp
|
||||||
scroll_bar.cpp
|
scroll_bar.cpp
|
||||||
|
scroll_helper.cpp
|
||||||
separator.cpp
|
separator.cpp
|
||||||
slider.cpp
|
slider.cpp
|
||||||
splitter.cpp
|
splitter.cpp
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
#include "ui/scroll_bar.h"
|
#include "ui/scroll_bar.h"
|
||||||
#include "ui/theme.h"
|
#include "ui/theme.h"
|
||||||
#include "ui/view.h"
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
@ -23,8 +22,9 @@ using namespace gfx;
|
||||||
int ScrollBar::m_wherepos = 0;
|
int ScrollBar::m_wherepos = 0;
|
||||||
int ScrollBar::m_whereclick = 0;
|
int ScrollBar::m_whereclick = 0;
|
||||||
|
|
||||||
ScrollBar::ScrollBar(int align)
|
ScrollBar::ScrollBar(int align, ScrollableViewDelegate* delegate)
|
||||||
: Widget(kViewScrollbarWidget)
|
: Widget(kViewScrollbarWidget)
|
||||||
|
, m_delegate(delegate)
|
||||||
, m_barWidth(getTheme()->getScrollbarSize())
|
, m_barWidth(getTheme()->getScrollbarSize())
|
||||||
, m_pos(0)
|
, m_pos(0)
|
||||||
, m_size(0)
|
, m_size(0)
|
||||||
|
@ -64,7 +64,6 @@ bool ScrollBar::onProcessMessage(Message* msg)
|
||||||
|
|
||||||
case kMouseDownMessage: {
|
case kMouseDownMessage: {
|
||||||
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
||||||
View* view = static_cast<View*>(getParent());
|
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
int u1, v1, u2, v2;
|
int u1, v1, u2, v2;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -87,7 +86,7 @@ bool ScrollBar::onProcessMessage(Message* msg)
|
||||||
u2 = x2 - border().right();
|
u2 = x2 - border().right();
|
||||||
v2 = y2 - border().bottom();
|
v2 = y2 - border().bottom();
|
||||||
|
|
||||||
Point scroll = view->getViewScroll();
|
Point scroll = m_delegate->getViewScroll();
|
||||||
|
|
||||||
if (this->getAlign() & HORIZONTAL) {
|
if (this->getAlign() & HORIZONTAL) {
|
||||||
// in the bar
|
// in the bar
|
||||||
|
@ -96,12 +95,12 @@ bool ScrollBar::onProcessMessage(Message* msg)
|
||||||
}
|
}
|
||||||
// left
|
// left
|
||||||
else if (MOUSE_IN(x1, y1, u1+pos-1, y2)) {
|
else if (MOUSE_IN(x1, y1, u1+pos-1, y2)) {
|
||||||
scroll.x -= view->getViewport()->getBounds().w/2;
|
scroll.x -= m_delegate->getVisibleSize().w/2;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
// right
|
// right
|
||||||
else if (MOUSE_IN(u1+pos+len, y1, x2, y2)) {
|
else if (MOUSE_IN(u1+pos+len, y1, x2, y2)) {
|
||||||
scroll.x += view->getViewport()->getBounds().w/2;
|
scroll.x += m_delegate->getVisibleSize().w/2;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,18 +111,18 @@ bool ScrollBar::onProcessMessage(Message* msg)
|
||||||
}
|
}
|
||||||
// left
|
// left
|
||||||
else if (MOUSE_IN(x1, y1, x2, v1+pos-1)) {
|
else if (MOUSE_IN(x1, y1, x2, v1+pos-1)) {
|
||||||
scroll.y -= view->getViewport()->getBounds().h/2;
|
scroll.y -= m_delegate->getVisibleSize().h/2;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
// right
|
// right
|
||||||
else if (MOUSE_IN(x1, v1+pos+len, x2, y2)) {
|
else if (MOUSE_IN(x1, v1+pos+len, x2, y2)) {
|
||||||
scroll.y += view->getViewport()->getBounds().h/2;
|
scroll.y += m_delegate->getVisibleSize().h/2;
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
view->setViewScroll(scroll);
|
m_delegate->setViewScroll(scroll);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,29 +135,29 @@ bool ScrollBar::onProcessMessage(Message* msg)
|
||||||
case kMouseMoveMessage:
|
case kMouseMoveMessage:
|
||||||
if (hasCapture()) {
|
if (hasCapture()) {
|
||||||
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
|
||||||
View* view = static_cast<View*>(getParent());
|
|
||||||
int pos, len, bar_size, viewport_size;
|
int pos, len, bar_size, viewport_size;
|
||||||
|
|
||||||
getScrollBarInfo(&pos, &len, &bar_size, &viewport_size);
|
getScrollBarInfo(&pos, &len, &bar_size, &viewport_size);
|
||||||
|
|
||||||
if (bar_size > len) {
|
if (bar_size > len) {
|
||||||
Point scroll = view->getViewScroll();
|
Point scroll = m_delegate->getViewScroll();
|
||||||
|
|
||||||
if (this->getAlign() & HORIZONTAL) {
|
if (getAlign() & HORIZONTAL) {
|
||||||
pos = (m_wherepos + mousePos.x - m_whereclick);
|
pos = (m_wherepos + mousePos.x - m_whereclick);
|
||||||
pos = MID(0, pos, bar_size - len);
|
pos = MID(0, pos, bar_size - len);
|
||||||
|
|
||||||
scroll.x = (m_size - viewport_size) * pos / (bar_size - len);
|
scroll.x = (m_size - viewport_size) * pos / (bar_size - len);
|
||||||
view->setViewScroll(scroll);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pos = (m_wherepos + mousePos.y - m_whereclick);
|
pos = (m_wherepos + mousePos.y - m_whereclick);
|
||||||
pos = MID(0, pos, bar_size - len);
|
pos = MID(0, pos, bar_size - len);
|
||||||
|
|
||||||
scroll.y = (m_size - viewport_size) * pos / (bar_size - len);
|
scroll.y = (m_size - viewport_size) * pos / (bar_size - len);
|
||||||
view->setViewScroll(scroll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_delegate->setViewScroll(scroll);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -184,19 +183,18 @@ void ScrollBar::onPaint(PaintEvent& ev)
|
||||||
|
|
||||||
void ScrollBar::getScrollBarInfo(int *_pos, int *_len, int *_bar_size, int *_viewport_size)
|
void ScrollBar::getScrollBarInfo(int *_pos, int *_len, int *_bar_size, int *_viewport_size)
|
||||||
{
|
{
|
||||||
View* view = static_cast<View*>(getParent());
|
|
||||||
int bar_size, viewport_size;
|
int bar_size, viewport_size;
|
||||||
int pos, len;
|
int pos, len;
|
||||||
int border_width;
|
int border_width;
|
||||||
|
|
||||||
if (getAlign() & HORIZONTAL) {
|
if (getAlign() & HORIZONTAL) {
|
||||||
bar_size = getBounds().w;
|
bar_size = getBounds().w;
|
||||||
viewport_size = view->getVisibleSize().w;
|
viewport_size = m_delegate->getVisibleSize().w;
|
||||||
border_width = border().height();
|
border_width = border().height();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bar_size = getBounds().h;
|
bar_size = getBounds().h;
|
||||||
viewport_size = view->getVisibleSize().h;
|
viewport_size = m_delegate->getVisibleSize().h;
|
||||||
border_width = border().width();
|
border_width = border().width();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,12 +202,15 @@ void ScrollBar::getScrollBarInfo(int *_pos, int *_len, int *_bar_size, int *_vie
|
||||||
len = bar_size;
|
len = bar_size;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
else {
|
else if (m_size > 0) {
|
||||||
len = bar_size * viewport_size / m_size;
|
len = bar_size * viewport_size / m_size;
|
||||||
len = MID(getTheme()->getScrollbarSize()*2-border_width, len, bar_size);
|
len = MID(getTheme()->getScrollbarSize()*2-border_width, len, bar_size);
|
||||||
pos = (bar_size-len) * m_pos / (m_size-viewport_size);
|
pos = (bar_size-len) * m_pos / (m_size-viewport_size);
|
||||||
pos = MID(0, pos, bar_size-len);
|
pos = MID(0, pos, bar_size-len);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
len = pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (_pos) *_pos = pos;
|
if (_pos) *_pos = pos;
|
||||||
if (_len) *_len = len;
|
if (_len) *_len = len;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2001-2013 David Capello
|
// Copyright (C) 2001-2013, 2015 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
|
@ -12,9 +12,17 @@
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
|
class ScrollableViewDelegate {
|
||||||
|
public:
|
||||||
|
virtual ~ScrollableViewDelegate() { }
|
||||||
|
virtual gfx::Size getVisibleSize() const = 0;
|
||||||
|
virtual gfx::Point getViewScroll() const = 0;
|
||||||
|
virtual void setViewScroll(const gfx::Point& pt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class ScrollBar : public Widget {
|
class ScrollBar : public Widget {
|
||||||
public:
|
public:
|
||||||
ScrollBar(int align);
|
ScrollBar(int align, ScrollableViewDelegate* delegate);
|
||||||
|
|
||||||
int getBarWidth() const { return m_barWidth; }
|
int getBarWidth() const { return m_barWidth; }
|
||||||
void setBarWidth(int barWidth) { m_barWidth = barWidth; }
|
void setBarWidth(int barWidth) { m_barWidth = barWidth; }
|
||||||
|
@ -36,6 +44,7 @@ namespace ui {
|
||||||
private:
|
private:
|
||||||
void getScrollBarInfo(int* _pos, int* _len, int* _bar_size, int* _viewport_size);
|
void getScrollBarInfo(int* _pos, int* _len, int* _bar_size, int* _viewport_size);
|
||||||
|
|
||||||
|
ScrollableViewDelegate* m_delegate;
|
||||||
int m_barWidth;
|
int m_barWidth;
|
||||||
int m_pos;
|
int m_pos;
|
||||||
int m_size;
|
int m_size;
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
// Aseprite UI Library
|
||||||
|
// Copyright (C) 2001-2013, 2015 David Capello
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ui/scroll_bar.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
void setup_scrollbars(const gfx::Size& scrollableSize,
|
||||||
|
gfx::Rect& viewportArea,
|
||||||
|
Widget& parent,
|
||||||
|
ScrollBar& hbar,
|
||||||
|
ScrollBar& vbar)
|
||||||
|
{
|
||||||
|
#define NEED_BAR(w, h, width) \
|
||||||
|
((scrollableSize.w > viewportArea.w) && \
|
||||||
|
(vbar.getBarWidth() < fullViewportArea.w) && \
|
||||||
|
(hbar.getBarWidth() < fullViewportArea.h))
|
||||||
|
|
||||||
|
const gfx::Rect fullViewportArea = viewportArea;
|
||||||
|
|
||||||
|
hbar.setSize(scrollableSize.w);
|
||||||
|
vbar.setSize(scrollableSize.h);
|
||||||
|
|
||||||
|
if (hbar.getParent()) parent.removeChild(&hbar);
|
||||||
|
if (vbar.getParent()) parent.removeChild(&vbar);
|
||||||
|
|
||||||
|
if (NEED_BAR(w, h, width)) {
|
||||||
|
viewportArea.h -= hbar.getBarWidth();
|
||||||
|
parent.addChild(&hbar);
|
||||||
|
|
||||||
|
if (NEED_BAR(h, w, height)) {
|
||||||
|
viewportArea.w -= vbar.getBarWidth();
|
||||||
|
if (NEED_BAR(w, h, width))
|
||||||
|
parent.addChild(&vbar);
|
||||||
|
else {
|
||||||
|
viewportArea.w += vbar.getBarWidth();
|
||||||
|
viewportArea.h += hbar.getBarWidth();
|
||||||
|
parent.removeChild(&hbar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (NEED_BAR(h, w, height)) {
|
||||||
|
viewportArea.w -= vbar.getBarWidth();
|
||||||
|
parent.addChild(&vbar);
|
||||||
|
|
||||||
|
if (NEED_BAR(w, h, width)) {
|
||||||
|
viewportArea.h -= hbar.getBarWidth();
|
||||||
|
if (NEED_BAR(h, w, height))
|
||||||
|
parent.addChild(&hbar);
|
||||||
|
else {
|
||||||
|
viewportArea.w += vbar.getBarWidth();
|
||||||
|
viewportArea.h += hbar.getBarWidth();
|
||||||
|
parent.removeChild(&vbar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent.hasChild(&hbar)) {
|
||||||
|
hbar.setBounds(gfx::Rect(viewportArea.x, viewportArea.y2(),
|
||||||
|
viewportArea.w, hbar.getBarWidth()));
|
||||||
|
hbar.setVisible(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hbar.setVisible(false);
|
||||||
|
|
||||||
|
if (parent.hasChild(&vbar)) {
|
||||||
|
vbar.setBounds(gfx::Rect(viewportArea.x2(), viewportArea.y,
|
||||||
|
vbar.getBarWidth(), viewportArea.h));
|
||||||
|
vbar.setVisible(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vbar.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ui
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Aseprite UI Library
|
||||||
|
// Copyright (C) 2001-2013, 2015 David Capello
|
||||||
|
//
|
||||||
|
// This file is released under the terms of the MIT license.
|
||||||
|
// Read LICENSE.txt for more information.
|
||||||
|
|
||||||
|
#ifndef UI_SCROLL_HELPER_H_INCLUDED
|
||||||
|
#define UI_SCROLL_HELPER_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gfx/rect.h"
|
||||||
|
#include "gfx/size.h"
|
||||||
|
|
||||||
|
namespace ui {
|
||||||
|
|
||||||
|
class ScrollBar;
|
||||||
|
|
||||||
|
void setup_scrollbars(const gfx::Size& scrollableSize,
|
||||||
|
gfx::Rect& viewportArea,
|
||||||
|
Widget& parent,
|
||||||
|
ScrollBar& hbar,
|
||||||
|
ScrollBar& vbar);
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,6 +13,7 @@
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
#include "ui/preferred_size_event.h"
|
#include "ui/preferred_size_event.h"
|
||||||
#include "ui/resize_event.h"
|
#include "ui/resize_event.h"
|
||||||
|
#include "ui/scroll_helper.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/theme.h"
|
#include "ui/theme.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
@ -27,8 +28,8 @@ using namespace gfx;
|
||||||
|
|
||||||
View::View()
|
View::View()
|
||||||
: Widget(kViewWidget)
|
: Widget(kViewWidget)
|
||||||
, m_scrollbar_h(HORIZONTAL)
|
, m_scrollbar_h(HORIZONTAL, this)
|
||||||
, m_scrollbar_v(VERTICAL)
|
, m_scrollbar_v(VERTICAL, this)
|
||||||
{
|
{
|
||||||
m_hasBars = true;
|
m_hasBars = true;
|
||||||
|
|
||||||
|
@ -89,81 +90,35 @@ Size View::getScrollableSize()
|
||||||
|
|
||||||
void View::setScrollableSize(const Size& sz)
|
void View::setScrollableSize(const Size& sz)
|
||||||
{
|
{
|
||||||
#define CHECK(w, h, width) \
|
gfx::Rect viewportArea = getChildrenBounds();
|
||||||
((sz.w > (m_viewport.getBounds().w \
|
|
||||||
- m_viewport.border().width())) && \
|
|
||||||
(VBAR_SIZE < pos.w) && \
|
|
||||||
(HBAR_SIZE < pos.h))
|
|
||||||
|
|
||||||
m_scrollbar_h.setSize(sz.w);
|
|
||||||
m_scrollbar_v.setSize(sz.h);
|
|
||||||
|
|
||||||
gfx::Rect pos = getChildrenBounds();
|
|
||||||
|
|
||||||
// Setup scroll-bars
|
|
||||||
if (m_scrollbar_h.getParent()) removeChild(&m_scrollbar_h);
|
|
||||||
if (m_scrollbar_v.getParent()) removeChild(&m_scrollbar_v);
|
|
||||||
|
|
||||||
if (m_hasBars) {
|
if (m_hasBars) {
|
||||||
if (CHECK(w, h, width)) {
|
setup_scrollbars(sz,
|
||||||
pos.h -= HBAR_SIZE;
|
viewportArea,
|
||||||
addChild(&m_scrollbar_h);
|
*this,
|
||||||
|
m_scrollbar_h,
|
||||||
if (CHECK(h, w, height)) {
|
m_scrollbar_v);
|
||||||
pos.w -= VBAR_SIZE;
|
}
|
||||||
if (CHECK(w, h, width))
|
else {
|
||||||
addChild(&m_scrollbar_v);
|
if (m_scrollbar_h.getParent()) removeChild(&m_scrollbar_h);
|
||||||
else {
|
if (m_scrollbar_v.getParent()) removeChild(&m_scrollbar_v);
|
||||||
pos.w += VBAR_SIZE;
|
m_scrollbar_h.setVisible(false);
|
||||||
pos.h += HBAR_SIZE;
|
m_scrollbar_v.setVisible(false);
|
||||||
removeChild(&m_scrollbar_h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (CHECK(h, w, height)) {
|
|
||||||
pos.w -= VBAR_SIZE;
|
|
||||||
addChild(&m_scrollbar_v);
|
|
||||||
|
|
||||||
if (CHECK(w, h, width)) {
|
|
||||||
pos.h -= HBAR_SIZE;
|
|
||||||
if (CHECK(h, w, height))
|
|
||||||
addChild(&m_scrollbar_h);
|
|
||||||
else {
|
|
||||||
pos.w += VBAR_SIZE;
|
|
||||||
pos.h += HBAR_SIZE;
|
|
||||||
removeChild(&m_scrollbar_v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasChild(&m_scrollbar_h)) {
|
|
||||||
m_scrollbar_h.setBounds(gfx::Rect(pos.x, pos.y2(), pos.w, HBAR_SIZE));
|
|
||||||
m_scrollbar_h.setVisible(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_scrollbar_h.setVisible(false);
|
|
||||||
|
|
||||||
if (hasChild(&m_scrollbar_v)) {
|
|
||||||
m_scrollbar_v.setBounds(gfx::Rect(pos.x2(), pos.y, VBAR_SIZE, pos.h));
|
|
||||||
m_scrollbar_v.setVisible(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_scrollbar_v.setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
invalidate();
|
invalidate();
|
||||||
m_viewport.setBounds(pos);
|
m_viewport.setBounds(viewportArea);
|
||||||
setViewScroll(getViewScroll()); // Setup the same scroll-point
|
setViewScroll(getViewScroll()); // Setup the same scroll-point
|
||||||
}
|
}
|
||||||
|
|
||||||
Size View::getVisibleSize()
|
Size View::getVisibleSize() const
|
||||||
{
|
{
|
||||||
return Size(m_viewport.getBounds().w - m_viewport.border().width(),
|
return Size(m_viewport.getBounds().w - m_viewport.border().width(),
|
||||||
m_viewport.getBounds().h - m_viewport.border().height());
|
m_viewport.getBounds().h - m_viewport.border().height());
|
||||||
}
|
}
|
||||||
|
|
||||||
Point View::getViewScroll()
|
Point View::getViewScroll() const
|
||||||
{
|
{
|
||||||
return Point(m_scrollbar_h.getPos(),
|
return Point(m_scrollbar_h.getPos(),
|
||||||
m_scrollbar_v.getPos());
|
m_scrollbar_v.getPos());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2001-2013 David Capello
|
// Copyright (C) 2001-2013, 2015 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
|
@ -16,56 +16,55 @@
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
class View : public Widget
|
class View : public Widget
|
||||||
{
|
, public ScrollableViewDelegate {
|
||||||
public:
|
public:
|
||||||
View();
|
View();
|
||||||
|
|
||||||
bool hasScrollBars();
|
bool hasScrollBars();
|
||||||
ScrollBar* getHorizontalBar() { return &m_scrollbar_h; }
|
ScrollBar* getHorizontalBar() { return &m_scrollbar_h; }
|
||||||
ScrollBar* getVerticalBar() { return &m_scrollbar_v; }
|
ScrollBar* getVerticalBar() { return &m_scrollbar_v; }
|
||||||
|
|
||||||
void attachToView(Widget* viewableWidget);
|
void attachToView(Widget* viewableWidget);
|
||||||
Widget* attachedWidget();
|
Widget* attachedWidget();
|
||||||
|
|
||||||
void hideScrollBars();
|
void hideScrollBars();
|
||||||
void showScrollBars();
|
void showScrollBars();
|
||||||
void makeVisibleAllScrollableArea();
|
void makeVisibleAllScrollableArea();
|
||||||
|
|
||||||
// Returns the maximum viewable size requested by the attached
|
// Returns the maximum viewable size requested by the attached
|
||||||
// widget in the viewport.
|
// widget in the viewport.
|
||||||
gfx::Size getScrollableSize();
|
gfx::Size getScrollableSize();
|
||||||
void setScrollableSize(const gfx::Size& sz);
|
void setScrollableSize(const gfx::Size& sz);
|
||||||
|
|
||||||
// Returns the visible/available size to see the attached widget.
|
// Returns the visible/available size to see the attached widget.
|
||||||
gfx::Size getVisibleSize();
|
gfx::Size getVisibleSize() const override;
|
||||||
|
gfx::Point getViewScroll() const override;
|
||||||
|
void setViewScroll(const gfx::Point& pt) override;
|
||||||
|
|
||||||
gfx::Point getViewScroll();
|
void updateView();
|
||||||
void setViewScroll(const gfx::Point& pt);
|
|
||||||
|
|
||||||
void updateView();
|
Viewport* getViewport();
|
||||||
|
gfx::Rect getViewportBounds();
|
||||||
|
|
||||||
Viewport* getViewport();
|
// For viewable widgets
|
||||||
gfx::Rect getViewportBounds();
|
static View* getView(Widget* viewableWidget);
|
||||||
|
|
||||||
// For viewable widgets
|
protected:
|
||||||
static View* getView(Widget* viewableWidget);
|
// Events
|
||||||
|
bool onProcessMessage(Message* msg) override;
|
||||||
|
void onResize(ResizeEvent& ev) override;
|
||||||
|
void onPreferredSize(PreferredSizeEvent& ev) override;
|
||||||
|
void onPaint(PaintEvent& ev) override;
|
||||||
|
|
||||||
protected:
|
virtual void onScrollChange();
|
||||||
// Events
|
|
||||||
bool onProcessMessage(Message* msg) override;
|
|
||||||
void onResize(ResizeEvent& ev) override;
|
|
||||||
void onPreferredSize(PreferredSizeEvent& ev) override;
|
|
||||||
void onPaint(PaintEvent& ev) override;
|
|
||||||
|
|
||||||
virtual void onScrollChange();
|
private:
|
||||||
|
bool m_hasBars;
|
||||||
private:
|
Viewport m_viewport;
|
||||||
bool m_hasBars;
|
ScrollBar m_scrollbar_h;
|
||||||
Viewport m_viewport;
|
ScrollBar m_scrollbar_v;
|
||||||
ScrollBar m_scrollbar_h;
|
};
|
||||||
ScrollBar m_scrollbar_v;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ui
|
} // namespace ui
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue