From 2ee6f6be62cfc6858e24bef8cc2df4cb4a2e9cda Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 4 Aug 2008 16:39:36 +0100 Subject: [PATCH] Tidied and simplified video display widget, and added cursor support to the ibeam and arrow tool --- src/gui/panels/timeline-panel.cpp | 17 ++- src/gui/panels/timeline-panel.hpp | 3 + src/gui/widgets/timeline-widget.cpp | 21 +-- src/gui/widgets/timeline-widget.hpp | 1 + src/gui/widgets/timeline/header-container.cpp | 4 +- src/gui/widgets/timeline/header-container.hpp | 132 ++++++++-------- .../widgets/timeline/timeline-arrow-tool.cpp | 9 +- .../widgets/timeline/timeline-arrow-tool.hpp | 5 +- src/gui/widgets/timeline/timeline-body.cpp | 6 +- .../widgets/timeline/timeline-ibeam-tool.cpp | 10 +- .../widgets/timeline/timeline-ibeam-tool.hpp | 5 +- src/gui/widgets/timeline/timeline-tool.cpp | 23 ++- src/gui/widgets/timeline/timeline-tool.hpp | 18 ++- src/gui/widgets/video-display-widget.cpp | 143 +++++------------- src/gui/widgets/video-display-widget.hpp | 39 +++-- 15 files changed, 217 insertions(+), 219 deletions(-) diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 905a7b035..b03b4604f 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -38,7 +38,8 @@ TimelinePanel::TimelinePanel() : arrowTool(Gtk::StockID("arrow")), iBeamTool(Gtk::StockID("i_beam")), zoomIn(Stock::ZOOM_IN), - zoomOut(Stock::ZOOM_OUT) + zoomOut(Stock::ZOOM_OUT), + updatingToolbar(false) { // Setup the toolbar toolbar.append(arrowTool, mem_fun(this, @@ -63,6 +64,7 @@ TimelinePanel::TimelinePanel() : void TimelinePanel::on_arrow_tool() { + if(updatingToolbar) return; timelineWidget.set_tool(timeline::Arrow); update_tool_buttons(); } @@ -70,6 +72,7 @@ TimelinePanel::on_arrow_tool() void TimelinePanel::on_ibeam_tool() { + if(updatingToolbar) return; timelineWidget.set_tool(timeline::IBeam); update_tool_buttons(); } @@ -77,6 +80,7 @@ TimelinePanel::on_ibeam_tool() void TimelinePanel::on_zoom_in() { + timelineWidget.zoom_view(ZoomToolSteps); update_zoom_buttons(); } @@ -90,17 +94,14 @@ TimelinePanel::on_zoom_out() void TimelinePanel::update_tool_buttons() -{ - // This is included to prevent recursion - static bool updating = false; - - if(!updating) +{ + if(!updatingToolbar) { - updating = true; + updatingToolbar = true; const timeline::ToolType tool = timelineWidget.get_tool(); arrowTool.set_active(tool == timeline::Arrow); iBeamTool.set_active(tool == timeline::IBeam); - updating = false; + updatingToolbar = false; } } diff --git a/src/gui/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp index dc228403c..01791f91b 100644 --- a/src/gui/panels/timeline-panel.hpp +++ b/src/gui/panels/timeline-panel.hpp @@ -69,6 +69,9 @@ private: Gtk::ToolButton zoomIn; Gtk::ToolButton zoomOut; + // Internals + bool updatingToolbar; + //----- Constants -----// static const int ZoomToolSteps; }; diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index a56c29672..6b9d83be2 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -177,25 +177,28 @@ TimelineWidget::set_tool(ToolType tool_type) { // Tidy up old tool if(tool != NULL) - { - // Do we need to change tools? - if(tool->get_type() == tool_type) - return; - - delete tool; - } + { + // Do we need to change tools? + //if(tool->get_type() == tool_type) + // return; + + delete tool; + } // Create the new tool switch(tool_type) { case timeline::Arrow: - tool = new timeline::ArrowTool(); + tool = new timeline::ArrowTool(this); break; case timeline::IBeam: - tool = new timeline::IBeamTool(); + tool = new timeline::IBeamTool(this); break; } + + // Apply the cursor if possible + tool->apply_cursor(); } void diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index cc49f7897..e5e90fe92 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -148,6 +148,7 @@ protected: friend class timeline::TimelineBody; friend class timeline::HeaderContainer; + friend class timeline::Tool; }; } // namespace widgets diff --git a/src/gui/widgets/timeline/header-container.cpp b/src/gui/widgets/timeline/header-container.cpp index 5e74da3eb..dfc085fc1 100644 --- a/src/gui/widgets/timeline/header-container.cpp +++ b/src/gui/widgets/timeline/header-container.cpp @@ -39,7 +39,9 @@ HeaderContainer::HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline { REQUIRE(timeline_widget != NULL); - set_flags(Gtk::NO_WINDOW); // This widget will not have a window at first + // This widget will not have a window at first + set_flags(Gtk::NO_WINDOW); + set_redraw_on_allocate(false); // Connect to the timeline widget's vertical scroll event, diff --git a/src/gui/widgets/timeline/header-container.hpp b/src/gui/widgets/timeline/header-container.hpp index 69d13b953..3a6d43065 100644 --- a/src/gui/widgets/timeline/header-container.hpp +++ b/src/gui/widgets/timeline/header-container.hpp @@ -46,80 +46,80 @@ class Track; * associated with timeline tracks. */ class HeaderContainer : public Gtk::Container - { - public: - /** - * Constructor - * - * @param[in] timeline_widget A pointer to the owner timeline widget - */ - HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget); - - /** - * Attaches the header all the header widgets of root - * tracks to this control. - * - * @note This must be called when the track list changes - * to synchronise the headers with the timeline body and - * the backend. - */ - void update_headers(); - - /* ===== Overrides ===== */ - private: - void on_realize(); - void on_unrealize(); +{ +public: + /** + * Constructor + * + * @param[in] timeline_widget A pointer to the owner timeline widget + */ + HeaderContainer(lumiera::gui::widgets::TimelineWidget *timeline_widget); - void on_size_allocate (Gtk::Allocation& allocation); - void on_size_request (Gtk::Requisition* requisition); - - void forall_vfunc(gboolean include_internals, GtkCallback callback, - gpointer callback_data); - - /* ===== Events ===== */ - private: - void on_scroll(); + /** + * Attaches the header all the header widgets of root + * tracks to this control. + * + * @note This must be called when the track list changes + * to synchronise the headers with the timeline body and + * the backend. + */ + void update_headers(); + + /* ===== Overrides ===== */ +private: + void on_realize(); + void on_unrealize(); + + void on_size_allocate (Gtk::Allocation& allocation); + void on_size_request (Gtk::Requisition* requisition); - /* ===== Internals ===== */ - private: + void forall_vfunc(gboolean include_internals, GtkCallback callback, + gpointer callback_data); - /** - * Moves all the header widgets to the correct position - * given scroll, stacking etc. - */ - void layout_headers(); + /* ===== Events ===== */ +private: + void on_scroll(); - private: + /* ===== Internals ===== */ +private: + + /** + * Moves all the header widgets to the correct position + * given scroll, stacking etc. + */ + void layout_headers(); - /** - * The owner TimelineWidget of which this class is a helper - */ - lumiera::gui::widgets::TimelineWidget *timelineWidget; +private: - /** - * A structure to represent a header widget and it's - * associated track - */ - struct RootHeader - { - Glib::RefPtr widget; - Track *track; - }; - - /** - * Contains a list of the root currently present on - * the timeline view - */ - std::vector< RootHeader > rootHeaders; + /** + * The owner TimelineWidget of which this class is a helper + */ + lumiera::gui::widgets::TimelineWidget *timelineWidget; - /** - * The widget's window object. - * - * @note This is needed for the sake of clipping when - * widgets are scrolled. - */ - Glib::RefPtr gdkWindow; + /** + * A structure to represent a header widget and it's + * associated track + */ + struct RootHeader + { + Glib::RefPtr widget; + Track *track; }; + + /** + * Contains a list of the root currently present on + * the timeline view + */ + std::vector< RootHeader > rootHeaders; + + /** + * The widget's window object. + * + * @note This is needed for the sake of clipping when + * widgets are scrolled. + */ + Glib::RefPtr gdkWindow; +}; } // namespace timeline } // namespace widgets diff --git a/src/gui/widgets/timeline/timeline-arrow-tool.cpp b/src/gui/widgets/timeline/timeline-arrow-tool.cpp index 28c63e1ee..4e65165f5 100644 --- a/src/gui/widgets/timeline/timeline-arrow-tool.cpp +++ b/src/gui/widgets/timeline/timeline-arrow-tool.cpp @@ -27,7 +27,8 @@ namespace gui { namespace widgets { namespace timeline { -ArrowTool::ArrowTool() +ArrowTool::ArrowTool(TimelineWidget *timeline_widget) : + Tool(timeline_widget) { } @@ -38,6 +39,12 @@ ArrowTool::get_type() const return Arrow; } +Gdk::Cursor +ArrowTool::get_cursor() const +{ + return Gdk::Cursor(Gdk::ARROW); +} + } // namespace timeline } // namespace widgets } // namespace gui diff --git a/src/gui/widgets/timeline/timeline-arrow-tool.hpp b/src/gui/widgets/timeline/timeline-arrow-tool.hpp index edf287767..05f4ef562 100644 --- a/src/gui/widgets/timeline/timeline-arrow-tool.hpp +++ b/src/gui/widgets/timeline/timeline-arrow-tool.hpp @@ -37,9 +37,12 @@ namespace timeline { class ArrowTool : public Tool { public: - ArrowTool(); + ArrowTool(TimelineWidget *timeline_widget); ToolType get_type() const; + +protected: + Gdk::Cursor get_cursor() const; }; } // namespace timeline diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index d2e711638..63edb6a1a 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -61,7 +61,6 @@ TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widge "Track Background", "The background colour of timeline tracks", GDK_TYPE_COLOR, G_PARAM_READABLE)); - } void @@ -69,12 +68,15 @@ TimelineBody::on_realize() { Widget::on_realize(); - // We wish to receive all event notifications + // We wish to receive event notifications add_events( Gdk::POINTER_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); + + // Apply the cursor if possible + timelineWidget->tool->apply_cursor(); } void diff --git a/src/gui/widgets/timeline/timeline-ibeam-tool.cpp b/src/gui/widgets/timeline/timeline-ibeam-tool.cpp index f6c9bf0cc..8225ced80 100644 --- a/src/gui/widgets/timeline/timeline-ibeam-tool.cpp +++ b/src/gui/widgets/timeline/timeline-ibeam-tool.cpp @@ -27,9 +27,9 @@ namespace gui { namespace widgets { namespace timeline { -IBeamTool::IBeamTool() +IBeamTool::IBeamTool(TimelineWidget *timeline_widget) : + Tool(timeline_widget) { - } ToolType @@ -38,6 +38,12 @@ IBeamTool::get_type() const return IBeam; } +Gdk::Cursor +IBeamTool::get_cursor() const +{ + return Gdk::Cursor(Gdk::XTERM); +} + } // namespace timeline } // namespace widgets } // namespace gui diff --git a/src/gui/widgets/timeline/timeline-ibeam-tool.hpp b/src/gui/widgets/timeline/timeline-ibeam-tool.hpp index 848c75b60..79eb36c8c 100644 --- a/src/gui/widgets/timeline/timeline-ibeam-tool.hpp +++ b/src/gui/widgets/timeline/timeline-ibeam-tool.hpp @@ -38,9 +38,12 @@ namespace timeline { class IBeamTool : public Tool { public: - IBeamTool(); + IBeamTool(TimelineWidget *timeline_widget); ToolType get_type() const; + +protected: + Gdk::Cursor get_cursor() const; }; } // namespace timeline diff --git a/src/gui/widgets/timeline/timeline-tool.cpp b/src/gui/widgets/timeline/timeline-tool.cpp index e1b8f5c0f..21ceacda7 100644 --- a/src/gui/widgets/timeline/timeline-tool.cpp +++ b/src/gui/widgets/timeline/timeline-tool.cpp @@ -21,15 +21,36 @@ * *****************************************************/ #include "timeline-tool.hpp" +#include "../timeline-widget.hpp" namespace lumiera { namespace gui { namespace widgets { namespace timeline { -Tool::Tool() +Tool::Tool(TimelineWidget *timeline_widget) : + timelineWidget(timeline_widget) { + REQUIRE(timeline_widget != NULL); + REQUIRE(timeline_widget->body != NULL); +} +bool +Tool::apply_cursor() +{ + REQUIRE(timelineWidget != NULL); + + if(timelineWidget->body == NULL) + return false; + + Glib::RefPtr window = + timelineWidget->body->get_window(); + if(!window) + return false; + + window->set_cursor(get_cursor()); + + return true; } } // namespace timeline diff --git a/src/gui/widgets/timeline/timeline-tool.hpp b/src/gui/widgets/timeline/timeline-tool.hpp index 1007aace6..675781747 100644 --- a/src/gui/widgets/timeline/timeline-tool.hpp +++ b/src/gui/widgets/timeline/timeline-tool.hpp @@ -27,11 +27,14 @@ #ifndef TIMELINE_TOOL_HPP #define TIMELINE_TOOL_HPP -#include +#include "../../gtk-lumiera.hpp" namespace lumiera { namespace gui { namespace widgets { + +class TimelineWidget; + namespace timeline { enum ToolType @@ -43,10 +46,19 @@ enum ToolType class Tool { -public: - Tool(); +protected: + Tool(TimelineWidget *timeline_widget); +public: virtual ToolType get_type() const = 0; + + bool apply_cursor(); + +protected: + virtual Gdk::Cursor get_cursor() const = 0; + +protected: + TimelineWidget *timelineWidget; }; diff --git a/src/gui/widgets/video-display-widget.cpp b/src/gui/widgets/video-display-widget.cpp index 39aee4678..fc400cf5d 100644 --- a/src/gui/widgets/video-display-widget.cpp +++ b/src/gui/widgets/video-display-widget.cpp @@ -36,128 +36,67 @@ namespace gui { namespace widgets { VideoDisplayWidget::VideoDisplayWidget() : - gdkWindow(NULL), displayer(NULL) - { - set_flags(Gtk::NO_WINDOW); - } +{ +} VideoDisplayWidget::~VideoDisplayWidget() - { - if(displayer != NULL) - delete displayer; - } +{ + if(displayer != NULL) + delete displayer; +} void VideoDisplayWidget::on_realize() - { - set_flags(Gtk::NO_WINDOW); +{ + // Call base class: + Gtk::Widget::on_realize(); - // Call base class: - Gtk::Widget::on_realize(); + // Set colors + modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black")); - // Create the GdkWindow: - GdkWindowAttr attributes; - memset(&attributes, 0, sizeof(attributes)); + if(displayer != NULL) + delete displayer; + displayer = createDisplayer(this, 320, 240); - Gtk::Allocation allocation = get_allocation(); - - // Set initial position and size of the Gdk::Window: - attributes.x = allocation.get_x(); - attributes.y = allocation.get_y(); - attributes.width = allocation.get_width(); - attributes.height = allocation.get_height(); - - attributes.event_mask = get_events () | Gdk::EXPOSURE_MASK; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - - gdkWindow = Gdk::Window::create(get_window() /* parent */, &attributes, - GDK_WA_X | GDK_WA_Y); - unset_flags(Gtk::NO_WINDOW); - set_window(gdkWindow); - - // Set colors - modify_bg(Gtk::STATE_NORMAL, Gdk::Color("black")); - - // Make the widget receive expose events - gdkWindow->set_user_data(gobj()); - - if(displayer != NULL) - delete displayer; - displayer = createDisplayer(this, 320, 240); - - add_events(Gdk::ALL_EVENTS_MASK); - } - -void -VideoDisplayWidget::on_unrealize() - { - gdkWindow.clear(); - - //Call base class: - Gtk::Widget::on_unrealize(); - } + add_events(Gdk::ALL_EVENTS_MASK); +} bool VideoDisplayWidget::on_button_press_event (GdkEventButton* event) - { - unsigned char buffer[320 * 240 * 4]; +{ + unsigned char buffer[320 * 240 * 4]; - for(int i = 0; i < 320*240*4; i++) - buffer[i] = rand(); + for(int i = 0; i < 320*240*4; i++) + buffer[i] = rand(); - displayer->put((void*)buffer); + displayer->put((void*)buffer); - return true; - } - -bool -VideoDisplayWidget::on_expose_event(GdkEventExpose* event) - { - // This is where we draw on the window - /*Glib::RefPtr window = get_window(); - if(window) - { - Cairo::RefPtr cr = window->create_cairo_context(); - if(event) - { - // clip to the area that needs to be re-exposed so we don't draw any - // more than we need to. - cr->rectangle(event->area.x, event->area.y, - event->area.width, event->area.height); - cr->clip(); - } - - // Paint the background - cr->set_source_rgb(0.0, 0.0, 0.0); - cr->paint(); - }*/ - return true; - } + return true; +} Displayer* VideoDisplayWidget::createDisplayer( Gtk::Widget *drawingArea, int width, int height ) - { - REQUIRE(drawingArea != NULL); - REQUIRE(width > 0 && height > 0); - - Displayer *displayer = NULL; - - displayer = new XvDisplayer( drawingArea, width, height ); - if ( !displayer->usable() ) - { - delete displayer; - displayer = NULL; - } +{ + REQUIRE(drawingArea != NULL); + REQUIRE(width > 0 && height > 0); + + Displayer *displayer = NULL; + + displayer = new XvDisplayer( drawingArea, width, height ); + if ( !displayer->usable() ) + { + delete displayer; + displayer = NULL; + } - if ( displayer == NULL ) - { - displayer = new GdkDisplayer( drawingArea, width, height ); - } + if ( displayer == NULL ) + { + displayer = new GdkDisplayer( drawingArea, width, height ); + } - return displayer; - } + return displayer; +} } // namespace widgets } // namespace gui diff --git a/src/gui/widgets/video-display-widget.hpp b/src/gui/widgets/video-display-widget.hpp index 66e224c18..d525a7297 100644 --- a/src/gui/widgets/video-display-widget.hpp +++ b/src/gui/widgets/video-display-widget.hpp @@ -36,34 +36,29 @@ namespace lumiera { namespace gui { namespace widgets { - class VideoDisplayWidget : public Gtk::Widget - { - public: - VideoDisplayWidget(); +class VideoDisplayWidget : public Gtk::DrawingArea +{ +public: + VideoDisplayWidget(); - ~VideoDisplayWidget(); + ~VideoDisplayWidget(); - /* ===== Overrides ===== */ - private: - virtual void on_realize(); + /* ===== Overrides ===== */ +private: + virtual void on_realize(); - virtual void on_unrealize(); - - virtual bool on_expose_event(GdkEventExpose* event); + // TEST CODE!!!! + virtual bool on_button_press_event (GdkEventButton* event); - // TEST CODE!!!! - virtual bool on_button_press_event (GdkEventButton* event); + /* ===== Internals ===== */ +private: + static Displayer* + createDisplayer( Gtk::Widget *drawingArea, int width, int height ); - /* ===== Internals ===== */ - private: - static Displayer* - createDisplayer( Gtk::Widget *drawingArea, int width, int height ); +private: - private: - Glib::RefPtr gdkWindow; - - Displayer *displayer; - }; + Displayer *displayer; +}; } // namespace widgets } // namespace gui