mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 21:39:57 +00:00
Move app::Tabs animation related stuff to app::AnimatedWidget
This commit is contained in:
parent
2cfef9e250
commit
47948ee888
84
src/app/ui/animated_widget.h
Normal file
84
src/app/ui/animated_widget.h
Normal file
@ -0,0 +1,84 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 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
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_ANIMATED_WIDGET_H_INCLUDED
|
||||
#define APP_UI_ANIMATED_WIDGET_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "base/connection.h"
|
||||
#include "ui/timer.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class AnimatedWidget {
|
||||
public:
|
||||
AnimatedWidget()
|
||||
: m_timer(1000/60)
|
||||
, m_animation(0)
|
||||
{
|
||||
m_scopedConn = m_timer.Tick.connect(&AnimatedWidget::onTick, this);
|
||||
}
|
||||
|
||||
~AnimatedWidget() {
|
||||
m_timer.stop();
|
||||
}
|
||||
|
||||
// For each animation frame
|
||||
virtual void onAnimationStart() { }
|
||||
virtual void onAnimationStop() { }
|
||||
virtual void onAnimationFrame() { }
|
||||
|
||||
protected:
|
||||
void startAnimation(int animation, int lifespan) {
|
||||
// Stop previous animation
|
||||
if (m_animation)
|
||||
stopAnimation();
|
||||
|
||||
m_animation = animation;
|
||||
m_animationTime = 0;
|
||||
m_animationLifespan = lifespan;
|
||||
m_timer.start();
|
||||
|
||||
onAnimationStart();
|
||||
}
|
||||
|
||||
void stopAnimation() {
|
||||
m_animation = 0;
|
||||
m_timer.stop();
|
||||
onAnimationStop();
|
||||
}
|
||||
|
||||
int animation() const {
|
||||
return m_animation;
|
||||
}
|
||||
|
||||
double animationTime() const {
|
||||
return double(m_animationTime) / double(m_animationLifespan);
|
||||
}
|
||||
|
||||
private:
|
||||
void onTick() {
|
||||
if (m_animation) {
|
||||
if (m_animationTime == m_animationLifespan)
|
||||
stopAnimation();
|
||||
else
|
||||
++m_animationTime;
|
||||
|
||||
onAnimationFrame();
|
||||
}
|
||||
}
|
||||
|
||||
ui::Timer m_timer;
|
||||
int m_animation;
|
||||
int m_animationTime;
|
||||
int m_animationLifespan;
|
||||
ScopedConnection m_scopedConn;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -61,8 +61,6 @@ Tabs::Tabs(TabsDelegate* delegate)
|
||||
, m_clickedCloseButton(false)
|
||||
, m_selected(nullptr)
|
||||
, m_delegate(delegate)
|
||||
, m_timer(1000/60, this)
|
||||
, m_ani(ANI_NONE)
|
||||
, m_removedTab(nullptr)
|
||||
, m_isDragging(false)
|
||||
, m_floatingTab(nullptr)
|
||||
@ -80,7 +78,7 @@ Tabs::~Tabs()
|
||||
}
|
||||
|
||||
// Stop animation
|
||||
stopAni();
|
||||
stopAnimation();
|
||||
|
||||
// Remove all tabs
|
||||
for (Tab* tab : m_list)
|
||||
@ -91,7 +89,7 @@ Tabs::~Tabs()
|
||||
void Tabs::addTab(TabView* tabView, int pos)
|
||||
{
|
||||
resetOldPositions();
|
||||
startAni(ANI_ADDING_TAB, ANI_ADDING_TAB_TICKS);
|
||||
startAnimation(ANI_ADDING_TAB, ANI_ADDING_TAB_TICKS);
|
||||
|
||||
Tab* tab = new Tab(tabView);
|
||||
if (pos < 0)
|
||||
@ -137,7 +135,7 @@ void Tabs::removeTab(TabView* tabView)
|
||||
tab->view = nullptr; // The view will be destroyed after Tabs::removeTab() anyway
|
||||
|
||||
resetOldPositions();
|
||||
startAni(ANI_REMOVING_TAB, ANI_REMOVING_TAB_TICKS);
|
||||
startAnimation(ANI_REMOVING_TAB, ANI_REMOVING_TAB_TICKS);
|
||||
updateTabs();
|
||||
}
|
||||
|
||||
@ -270,9 +268,9 @@ bool Tabs::onProcessMessage(Message* msg)
|
||||
m_list.insert(m_list.begin()+i, m_selected);
|
||||
m_dragTabIndex = i;
|
||||
|
||||
resetOldPositions(double(m_ani_t) / double(m_ani_T));
|
||||
resetOldPositions(animationTime());
|
||||
updateTabs();
|
||||
startAni(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
startAnimation(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
}
|
||||
|
||||
if (justDocked)
|
||||
@ -367,18 +365,6 @@ bool Tabs::onProcessMessage(Message* msg)
|
||||
return true;
|
||||
}
|
||||
|
||||
case kTimerMessage: {
|
||||
if (m_ani != ANI_NONE) {
|
||||
if (m_ani_t == m_ani_T)
|
||||
stopAni();
|
||||
else
|
||||
++m_ani_t;
|
||||
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Widget::onProcessMessage(msg);
|
||||
@ -390,7 +376,7 @@ void Tabs::onPaint(PaintEvent& ev)
|
||||
Graphics* g = ev.getGraphics();
|
||||
gfx::Rect rect = getClientBounds();
|
||||
gfx::Rect box(rect.x, rect.y, rect.w,
|
||||
(m_list.empty() && m_ani == ANI_NONE ? 0:
|
||||
(m_list.empty() && animation() == ANI_NONE ? 0:
|
||||
theme->dimensions.tabsHeight() - theme->dimensions.tabsEmptyHeight()));
|
||||
|
||||
g->fillRect(theme->colors.windowFace(), g->getClipBounds());
|
||||
@ -410,7 +396,7 @@ void Tabs::onPaint(PaintEvent& ev)
|
||||
}
|
||||
|
||||
// Draw deleted tab
|
||||
if (m_ani == ANI_REMOVING_TAB && m_removedTab) {
|
||||
if (animation() == ANI_REMOVING_TAB && m_removedTab) {
|
||||
m_removedTab->width = 0;
|
||||
box = getTabBounds(m_removedTab);
|
||||
drawTab(g, box, m_removedTab, 0,
|
||||
@ -420,12 +406,12 @@ void Tabs::onPaint(PaintEvent& ev)
|
||||
|
||||
// Tab that is being dragged
|
||||
if (m_selected && m_selected != m_floatingTab) {
|
||||
double t = double(m_ani_t) / double(m_ani_T);
|
||||
double t = animationTime();
|
||||
Tab* tab = m_selected;
|
||||
box = getTabBounds(tab);
|
||||
|
||||
int dy = 0;
|
||||
if (m_ani == ANI_ADDING_TAB)
|
||||
if (animation() == ANI_ADDING_TAB)
|
||||
dy = int(box.h - box.h * t);
|
||||
|
||||
drawTab(g, box, m_selected, dy, (tab == m_hot), true);
|
||||
@ -443,7 +429,7 @@ void Tabs::onPreferredSize(PreferredSizeEvent& ev)
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
gfx::Size reqsize(0, 0);
|
||||
|
||||
if (m_list.empty() && m_ani == ANI_NONE)
|
||||
if (m_list.empty() && animation() == ANI_NONE)
|
||||
reqsize.h = theme->dimensions.tabsEmptyHeight();
|
||||
else
|
||||
reqsize.h = theme->dimensions.tabsHeight();
|
||||
@ -665,23 +651,13 @@ void Tabs::resetOldPositions(double t)
|
||||
}
|
||||
}
|
||||
|
||||
void Tabs::startAni(Ani ani, int T)
|
||||
void Tabs::onAnimationFrame()
|
||||
{
|
||||
// Stop previous animation
|
||||
if (m_ani != ANI_NONE)
|
||||
stopAni();
|
||||
|
||||
m_ani = ani;
|
||||
m_ani_t = 0;
|
||||
m_ani_T = T;
|
||||
m_timer.start();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void Tabs::stopAni()
|
||||
void Tabs::onAnimationStop()
|
||||
{
|
||||
m_ani = ANI_NONE;
|
||||
m_timer.stop();
|
||||
|
||||
if (m_list.empty()) {
|
||||
Widget* root = getRoot();
|
||||
if (root)
|
||||
@ -711,9 +687,9 @@ void Tabs::stopDrag()
|
||||
m_selected->oldWidth = m_selected->width;
|
||||
}
|
||||
|
||||
resetOldPositions(double(m_ani_t) / double(m_ani_T));
|
||||
resetOldPositions(animationTime());
|
||||
updateTabs();
|
||||
startAni(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
startAnimation(ANI_REORDER_TABS, ANI_REORDER_TABS_TICKS);
|
||||
}
|
||||
|
||||
gfx::Rect Tabs::getTabBounds(Tab* tab)
|
||||
@ -721,12 +697,12 @@ gfx::Rect Tabs::getTabBounds(Tab* tab)
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
gfx::Rect rect = getClientBounds();
|
||||
gfx::Rect box(rect.x, rect.y, rect.w,
|
||||
(m_list.empty() && m_ani == ANI_NONE ? 0:
|
||||
(m_list.empty() && animation() == ANI_NONE ? 0:
|
||||
theme->dimensions.tabsHeight() - theme->dimensions.tabsEmptyHeight()));
|
||||
int startX = m_border*guiscale();
|
||||
double t = double(m_ani_t) / double(m_ani_T);
|
||||
double t = animationTime();
|
||||
|
||||
if (m_ani == ANI_NONE) {
|
||||
if (animation() == ANI_NONE) {
|
||||
box.x = startX + tab->x;
|
||||
box.w = tab->width;
|
||||
}
|
||||
@ -773,7 +749,7 @@ void Tabs::createFloatingTab(Tab* tab)
|
||||
|
||||
m_floatingTab = tab;
|
||||
m_removedTab = nullptr;
|
||||
startAni(ANI_REMOVING_TAB, ANI_REMOVING_TAB_TICKS);
|
||||
startAnimation(ANI_REMOVING_TAB, ANI_REMOVING_TAB_TICKS);
|
||||
updateTabs();
|
||||
}
|
||||
|
||||
@ -790,7 +766,7 @@ void Tabs::destroyFloatingTab()
|
||||
m_floatingTab = nullptr;
|
||||
|
||||
resetOldPositions();
|
||||
startAni(ANI_ADDING_TAB, ANI_ADDING_TAB_TICKS);
|
||||
startAnimation(ANI_ADDING_TAB, ANI_ADDING_TAB_TICKS);
|
||||
updateTabs();
|
||||
|
||||
tab->oldX = tab->x;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define APP_UI_TABS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/animated_widget.h"
|
||||
#include "ui/mouse_buttons.h"
|
||||
#include "ui/timer.h"
|
||||
#include "ui/widget.h"
|
||||
@ -74,7 +75,8 @@ namespace app {
|
||||
};
|
||||
|
||||
// Tabs control. Used to show opened documents.
|
||||
class Tabs : public ui::Widget {
|
||||
class Tabs : public ui::Widget
|
||||
, public AnimatedWidget {
|
||||
struct Tab {
|
||||
TabView* view;
|
||||
std::string text;
|
||||
@ -90,10 +92,12 @@ namespace app {
|
||||
typedef std::vector<Tab*> TabsList;
|
||||
typedef TabsList::iterator TabsListIterator;
|
||||
|
||||
enum Ani { ANI_NONE,
|
||||
ANI_ADDING_TAB,
|
||||
ANI_REMOVING_TAB,
|
||||
ANI_REORDER_TABS };
|
||||
enum Ani : int {
|
||||
ANI_NONE,
|
||||
ANI_ADDING_TAB,
|
||||
ANI_REMOVING_TAB,
|
||||
ANI_REORDER_TABS
|
||||
};
|
||||
|
||||
public:
|
||||
Tabs(TabsDelegate* delegate);
|
||||
@ -113,12 +117,12 @@ namespace app {
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onPreferredSize(ui::PreferredSizeEvent& ev) override;
|
||||
void onAnimationFrame() override;
|
||||
void onAnimationStop() override;
|
||||
|
||||
private:
|
||||
void resetOldPositions();
|
||||
void resetOldPositions(double t);
|
||||
void startAni(Ani ani, int T);
|
||||
void stopAni();
|
||||
|
||||
void selectTabInternal(Tab* tab);
|
||||
void drawTab(ui::Graphics* g, const gfx::Rect& box, Tab* tab, int dy, bool hover, bool selected);
|
||||
@ -146,10 +150,6 @@ namespace app {
|
||||
TabsDelegate* m_delegate;
|
||||
|
||||
// Variables for animation purposes
|
||||
ui::Timer m_timer;
|
||||
Ani m_ani; // Current animation
|
||||
int m_ani_t; // Number of ticks from the beginning of the transition/animation
|
||||
int m_ani_T; // Number of ticks in total for the current transition/animation
|
||||
Tab* m_removedTab;
|
||||
|
||||
// Drag-and-drop
|
||||
|
Loading…
x
Reference in New Issue
Block a user