Finished TimelineState work
This commit is contained in:
parent
2933deaa20
commit
7766a223eb
7 changed files with 254 additions and 120 deletions
|
|
@ -37,6 +37,7 @@ using namespace Gtk;
|
|||
using namespace sigc;
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
using namespace util;
|
||||
using namespace gui::widgets;
|
||||
using namespace gui::model;
|
||||
|
||||
|
|
@ -62,24 +63,23 @@ TimelinePanel::TimelinePanel(workspace::WorkspaceWindow
|
|||
zoomOut(Stock::ZOOM_OUT),
|
||||
updatingToolbar(false),
|
||||
currentTool(timeline::IBeam)
|
||||
{
|
||||
//timelineWidget.mouse_hover_signal().connect(
|
||||
// mem_fun(this, &TimelinePanel::on_mouse_hover));
|
||||
//timelineWidget.playback_period_drag_released_signal().connect(
|
||||
// mem_fun(this, &TimelinePanel::on_playback_period_drag_released));
|
||||
|
||||
{
|
||||
// Hook up notifications
|
||||
workspace.get_project().get_sequences().signal_changed().connect(
|
||||
mem_fun(this, &TimelinePanel::on_sequence_list_changed));
|
||||
|
||||
// Setup the notebook
|
||||
notebook.signal_switch_page().connect(
|
||||
mem_fun(this, &TimelinePanel::on_page_switched));
|
||||
notebook.popup_enable();
|
||||
// Setup the sequence chooser
|
||||
sequenceChooserModel = Gtk::ListStore::create(sequenceChooserColumns);
|
||||
ENSURE(sequenceChooserModel);
|
||||
|
||||
// Setup the sequence chooser;
|
||||
sequenceChooser.set_model(sequenceChooserModel);
|
||||
sequenceChooser.pack_start(sequenceChooserColumns.nameColumn);
|
||||
sequenceChooser.show_all();
|
||||
panelBar.pack_start(sequenceChooser, PACK_EXPAND_WIDGET);
|
||||
|
||||
sequenceChooserChangedConnection = sequenceChooser.signal_changed().
|
||||
connect( sigc::mem_fun(*this, &TimelinePanel::on_sequence_chosen) );
|
||||
|
||||
panelBar.pack_start(sequenceChooser, PACK_SHRINK);
|
||||
|
||||
// Setup the toolbar
|
||||
timeIndicatorButton.add(timeIndicator);
|
||||
|
|
@ -112,11 +112,13 @@ TimelinePanel::TimelinePanel(workspace::WorkspaceWindow
|
|||
toolbar.show_all();
|
||||
panelBar.pack_start(toolbar, PACK_SHRINK);
|
||||
|
||||
// Add the notebook
|
||||
pack_start(notebook, PACK_EXPAND_WIDGET);
|
||||
// Setup the timeline widget
|
||||
shared_ptr<Sequence> sequence
|
||||
= *workspace.get_project().get_sequences().begin();
|
||||
timelineWidget.reset(new TimelineWidget(load_state(sequence)));
|
||||
pack_start(*timelineWidget, PACK_EXPAND_WIDGET);
|
||||
|
||||
// Set the initial UI state
|
||||
update_notebook();
|
||||
update_sequence_chooser();
|
||||
update_tool_buttons();
|
||||
update_zoom_buttons();
|
||||
|
|
@ -165,32 +167,16 @@ TimelinePanel::on_ibeam_tool()
|
|||
void
|
||||
TimelinePanel::on_zoom_in()
|
||||
{
|
||||
TimelineWidget *const widget = get_current_page();
|
||||
REQUIRE(widget != NULL);
|
||||
|
||||
widget->zoom_view(ZoomToolSteps);
|
||||
REQUIRE(timelineWidget);
|
||||
timelineWidget->zoom_view(ZoomToolSteps);
|
||||
update_zoom_buttons();
|
||||
}
|
||||
|
||||
void
|
||||
TimelinePanel::on_zoom_out()
|
||||
{
|
||||
TimelineWidget *const widget = get_current_page();
|
||||
REQUIRE(widget != NULL);
|
||||
|
||||
widget->zoom_view(-ZoomToolSteps);
|
||||
update_zoom_buttons();
|
||||
}
|
||||
|
||||
void
|
||||
TimelinePanel::on_page_switched(GtkNotebookPage*, guint)
|
||||
{
|
||||
// The page has changed. Update the UI for this new page
|
||||
|
||||
// Set the tool in the new page to be the same as the tool in the last
|
||||
// page
|
||||
set_tool(currentTool);
|
||||
|
||||
REQUIRE(timelineWidget);
|
||||
timelineWidget->zoom_view(-ZoomToolSteps);
|
||||
update_zoom_buttons();
|
||||
}
|
||||
|
||||
|
|
@ -206,11 +192,10 @@ TimelinePanel::on_playback_period_drag_released()
|
|||
//----- TEST CODE - this needs to set the playback point via the
|
||||
// real backend
|
||||
|
||||
TimelineWidget *const widget = get_current_page();
|
||||
REQUIRE(widget != NULL);
|
||||
REQUIRE(timelineWidget);
|
||||
|
||||
widget->get_state()->set_playback_point(
|
||||
widget->get_state()->get_playback_period_start());
|
||||
timelineWidget->get_state()->set_playback_point(
|
||||
timelineWidget->get_state()->get_playback_period_start());
|
||||
//----- END TEST CODE
|
||||
|
||||
play();
|
||||
|
|
@ -219,55 +204,63 @@ TimelinePanel::on_playback_period_drag_released()
|
|||
void
|
||||
TimelinePanel::on_sequence_list_changed()
|
||||
{
|
||||
update_notebook();
|
||||
update_sequence_chooser();
|
||||
}
|
||||
|
||||
void
|
||||
TimelinePanel::on_sequence_chosen()
|
||||
{
|
||||
REQUIRE(timelineWidget);
|
||||
|
||||
Gtk::TreeIter iter = sequenceChooser.get_active();
|
||||
if(iter)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
void
|
||||
TimelinePanel::update_sequence_chooser()
|
||||
{
|
||||
sequenceChooser.clear_items();
|
||||
REQUIRE(sequenceChooserModel);
|
||||
|
||||
// Block the event handler
|
||||
sequenceChooserChangedConnection.block();
|
||||
|
||||
// Repopulate the sequence chooser
|
||||
sequenceChooserModel->clear();
|
||||
|
||||
shared_ptr<timeline::TimelineState> state =
|
||||
timelineWidget->get_state();
|
||||
REQUIRE(state);
|
||||
|
||||
BOOST_FOREACH( shared_ptr< model::Sequence > sequence,
|
||||
workspace.get_project().get_sequences() )
|
||||
{
|
||||
sequenceChooser.append_text(sequence->get_name());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimelinePanel::update_notebook()
|
||||
{
|
||||
std::map<const model::Sequence*, shared_ptr<TimelineWidget> >
|
||||
old_pages;
|
||||
old_pages.swap(notebook_pages);
|
||||
|
||||
BOOST_FOREACH( shared_ptr< model::Sequence > sequence,
|
||||
workspace.get_project().get_sequences() )
|
||||
{
|
||||
std::map<const model::Sequence*, shared_ptr<TimelineWidget> >::
|
||||
iterator iterator = old_pages.find(sequence.get());
|
||||
if(iterator != old_pages.end())
|
||||
{
|
||||
// This sequence has not been changed
|
||||
// leave it in the new list
|
||||
notebook_pages[iterator->first] = iterator->second;
|
||||
old_pages.erase(iterator->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a new sequence, add it in
|
||||
shared_ptr< timeline::TimelineState > state(
|
||||
new timeline::TimelineState(sequence));
|
||||
shared_ptr< TimelineWidget > widget(
|
||||
new TimelineWidget(state));
|
||||
notebook_pages[sequence.get()] = widget;
|
||||
notebook.append_page(*widget.get(), sequence->get_name());
|
||||
notebook.set_tab_reorderable(*widget.get());
|
||||
}
|
||||
Gtk::TreeIter iter = sequenceChooserModel->append();
|
||||
Gtk::TreeModel::Row row = *iter;
|
||||
row[sequenceChooserColumns.sequenceColumn] = sequence;
|
||||
row[sequenceChooserColumns.nameColumn] = sequence->get_name();
|
||||
|
||||
if(state->get_sequence() == sequence)
|
||||
sequenceChooser.set_active(iter);
|
||||
}
|
||||
|
||||
notebook.show_all_children();
|
||||
// Unblock the event handler
|
||||
sequenceChooserChangedConnection.unblock();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -292,17 +285,14 @@ TimelinePanel::update_tool_buttons()
|
|||
void
|
||||
TimelinePanel::update_zoom_buttons()
|
||||
{
|
||||
TimelineWidget *const widget = get_current_page();
|
||||
REQUIRE(timelineWidget);
|
||||
|
||||
timeline::TimelineViewWindow &viewWindow =
|
||||
timelineWidget->get_state()->get_view_window();
|
||||
|
||||
if(widget != NULL)
|
||||
{
|
||||
timeline::TimelineViewWindow &viewWindow =
|
||||
widget->get_state()->get_view_window();
|
||||
|
||||
zoomIn.set_sensitive(viewWindow.get_time_scale() != 1);
|
||||
zoomOut.set_sensitive(viewWindow.get_time_scale()
|
||||
!= TimelineWidget::MaxScale);
|
||||
}
|
||||
zoomIn.set_sensitive(viewWindow.get_time_scale() != 1);
|
||||
zoomOut.set_sensitive(viewWindow.get_time_scale()
|
||||
!= TimelineWidget::MaxScale);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -327,15 +317,13 @@ TimelinePanel::is_playing() const
|
|||
void
|
||||
TimelinePanel::set_tool(timeline::ToolType tool)
|
||||
{
|
||||
REQUIRE(timelineWidget);
|
||||
|
||||
if(updatingToolbar) return;
|
||||
|
||||
TimelineWidget *const widget = get_current_page();
|
||||
if(widget != NULL)
|
||||
{
|
||||
currentTool = tool;
|
||||
widget->set_tool(tool);
|
||||
update_tool_buttons();
|
||||
}
|
||||
currentTool = tool;
|
||||
timelineWidget->set_tool(tool);
|
||||
update_tool_buttons();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -344,17 +332,6 @@ TimelinePanel::show_time(gavl_time_t time)
|
|||
timeIndicator.set_text(lumiera_tmpbuf_print_time(time));
|
||||
}
|
||||
|
||||
TimelineWidget*
|
||||
TimelinePanel::get_current_page()
|
||||
{
|
||||
Notebook::PageList::iterator page_iterator = notebook.get_current();
|
||||
if(!page_iterator) return NULL;
|
||||
|
||||
Widget* const widget = (*page_iterator).get_child();
|
||||
REQUIRE(widget != NULL);
|
||||
return (TimelineWidget*)widget;
|
||||
}
|
||||
|
||||
bool
|
||||
TimelinePanel::on_frame()
|
||||
{
|
||||
|
|
@ -374,5 +351,18 @@ TimelinePanel::on_frame()
|
|||
return true;
|
||||
}
|
||||
|
||||
shared_ptr<timeline::TimelineState>
|
||||
TimelinePanel::load_state(weak_ptr<Sequence> sequence)
|
||||
{
|
||||
if(contains(timelineStates, sequence))
|
||||
return timelineStates[sequence];
|
||||
|
||||
shared_ptr<Sequence> shared_sequence = sequence.lock();
|
||||
if(shared_sequence)
|
||||
return shared_ptr< timeline::TimelineState >(
|
||||
new timeline::TimelineState(shared_sequence));
|
||||
return shared_ptr< timeline::TimelineState >();
|
||||
}
|
||||
|
||||
} // namespace panels
|
||||
} // namespace gui
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
using namespace gui::widgets;
|
||||
|
||||
namespace gui {
|
||||
|
||||
|
||||
namespace model {
|
||||
class Sequence;
|
||||
}
|
||||
|
|
@ -70,20 +70,25 @@ private:
|
|||
void on_zoom_out();
|
||||
|
||||
void on_time_pressed();
|
||||
|
||||
void on_page_switched(GtkNotebookPage*, guint);
|
||||
|
||||
|
||||
void on_mouse_hover(gavl_time_t time);
|
||||
void on_playback_period_drag_released();
|
||||
|
||||
/**
|
||||
* An event handler for when the list of sequences changes.
|
||||
**/
|
||||
void on_sequence_list_changed();
|
||||
|
||||
/**
|
||||
* An event handler for when a new sequence is chosen in the
|
||||
* sequenceChooser.
|
||||
**/
|
||||
void on_sequence_chosen();
|
||||
|
||||
private:
|
||||
|
||||
void update_sequence_chooser();
|
||||
|
||||
void update_notebook();
|
||||
|
||||
|
||||
void update_playback_buttons();
|
||||
void update_tool_buttons();
|
||||
void update_zoom_buttons();
|
||||
|
|
@ -97,8 +102,36 @@ private:
|
|||
void set_tool(gui::widgets::timeline::ToolType tool);
|
||||
|
||||
void show_time(gavl_time_t time);
|
||||
|
||||
boost::shared_ptr<widgets::timeline::TimelineState> load_state(
|
||||
boost::weak_ptr<model::Sequence> sequence);
|
||||
|
||||
TimelineWidget* get_current_page();
|
||||
private:
|
||||
|
||||
/**
|
||||
* The definition of the sequence chooser combo box columns
|
||||
**/
|
||||
class SequenceChooserColumns : public Gtk::TreeModel::ColumnRecord
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
**/
|
||||
SequenceChooserColumns()
|
||||
{ add(nameColumn); add(sequenceColumn); }
|
||||
|
||||
/**
|
||||
* An invisible column which will be used to identify the sequence
|
||||
* of a row.
|
||||
**/
|
||||
Gtk::TreeModelColumn< boost::weak_ptr<model::Sequence> >
|
||||
sequenceColumn;
|
||||
|
||||
/**
|
||||
* The column to use as the label for the combo box widget items.
|
||||
**/
|
||||
Gtk::TreeModelColumn< Glib::ustring > nameColumn;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -106,12 +139,19 @@ private:
|
|||
|
||||
// Grip Widgets
|
||||
ButtonBar toolbar;
|
||||
Gtk::ComboBoxText sequenceChooser;
|
||||
|
||||
// Sequence Chooser
|
||||
SequenceChooserColumns sequenceChooserColumns;
|
||||
Glib::RefPtr<Gtk::ListStore> sequenceChooserModel;
|
||||
Gtk::ComboBox sequenceChooser;
|
||||
sigc::connection sequenceChooserChangedConnection;
|
||||
|
||||
// Body Widgets
|
||||
Gtk::Notebook notebook;
|
||||
std::map< const model::Sequence*, boost::shared_ptr<TimelineWidget> >
|
||||
notebook_pages;
|
||||
boost::scoped_ptr<TimelineWidget> timelineWidget;
|
||||
|
||||
std::map< boost::weak_ptr<model::Sequence>,
|
||||
boost::shared_ptr<widgets::timeline::TimelineState> >
|
||||
timelineStates;
|
||||
|
||||
// Toolbar Widgets
|
||||
Gtk::Label timeIndicator;
|
||||
|
|
|
|||
|
|
@ -109,8 +109,14 @@ TimelineWidget::get_state()
|
|||
void
|
||||
TimelineWidget::set_state(shared_ptr<timeline::TimelineState> new_state)
|
||||
{
|
||||
if(!new_state)
|
||||
return;
|
||||
|
||||
state = new_state;
|
||||
REQUIRE(state);
|
||||
|
||||
// Clear the track tree
|
||||
trackMap.clear();
|
||||
|
||||
// Hook up event handlers
|
||||
state->get_view_window().changed_signal().connect( sigc::mem_fun(
|
||||
|
|
@ -125,6 +131,9 @@ TimelineWidget::set_state(shared_ptr<timeline::TimelineState> new_state)
|
|||
&TimelineWidget::on_body_changed));
|
||||
|
||||
update_tracks();
|
||||
|
||||
// Send the state changed signal
|
||||
stateChangedSignal.emit();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -175,6 +184,11 @@ TimelineWidget::hovering_track_changed_signal() const
|
|||
{
|
||||
return hoveringTrackChangedSignal;
|
||||
}
|
||||
sigc::signal<void>
|
||||
TimelineWidget::state_changed_signal() const
|
||||
{
|
||||
return stateChangedSignal;
|
||||
}
|
||||
|
||||
/* ===== Events ===== */
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ class TimelineWidget : public Gtk::Table
|
|||
public:
|
||||
/**
|
||||
* Constructor
|
||||
* @param source_state The state that will be used as the data source
|
||||
* for this timeline widget.
|
||||
*/
|
||||
TimelineWidget(
|
||||
boost::shared_ptr<timeline::TimelineState> source_state);
|
||||
|
|
@ -69,8 +71,17 @@ public:
|
|||
/* ===== Data Access ===== */
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets a pointer to the current state object.
|
||||
* @return The state object that the timeline widget is currently
|
||||
* working with.
|
||||
**/
|
||||
boost::shared_ptr<timeline::TimelineState> get_state();
|
||||
|
||||
/**
|
||||
* Replaces the current TimelineState object with another.
|
||||
* @param new_state The new state to swap in.
|
||||
**/
|
||||
void set_state(boost::shared_ptr<timeline::TimelineState> new_state);
|
||||
|
||||
/**
|
||||
|
|
@ -101,6 +112,8 @@ public:
|
|||
|
||||
sigc::signal<void, boost::shared_ptr<timeline::Track> >
|
||||
hovering_track_changed_signal() const;
|
||||
|
||||
sigc::signal<void> state_changed_signal() const;
|
||||
|
||||
/* ===== Events ===== */
|
||||
protected:
|
||||
|
|
@ -217,6 +230,10 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The state that will be used as the data source for this timeline
|
||||
* widget.
|
||||
**/
|
||||
boost::shared_ptr<timeline::TimelineState> state;
|
||||
|
||||
// Model Data
|
||||
|
|
@ -251,6 +268,7 @@ protected:
|
|||
sigc::signal<void> playbackPeriodDragReleasedSignal;
|
||||
sigc::signal<void, boost::shared_ptr<timeline::Track> >
|
||||
hoveringTrackChangedSignal;
|
||||
sigc::signal<void> stateChangedSignal;
|
||||
|
||||
bool update_tracks_frozen;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,11 +50,14 @@ TimelineBody::TimelineBody(TimelineWidget &timeline_widget) :
|
|||
timelineWidget(timeline_widget)
|
||||
{
|
||||
// Connect up some events
|
||||
view_window().changed_signal().connect(
|
||||
sigc::mem_fun(this, &TimelineBody::on_update_view) );
|
||||
timeline_widget.state_changed_signal().connect(
|
||||
sigc::mem_fun(this, &TimelineBody::on_state_changed) );
|
||||
|
||||
// Install style properties
|
||||
register_styles();
|
||||
|
||||
// Reset the state
|
||||
on_state_changed();
|
||||
}
|
||||
|
||||
TimelineBody::~TimelineBody()
|
||||
|
|
@ -270,6 +273,17 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event)
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TimelineBody::on_state_changed()
|
||||
{
|
||||
// Connect up some events
|
||||
view_window().changed_signal().connect(
|
||||
sigc::mem_fun(this, &TimelineBody::on_update_view) );
|
||||
|
||||
// Redraw
|
||||
queue_draw();
|
||||
}
|
||||
|
||||
void
|
||||
TimelineBody::draw_tracks(Cairo::RefPtr<Cairo::Context> cr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public:
|
|||
* @param tool_type The type of tool to set.
|
||||
*/
|
||||
void set_tool(ToolType tool_type);
|
||||
|
||||
|
||||
/* ===== Events ===== */
|
||||
protected:
|
||||
|
||||
|
|
@ -111,6 +111,12 @@ protected:
|
|||
*/
|
||||
bool on_motion_notify_event(GdkEventMotion *event);
|
||||
|
||||
/**
|
||||
* The event handler for when the TimelineWidget's state object is
|
||||
* replaced.
|
||||
**/
|
||||
void on_state_changed();
|
||||
|
||||
/* ===== Internals ===== */
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -37,14 +37,28 @@ class Sequence;
|
|||
namespace widgets {
|
||||
namespace timeline {
|
||||
|
||||
/**
|
||||
* TimelineState is a container for the state data for TimelineWidget.
|
||||
* @remarks TimelineState s can be swapped out so that TimelineWidget
|
||||
* can flip between different views.
|
||||
**/
|
||||
class TimelineState
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param source_sequence The sequence on which the TimelineWidget
|
||||
* will operate when this TimelineState is attached.
|
||||
**/
|
||||
TimelineState(boost::shared_ptr<model::Sequence> source_sequence);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Gets the sequence that is attached to this timeline state object.
|
||||
* @return Returns a shared_ptr to the sequence object.
|
||||
**/
|
||||
boost::shared_ptr<model::Sequence> get_sequence() const;
|
||||
|
||||
/**
|
||||
|
|
@ -104,9 +118,15 @@ public:
|
|||
*/
|
||||
gavl_time_t get_playback_point() const;
|
||||
|
||||
|
||||
/**
|
||||
* A signal to notify when the selected period has changed.
|
||||
**/
|
||||
sigc::signal<void> selection_changed_signal() const;
|
||||
|
||||
/**
|
||||
* A signal to notify when the playback point or playback periods have
|
||||
* changed.
|
||||
**/
|
||||
sigc::signal<void> playback_changed_signal() const;
|
||||
|
||||
private:
|
||||
|
|
@ -120,17 +140,49 @@ private:
|
|||
boost::shared_ptr<model::Sequence> sequence;
|
||||
|
||||
// View State
|
||||
/**
|
||||
* The ViewWindow for the TimelineWidget display with.
|
||||
**/
|
||||
timeline::TimelineViewWindow viewWindow;
|
||||
|
||||
// Selection State
|
||||
|
||||
/**
|
||||
* The start time of the selection period.
|
||||
**/
|
||||
gavl_time_t selectionStart;
|
||||
|
||||
/**
|
||||
* The end time of the selection period.
|
||||
**/
|
||||
gavl_time_t selectionEnd;
|
||||
|
||||
/**
|
||||
* The start time of the playback period.
|
||||
**/
|
||||
gavl_time_t playbackPeriodStart;
|
||||
|
||||
/**
|
||||
* The end time of the playback period.
|
||||
**/
|
||||
gavl_time_t playbackPeriodEnd;
|
||||
|
||||
/**
|
||||
* The time of the playback point.
|
||||
**/
|
||||
gavl_time_t playbackPoint;
|
||||
|
||||
// Signals
|
||||
|
||||
/**
|
||||
* A signal to notify when the selected period has changed.
|
||||
**/
|
||||
sigc::signal<void> selectionChangedSignal;
|
||||
|
||||
/**
|
||||
* A signal to notify when the playback point or playback periods have
|
||||
* changed.
|
||||
**/
|
||||
sigc::signal<void> playbackChangedSignal;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue