Join latest GUI addions (zoom slider) and player design/implementation work

This commit is contained in:
Fischlurch 2011-10-20 04:29:14 +02:00
commit c06c49e782
15 changed files with 514 additions and 185 deletions

View file

@ -23,10 +23,12 @@
#include "gui/gtk-lumiera.hpp"
#include "gui/panels/timeline-panel.hpp"
#include "gui/widgets/timeline/timeline-zoom-scale.hpp"
#include "gui/workspace/workspace-window.hpp"
#include "gui/model/project.hpp"
#include "gui/controller/controller.hpp"
#include "lib/util.hpp"
#include <boost/foreach.hpp>
@ -34,6 +36,7 @@
using namespace Gtk;
using namespace sigc;
using namespace gui::widgets;
using namespace gui::widgets::timeline;
using namespace gui::model;
using boost::shared_ptr; ///////////////////////////////TICKET #796
@ -60,6 +63,7 @@ TimelinePanel::TimelinePanel (workspace::PanelManager &panel_manager,
, iBeamTool(Gtk::StockID("tool_i_beam"))
, zoomIn(Stock::ZOOM_IN)
, zoomOut(Stock::ZOOM_OUT)
, zoomScale()
, updatingToolbar(false)
, currentTool(timeline::Arrow)
{
@ -101,14 +105,15 @@ TimelinePanel::TimelinePanel (workspace::PanelManager &panel_manager,
toolbar.append(separator2);
toolbar.append(zoomIn, mem_fun(this, &TimelinePanel::on_zoom_in));
toolbar.append(zoomOut, mem_fun(this, &TimelinePanel::on_zoom_out));
toolbar.append(zoomScale);
zoomScale.signal_zoom().
connect(mem_fun(this,&TimelinePanel::on_zoom));
toolbar.show_all();
panelBar.pack_start(toolbar, PACK_SHRINK);
// Setup tooltips
sequenceChooser .set_tooltip_text(_("Change sequence"));
sequenceChooser .set_tooltip_text(_("Change sequence"));
previousButton .set_tooltip_text(_("To beginning"));
rewindButton .set_tooltip_text(_("Rewind"));
@ -122,12 +127,18 @@ TimelinePanel::TimelinePanel (workspace::PanelManager &panel_manager,
zoomIn .set_tooltip_text(_("Zoom in"));
zoomOut .set_tooltip_text(_("Zoom out"));
zoomScale .set_tooltip_text(_("Adjust timeline zoom scale"));
// Setup the timeline widget
shared_ptr<Sequence> sequence ///////////////////////////////TICKET #796
shared_ptr<Sequence> sequence ///////////////////////////////TICKET #796 : should use std::tr1::shared_ptr instead of boost
= *get_project().get_sequences().begin();
timelineWidget.reset(new TimelineWidget(load_state(sequence)));
pack_start(*timelineWidget, PACK_EXPAND_WIDGET);
// since TimelineWidget is now initialised,
// wire the zoom slider to react on timeline state changes
zoomScale.wireTimelineState (timelineWidget->get_state(),
timelineWidget->state_changed_signal());
// Set the initial UI state
update_sequence_chooser();
@ -136,7 +147,6 @@ TimelinePanel::TimelinePanel (workspace::PanelManager &panel_manager,
show_time (Time::ZERO);
}
const char*
TimelinePanel::get_title()
{
@ -183,6 +193,13 @@ TimelinePanel::on_ibeam_tool()
set_tool(timeline::IBeam);
}
void
TimelinePanel::on_zoom(double time_scale_ratio)
{
REQUIRE(timelineWidget);
timelineWidget->zoom_view(time_scale_ratio);
}
void
TimelinePanel::on_zoom_in()
{
@ -236,18 +253,19 @@ TimelinePanel::on_sequence_chosen()
{
weak_ptr<Sequence> sequence_ptr =
(*iter)[sequenceChooserColumns.sequenceColumn];
shared_ptr<Sequence> sequence(sequence_ptr.lock());
if(sequence)
{
shared_ptr<timeline::TimelineState> old_state(
timelineWidget->get_state());
REQUIRE(old_state);
if(sequence != old_state->get_sequence())
timelineWidget->set_state(load_state(sequence));
}
}
update_zoom_buttons();
}
@ -379,9 +397,10 @@ TimelinePanel::on_frame()
shared_ptr<timeline::TimelineState>
TimelinePanel::load_state(weak_ptr<Sequence> sequence)
{
/* state exists */
if(contains(timelineStates, sequence))
return timelineStates[sequence];
return timelineStates[sequence];
shared_ptr<Sequence> shared_sequence = sequence.lock();
if(shared_sequence)
{

View file

@ -32,6 +32,8 @@
#include "gui/panels/panel.hpp"
#include "gui/widgets/timecode-widget.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/widgets/timeline/timeline-zoom-scale.hpp"
#include "lib/time/timevalue.hpp"
#include <boost/scoped_ptr.hpp>
@ -87,6 +89,7 @@ private:
void on_arrow_tool();
void on_ibeam_tool();
void on_zoom(double time_scale_ratio);
void on_zoom_in();
void on_zoom_out();
@ -171,7 +174,7 @@ private:
boost::scoped_ptr<TimelineWidget> timelineWidget;
std::map< boost::weak_ptr<model::Sequence>,
boost::shared_ptr<widgets::timeline::TimelineState> > ///////////////////////////////TICKET #796
boost::shared_ptr<widgets::timeline::TimelineState> > ///////////////////////////////TICKET #796 : should use std::tr1::shared_ptr
timelineStates;
// Toolbar Widgets
@ -191,6 +194,7 @@ private:
MiniButton zoomIn;
MiniButton zoomOut;
gui::widgets::timeline::TimelineZoomScale zoomScale;
Gtk::SeparatorToolItem separator2;

View file

@ -41,7 +41,7 @@ const int TimelineWidget::TrackPadding = 1;
const int TimelineWidget::HeaderWidth = 150;
const int TimelineWidget::HeaderIndentWidth = 10;
const double TimelineWidget::ZoomIncrement = 1.25;
const int64_t TimelineWidget::MaxScale = 30000000;
const int64_t TimelineWidget::MaxScale = 30000000; // 30 Million
TimelineWidget::TimelineWidget(
boost::shared_ptr<timeline::TimelineState> source_state) :
@ -102,6 +102,7 @@ TimelineWidget::get_state()
void
TimelineWidget::set_state(shared_ptr<timeline::TimelineState> new_state)
{
state = new_state;
// Clear the track tree
@ -125,17 +126,17 @@ TimelineWidget::set_state(shared_ptr<timeline::TimelineState> new_state)
update_tracks();
// Send the state changed signal
stateChangedSignal.emit();
stateChangedSignal.emit (state);
}
void
TimelineWidget::zoom_view(int zoom_size)
TimelineWidget::zoom_view(double timescale_ratio)
{
if(state)
{
const int view_width = body->get_allocation().get_width();
state->get_view_window().zoom_view(view_width / 2, zoom_size);
}
{
const int view_width = body->get_allocation().get_width();
state->get_view_window().zoom_view(view_width / 2, timescale_ratio);
}
}
ToolType
@ -178,7 +179,7 @@ TimelineWidget::hovering_track_changed_signal() const
return hoveringTrackChangedSignal;
}
sigc::signal<void>
TimelineWidget::TimelineStateChangeSignal
TimelineWidget::state_changed_signal() const
{
return stateChangedSignal;
@ -212,10 +213,12 @@ TimelineWidget::on_view_window_changed()
if(state)
{
timeline::TimelineViewWindow &window = state->get_view_window();
const int view_width = body->get_allocation().get_width();
horizontalAdjustment.set_page_size(
window.get_time_scale() * view_width);
horizontalAdjustment.set_value(_raw(window.get_time_offset()));
}
}

View file

@ -98,7 +98,7 @@ public:
* @param zoom_size The number of steps to zoom by. The scale factor
* is 1.25^(-zoom_size).
*/
void zoom_view(int zoom_size);
void zoom_view(double timescale_ratio);
/**
* Gets the type of the tool currently active.
@ -115,14 +115,16 @@ public:
public:
/* ===== Signals ===== */
typedef sigc::signal<void, boost::shared_ptr<timeline::TimelineState> > TimelineStateChangeSignal;
typedef sigc::signal<void, boost::shared_ptr<timeline::Track> > HoveringTrackChangedSignal;
sigc::signal<void, lib::time::Time> mouse_hover_signal() const;
sigc::signal<void> playback_period_drag_released_signal() const;
sigc::signal<void, boost::shared_ptr<timeline::Track> >
hovering_track_changed_signal() const;
HoveringTrackChangedSignal hovering_track_changed_signal() const;
sigc::signal<void> state_changed_signal() const;
TimelineStateChangeSignal state_changed_signal() const;
/* ===== Events ===== */
protected:
@ -275,9 +277,8 @@ protected:
// Signals
sigc::signal<void, Time> mouseHoverSignal;
sigc::signal<void> playbackPeriodDragReleasedSignal;
sigc::signal<void, boost::shared_ptr<timeline::Track> >
hoveringTrackChangedSignal;
sigc::signal<void> stateChangedSignal;
HoveringTrackChangedSignal hoveringTrackChangedSignal;
TimelineStateChangeSignal stateChangedSignal;
bool update_tracks_frozen;

View file

@ -39,6 +39,8 @@ using namespace lumiera;
using gui::util::CairoUtil;
using boost::shared_ptr; ////////////////////TICKET #796
namespace gui {
namespace widgets {
namespace timeline {
@ -61,7 +63,7 @@ TimelineBody::TimelineBody (TimelineWidget &timelineWidget)
register_styles();
// Reset the state
on_state_changed();
propagateStateChange();
}
TimelineBody::~TimelineBody()
@ -69,6 +71,13 @@ TimelineBody::~TimelineBody()
WARN_IF(!tool, gui, "An invalid tool pointer is unexpected here");
}
TimelineViewWindow&
TimelineBody::viewWindow() const
{
REQUIRE(timelineState);
return timelineState->get_view_window();
}
TimelineWidget&
TimelineBody::getTimelineWidget () const
{
@ -147,7 +156,7 @@ TimelineBody::on_expose_event(GdkEventExpose* event)
// Makes sure the widget styles have been loaded
read_styles();
if(timelineWidget.get_state())
if (timelineState)
{
// Prepare to render via cairo
const Allocation allocation = get_allocation();
@ -169,9 +178,9 @@ TimelineBody::on_scroll_event (GdkEventScroll* event)
{
REQUIRE(event != NULL);
if(timelineWidget.get_state())
if (timelineState)
{
TimelineViewWindow &window = view_window();
TimelineViewWindow &window = viewWindow();
const Allocation allocation = get_allocation();
if(event->state & GDK_CONTROL_MASK)
@ -255,17 +264,16 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
{
REQUIRE(event != NULL);
if(timelineWidget.get_state())
if (timelineState)
{
// Handle a middle-mouse drag if one is occuring
switch(dragType)
{
case Shift:
{
TimelineViewWindow &window = view_window();
/////////////////////////////TICKET# 795 : don't reach in from outside and manipulate internals of the timeline view!
/////////////////////////////TICKET #795 : don't reach in from outside and manipulate internals of the timeline view!
///////////////////////////// : either encapsulate this entirely here, or leave it to the timeline view!
TimelineViewWindow &window = viewWindow();
const int64_t scale = window.get_time_scale();
window.set_time_offset(beginShiftTimeOffset
+ TimeValue(scale * (mouseDownX - event->x)));
@ -294,12 +302,20 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
}
void
TimelineBody::on_state_changed()
TimelineBody::on_state_changed (shared_ptr<TimelineState> newState)
{
if(timelineWidget.get_state())
REQUIRE (newState);
timelineState = newState;
propagateStateChange();
}
void
TimelineBody::propagateStateChange()
{
if (timelineState)
{
// Connect up some events
view_window().changed_signal().connect(
viewWindow().changed_signal().connect(
sigc::mem_fun(this, &TimelineBody::on_update_view) );
}
@ -373,7 +389,7 @@ TimelineBody::draw_track(Cairo::RefPtr<Cairo::Context> cr,
// Render the track
cr->save();
TimelineViewWindow &window = view_window();
TimelineViewWindow &window = viewWindow();
timeline_track->draw_track(cr, &window);
cr->restore();
}
@ -386,12 +402,11 @@ TimelineBody::draw_selection(Cairo::RefPtr<Cairo::Context> cr)
// Prepare
const Allocation allocation = get_allocation();
shared_ptr<TimelineState> state = timelineWidget.get_state();
REQUIRE(state);
REQUIRE(timelineState);
TimelineViewWindow const& window = state->get_view_window();
const int start_x = window.time_to_x(state->getSelectionStart());
const int end_x = window.time_to_x(state->getSelectionEnd());
TimelineViewWindow const& window = timelineState->get_view_window();
const int start_x = window.time_to_x(timelineState->getSelectionStart());
const int end_x = window.time_to_x(timelineState->getSelectionEnd());
// Draw the cover
if(end_x > 0 && start_x < allocation.get_width())
@ -427,16 +442,13 @@ TimelineBody::draw_playback_point(Cairo::RefPtr<Cairo::Context> cr)
{
REQUIRE(cr);
// Prepare
shared_ptr<TimelineState> state = timelineWidget.get_state();
if(state)
if (timelineState)
{
if (!state->isPlaying()) return;
if (!timelineState->isPlaying()) return;
const Allocation allocation = get_allocation();
Time point = state->getPlaybackPoint();
const int x = view_window().time_to_x(point);
Time point = timelineState->getPlaybackPoint();
const int x = viewWindow().time_to_x(point);
// Set source
cr->set_source(playbackPointColour);
@ -455,10 +467,10 @@ TimelineBody::draw_playback_point(Cairo::RefPtr<Cairo::Context> cr)
void
TimelineBody::begin_shift_drag()
{
if(timelineWidget.get_state())
if (timelineState)
{
dragType = Shift;
beginShiftTimeOffset = view_window().get_time_offset();
beginShiftTimeOffset = viewWindow().get_time_offset();
beginShiftVerticalOffset = get_vertical_offset();
}
}
@ -475,14 +487,6 @@ TimelineBody::set_vertical_offset(int offset)
timelineWidget.verticalAdjustment.set_value(offset);
}
TimelineViewWindow&
TimelineBody::view_window() const
{
shared_ptr<TimelineState> state = timelineWidget.get_state();
REQUIRE(state);
return state->get_view_window();
}
void
TimelineBody::register_styles() const
{

View file

@ -68,10 +68,7 @@ public:
*/
TimelineBody(gui::widgets::TimelineWidget &timeline_widget);
/**
* Destructor
*/
~TimelineBody();
virtual ~TimelineBody();
TimelineWidget&
getTimelineWidget () const;
@ -125,13 +122,18 @@ protected:
bool on_motion_notify_event(GdkEventMotion *event);
/**
* The event handler for when the TimelineWidget's state object is
* replaced.
* The event handler for when the TimelineWidget's state is switched.
*/
void on_state_changed();
void on_state_changed (boost::shared_ptr<TimelineState> newState);
/* ===== Internals ===== */
private:
/**
* Access the current timeline view window
* @warning must not be called unless the TimlineWidget
* has a valid state.
*/
TimelineViewWindow& viewWindow() const;
/**
* Draws the timeline tracks.
@ -161,13 +163,9 @@ private:
void set_vertical_offset(int offset);
/**
* A helper function to get the view window
* @remarks This function must not be called unless the TimlineWidget
* has a valid state.
*/
TimelineViewWindow& view_window() const;
/** adjust to the new timeline state */
void propagateStateChange();
/**
* Registers all the styles that this class will respond to.
*/
@ -202,6 +200,8 @@ private:
Cairo::RefPtr<Cairo::SolidPattern> playbackPointColour;
gui::widgets::TimelineWidget &timelineWidget;
boost::shared_ptr<TimelineState> timelineState; ////////////////////TICKET #796 : should use std::tr1::shared_ptr
friend class Tool;
friend class ArrowTool;

View file

@ -75,6 +75,14 @@ TimelineRuler::TimelineRuler (TimelineWidget &timeline_widget)
register_styles();
}
TimelineViewWindow&
TimelineRuler::viewWindow() const
{
REQUIRE(timelineState);
return timelineState->get_view_window();
}
void
TimelineRuler::set_mouse_chevron_offset(int offset)
{
@ -114,7 +122,7 @@ TimelineRuler::on_expose_event(GdkEventExpose* event)
if(!window)
return false;
if(timelineWidget.get_state())
if (timelineState)
{
// Prepare to render via cairo
const Allocation allocation = get_allocation();
@ -160,11 +168,11 @@ TimelineRuler::on_button_press_event(GdkEventButton* event)
{
REQUIRE(event != NULL);
if(timelineWidget.get_state())
if (timelineState)
{
if(event->button == 1)
{
pinnedDragTime = view_window().x_to_time(event->x);
pinnedDragTime = viewWindow().x_to_time(event->x);
isDragging = true;
}
}
@ -219,34 +227,40 @@ TimelineRuler::on_size_allocate(Gtk::Allocation& allocation)
}
void
TimelineRuler::on_state_changed()
TimelineRuler::on_state_changed (shared_ptr<TimelineState> newState)
{
if(timelineWidget.get_state())
{
// Connect up some events
view_window().changed_signal().connect(
sigc::mem_fun(this, &TimelineRuler::on_update_view) );
}
REQUIRE (newState);
timelineState = newState;
propagateStateChange();
}
void
TimelineRuler::propagateStateChange()
{
// Connect up some events
viewWindow().changed_signal().connect(
sigc::mem_fun(this, &TimelineRuler::on_update_view) );
// Redraw
on_update_view();
}
void
TimelineRuler::set_leading_x(const int x)
{
shared_ptr<TimelineState> state = timelineWidget.get_state();
if(state)
if (timelineState)
{
TimeVar newStartPoint (view_window().x_to_time(x));
TimeVar newStartPoint (viewWindow().x_to_time(x));
Offset selectionLength (pinnedDragTime, newStartPoint);
if (newStartPoint > pinnedDragTime)
newStartPoint=pinnedDragTime; // use the smaller one as selection start
state->setPlaybackPeriod (Mutation::changeTime(newStartPoint) );
state->setPlaybackPeriod (Mutation::changeDuration(selectionLength));
timelineState->setPlaybackPeriod (Mutation::changeTime(newStartPoint) );
timelineState->setPlaybackPeriod (Mutation::changeDuration(selectionLength));
//////////////////////////////////////////////////////TICKET #797 : this is cheesy. Should provide a single Mutation to change all at once
////////////////////TODO : code duplication with timeline-ibeam-tool 205
}
@ -260,7 +274,7 @@ TimelineRuler::draw_ruler(Cairo::RefPtr<Cairo::Context> cr,
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
const TimelineViewWindow &window = view_window();
const TimelineViewWindow &window = viewWindow();
const gavl_time_t left_offset = _raw(window.get_time_offset());
const int64_t time_scale = window.get_time_scale();
@ -361,16 +375,15 @@ TimelineRuler::draw_selection(Cairo::RefPtr<Cairo::Context> cr,
REQUIRE(cr);
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
REQUIRE(timelineState);
shared_ptr<TimelineState> state = timelineWidget.get_state();
REQUIRE(state);
const TimelineViewWindow &window = state->get_view_window();
const TimelineViewWindow &window = timelineState->get_view_window();
Glib::RefPtr<Style> style = get_style();
Gdk::Cairo::set_source_color(cr, style->get_fg(STATE_NORMAL));
// Draw the selection start chevron
const int a = 1 + window.time_to_x(state->getSelectionStart());
const int a = 1 + window.time_to_x(timelineState->getSelectionStart());
if(a >= 0 && a < ruler_rect.get_width())
{
cr->move_to(a, ruler_rect.get_height());
@ -380,7 +393,7 @@ TimelineRuler::draw_selection(Cairo::RefPtr<Cairo::Context> cr,
}
// Draw the selection end chevron
const int b = window.time_to_x(state->getSelectionEnd());
const int b = window.time_to_x(timelineState->getSelectionEnd());
if(b >= 0 && b < ruler_rect.get_width())
{
cr->move_to(b, ruler_rect.get_height());
@ -397,18 +410,17 @@ TimelineRuler::draw_playback_period(Cairo::RefPtr<Cairo::Context> cr,
REQUIRE(cr);
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
REQUIRE(timelineState);
shared_ptr<TimelineState> state = timelineWidget.get_state();
REQUIRE(state);
const TimelineViewWindow &window = state->get_view_window();
const TimelineViewWindow &window = timelineState->get_view_window();
// Calculate coordinates
const float halfSize = playbackPeriodArrowSize / 2;
const float a = 1.5f + window.time_to_x(state->getPlaybackPeriodStart());
const float a = 1.5f + window.time_to_x(timelineState->getPlaybackPeriodStart());
const float b = a + halfSize;
const float d = 0.5f + window.time_to_x(state->getPlaybackPeriodEnd());
const float d = 0.5f + window.time_to_x(timelineState->getPlaybackPeriodEnd());
const float c = d - halfSize;
@ -465,14 +477,12 @@ TimelineRuler::draw_playback_point(Cairo::RefPtr<Cairo::Context> cr,
REQUIRE(cr);
REQUIRE(ruler_rect.get_width() > 0);
REQUIRE(ruler_rect.get_height() > 0);
REQUIRE(timelineState);
shared_ptr<TimelineState> state = timelineWidget.get_state();
REQUIRE(state);
if (!state->isPlaying()) return;
if (!timelineState->isPlaying()) return;
TimelineViewWindow const& window = state->get_view_window();
Time point = state->getPlaybackPoint();
const int x = window.time_to_x(point);
Time point = timelineState->getPlaybackPoint();
const int x = viewWindow().time_to_x(point);
cr->move_to(x + 0.5, ruler_rect.get_height());
cr->rel_line_to(0, -playbackPointSize);
@ -494,7 +504,6 @@ TimelineRuler::calculate_major_spacing() const
{
unsigned int i;
const int64_t time_scale = view_window().get_time_scale();
const gavl_time_t major_spacings[] = {
GAVL_TIME_SCALE / 1000,
GAVL_TIME_SCALE / 400,
@ -520,6 +529,8 @@ TimelineRuler::calculate_major_spacing() const
60ll * 60ll * GAVL_TIME_SCALE
};
const int64_t time_scale = viewWindow().get_time_scale();
for(i = 0; i < sizeof(major_spacings) / sizeof(gavl_time_t); i++)
{
const int64_t division_width = major_spacings[i] / time_scale;
@ -531,14 +542,6 @@ TimelineRuler::calculate_major_spacing() const
return major_spacings[i];
}
TimelineViewWindow&
TimelineRuler::view_window() const
{
shared_ptr<TimelineState> state = timelineWidget.get_state();
REQUIRE(state);
return state->get_view_window();
}
void
TimelineRuler::register_styles() const
{

View file

@ -29,6 +29,7 @@
#include "gui/gtk-lumiera.hpp"
#include "lib/time/timevalue.hpp"
#include "gui/widgets/timeline/timeline-state.hpp"
namespace gui {
namespace widgets {
@ -108,10 +109,9 @@ private:
void on_size_allocate(Gtk::Allocation& allocation);
/**
* The event handler for when the TimelineWidget's state object is
* replaced.
* The event handler for when the TimelineWidget's state is switched.
*/
void on_state_changed();
void on_state_changed (boost::shared_ptr<TimelineState> newState); ////////////////////TICKET #796 : should use std::tr1::shared_ptr
private:
/* ===== Internal Methods ===== */
@ -161,7 +161,13 @@ private:
*/
void draw_playback_point(Cairo::RefPtr<Cairo::Context> cr,
const Gdk::Rectangle ruler_rect);
/**
* After notification of a timeline state switch
* do any local adjustments to adapt to the new state
*/
void propagateStateChange();
/**
* Given the current zoom, this function calculates the preiod
* between major graduations on the ruler scale.
@ -170,9 +176,9 @@ private:
gavl_time_t calculate_major_spacing() const;
/**
* A helper function to get the view window
* Access current timeline view window
*/
TimelineViewWindow& view_window() const;
TimelineViewWindow& viewWindow() const;
/**
* Registers all the styles that this class will respond to.
@ -233,6 +239,11 @@ private:
*/
gui::widgets::TimelineWidget &timelineWidget;
/**
* the currently active timeline state object
*/
boost::shared_ptr<TimelineState> timelineState; ////////////////////TICKET #796 : should use std::tr1::shared_ptr
/**
* The caches image of the ruler, over which the chevrons etc. will
* be drawn.

View file

@ -51,12 +51,11 @@ TimelineState::TimelineState (boost::shared_ptr<model::Sequence> source_sequence
REQUIRE(sequence);
////////////////////////////////////////////////////////////TICKET #798: how to handle GUI default state
viewWindow.set_time_scale(GAVL_TIME_SCALE / 200);
viewWindow.set_time_scale(21000000);
setSelection (Mutation::changeTime (Time(FSecs(2))));
setSelection (Mutation::changeDuration(Duration(FSecs(2))));
//////////////////////////////////////////////////////TICKET #797 : this is cheesy. Should provide a single Mutation to change all
//////////////////////////////////////////////////////TICKET #797 : this is cheesy. Should provide a single Mutation to change all
}
boost::shared_ptr<model::Sequence>

View file

@ -103,7 +103,7 @@ public:
* the GUI is really connected to the Player
*/
void setPlaybackPoint(Time newPos);
/**
* A signal to notify when the selected period has changed.
*/
@ -143,10 +143,9 @@ private:
* when actually integrated with the Player
*/
TimeVar playbackPoint_;
bool isPlayback_;
// Signals
/**

View file

@ -31,29 +31,29 @@ namespace gui {
namespace widgets {
namespace timeline {
TimelineViewWindow::TimelineViewWindow (Offset offset, int64_t scale)
: timeOffset(offset)
, timeScale(scale)
{
TODO("Create a function to limit timescale between 1 and MaxScale");
TODO("TICKET #795 Some functions need to be private");
}
Offset
TimelineViewWindow::get_time_offset() const /////////////////////TODO: this function shouldn't be accessible from outside
TimelineViewWindow::get_time_offset() const /////////////////////TICKET #795: this function shouldn't be accessible from outside
{
return Offset (timeOffset);
}
void
TimelineViewWindow::set_time_offset(TimeValue const& offset) /////////TODO: this function shouldn't be accessible from outside
TimelineViewWindow::set_time_offset(TimeValue const& offset) /////////TICKET #795: this function shouldn't be accessible from outside
{
timeOffset = offset;
changedSignal.emit();
}
int64_t
TimelineViewWindow::get_time_scale() const /////////////////////TODO: this function shouldn't be accessible from outside
TimelineViewWindow::get_time_scale() const /////////////////////TICKET #795: this function shouldn't be accessible from outside
{
return timeScale;
}
@ -66,21 +66,39 @@ TimelineViewWindow::set_time_scale(int64_t scale)
}
void
TimelineViewWindow::zoom_view(int point, int zoom_size)
{
int64_t new_time_scale = (double)timeScale * pow(1.25, -zoom_size);
// Limit zooming in too close
if(new_time_scale < 1) new_time_scale = 1;
// Nudge zoom problems caused by integer rounding
if(new_time_scale == timeScale && zoom_size < 0)
new_time_scale++;
// Limit zooming out too far
TimelineViewWindow::set_time_scale(double ratio)
{
int64_t max = TimelineWidget::MaxScale;
int64_t min = 1;
if(ratio <= 0.0)
{
set_time_scale((int64_t)min);
return;
}
if(ratio > 1.0)
{
ratio = 1.0;
}
set_time_scale((int64_t)(ratio * max));
}
void
TimelineViewWindow::zoom_view(int point, double time_scale_ratio)
{
TODO("Find a Central place for a Zoom Smoothing Factor Variable. Right now it is hard coded at 9.0");
int64_t new_time_scale =
(int64_t)( pow(time_scale_ratio, 9.0) * (double)TimelineWidget::MaxScale);
/* Prevent Zooming in To Close and Far */
if(new_time_scale < 1)
new_time_scale = 1;
if(new_time_scale > TimelineWidget::MaxScale)
new_time_scale = TimelineWidget::MaxScale;
// The view must be shifted so that the zoom is centred on the cursor
TimeVar newStartPoint = get_time_offset();
newStartPoint += TimeValue(point * (timeScale - new_time_scale));

View file

@ -94,14 +94,14 @@ public:
* zero
*/
void set_time_scale(int64_t time_scale);
void set_time_scale(double ratio);
/**
* Zooms the view in or out as by a number of steps while keeping a
* given point on the timeline still.
* @param zoom_size The number of steps to zoom by. The scale factor
* is 1.25^(-zoom_size).
* @param new_time_scale The number of steps to zoom by. The scale factor
* is 1.25^(-new_time_scale).
*/
void zoom_view(int point, int zoom_size);
void zoom_view(int point, double timescale_ratio);
/**
* Scrolls the view horizontally as a proportion of the view area.

View file

@ -0,0 +1,155 @@
/*
timeline-zoom-scale.cpp - Implementation of the zoom scale widget
Copyright (C) Lumiera.org
2011, Michael R. Fisher <mfisher31@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "gui/widgets/timeline/timeline-zoom-scale.hpp"
#include "gui/widgets/timeline-widget.hpp"
using namespace Gtk;
namespace gui {
namespace widgets {
class TimelineWidget;
namespace timeline {
/**
* @todo The initial adjustment value needs to
* match what the TimelineViewWindow's actual timeScale
* Value is. TimelineViewWindow::get_time_scale() is
* currently a public method, but will soon be private.
* Maybe TimelineViewWindow can have a zoom_adjustment
* that gets passed to this widget's Constructor?
*
* @todo actually there is a more involved problem.
* The TimelineWidget maintains a TimelineState, which in turn
* owns the TimelineViewWindow. Now, the problem is: when we
* switch to another Sequence (View), then this TimelineState
* gets switched too, causing also a entirely different TimelineViewWindow
* to become effective. Thus
* - how can we managed to be notified from that switch?
* - problem is: TimelineZoomScale widget is owned by the TimelinePannel.
* Likewise, TimelineWidget is owned by the TimelinePannel. But the
* state handling/switching logic is embedded within TimelineWidget
* - and finally: how can we translate the actual scale (in time units),
* as maintained within TimelineViewWindow, back into the adjustment
* used here (which uses a relative scale 0...1.0 )
*
*/
TimelineZoomScale::TimelineZoomScale()
: HBox()
, adjustment(0.5, 0.0, 1.0, 0.000001)
, slider()
, zoomIn(Stock::ZOOM_IN)
, zoomOut(Stock::ZOOM_OUT)
, button_step_size(0.03)
{
/* Setup the Slider Control */
slider.set_adjustment(adjustment);
slider.set_size_request(123,10);
slider.set_digits(6);
slider.set_inverted(true);
slider.set_draw_value(false);
/* Make our connections */
zoomIn.signal_clicked().
connect(sigc::mem_fun(this, &TimelineZoomScale::on_zoom_in_clicked));
zoomOut.signal_clicked().
connect(sigc::mem_fun(this, &TimelineZoomScale::on_zoom_out_clicked));
adjustment.signal_value_changed().
connect(sigc::mem_fun(this, &TimelineZoomScale::on_zoom));
/* Add Our Widgets and show them */
pack_start(zoomOut,PACK_SHRINK);
pack_start(slider,PACK_SHRINK);
pack_start(zoomIn,PACK_SHRINK);
show_all();
}
void
TimelineZoomScale::wireTimelineState (boost::shared_ptr<TimelineState> currentState,
TimelineWidget::TimelineStateChangeSignal stateChangeSignal)
{
on_timeline_state_changed (currentState);
stateChangeSignal.connect (sigc::mem_fun(this, &TimelineZoomScale::on_timeline_state_changed));
}
void
TimelineZoomScale::on_timeline_state_changed (boost::shared_ptr<TimelineState> newState)
{
REQUIRE (newState);
timelineState = newState;
int64_t current_scale =
getViewWindow().get_time_scale();
double linear_scale =
(double) current_scale / (double) TimelineWidget::MaxScale;
/* We have to Revese the Smoothing */
TODO("Find a central place for ZoomSmoothingFactor Variable. right now it is 9.0");
double new_relative_scale =
pow(linear_scale,(1.0/9.0));
adjustment.set_value(new_relative_scale);
}
void
TimelineZoomScale::on_zoom_in_clicked()
{
double newValue = adjustment.get_value() - button_step_size;
adjustment.set_value(newValue);
}
void
TimelineZoomScale::on_zoom_out_clicked()
{
double newValue = adjustment.get_value() + button_step_size;
adjustment.set_value(newValue);
}
void
TimelineZoomScale::on_zoom()
{
zoomSignal.emit(adjustment.get_value()) ;
}
sigc::signal<void, double>
TimelineZoomScale::signal_zoom()
{
return zoomSignal;
}
TimelineViewWindow&
TimelineZoomScale::getViewWindow()
{
REQUIRE (timelineState, "lifecycle error");
return timelineState->get_view_window();
}
} // namespace gui
} // namespace widgets
} // namespace timeline

View file

@ -0,0 +1,110 @@
/*
timeline-zoom-scale.hpp - Declaration of the zoom scale widget
Copyright (C) Lumiera.org
2011, Michael R. Fisher <mfisher31@gmail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/** @file timeline-zoom-scale.hpp
** This file contains the definition of the zoom scale widget
*/
#ifndef TIMELINE_ZOOM_SCALE_HPP
#define TIMELINE_ZOOM_SCALE_HPP
#include "gui/gtk-lumiera.hpp"
#include "gui/widgets/mini-button.hpp"
#include "gui/widgets/timeline-widget.hpp"
#include "gui/widgets/timeline/timeline-state.hpp"
#include "gui/widgets/timeline/timeline-view-window.hpp"
#include <boost/shared_ptr.hpp>
using namespace Gtk;
using namespace gui::widgets;
namespace gui {
namespace widgets {
namespace timeline {
class TimelineZoomScale : public Gtk::HBox
{
public:
/**
* Constructor
*/
TimelineZoomScale();
/**
* Accessor method to the zoomSignal
* @return the zoomSignal
*/
sigc::signal<void, double> signal_zoom();
void wireTimelineState (boost::shared_ptr<TimelineState> currentState,
TimelineWidget::TimelineStateChangeSignal);
private:
/* Event Handlers */
/**
* Update the slider position when the timeline state
* is changed.
*/
void on_timeline_state_changed (boost::shared_ptr<TimelineState> newState); ////////////////////TICKET #796 : should use std::tr1::shared_ptr
/**
* Event handler for when the zoomIn Button
* is clicked
*/
void on_zoom_in_clicked();
/**
* Event handler for when the zoomIn Button
* is clicked
*/
void on_zoom_out_clicked();
/**
* Event handler for when the adjustment
* value is changed
*/
void on_zoom();
/** access current timeline state */
TimelineViewWindow& getViewWindow();
/* Widgets */
Gtk::Adjustment adjustment;
Gtk::HScale slider;
MiniButton zoomIn;
MiniButton zoomOut;
private:
/* Signals */
sigc::signal<void, double> zoomSignal;
const double button_step_size;
boost::shared_ptr<TimelineState> timelineState;
};
} // namespace gui
} // namespace widgets
} // namespace timeline
#endif /* TIMELINE_ZOOM_SCALE_HPP */

View file

@ -19,52 +19,55 @@
// 1/11 - exploring numeric limits
// 1/11 - integer floor and wrap operation(s)
// 1/11 - how to fetch the path of the own executable -- at least under Linux?
#include <nobug.h>
// 10/11 - simple demo using a pointer and a struct
#include <iostream>
#include <string>
extern "C" {
#include <unistd.h>
}
#include "lib/error.hpp"
#include "lib/symbol.hpp"
using std::string;
using std::cout;
using std::endl;
using lib::Literal;
using lib::STRING_MAX_RELEVANT;
namespace error = lumiera::error;
Literal GET_PATH_TO_EXECUTABLE ("/proc/self/exe");
string
catchMyself ()
{
string buff(STRING_MAX_RELEVANT+1, '\0' );
ssize_t chars_read = readlink (GET_PATH_TO_EXECUTABLE, &buff[0], STRING_MAX_RELEVANT);
if (0 > chars_read || chars_read == ssize_t(STRING_MAX_RELEVANT))
throw error::Fatal ("unable to discover path of running executable");
buff.resize(chars_read);
return buff;
}
/**
* custom datastructure
* holding a constant char array with "hey"
*/
struct MyStruct
{
char data_[3];
const int length_;
MyStruct()
: length_(3)
{
const char *tmp = "hey";
for (int i=0; i<length_; ++i)
data_[i] = *(tmp+i);
}
};
// define a global variable holding a MyStruct
MyStruct theStruct;
void
printMyStruct(MyStruct* myPointer)
{
for (int i=0; i < myPointer->length_; ++i)
cout << myPointer->data_[i];
cout << "\n";
}
int
main (int, char**) //(int argc, char* argv[])
{
printMyStruct (&theStruct);
NOBUG_INIT;
cout << "\n\nwho am I? :" << catchMyself();
cout << "\n.gulp.\n";
return 0;