Tidied up, simplified and documented expand animation code
This commit is contained in:
parent
22c9e8b082
commit
b48d8fc49b
3 changed files with 130 additions and 59 deletions
|
|
@ -185,12 +185,6 @@ TimelineLayoutHelper::layout_headers_recursive(
|
|||
shared_ptr<timeline::Track> timeline_track =
|
||||
lookup_timeline_track(model_track);
|
||||
|
||||
// Is the track animating?
|
||||
const int track_animation_state =
|
||||
timeline_track->get_expand_animation_state();
|
||||
if(track_animation_state != Track::NoAnimationState)
|
||||
is_animating = true;
|
||||
|
||||
// Is the track going to be shown?
|
||||
if(parent_expanded)
|
||||
{
|
||||
|
|
@ -207,6 +201,11 @@ TimelineLayoutHelper::layout_headers_recursive(
|
|||
// Offset for the next header
|
||||
child_offset += track_height + TimelineWidget::TrackPadding;
|
||||
}
|
||||
|
||||
// Is the track animating?
|
||||
const bool is_track_animating =
|
||||
timeline_track->is_expand_animating();
|
||||
is_animating |= is_track_animating;
|
||||
|
||||
// Recurse to children
|
||||
const bool expand_child =
|
||||
|
|
@ -218,15 +217,11 @@ TimelineLayoutHelper::layout_headers_recursive(
|
|||
header_width, indent_width, depth + 1, expand_child);
|
||||
|
||||
// Do collapse animation as necessary
|
||||
if(track_animation_state != Track::NoAnimationState)
|
||||
{
|
||||
// Tick the track expand animation
|
||||
timeline_track->tick_expand_animation();
|
||||
|
||||
if(is_track_animating)
|
||||
{
|
||||
// Calculate the height of te area which will be
|
||||
// shown as expanded
|
||||
const float a = ((float)track_animation_state /
|
||||
(float)Track::MaxExpandAnimation);
|
||||
const float a = timeline_track->get_expand_animation_state();
|
||||
child_branch_height *= a * a;
|
||||
const int y_limit =
|
||||
branch_offset + child_offset + child_branch_height;
|
||||
|
|
@ -248,6 +243,9 @@ TimelineLayoutHelper::layout_headers_recursive(
|
|||
if(rect.get_y() + rect.get_height() > y_limit)
|
||||
headerBoxes.erase(track);
|
||||
}
|
||||
|
||||
// Tick the track expand animation
|
||||
timeline_track->tick_expand_animation();
|
||||
}
|
||||
|
||||
child_offset += child_branch_height;
|
||||
|
|
|
|||
|
|
@ -36,26 +36,19 @@ namespace gui {
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
const int Track::NoAnimationState = -1;
|
||||
const int Track::MaxExpandAnimation = 65536;
|
||||
const double Track::ExpandAnimationPeriod = 0.15;
|
||||
|
||||
Glib::Timer Track::timer;
|
||||
const float Track::ExpandAnimationPeriod = 0.15;
|
||||
|
||||
Track::Track(TimelineWidget &timeline_widget,
|
||||
shared_ptr<model::Track> track) :
|
||||
timelineWidget(timeline_widget),
|
||||
model_track(track),
|
||||
expanded(true),
|
||||
expandAnimationState(Track::NoAnimationState),
|
||||
expandDirection(None),
|
||||
enableButton(Gtk::StockID("track_enabled")),
|
||||
lockButton(Gtk::StockID("track_unlocked"))
|
||||
{
|
||||
REQUIRE(model_track);
|
||||
|
||||
// Ensure that the timer is running
|
||||
timer.start();
|
||||
|
||||
titleMenuButton.set_relief(RELIEF_HALF);
|
||||
|
||||
buttonBar.append(enableButton);
|
||||
|
|
@ -121,71 +114,81 @@ Track::get_expanded() const
|
|||
void
|
||||
Track::expand_collapse(ExpandDirection direction)
|
||||
{
|
||||
REQUIRE(direction != None);
|
||||
|
||||
expandDirection = direction;
|
||||
if(direction == Expand)
|
||||
{
|
||||
expanded = true;
|
||||
expandAnimationState = 0;
|
||||
expandAnimationState = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
expanded = false;
|
||||
expandAnimationState = MaxExpandAnimation;
|
||||
expandAnimationState = 1.0;
|
||||
}
|
||||
|
||||
lastTickTime = timer.elapsed();
|
||||
|
||||
// Create a timer if we don't already have one
|
||||
if(!expand_timer)
|
||||
{
|
||||
expand_timer.reset(new Glib::Timer());
|
||||
expand_timer->start();
|
||||
}
|
||||
else // Reset the timer if we do
|
||||
expand_timer->reset();
|
||||
}
|
||||
|
||||
int
|
||||
float
|
||||
Track::get_expand_animation_state() const
|
||||
{
|
||||
ENSURE((expandAnimationState >= 0 &&
|
||||
expandAnimationState <= MaxExpandAnimation) ||
|
||||
expandAnimationState == NoAnimationState);
|
||||
ENSURE(expandAnimationState >= 0.0 &&
|
||||
expandAnimationState <= 1.0);
|
||||
return expandAnimationState;
|
||||
}
|
||||
|
||||
bool
|
||||
Track::is_expand_animating() const
|
||||
{
|
||||
return expandDirection != None;
|
||||
}
|
||||
|
||||
void
|
||||
Track::tick_expand_animation()
|
||||
{
|
||||
if(expandAnimationState <= NoAnimationState)
|
||||
{
|
||||
WARN(gui, "tick_expand_animation() was called when"
|
||||
" expandAnimationState was set to NoAnimationState");
|
||||
return;
|
||||
}
|
||||
|
||||
const double delta = MaxExpandAnimation * (timer.elapsed() - lastTickTime) / ExpandAnimationPeriod;
|
||||
REQUIRE(expandDirection != None); // tick_expand_animation should not
|
||||
// be unless is_expand_animating
|
||||
// returns true
|
||||
REQUIRE(expand_timer);
|
||||
const float delta =
|
||||
(float)expand_timer->elapsed() / ExpandAnimationPeriod;
|
||||
expand_timer->reset(); // reset the timer to t=0
|
||||
|
||||
if(expandDirection == Expand)
|
||||
{
|
||||
expandAnimationState += delta;
|
||||
if(expandAnimationState >= MaxExpandAnimation)
|
||||
expandAnimationState = NoAnimationState;
|
||||
if(expandAnimationState >= 1.0)
|
||||
expandDirection = None;
|
||||
}
|
||||
else
|
||||
{
|
||||
expandAnimationState -= delta;
|
||||
if(expandAnimationState <= 0)
|
||||
expandAnimationState = NoAnimationState;
|
||||
if(expandAnimationState <= 0.0)
|
||||
expandDirection = None;
|
||||
}
|
||||
|
||||
lastTickTime = timer.elapsed();
|
||||
|
||||
ENSURE((expandAnimationState >= 0 &&
|
||||
expandAnimationState <= MaxExpandAnimation) ||
|
||||
expandAnimationState == NoAnimationState);
|
||||
if(expandDirection == None)
|
||||
expand_timer.reset(); // We've finished with the timer - delete it
|
||||
}
|
||||
|
||||
Gtk::ExpanderStyle
|
||||
Track::get_expander_style() const
|
||||
{
|
||||
const int notch = Track::MaxExpandAnimation / 3;
|
||||
const int notch = 1.0 / 3.0;
|
||||
if(expanded)
|
||||
{
|
||||
if(expandAnimationState == Track::NoAnimationState)
|
||||
if(expandDirection == None)
|
||||
return EXPANDER_EXPANDED;
|
||||
else if(expandAnimationState >= notch * 2)
|
||||
else if(expandAnimationState >= notch * 2.0)
|
||||
return EXPANDER_SEMI_EXPANDED;
|
||||
else if(expandAnimationState >= notch)
|
||||
return EXPANDER_SEMI_COLLAPSED;
|
||||
|
|
@ -194,11 +197,11 @@ Track::get_expander_style() const
|
|||
}
|
||||
else
|
||||
{
|
||||
if(expandAnimationState == Track::NoAnimationState)
|
||||
if(expandDirection == None)
|
||||
return EXPANDER_COLLAPSED;
|
||||
else if(expandAnimationState <= notch)
|
||||
return EXPANDER_SEMI_COLLAPSED;
|
||||
else if(expandAnimationState <= notch * 2)
|
||||
else if(expandAnimationState <= notch * 2.0)
|
||||
return EXPANDER_SEMI_EXPANDED;
|
||||
else
|
||||
return EXPANDER_EXPANDED;
|
||||
|
|
|
|||
|
|
@ -37,12 +37,23 @@ namespace timeline {
|
|||
|
||||
class TimelineViewWindow;
|
||||
|
||||
/**
|
||||
* Timeline tracks are created by the timeline widget to correspond to
|
||||
* model tracks. Timeline tracks are used to store UI specific state
|
||||
* data.
|
||||
**/
|
||||
class Track : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* An enum used by the branch expand/collapse animation.
|
||||
* ExpandDirection represents whether the branch us being expanded or
|
||||
* collapsed, or neither.
|
||||
**/
|
||||
enum ExpandDirection
|
||||
{
|
||||
None,
|
||||
Expand,
|
||||
Collapse
|
||||
};
|
||||
|
|
@ -57,15 +68,48 @@ public:
|
|||
|
||||
int get_height() const;
|
||||
|
||||
/**
|
||||
* Gets whether the descendant tracks are expanded or collapsed.
|
||||
* @return Returns true if the branch is expanded, false if it's
|
||||
* collapsed.
|
||||
* @see expand_collapse
|
||||
**/
|
||||
bool get_expanded() const;
|
||||
|
||||
/**
|
||||
* Expands or collapses this branch.
|
||||
* @param direction Specifies whether this branch should be expanded
|
||||
* or collapse. direction must not equal None
|
||||
**/
|
||||
void expand_collapse(ExpandDirection direction);
|
||||
|
||||
// -1 for no animation
|
||||
int get_expand_animation_state() const;
|
||||
/**
|
||||
* The current expand state.
|
||||
* @return Returns the expand state value, this value is a number
|
||||
* between 0 and 1.0, and is recalculated by tick_expand_animation().
|
||||
* @remarks A value of 1.0 is given when the branch is fully expanded
|
||||
* (and animating), 0.0 is given when the branch is fully collapsed
|
||||
* (and animating). When the branch is not animating this value has
|
||||
* an indeterminate value.
|
||||
* @see tick_expand_animation
|
||||
**/
|
||||
float get_expand_animation_state() const;
|
||||
|
||||
/**
|
||||
* Gets whether the branch is animation.
|
||||
* @return Returns true if the branch is animating, false if not.
|
||||
**/
|
||||
bool is_expand_animating() const;
|
||||
|
||||
/**
|
||||
* When this track is being animated, tick_expand_animation must be
|
||||
* called repeatedly to cause the animation to progress.
|
||||
**/
|
||||
void tick_expand_animation();
|
||||
|
||||
/**
|
||||
* Calculates the expander style, given the animation state.
|
||||
**/
|
||||
Gtk::ExpanderStyle get_expander_style() const;
|
||||
|
||||
void show_header_context_menu(guint button, guint32 time);
|
||||
|
|
@ -75,9 +119,12 @@ public:
|
|||
const = 0;
|
||||
|
||||
public:
|
||||
static const int NoAnimationState;
|
||||
static const int MaxExpandAnimation;
|
||||
static const double ExpandAnimationPeriod;
|
||||
//----- Constants -----//
|
||||
|
||||
/**
|
||||
* Specifies the period of the expand animation in seconds.
|
||||
**/
|
||||
static const float ExpandAnimationPeriod;
|
||||
|
||||
private:
|
||||
//----- Internals -----//
|
||||
|
|
@ -96,13 +143,36 @@ protected:
|
|||
boost::shared_ptr<model::Track> model_track;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* This bool is true if this branch is expanded. false if it is
|
||||
* collapsed.
|
||||
**/
|
||||
bool expanded;
|
||||
|
||||
/**
|
||||
* This enum specifies which direction the expand/collapse animation
|
||||
* is moving - if any.
|
||||
* @remarks If no animation is occuring, expandDirection is set to
|
||||
* None.
|
||||
**/
|
||||
ExpandDirection expandDirection;
|
||||
|
||||
/**
|
||||
* The current expand state.
|
||||
* @remarks This value is a number between 0 and 1.0,
|
||||
* and is recalculated by tick_expand_animation(). This variable is
|
||||
* set to 1.0 when the branch is fully expanded (and animating) and
|
||||
* 0.0 when the branch is fully collapsed (and animating). When the
|
||||
* branch is not animating this value has an indeterminate value.
|
||||
* @see tick_expand_animation
|
||||
**/
|
||||
double expandAnimationState;
|
||||
|
||||
static Glib::Timer timer;
|
||||
double lastTickTime;
|
||||
/**
|
||||
* An internal timer used for the expand/collapse animation.
|
||||
**/
|
||||
boost::scoped_ptr<Glib::Timer> expand_timer;
|
||||
|
||||
//----- Header Widgets ------//
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue