From 653f820c7ede8e65232b8b13322fafe7af9d0f1b Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 13 Apr 2009 16:11:50 +0100 Subject: [PATCH] Improved switching implementation --- src/gui/panels/panel.cpp | 83 ++++++++++++++----- src/gui/panels/panel.hpp | 58 +++++++++---- src/gui/panels/resources-panel.cpp | 5 +- src/gui/panels/resources-panel.hpp | 7 +- src/gui/panels/timeline-panel.cpp | 25 +++--- src/gui/panels/timeline-panel.hpp | 12 +-- src/gui/panels/viewer-panel.cpp | 7 +- src/gui/panels/viewer-panel.hpp | 6 +- src/gui/widgets/panel-bar.cpp | 4 +- .../timeline/timeline-header-container.cpp | 5 +- src/gui/workspace/panel-manager.cpp | 58 ++++++++----- src/gui/workspace/panel-manager.hpp | 36 +++++--- 12 files changed, 207 insertions(+), 99 deletions(-) diff --git a/src/gui/panels/panel.cpp b/src/gui/panels/panel.cpp index fcb6de6a8..526ab5a7e 100644 --- a/src/gui/panels/panel.cpp +++ b/src/gui/panels/panel.cpp @@ -22,12 +22,16 @@ #include "panel.hpp" #include "../gtk-lumiera.hpp" +#include "../workspace/panel-manager.hpp" +#include "../workspace/workspace-window.hpp" #include +using namespace Gtk; + namespace gui { namespace panels { -Panel::Panel(workspace::WorkspaceWindow &workspace_window, +/*Panel::Panel(workspace::WorkspaceWindow &workspace_window, const gchar *name, const gchar *long_name, GdlDockItemBehavior behavior) : workspace(workspace_window), @@ -59,55 +63,88 @@ Panel::Panel(workspace::WorkspaceWindow &workspace_window, internal_setup(); ENSURE(dock_item != NULL); +}*/ + +Panel::Panel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item, const gchar *stock_id) : + panelManager(panel_manager), + dockItem(dock_item), + panelBar(*this, stock_id) +{ + REQUIRE(dockItem); + g_object_ref(dockItem); + + // Set the dock item title + StockItem stock_item; + REQUIRE(StockItem::lookup(Gtk::StockID(stock_id), stock_item)); + + Glib::Value val; + val.init(val.value_type()); + val.set(stock_item.get_label()); + g_object_set_property (G_OBJECT (dockItem), "long-name", val.gobj()); + + // Set the grip handle + GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP( + gdl_dock_item_get_grip(dockItem)); + gdl_dock_item_grip_show_handle(grip); + gdl_dock_item_grip_set_label(grip, ((Widget&)panelBar).gobj()); + + // Set up the panel body + gtk_container_add ((GtkContainer*)dockItem, (GtkWidget*)gobj()); + + gtk_widget_show ((GtkWidget*)dockItem); } Panel::~Panel() { - REQUIRE(dock_item != NULL); - g_object_unref(dock_item); - dock_item = NULL; + REQUIRE(dockItem != NULL); + g_object_unref(dockItem); + dockItem = NULL; } GdlDockItem* Panel::get_dock_item() const { - return dock_item; + return dockItem; } void Panel::show(bool show) { - REQUIRE(dock_item != NULL); - if(show) gdl_dock_item_show_item (dock_item); - else gdl_dock_item_hide_item (dock_item); + REQUIRE(dockItem != NULL); + if(show) gdl_dock_item_show_item (dockItem); + else gdl_dock_item_hide_item (dockItem); } bool Panel::is_shown() const { - REQUIRE(dock_item != NULL); - return GTK_WIDGET_VISIBLE((GtkWidget*)dock_item); + REQUIRE(dockItem != NULL); + return GTK_WIDGET_VISIBLE((GtkWidget*)dockItem); +} + +workspace::PanelManager& +Panel::get_panel_manager() +{ + return panelManager; } workspace::WorkspaceWindow& Panel::get_workspace_window() { - return workspace; + return panelManager.get_workspace_window(); } -void -Panel::internal_setup() +model::Project& +Panel::get_project() { - REQUIRE(dock_item != NULL); - REQUIRE(gobj() != NULL); - - GdlDockItemGrip *grip = GDL_DOCK_ITEM_GRIP( - gdl_dock_item_get_grip(dock_item)); - gdl_dock_item_grip_show_handle(grip); - gdl_dock_item_grip_set_label(grip, ((Widget&)panelBar).gobj()); - - gtk_container_add ((GtkContainer*)dock_item, (GtkWidget*)gobj()); - gtk_widget_show ((GtkWidget*)dock_item); + return panelManager.get_workspace_window().get_project(); +} + +controller::Controller& +Panel::get_controller() +{ + return panelManager.get_workspace_window().get_controller(); } } // namespace panels diff --git a/src/gui/panels/panel.hpp b/src/gui/panels/panel.hpp index 8db6ace47..a78898b9c 100644 --- a/src/gui/panels/panel.hpp +++ b/src/gui/panels/panel.hpp @@ -35,7 +35,7 @@ namespace gui { namespace workspace { -class WorkspaceWindow; +class PanelManager; } namespace panels { @@ -53,9 +53,9 @@ protected: * @param long_name The name to display on the caption * @param behavior The GDL behaviour of this item */ - Panel(workspace::WorkspaceWindow &workspace_window, - const gchar *name, const gchar *long_name, - GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + //Panel(workspace::WorkspaceWindow &workspace_window, + // 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 @@ -65,9 +65,18 @@ protected: * @param stock_id The id of the stock item to display on the caption * @param behavior The GDL behaviour of this item */ - Panel(workspace::WorkspaceWindow &owner_window, - const gchar *name, const gchar *long_name, const gchar *stock_id, - GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + //Panel(workspace::WorkspaceWindow &owner_window, + // const gchar *name, const gchar *long_name, const gchar *stock_id, + // GdlDockItemBehavior behavior = GDL_DOCK_ITEM_BEH_NORMAL); + + /** + * Contructor. + * @param panel_manager The owner panel manager widget. + * @param dock_item The GdlDockItem that will host this panel. + * @param stock_id The stock_id of this panel. + **/ + Panel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item, const gchar *stock_id); public: /** @@ -92,25 +101,44 @@ public: */ bool is_shown() const; + /** + * Returns a reference to the owner panel manager object. + **/ + workspace::PanelManager& get_panel_manager(); + +protected: + /** * Returns a reference to the owner workspace window object. **/ workspace::WorkspaceWindow& get_workspace_window(); -private: /** - * @internal Used by both constructors - * The internal constructor for this class, whose purpose - * is to set up the internal container widgets. - */ - void internal_setup(); + * Returns a reference to the project + **/ + model::Project& get_project(); + + /** + * Returns a reference to the controller + **/ + controller::Controller& get_controller(); protected: - workspace::WorkspaceWindow &workspace; + /** + * The owner panel manager object. + **/ + workspace::PanelManager &panelManager; - GdlDockItem* dock_item; + /** + * The owner dock item widget that will host the widgets in this + * panel. + **/ + GdlDockItem* dockItem; + /** + * The panel bar to attach to the panel grip. + **/ widgets::PanelBar panelBar; }; diff --git a/src/gui/panels/resources-panel.cpp b/src/gui/panels/resources-panel.cpp index 67008f788..33ce4fc45 100644 --- a/src/gui/panels/resources-panel.cpp +++ b/src/gui/panels/resources-panel.cpp @@ -26,8 +26,9 @@ namespace gui { namespace panels { -ResourcesPanel::ResourcesPanel(workspace::WorkspaceWindow &workspace_window) : - Panel(workspace_window, "resources", get_title(), get_stock_id()) +ResourcesPanel::ResourcesPanel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item) : + Panel(panel_manager, dock_item, get_stock_id()) { notebook.append_page(media, _("Media")); notebook.append_page(clips, _("Clips")); diff --git a/src/gui/panels/resources-panel.hpp b/src/gui/panels/resources-panel.hpp index 74cb0c69c..5c725dc3c 100644 --- a/src/gui/panels/resources-panel.hpp +++ b/src/gui/panels/resources-panel.hpp @@ -34,12 +34,13 @@ namespace panels { class ResourcesPanel : public Panel { public: - /** * Contructor. - * @param workspace_window The window that owns this panel. + * @param panel_manager The owner panel manager widget. + * @param dock_item The GdlDockItem that will host this panel. **/ - ResourcesPanel(workspace::WorkspaceWindow &workspace_window); + ResourcesPanel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item); /** * Get the title of the panel. diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 6206e4e42..1092dd251 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -46,9 +46,9 @@ namespace panels { const int TimelinePanel::ZoomToolSteps = 2; // 2 seems comfortable -TimelinePanel::TimelinePanel(workspace::WorkspaceWindow - &workspace_window) : - Panel(workspace_window, "timeline", get_title(), get_stock_id()), +TimelinePanel::TimelinePanel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item) : + Panel(panel_manager, dock_item, get_stock_id()), timeIndicator(), timeIndicatorButton(), previousButton(Stock::MEDIA_PREVIOUS), @@ -65,8 +65,8 @@ TimelinePanel::TimelinePanel(workspace::WorkspaceWindow currentTool(timeline::IBeam) { // Hook up notifications - workspace.get_project().get_sequences().signal_changed().connect( - mem_fun(this, &TimelinePanel::on_sequence_list_changed)); + get_project().get_sequences().signal_changed().connect(mem_fun(this, + &TimelinePanel::on_sequence_list_changed)); // Setup the sequence chooser sequenceChooserModel = Gtk::ListStore::create(sequenceChooserColumns); @@ -114,7 +114,7 @@ TimelinePanel::TimelinePanel(workspace::WorkspaceWindow // Setup the timeline widget shared_ptr sequence - = *workspace.get_project().get_sequences().begin(); + = *get_project().get_sequences().begin(); timelineWidget.reset(new TimelineWidget(load_state(sequence))); pack_start(*timelineWidget, PACK_EXPAND_WIDGET); @@ -160,7 +160,7 @@ TimelinePanel::on_play_pause() void TimelinePanel::on_stop() { - workspace.get_controller().get_playback_controller().stop(); + get_controller().get_playback_controller().stop(); update_playback_buttons(); } @@ -259,7 +259,7 @@ TimelinePanel::update_sequence_chooser() timelineWidget->get_state(); BOOST_FOREACH( shared_ptr< model::Sequence > sequence, - workspace.get_project().get_sequences() ) + get_project().get_sequences() ) { Gtk::TreeIter iter = sequenceChooserModel->append(); Gtk::TreeModel::Row row = *iter; @@ -318,20 +318,19 @@ TimelinePanel::update_zoom_buttons() void TimelinePanel::play() { - workspace.get_controller().get_playback_controller().play(); + get_controller().get_playback_controller().play(); } void TimelinePanel::pause() { - workspace.get_controller().get_playback_controller().pause(); + get_controller().get_playback_controller().pause(); } bool -TimelinePanel::is_playing() const +TimelinePanel::is_playing() { - return workspace.get_controller().get_playback_controller(). - is_playing(); + return get_controller().get_playback_controller().is_playing(); } void diff --git a/src/gui/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp index ea33ee5f2..587b63427 100644 --- a/src/gui/panels/timeline-panel.hpp +++ b/src/gui/panels/timeline-panel.hpp @@ -47,10 +47,12 @@ class TimelinePanel : public Panel { public: /** - * Constructor - * @param workspace_window The window that owns this panel. - */ - TimelinePanel(workspace::WorkspaceWindow &workspace_window); + * Contructor. + * @param panel_manager The owner panel manager widget. + * @param dock_item The GdlDockItem that will host this panel. + **/ + TimelinePanel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item); /** * Destructor @@ -109,7 +111,7 @@ private: void pause(); - bool is_playing() const; + bool is_playing(); void set_tool(gui::widgets::timeline::ToolType tool); diff --git a/src/gui/panels/viewer-panel.cpp b/src/gui/panels/viewer-panel.cpp index e3fb168fc..f8ab93b4e 100644 --- a/src/gui/panels/viewer-panel.cpp +++ b/src/gui/panels/viewer-panel.cpp @@ -36,14 +36,15 @@ using namespace gui::controller; namespace gui { namespace panels { -ViewerPanel::ViewerPanel(workspace::WorkspaceWindow &workspace_window) : - Panel(workspace_window, "viewer", get_title(), get_stock_id()) +ViewerPanel::ViewerPanel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item) : + Panel(panel_manager, dock_item, get_stock_id()) { //----- Pack in the Widgets -----// pack_start(display, PACK_EXPAND_WIDGET); PlaybackController &playback = - workspace_window.get_controller().get_playback_controller(); + get_controller().get_playback_controller(); FrameDestination outputDestination (sigc::mem_fun(this, &ViewerPanel::on_frame)); playback.use_display (DisplayService::setUp (outputDestination)); diff --git a/src/gui/panels/viewer-panel.hpp b/src/gui/panels/viewer-panel.hpp index ecaac8f5d..a51b3997f 100644 --- a/src/gui/panels/viewer-panel.hpp +++ b/src/gui/panels/viewer-panel.hpp @@ -42,9 +42,11 @@ class ViewerPanel : public Panel public: /** * Contructor. - * @param workspace_window The window that owns this panel. + * @param panel_manager The owner panel manager widget. + * @param dock_item The GdlDockItem that will host this panel. **/ - ViewerPanel(workspace::WorkspaceWindow &owner_window); + ViewerPanel(workspace::PanelManager &panel_manager, + GdlDockItem *dock_item); /** * Get the title of the panel. diff --git a/src/gui/widgets/panel-bar.cpp b/src/gui/widgets/panel-bar.cpp index 115943fad..95a4b831f 100644 --- a/src/gui/widgets/panel-bar.cpp +++ b/src/gui/widgets/panel-bar.cpp @@ -129,9 +129,7 @@ PanelBar::on_size_allocate(Gtk::Allocation& allocation) void PanelBar::on_panel_type(int type_index) { - workspace::PanelManager &manager = panel.get_workspace_window(). - get_panel_manager(); - manager.switch_panel(panel, type_index); + panel.get_panel_manager().switch_panel(panel, type_index); } void diff --git a/src/gui/widgets/timeline/timeline-header-container.cpp b/src/gui/widgets/timeline/timeline-header-container.cpp index e8fa1ee52..9a023fae3 100644 --- a/src/gui/widgets/timeline/timeline-header-container.cpp +++ b/src/gui/widgets/timeline/timeline-header-container.cpp @@ -290,7 +290,10 @@ TimelineHeaderContainer::forall_vfunc(gboolean /* include_internals */, BOOST_FOREACH( pair, timelineWidget.trackMap ) { REQUIRE(pair.second); - callback(pair.second->get_header_widget().gobj(), callback_data); + GtkWidget *widget = pair.second->get_header_widget().gobj(); + + REQUIRE(widget); + callback(widget, callback_data); } } diff --git a/src/gui/workspace/panel-manager.cpp b/src/gui/workspace/panel-manager.cpp index a11f78ebc..56be3570e 100644 --- a/src/gui/workspace/panel-manager.cpp +++ b/src/gui/workspace/panel-manager.cpp @@ -40,6 +40,8 @@ const PanelManager::PanelDescription PanelManager::Panel(), PanelManager::Panel() }; + +unsigned short PanelManager::panelID = 0; PanelManager::PanelManager(WorkspaceWindow &workspace_window) : workspaceWindow(workspace_window), @@ -111,26 +113,23 @@ PanelManager::get_dock_bar() const return dockBar; } +WorkspaceWindow& +PanelManager::get_workspace_window() +{ + return workspaceWindow; +} + void PanelManager::switch_panel(panels::Panel &old_panel, int new_panel_description_index) { REQUIRE(new_panel_description_index >= 0 && new_panel_description_index < get_panel_description_count()); - shared_ptr new_panel( - panelDescriptionList[new_panel_description_index].create( - workspaceWindow)); - - new_panel->show_all(); - - panels.push_back(new_panel); - - gdl_dock_object_dock (GDL_DOCK_OBJECT(old_panel.get_dock_item()), - GDL_DOCK_OBJECT(new_panel->get_dock_item()), - GDL_DOCK_CENTER, NULL); - - gdl_dock_object_unbind(GDL_DOCK_OBJECT(old_panel.get_dock_item())); + // Get the dock item + GdlDockItem *dock_item = old_panel.get_dock_item(); + g_object_ref(dock_item); + // Release the old panel list< boost::shared_ptr >::iterator i; for(i = panels.begin(); i != panels.end(); i++) { @@ -140,6 +139,16 @@ void PanelManager::switch_panel(panels::Panel &old_panel, break; } } + + // Create the new panel + shared_ptr new_panel( + panelDescriptionList[new_panel_description_index].create( + *this, dock_item)); + g_object_unref(dock_item); + + new_panel->show_all(); + + panels.push_back(new_panel); } int @@ -159,11 +168,11 @@ void PanelManager::create_panels() { shared_ptr resourcesPanel( - (panels::Panel*)new ResourcesPanel(workspaceWindow)); + create_panel_by_name("ResourcesPanel")); shared_ptr viewerPanel( - (panels::Panel*)new ViewerPanel(workspaceWindow)); + create_panel_by_name("ViewerPanel")); shared_ptr timelinePanel( - (panels::Panel*)new TimelinePanel(workspaceWindow)); + create_panel_by_name("TimelinePanel")); gdl_dock_add_item(dock, resourcesPanel->get_dock_item(), GDL_DOCK_LEFT); @@ -179,13 +188,24 @@ PanelManager::create_panels() shared_ptr PanelManager::create_panel_by_name(const char* class_name) -{ +{ const int count = get_panel_description_count(); for(int i = 0; i < count; i++) { if(strstr(panelDescriptionList[i].get_class_name(), class_name)) - return shared_ptr(panelDescriptionList[i].create( - workspaceWindow)); + { + // Make a unique name for the panel + char name[5]; + snprintf(name, sizeof(name), "%X", panelID++); + + // Create a dock item + GdlDockItem *dock_item = GDL_DOCK_ITEM( + gdl_dock_item_new(name, "", GDL_DOCK_ITEM_BEH_NORMAL)); + + // Create the panel object + return shared_ptr( + panelDescriptionList[i].create(*this, dock_item)); + } } ERROR(gui, "Unable to create a panel with class name %s", class_name); diff --git a/src/gui/workspace/panel-manager.hpp b/src/gui/workspace/panel-manager.hpp index 5e13da0b1..5abd454c6 100644 --- a/src/gui/workspace/panel-manager.hpp +++ b/src/gui/workspace/panel-manager.hpp @@ -76,6 +76,11 @@ public: **/ GdlDockBar* get_dock_bar() const; + /** + * Returns a reference to the owner workspace window. + **/ + WorkspaceWindow& get_workspace_window(); + void switch_panel(panels::Panel &old_panel, int new_panel_description_index); @@ -142,6 +147,11 @@ private: * The list of created panels. **/ std::list< boost::shared_ptr > panels; + + /** + * An accumulator for the panel id. + **/ + static unsigned short panelID; private: @@ -150,6 +160,11 @@ private: **/ class PanelDescription { + protected: + + typedef boost::shared_ptr (*const CreatePanelProc)( + PanelManager&, GdlDockItem*); + protected: /** * Constructor @@ -161,9 +176,7 @@ private: * instantiate the panel object. **/ PanelDescription(const char* class_name, const char *title, - const gchar *stock_id, - boost::shared_ptr (*const create_panel_proc)( - WorkspaceWindow&)) : + const gchar *stock_id, CreatePanelProc create_panel_proc) : className(class_name), titleName(title), stockID(stock_id), @@ -203,12 +216,15 @@ private: /** * Creates an instance of this panel. + * @param panel_manager The owner panel manager. + * @param dock_item The GdlDockItem that will host this panel. + * @return Returns a shared pointer to the panel object. **/ boost::shared_ptr create( - WorkspaceWindow& owner_window) const + PanelManager &panel_manager, GdlDockItem* dock_item) const { REQUIRE(createPanelProc); - return createPanelProc(owner_window); + return createPanelProc(panel_manager, dock_item); } private: @@ -230,8 +246,7 @@ private: /** * A pointer to a function that will instantiate the panel object. **/ - boost::shared_ptr (*const createPanelProc)( - WorkspaceWindow&); + CreatePanelProc createPanelProc; }; /** @@ -253,14 +268,15 @@ private: private: /** * A helper function that will create a panel of type P - * @param workspace_window The owner workspace window. + * @param panel_manager The owner panel manager. + * @param dock_item The GdlDockItem that will host this panel. * @return Returns a shared pointer to the panel object. **/ static boost::shared_ptr create_panel( - WorkspaceWindow &workspace_window) + PanelManager &panel_manager, GdlDockItem* dock_item) { return boost::shared_ptr( - new P(workspace_window)); + new P(panel_manager, dock_item)); } };