From 9d11081ff77c637698dc53bfe5ed002b832873fb Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 22 Nov 2008 16:34:49 +0000 Subject: [PATCH] Added sequences, and tabs in the timeline view to display them --- src/gui/Makefile.am | 2 + src/gui/model/project.cpp | 12 +++ src/gui/model/project.hpp | 14 ++- src/gui/panels/assets-panel.cpp | 6 +- src/gui/panels/assets-panel.hpp | 18 ++-- src/gui/panels/panel.cpp | 21 +++- src/gui/panels/panel.hpp | 19 +++- src/gui/panels/timeline-panel.cpp | 132 ++++++++++++++++++------- src/gui/panels/timeline-panel.hpp | 24 ++++- src/gui/panels/viewer-panel.cpp | 4 +- src/gui/panels/viewer-panel.hpp | 3 +- src/gui/workspace/workspace-window.cpp | 6 +- 12 files changed, 203 insertions(+), 58 deletions(-) diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 9d3248f11..6830f69fe 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -77,6 +77,8 @@ lumigui_SOURCES = \ $(lumigui_srcdir)/widgets/timeline/clip.hpp \ $(lumigui_srcdir)/model/project.cpp \ $(lumigui_srcdir)/model/project.hpp \ + $(lumigui_srcdir)/model/sequence.cpp \ + $(lumigui_srcdir)/model/sequence.hpp \ $(lumigui_srcdir)/output/displayer.cpp \ $(lumigui_srcdir)/output/displayer.hpp \ $(lumigui_srcdir)/output/gdkdisplayer.cpp \ diff --git a/src/gui/model/project.cpp b/src/gui/model/project.cpp index 71bfe02eb..eb967d319 100644 --- a/src/gui/model/project.cpp +++ b/src/gui/model/project.cpp @@ -21,13 +21,25 @@ * *****************************************************/ #include "project.hpp" +#include "sequence.hpp" namespace gui { namespace model { Project::Project() { + // TEST CODE + sequenceA.set_name("Sequence A"); + sequenceB.set_name("Sequence B"); + sequences.push_back(&sequenceA); + sequences.push_back(&sequenceB); +} + +std::list& +Project::get_sequences() +{ + return sequences; } } // namespace model diff --git a/src/gui/model/project.hpp b/src/gui/model/project.hpp index aa899bf56..7a1798ccb 100644 --- a/src/gui/model/project.hpp +++ b/src/gui/model/project.hpp @@ -27,13 +27,25 @@ #ifndef PROJECT_HPP #define PROJECT_HPP +#include "sequence.hpp" + namespace gui { namespace model { - + class Project { public: Project(); + + std::list& get_sequences(); + +private: + + std::list sequences; + + // TEST CODE + Sequence sequenceA; + Sequence sequenceB; }; } // namespace model diff --git a/src/gui/panels/assets-panel.cpp b/src/gui/panels/assets-panel.cpp index 15e079dcc..316ebf256 100644 --- a/src/gui/panels/assets-panel.cpp +++ b/src/gui/panels/assets-panel.cpp @@ -26,9 +26,9 @@ namespace gui { namespace panels { -AssetsPanel::AssetsPanel() : - Panel("assets", _("Assets"), "panel_assets"), - placeholder("Placeholder label. Is this supposed to be titled assets\nas in the proc layer? or resources\nas in cinelerra?") +AssetsPanel::AssetsPanel(model::Project *const owner_project) : + Panel(owner_project, "assets", _("Assets"), "panel_assets"), + placeholder("Assets/Media") { pack_start(placeholder); } diff --git a/src/gui/panels/assets-panel.hpp b/src/gui/panels/assets-panel.hpp index 6f9dc8ec2..05c473dca 100644 --- a/src/gui/panels/assets-panel.hpp +++ b/src/gui/panels/assets-panel.hpp @@ -31,14 +31,18 @@ namespace gui { namespace panels { - class AssetsPanel : public Panel - { - public: - AssetsPanel(); +class AssetsPanel : public Panel +{ +public: + /** + * Constructor + * @param owner_project The project associated with this panel. + **/ + AssetsPanel(model::Project *const owner_project); - protected: - Gtk::Label placeholder; - }; +protected: + Gtk::Label placeholder; +}; } // namespace panels } // namespace gui diff --git a/src/gui/panels/panel.cpp b/src/gui/panels/panel.cpp index e6101ae2a..05fb096b1 100644 --- a/src/gui/panels/panel.cpp +++ b/src/gui/panels/panel.cpp @@ -26,9 +26,15 @@ namespace gui { namespace panels { -Panel::Panel(const gchar *name, const gchar *long_name, - GdlDockItemBehavior behavior) +Panel::Panel(model::Project *const owner_project, + const gchar *name, const gchar *long_name, + GdlDockItemBehavior behavior) : + project(owner_project) { + REQUIRE(owner_project != NULL); + REQUIRE(name != NULL); + REQUIRE(long_name != NULL); + dock_item = (GdlDockItem*)gdl_dock_item_new ( name, long_name, behavior); internal_setup(); @@ -36,9 +42,16 @@ Panel::Panel(const gchar *name, const gchar *long_name, ENSURE(dock_item != NULL); } -Panel::Panel(const gchar *name, const gchar *long_name, const gchar *stock_id, - GdlDockItemBehavior behavior) +Panel::Panel(model::Project *const owner_project, + const gchar *name, const gchar *long_name, const gchar *stock_id, + GdlDockItemBehavior behavior) : + project(owner_project) { + REQUIRE(owner_project != NULL); + REQUIRE(name != NULL); + REQUIRE(long_name != NULL); + REQUIRE(stock_id != NULL); + dock_item = (GdlDockItem*)gdl_dock_item_new_with_stock ( name, long_name, stock_id, behavior); g_object_ref(dock_item); diff --git a/src/gui/panels/panel.hpp b/src/gui/panels/panel.hpp index 6054e9932..669a7a4f1 100644 --- a/src/gui/panels/panel.hpp +++ b/src/gui/panels/panel.hpp @@ -31,6 +31,11 @@ #include namespace gui { + +namespace model { +class Project; +} + namespace panels { /** @@ -41,23 +46,30 @@ class Panel : public Gtk::VBox protected: /** * Constructs a panel object + * @param owner_project The project associated with this panel. * @param name The internal name of this panel * @param long_name The name to display on the caption * @param behavior The GDL behaviour of this item */ - Panel(const gchar *name, const gchar *long_name, + Panel(model::Project *const owner_project, + const gchar *name, const gchar *long_name, GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); /** * Constructs a panel object with a stock item for a caption + * @param owner_project The project associated with this panel. * @param name The internal name of this panel * @param long_name The name to display on the caption * @param stock_id The id of the stock item to display on the caption * @param behavior The GDL behaviour of this item */ - Panel(const gchar *name, const gchar *long_name, const gchar *stock_id, + Panel(model::Project *const owner_project, + const gchar *name, const gchar *long_name, const gchar *stock_id, GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + /** + * Destructor + **/ ~Panel(); public: @@ -86,6 +98,9 @@ private: void internal_setup(); protected: + + model::Project *const project; + GdlDockItem* dock_item; }; diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 3deab7969..47aa72401 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -20,9 +20,13 @@ * *****************************************************/ +#include + #include "../gtk-lumiera.hpp" #include "timeline-panel.hpp" +#include "../model/project.hpp" + extern "C" { #include "../../lib/time.h" } @@ -30,14 +34,15 @@ extern "C" { using namespace Gtk; using namespace sigc; using namespace gui::widgets; +using namespace gui::model; namespace gui { namespace panels { const int TimelinePanel::ZoomToolSteps = 2; // 2 seems comfortable -TimelinePanel::TimelinePanel() : - Panel("timeline", _("Timeline"), "panel_timeline"), +TimelinePanel::TimelinePanel(model::Project *const owner_project) : + Panel(owner_project, "timeline", _("Timeline"), "panel_timeline"), previousButton(Stock::MEDIA_PREVIOUS), rewindButton(Stock::MEDIA_REWIND), playPauseButton(Stock::MEDIA_PLAY), @@ -49,14 +54,17 @@ TimelinePanel::TimelinePanel() : zoomIn(Stock::ZOOM_IN), zoomOut(Stock::ZOOM_OUT), timeIndicator(), - updatingToolbar(false) + updatingToolbar(false), + currentTool(timeline::IBeam) { // Setup the widget - 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)); - + //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)); + notebook.signal_switch_page().connect( + mem_fun(this, &TimelinePanel::on_page_switched)); + // Setup the toolbar timeIndicatorButton.set_label_widget(timeIndicator); @@ -83,20 +91,26 @@ TimelinePanel::TimelinePanel() : toolbar.append(zoomIn, mem_fun(this, &TimelinePanel::on_zoom_in)); toolbar.append(zoomOut, mem_fun(this, &TimelinePanel::on_zoom_out)); -// doesn't compile on Etch -// toolbar.set_icon_size(IconSize(ICON_SIZE_LARGE_TOOLBAR)); toolbar.set_toolbar_style(TOOLBAR_ICONS); // Add the toolbar pack_start(toolbar, PACK_SHRINK); - pack_start(timelineWidget, PACK_EXPAND_WIDGET); + pack_start(notebook, PACK_EXPAND_WIDGET); // Set the initial UI state + update_notebook(); update_tool_buttons(); update_zoom_buttons(); show_time(0); } +TimelinePanel::~TimelinePanel() +{ + // Free allocated widgets + BOOST_FOREACH( TimelineWidget* widget, notebook_pages ) + delete widget; +} + void TimelinePanel::on_play_pause() { @@ -117,40 +131,54 @@ void TimelinePanel::on_stop() { // TEST CODE! - timelineWidget.set_playback_point(GAVL_TIME_UNDEFINED); + /*timelineWidget.set_playback_point(GAVL_TIME_UNDEFINED); frameEvent.disconnect(); show_time(timelineWidget.get_playback_period_start()); - update_playback_buttons(); + update_playback_buttons();*/ } void TimelinePanel::on_arrow_tool() { - if(updatingToolbar) return; - timelineWidget.set_tool(timeline::Arrow); - update_tool_buttons(); + set_tool(timeline::Arrow); } void TimelinePanel::on_ibeam_tool() -{ - if(updatingToolbar) return; - timelineWidget.set_tool(timeline::IBeam); - update_tool_buttons(); +{ + set_tool(timeline::IBeam); } void TimelinePanel::on_zoom_in() { - timelineWidget.get_view_window().zoom_view(ZoomToolSteps); + TimelineWidget *const widget = get_current_page(); + ASSERT(widget != NULL); + + widget->get_view_window().zoom_view(ZoomToolSteps); update_zoom_buttons(); } void TimelinePanel::on_zoom_out() { - timelineWidget.get_view_window().zoom_view(-ZoomToolSteps); + TimelineWidget *const widget = get_current_page(); + ASSERT(widget != NULL); + + widget->get_view_window().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); + update_zoom_buttons(); } @@ -165,13 +193,28 @@ TimelinePanel::on_playback_period_drag_released() { //----- TEST CODE - this needs to set the playback point via the // real backend - timelineWidget.set_playback_point( - timelineWidget.get_playback_period_start()); + + TimelineWidget *const widget = get_current_page(); + ASSERT(widget != NULL); + + widget->set_playback_point(widget->get_playback_period_start()); //----- END TEST CODE play(); } +void +TimelinePanel::update_notebook() +{ + BOOST_FOREACH( Sequence* const sequence, project->get_sequences() ) + { + TimelineWidget * const widget = new TimelineWidget(); + notebook_pages.push_back(widget); + notebook.append_page(*widget, sequence->get_name()); + notebook.set_tab_reorderable(*widget); + } +} + void TimelinePanel::update_playback_buttons() { @@ -185,9 +228,8 @@ TimelinePanel::update_tool_buttons() if(!updatingToolbar) { updatingToolbar = true; - const timeline::ToolType tool = timelineWidget.get_tool(); - arrowTool.set_active(tool == timeline::Arrow); - iBeamTool.set_active(tool == timeline::IBeam); + arrowTool.set_active(currentTool == timeline::Arrow); + iBeamTool.set_active(currentTool == timeline::IBeam); updatingToolbar = false; } } @@ -195,21 +237,24 @@ TimelinePanel::update_tool_buttons() void TimelinePanel::update_zoom_buttons() { - zoomIn.set_sensitive(timelineWidget.get_view_window().get_time_scale() + TimelineWidget *const widget = get_current_page(); + ASSERT(widget != NULL); + + zoomIn.set_sensitive(widget->get_view_window().get_time_scale() != 1); - zoomOut.set_sensitive(timelineWidget.get_view_window().get_time_scale() + zoomOut.set_sensitive(widget->get_view_window().get_time_scale() != TimelineWidget::MaxScale); } void TimelinePanel::play() { - if(timelineWidget.get_playback_point() == GAVL_TIME_UNDEFINED) + /*if(timelineWidget.get_playback_point() == GAVL_TIME_UNDEFINED) timelineWidget.set_playback_point( timelineWidget.get_playback_period_start()); frameEvent = Glib::signal_timeout().connect( sigc::mem_fun(this, &TimelinePanel::on_frame), - 1000 / 25); + 1000 / 25);*/ } bool @@ -219,17 +264,38 @@ TimelinePanel::is_playing() const return frameEvent.connected(); } +void +TimelinePanel::set_tool(timeline::ToolType tool) +{ + if(updatingToolbar) return; + + TimelineWidget *const widget = get_current_page(); + ASSERT(widget != NULL); + + currentTool = tool; + widget->set_tool(tool); + update_tool_buttons(); +} + void TimelinePanel::show_time(gavl_time_t time) { timeIndicator.set_text(lumiera_tmpbuf_print_time(time)); } +TimelineWidget* +TimelinePanel::get_current_page() +{ + Widget* const widget = (*notebook.get_current()).get_child(); + REQUIRE(widget != NULL); + return (TimelineWidget*)widget; +} + bool TimelinePanel::on_frame() { // TEST CODE! - const gavl_time_t point = timelineWidget.get_playback_point() + /*const gavl_time_t point = timelineWidget.get_playback_point() + GAVL_TIME_SCALE / 25; if(point < timelineWidget.get_playback_period_end()) { @@ -239,7 +305,7 @@ TimelinePanel::on_frame() } else - on_stop(); + on_stop();*/ return true; } diff --git a/src/gui/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp index 1826b87b1..71f676816 100644 --- a/src/gui/panels/timeline-panel.hpp +++ b/src/gui/panels/timeline-panel.hpp @@ -43,8 +43,15 @@ class TimelinePanel : public Panel public: /** * Constructor + * @param owner_project The project associated with this panel. */ - TimelinePanel(); + TimelinePanel(model::Project *const owner_project); + + + /** + * Destructor + **/ + ~TimelinePanel(); private: //----- Event Handlers -----// @@ -60,10 +67,15 @@ private: void on_time_pressed(); + void on_page_switched(GtkNotebookPage*, guint); + void on_mouse_hover(gavl_time_t time); void on_playback_period_drag_released(); private: + + void update_notebook(); + void update_playback_buttons(); void update_tool_buttons(); void update_zoom_buttons(); @@ -71,7 +83,11 @@ private: void play(); bool is_playing() const; + void set_tool(gui::widgets::timeline::ToolType tool); + void show_time(gavl_time_t time); + + TimelineWidget* get_current_page(); private: @@ -80,7 +96,10 @@ private: // Widgets Gtk::Toolbar toolbar; Gtk::HBox toolStrip; - TimelineWidget timelineWidget; + + // Body Widgets + Gtk::Notebook notebook; + std::list notebook_pages; // Toolbar Widgets @@ -106,6 +125,7 @@ private: // Internals bool updatingToolbar; + gui::widgets::timeline::ToolType currentTool; private: // TEST CODE diff --git a/src/gui/panels/viewer-panel.cpp b/src/gui/panels/viewer-panel.cpp index e280694f3..070dd2d29 100644 --- a/src/gui/panels/viewer-panel.cpp +++ b/src/gui/panels/viewer-panel.cpp @@ -29,8 +29,8 @@ using namespace Gtk; namespace gui { namespace panels { -ViewerPanel::ViewerPanel() : - Panel("viewer", _("Viewer"), "panel_viewer") +ViewerPanel::ViewerPanel(model::Project *const owner_project) : + Panel(owner_project, "viewer", _("Viewer"), "panel_viewer") { //----- Pack in the Widgets -----// pack_start(display, PACK_EXPAND_WIDGET); diff --git a/src/gui/panels/viewer-panel.hpp b/src/gui/panels/viewer-panel.hpp index a53e30561..027ab1fc2 100644 --- a/src/gui/panels/viewer-panel.hpp +++ b/src/gui/panels/viewer-panel.hpp @@ -42,8 +42,9 @@ class ViewerPanel : public Panel public: /** * Contructor. + @param owner_project The project associated with this panel. **/ - ViewerPanel(); + ViewerPanel(model::Project *const owner_project); protected: diff --git a/src/gui/workspace/workspace-window.cpp b/src/gui/workspace/workspace-window.cpp index f3b9e3c97..c7d2f9bf8 100644 --- a/src/gui/workspace/workspace-window.cpp +++ b/src/gui/workspace/workspace-window.cpp @@ -140,11 +140,11 @@ WorkspaceWindow::create_ui() baseContainer.pack_start(*toolbar, Gtk::PACK_SHRINK); //----- Create the Panels -----// - assetsPanel = new AssetsPanel(); + assetsPanel = new AssetsPanel(project); ENSURE(assetsPanel != NULL); - viewerPanel = new ViewerPanel(); + viewerPanel = new ViewerPanel(project); ENSURE(viewerPanel != NULL); - timelinePanel = new TimelinePanel(); + timelinePanel = new TimelinePanel(project); ENSURE(timelinePanel != NULL); //----- Create the Dock -----//