From e3d6026d0bd6fc0d844481dcf6b4a50c49e81c23 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 17 Jul 2008 19:35:49 +0100 Subject: [PATCH 01/12] Retired VideoTrack - all tracks are the same --- src/gui/Makefile.am | 2 - src/gui/widgets/timeline-widget.hpp | 5 +- src/gui/widgets/timeline/track.cpp | 37 +++++++++------ src/gui/widgets/timeline/track.hpp | 7 +-- src/gui/widgets/timeline/video-track.cpp | 60 ------------------------ src/gui/widgets/timeline/video-track.hpp | 58 ----------------------- 6 files changed, 28 insertions(+), 141 deletions(-) delete mode 100644 src/gui/widgets/timeline/video-track.cpp delete mode 100644 src/gui/widgets/timeline/video-track.hpp diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index b1560e485..14cdc33c2 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -58,8 +58,6 @@ lumigui_SOURCES = \ $(lumigui_srcdir)/widgets/timeline/header-container.hpp \ $(lumigui_srcdir)/widgets/timeline/track.cpp \ $(lumigui_srcdir)/widgets/timeline/track.hpp \ - $(lumigui_srcdir)/widgets/timeline/video-track.cpp \ - $(lumigui_srcdir)/widgets/timeline/video-track.hpp \ $(lumigui_srcdir)/widgets/timeline/timeline-body.cpp \ $(lumigui_srcdir)/widgets/timeline/timeline-body.hpp \ $(lumigui_srcdir)/widgets/timeline/timeline-ruler.cpp \ diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index 669060038..c179a4d59 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -31,7 +31,6 @@ #include "timeline/timeline-body.hpp" #include "timeline/timeline-ruler.hpp" #include "timeline/track.hpp" -#include "timeline/video-track.hpp" namespace lumiera { namespace gui { @@ -119,8 +118,8 @@ protected: int totalHeight; - timeline::VideoTrack video1; - timeline::VideoTrack video2; + timeline::Track video1; + timeline::Track video2; std::vector tracks; timeline::HeaderContainer *headerContainer; diff --git a/src/gui/widgets/timeline/track.cpp b/src/gui/widgets/timeline/track.cpp index 3ae90ff41..a19541476 100644 --- a/src/gui/widgets/timeline/track.cpp +++ b/src/gui/widgets/timeline/track.cpp @@ -27,28 +27,35 @@ namespace gui { namespace widgets { namespace timeline { -Track::Track() - { - - } +Track::Track() : + headerWidget("HeaderTest") +{ + +} + +Gtk::Widget& +Track::get_header_widget() +{ + return headerWidget; +} Glib::ustring Track::get_title() - { - return "Hello"; - } - -/*int +{ + return "Hello"; +} + +int Track::get_height() - { - return get_header_widget().get_allocation().get_height(); - }*/ +{ + return 100; +} void Track::draw_track(Cairo::RefPtr cairo) - { - - } +{ + +} } // namespace timeline } // namespace widgets diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp index 7c338d7bb..168aab390 100644 --- a/src/gui/widgets/timeline/track.hpp +++ b/src/gui/widgets/timeline/track.hpp @@ -40,13 +40,14 @@ class Track Glib::ustring get_title(); - virtual Gtk::Widget& get_header_widget() = 0; + Gtk::Widget& get_header_widget(); - virtual int get_height() = 0; + int get_height(); - virtual void draw_track(Cairo::RefPtr cairo); + void draw_track(Cairo::RefPtr cairo); protected: + Gtk::Label headerWidget; }; diff --git a/src/gui/widgets/timeline/video-track.cpp b/src/gui/widgets/timeline/video-track.cpp deleted file mode 100644 index 4242f0e3f..000000000 --- a/src/gui/widgets/timeline/video-track.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - video-track.cpp - Implementation of the timeline video track object - - Copyright (C) Lumiera.org - 2008, Joel Holdsworth - - 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 "video-track.hpp" - -using namespace Gtk; - -namespace lumiera { -namespace gui { -namespace widgets { -namespace timeline { - -VideoTrack::VideoTrack() : - headerWidget("HeaderTest") - { - - } - -Gtk::Widget& -VideoTrack::get_header_widget() - { - return headerWidget; - } - -int -VideoTrack::get_height() - { - return 100; - } - -void -VideoTrack::draw_track(Cairo::RefPtr cairo) - { - - } - -} // namespace timeline -} // namespace widgets -} // namespace gui -} // namespace lumiera - diff --git a/src/gui/widgets/timeline/video-track.hpp b/src/gui/widgets/timeline/video-track.hpp deleted file mode 100644 index d72b4b1c9..000000000 --- a/src/gui/widgets/timeline/video-track.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - video-track.hpp - Declaration of the timeline video track object - - Copyright (C) Lumiera.org - 2008, Joel Holdsworth - - 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 video-track.hpp - ** This file contains the definition of video track object - */ - -#ifndef VIDEO_TRACK_HPP -#define VIDEO_TRACK_HPP - -#include "track.hpp" - -namespace lumiera { -namespace gui { -namespace widgets { -namespace timeline { - -class VideoTrack : public Track - { - public: - VideoTrack(); - - virtual Gtk::Widget& get_header_widget(); - - virtual int get_height(); - - virtual void draw_track(Cairo::RefPtr cairo); - - protected: - Gtk::Label headerWidget; - Gtk::Frame headerFrame; - }; - -} // namespace timeline -} // namespace widgets -} // namespace gui -} // namespace lumiera - -#endif // VIDEO_TRACK_HPP - From 4907b19cce890df60b5e6358274a23816556eda7 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Sat, 19 Jul 2008 16:35:56 +0100 Subject: [PATCH 02/12] Set the page size of the horizontal timeline scroll bar --- src/gui/widgets/timeline-widget.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 5011103ac..e1956ad93 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -106,6 +106,9 @@ TimelineWidget::set_time_scale(int64_t time_scale) { timeScale = time_scale; ruler.set_time_scale(time_scale); + + const int view_width = body->get_allocation().get_width(); + horizontalAdjustment.set_page_size(timeScale * view_width); } void @@ -186,9 +189,14 @@ TimelineWidget::update_scroll() //----- Horizontal Scroll ------// + // TEST CODE horizontalAdjustment.set_upper(1000 * GAVL_TIME_SCALE / 200); horizontalAdjustment.set_lower(-1000 * GAVL_TIME_SCALE / 200); + // Set the page size + horizontalAdjustment.set_page_size( + timeScale * body_allocation.get_width()); + //----- Vertical Scroll -----// // Calculate the vertical length that can be scrolled: From 9bad04751f48547ba210de851fed7dcc802b1a2a Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 23 Jul 2008 23:23:48 +0100 Subject: [PATCH 03/12] Fixed scroll layout loop bug. --- src/gui/widgets/timeline-widget.cpp | 10 +++++++--- src/gui/widgets/timeline/track.cpp | 4 ++-- src/gui/widgets/timeline/track.hpp | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index e1956ad93..3146824d7 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -58,7 +58,7 @@ TimelineWidget::TimelineWidget() : this, &TimelineWidget::on_scroll) ); body->signal_motion_notify_event().connect( sigc::mem_fun( this, &TimelineWidget::on_motion_in_body_notify_event) ); - + set_time_scale(GAVL_TIME_SCALE / 200); attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); @@ -212,10 +212,14 @@ TimelineWidget::update_scroll() verticalAdjustment.set_upper(y_scroll_length); // Hide the scrollbar if no scrolling is possible - if(y_scroll_length == 0 && verticalScroll.is_visible()) +#if 0 + // Having this code included seems to cause a layout loop as the + // window is shrunk + if(y_scroll_length <= 0 && verticalScroll.is_visible()) verticalScroll.hide(); - else if(y_scroll_length != 0 && !verticalScroll.is_visible()) + else if(y_scroll_length > 0 && !verticalScroll.is_visible()) verticalScroll.show(); +#endif } int diff --git a/src/gui/widgets/timeline/track.cpp b/src/gui/widgets/timeline/track.cpp index a19541476..59d3c7d21 100644 --- a/src/gui/widgets/timeline/track.cpp +++ b/src/gui/widgets/timeline/track.cpp @@ -28,9 +28,9 @@ namespace widgets { namespace timeline { Track::Track() : - headerWidget("HeaderTest") + label("XHeaderTest") { - + headerWidget.pack_start(label); } Gtk::Widget& diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp index 168aab390..3abbf036d 100644 --- a/src/gui/widgets/timeline/track.hpp +++ b/src/gui/widgets/timeline/track.hpp @@ -47,7 +47,8 @@ class Track void draw_track(Cairo::RefPtr cairo); protected: - Gtk::Label headerWidget; + Gtk::VBox headerWidget; + Gtk::Label label; }; From ecf392968beecb370c31bc570a3127732cff9465 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 28 Jul 2008 23:45:20 +0100 Subject: [PATCH 04/12] Implemented new icon workflow --- .../{ => prerendered/16x16}/assets-panel.png | Bin .../16x16}/timeline-panel.png | Bin .../{ => prerendered/16x16}/viewer-panel.png | Bin icons/render-icons.py | 127 +++ icons/svg/arrow.svg | 732 ++++++++++++++++++ icons/svg/i-beam.svg | 690 +++++++++++++++++ src/gui/Makefile.am | 24 +- 7 files changed, 1561 insertions(+), 12 deletions(-) rename icons/{ => prerendered/16x16}/assets-panel.png (100%) rename icons/{ => prerendered/16x16}/timeline-panel.png (100%) rename icons/{ => prerendered/16x16}/viewer-panel.png (100%) create mode 100755 icons/render-icons.py create mode 100644 icons/svg/arrow.svg create mode 100644 icons/svg/i-beam.svg diff --git a/icons/assets-panel.png b/icons/prerendered/16x16/assets-panel.png similarity index 100% rename from icons/assets-panel.png rename to icons/prerendered/16x16/assets-panel.png diff --git a/icons/timeline-panel.png b/icons/prerendered/16x16/timeline-panel.png similarity index 100% rename from icons/timeline-panel.png rename to icons/prerendered/16x16/timeline-panel.png diff --git a/icons/viewer-panel.png b/icons/prerendered/16x16/viewer-panel.png similarity index 100% rename from icons/viewer-panel.png rename to icons/prerendered/16x16/viewer-panel.png diff --git a/icons/render-icons.py b/icons/render-icons.py new file mode 100755 index 000000000..4ebbd3fc4 --- /dev/null +++ b/icons/render-icons.py @@ -0,0 +1,127 @@ +#!/usr/bin/python + +# render-icons.py - Icon rendering utility script +# +# Copyright (C) Lumiera.org +# 2008, Joel Holdsworth +# +# 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. + +from xml.dom import minidom +import os +import shutil + +svgDir = "svg" +prerenderedDir = "prerendered" +inkscapePath = "/usr/bin/inkscape" +artworkLayerPrefix = "artwork:" + +def createDirectory( name ): + if os.path.exists(name) == False: + os.mkdir(name) + +def copyMergeDirectory( src, dst ): + listing = os.listdir(src) + for file_name in listing: + src_file_path = os.path.join(src, file_name) + dst_file_path = os.path.join(dst, file_name) + shutil.copyfile(src_file_path, dst_file_path) + +def getDocumentSize( svg_element ): + width = float(svg_element.getAttribute("width")) + height = float(svg_element.getAttribute("height")) + return [width, height] + +def findChildLayerElement( parent_element ): + for node in parent_element.childNodes: + if node.nodeType == minidom.Node.ELEMENT_NODE: + if node.tagName == "g": + if node.getAttribute("inkscape:groupmode") == "layer": + return node + return None + +def parsePlateLayer( layer ): + rectangles = [] + for node in layer.childNodes: + if node.nodeType == minidom.Node.ELEMENT_NODE: + if node.tagName == "rect": + x = float(node.getAttribute("x")) + y = float(node.getAttribute("y")) + width = float(node.getAttribute("width")) + height = float(node.getAttribute("height")) + rectangles.append([x, y, width, height]) + return rectangles + + +def parseSVG( file_path ): + print "Rendering " + file_path + svgdoc = minidom.parse(file_path) + for root_node in svgdoc.childNodes: + if root_node.nodeType == minidom.Node.ELEMENT_NODE: + if root_node.tagName == "svg": + size = getDocumentSize( root_node ) + layer = findChildLayerElement( root_node ) + if layer != None: + layer_name = layer.getAttribute("inkscape:label") + if layer_name[:len(artworkLayerPrefix)] == artworkLayerPrefix: + artwork_name = layer_name[len(artworkLayerPrefix):] + plate = findChildLayerElement( layer ) + if plate != None: + return artwork_name, size, parsePlateLayer( plate ) + return None + +def renderSVGIcons(): + listing = os.listdir(svgDir) + for file_path in listing: + [root, extension] = os.path.splitext(file_path) + if extension.lower() == ".svg": + file_path = os.path.join(svgDir, file_path) + artwork_name, doc_size, rectangles = parseSVG(file_path) + for rectangle in rectangles: + x1 = rectangle[0] + y1 = doc_size[1] - rectangle[1] - rectangle[3] + x2 = x1 + rectangle[2] + y2 = y1 + rectangle[3] + os.spawnlp(os.P_WAIT, inkscapePath, inkscapePath, + file_path, + "-z", + "-a %g:%g:%g:%g" % (x1, y1, x2, y2), + "-w %g" % (rectangle[2]), "-h %g" % (rectangle[3]), + "--export-png=%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name)) + +def copyPrerenderedIcons(): + listing = os.listdir(prerenderedDir) + for list_item in listing: + src_dir = os.path.join(prerenderedDir, list_item) + copyMergeDirectory(src_dir, list_item) + +def main(): + + # Create the icons folders + createDirectory("48x48") + createDirectory("32x32") + createDirectory("24x24") + createDirectory("22x22") + createDirectory("16x16") + + # Render the SVG icons + renderSVGIcons() + + # Copy in prerendered icons + copyPrerenderedIcons() + +if __name__=="__main__": + main() + diff --git a/icons/svg/arrow.svg b/icons/svg/arrow.svg new file mode 100644 index 000000000..2434fad9d --- /dev/null +++ b/icons/svg/arrow.svg @@ -0,0 +1,732 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/svg/i-beam.svg b/icons/svg/i-beam.svg new file mode 100644 index 000000000..2f4e82f27 --- /dev/null +++ b/icons/svg/i-beam.svg @@ -0,0 +1,690 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 14cdc33c2..53f7c8452 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -75,19 +75,19 @@ lumigui_LDFLAGS = lumigui_LDADD = $(GTK_LUMIERA_LIBS) liblumicommon.a liblumi.a lumigui_DEPENDENCIES = \ - $(top_builddir)/lumiera_ui.rc \ - $(top_builddir)/assets-panel.png \ - $(top_builddir)/timeline-panel.png \ - $(top_builddir)/viewer-panel.png + $(top_builddir)/lumiera_ui.rc +# $(top_builddir)/assets-panel.png \ +# $(top_builddir)/timeline-panel.png \ +# $(top_builddir)/viewer-panel.png -$(top_builddir)/lumiera_ui.rc: - cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) +#$(top_builddir)/lumiera_ui.rc: +# cp $(lumigui_srcdir)/lumiera_ui.rc $(top_builddir) -$(top_builddir)/assets-panel.png: - cp $(top_srcdir)/icons/assets-panel.png $(top_builddir) -$(top_builddir)/timeline-panel.png: - cp $(top_srcdir)/icons/timeline-panel.png $(top_builddir) -$(top_builddir)/viewer-panel.png: - cp $(top_srcdir)/icons/viewer-panel.png $(top_builddir) +#$(top_builddir)/assets-panel.png: +# cp $(top_srcdir)/icons/assets-panel.png $(top_builddir) +#$(top_builddir)/timeline-panel.png: +# cp $(top_srcdir)/icons/timeline-panel.png $(top_builddir) +#$(top_builddir)/viewer-panel.png: +# cp $(top_srcdir)/icons/viewer-panel.png $(top_builddir) From 17d0883d09eb9c90f51d4e5c4fef42a031f6c68c Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Wed, 30 Jul 2008 00:12:37 +0100 Subject: [PATCH 05/12] Added basic support for multiple tools in the timeline view --- src/gui/Makefile.am | 6 ++ src/gui/panels/timeline-panel.cpp | 40 ++++++++++- src/gui/panels/timeline-panel.hpp | 7 ++ src/gui/widgets/timeline-widget.cpp | 71 +++++++++++++++---- src/gui/widgets/timeline-widget.hpp | 7 ++ .../widgets/timeline/timeline-arrow-tool.cpp | 45 ++++++++++++ .../widgets/timeline/timeline-arrow-tool.hpp | 50 +++++++++++++ .../widgets/timeline/timeline-ibeam-tool.cpp | 45 ++++++++++++ .../widgets/timeline/timeline-ibeam-tool.hpp | 51 +++++++++++++ src/gui/widgets/timeline/timeline-tool.cpp | 39 ++++++++++ src/gui/widgets/timeline/timeline-tool.hpp | 58 +++++++++++++++ src/gui/widgets/timeline/track.hpp | 22 +++--- src/gui/workspace/actions.cpp | 60 +++++++++++----- src/gui/workspace/actions.hpp | 11 ++- 14 files changed, 469 insertions(+), 43 deletions(-) create mode 100644 src/gui/widgets/timeline/timeline-arrow-tool.cpp create mode 100644 src/gui/widgets/timeline/timeline-arrow-tool.hpp create mode 100644 src/gui/widgets/timeline/timeline-ibeam-tool.cpp create mode 100644 src/gui/widgets/timeline/timeline-ibeam-tool.hpp create mode 100644 src/gui/widgets/timeline/timeline-tool.cpp create mode 100644 src/gui/widgets/timeline/timeline-tool.hpp diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 53f7c8452..e463100d4 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -62,6 +62,12 @@ lumigui_SOURCES = \ $(lumigui_srcdir)/widgets/timeline/timeline-body.hpp \ $(lumigui_srcdir)/widgets/timeline/timeline-ruler.cpp \ $(lumigui_srcdir)/widgets/timeline/timeline-ruler.hpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-tool.cpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-tool.hpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-arrow-tool.cpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-arrow-tool.hpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-ibeam-tool.cpp \ + $(lumigui_srcdir)/widgets/timeline/timeline-ibeam-tool.hpp \ $(lumigui_srcdir)/model/project.cpp \ $(lumigui_srcdir)/model/project.hpp \ $(lumigui_srcdir)/output/displayer.cpp \ diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index 3b6bfed84..ea46da0a0 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -25,6 +25,7 @@ using namespace Gtk; using namespace sigc; +using namespace lumiera::gui::widgets; namespace lumiera { namespace gui { @@ -34,23 +35,44 @@ const int TimelinePanel::ZoomToolSteps = 2; // 2 seems comfortable TimelinePanel::TimelinePanel() : Panel("timeline", _("Timeline"), "timeline_panel"), + arrowTool(Gtk::StockID("arrow")), + iBeamTool(Gtk::StockID("i_beam")), zoomIn(Stock::ZOOM_IN), zoomOut(Stock::ZOOM_OUT) { // Setup the toolbar + toolbar.append(arrowTool, mem_fun(this, + &TimelinePanel::on_arrow_tool)); + toolbar.append(iBeamTool, mem_fun(this, + &TimelinePanel::on_ibeam_tool)); toolbar.append(zoomIn, mem_fun(this, &TimelinePanel::on_zoom_in)); toolbar.append(zoomOut, mem_fun(this, &TimelinePanel::on_zoom_out)); - toolbar.set_icon_size(IconSize(ICON_SIZE_SMALL_TOOLBAR)); + 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); + update_tool_buttons(); update_zoom_buttons(); } +void +TimelinePanel::on_arrow_tool() +{ + timelineWidget.set_tool(timeline::Arrow); + update_tool_buttons(); +} + +void +TimelinePanel::on_ibeam_tool() +{ + timelineWidget.set_tool(timeline::IBeam); + update_tool_buttons(); +} + void TimelinePanel::on_zoom_in() { @@ -65,6 +87,22 @@ TimelinePanel::on_zoom_out() update_zoom_buttons(); } +void +TimelinePanel::update_tool_buttons() +{ + // This is included to prevent recursion + static bool updating = false; + + if(!updating) + { + updating = true; + const timeline::ToolType tool = timelineWidget.get_tool(); + arrowTool.set_active(tool == timeline::Arrow); + iBeamTool.set_active(tool == timeline::IBeam); + updating = false; + } +} + void TimelinePanel::update_zoom_buttons() { diff --git a/src/gui/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp index a14288c41..06e71ff71 100644 --- a/src/gui/panels/timeline-panel.hpp +++ b/src/gui/panels/timeline-panel.hpp @@ -42,10 +42,14 @@ public: private: //----- Event Handlers -----// + void on_arrow_tool(); + void on_ibeam_tool(); + void on_zoom_in(); void on_zoom_out(); private: + void update_tool_buttons(); void update_zoom_buttons(); private: @@ -57,6 +61,9 @@ private: TimelineWidget timelineWidget; // Toolbar Widgets + Gtk::ToggleToolButton arrowTool; + Gtk::ToggleToolButton iBeamTool; + Gtk::ToolButton zoomIn; Gtk::ToolButton zoomOut; diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 3146824d7..a56c29672 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -21,6 +21,8 @@ * *****************************************************/ #include "timeline-widget.hpp" +#include "timeline/timeline-arrow-tool.hpp" +#include "timeline/timeline-ibeam-tool.hpp" #include @@ -45,7 +47,8 @@ TimelineWidget::TimelineWidget() : horizontalAdjustment(0, 0, 0), verticalAdjustment(0, 0, 0), horizontalScroll(horizontalAdjustment), - verticalScroll(verticalAdjustment) + verticalScroll(verticalAdjustment), + tool(NULL) { body = new TimelineBody(this); ENSURE(body != NULL); @@ -71,14 +74,23 @@ TimelineWidget::TimelineWidget() : tracks.push_back(&video2); update_tracks(); + + set_tool(timeline::Arrow); } TimelineWidget::~TimelineWidget() { REQUIRE(body != NULL); - body->unreference(); + if(body != NULL) + body->unreference(); + REQUIRE(headerContainer != NULL); - headerContainer->unreference(); + if(headerContainer != NULL) + headerContainer->unreference(); + + REQUIRE(tool != NULL); + if(tool != NULL) + delete tool; } gavl_time_t @@ -111,15 +123,6 @@ TimelineWidget::set_time_scale(int64_t time_scale) horizontalAdjustment.set_page_size(timeScale * view_width); } -void -TimelineWidget::shift_view(int shift_size) -{ - const int view_width = body->get_allocation().get_width(); - - set_time_offset(get_time_offset() + - shift_size * timeScale * view_width / 16); -} - void TimelineWidget::zoom_view(int zoom_size) { @@ -151,6 +154,50 @@ TimelineWidget::zoom_view(int point, int zoom_size) set_time_scale(new_time_scale); } +void +TimelineWidget::shift_view(int shift_size) +{ + const int view_width = body->get_allocation().get_width(); + + set_time_offset(get_time_offset() + + shift_size * timeScale * view_width / 16); +} + +ToolType +TimelineWidget::get_tool() const +{ + REQUIRE(tool != NULL); + if(tool != NULL) + return tool->get_type(); + return None; +} + +void +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; + } + + // Create the new tool + switch(tool_type) + { + case timeline::Arrow: + tool = new timeline::ArrowTool(); + break; + + case timeline::IBeam: + tool = new timeline::IBeamTool(); + break; + } +} + void TimelineWidget::on_scroll() { diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index c179a4d59..cc49f7897 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -30,6 +30,7 @@ #include "timeline/header-container.hpp" #include "timeline/timeline-body.hpp" #include "timeline/timeline-ruler.hpp" +#include "timeline/timeline-tool.hpp" #include "timeline/track.hpp" namespace lumiera { @@ -95,6 +96,10 @@ public: **/ void shift_view(int shift_size); + timeline::ToolType get_tool() const; + + void set_tool(timeline::ToolType tool_type); + /* ===== Events ===== */ protected: void on_scroll(); @@ -130,6 +135,8 @@ protected: Gtk::HScrollbar horizontalScroll; Gtk::VScrollbar verticalScroll; + timeline::Tool *tool; + /* ===== Constants ===== */ public: static const int64_t MaxScale; diff --git a/src/gui/widgets/timeline/timeline-arrow-tool.cpp b/src/gui/widgets/timeline/timeline-arrow-tool.cpp new file mode 100644 index 000000000..28c63e1ee --- /dev/null +++ b/src/gui/widgets/timeline/timeline-arrow-tool.cpp @@ -0,0 +1,45 @@ +/* + timeline-arrow-tool.cpp - Implementation of the ArrowTool class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + 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 "timeline-arrow-tool.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +ArrowTool::ArrowTool() +{ + +} + +ToolType +ArrowTool::get_type() const +{ + return Arrow; +} + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/src/gui/widgets/timeline/timeline-arrow-tool.hpp b/src/gui/widgets/timeline/timeline-arrow-tool.hpp new file mode 100644 index 000000000..edf287767 --- /dev/null +++ b/src/gui/widgets/timeline/timeline-arrow-tool.hpp @@ -0,0 +1,50 @@ +/* + timeline-arrow-tool.hpp - Declaration of the ArrowTool class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + 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-arrow-tool.hpp + ** This file contains the definition of the arrow tool class + */ + +#ifndef TIMELINE_ARROW_TOOL_HPP +#define TIMELINE_ARROW_TOOL_HPP + +#include +#include "timeline-tool.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +class ArrowTool : public Tool +{ +public: + ArrowTool(); + + ToolType get_type() const; +}; + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // TIMELINE_ARROW_TOOL_HPP diff --git a/src/gui/widgets/timeline/timeline-ibeam-tool.cpp b/src/gui/widgets/timeline/timeline-ibeam-tool.cpp new file mode 100644 index 000000000..f6c9bf0cc --- /dev/null +++ b/src/gui/widgets/timeline/timeline-ibeam-tool.cpp @@ -0,0 +1,45 @@ +/* + timeline-ibeam-tool.cpp - Implementation of the IBeamTool class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + 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 "timeline-ibeam-tool.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +IBeamTool::IBeamTool() +{ + +} + +ToolType +IBeamTool::get_type() const +{ + return IBeam; +} + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/src/gui/widgets/timeline/timeline-ibeam-tool.hpp b/src/gui/widgets/timeline/timeline-ibeam-tool.hpp new file mode 100644 index 000000000..848c75b60 --- /dev/null +++ b/src/gui/widgets/timeline/timeline-ibeam-tool.hpp @@ -0,0 +1,51 @@ +/* + timeline-ibeam-tool.hpp - Declaration of the ArrowTool class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + 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-ibeam-tool.hpp + ** This file contains the definition of ibeam tool class + ** tool objects + */ + +#ifndef TIMELINE_IBEAM_TOOL_HPP +#define TIMELINE_IBEAM_TOOL_HPP + +#include +#include "timeline-tool.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +class IBeamTool : public Tool +{ +public: + IBeamTool(); + + ToolType get_type() const; +}; + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // TIMELINE_IBEAM_TOOL_HPP diff --git a/src/gui/widgets/timeline/timeline-tool.cpp b/src/gui/widgets/timeline/timeline-tool.cpp new file mode 100644 index 000000000..e1b8f5c0f --- /dev/null +++ b/src/gui/widgets/timeline/timeline-tool.cpp @@ -0,0 +1,39 @@ +/* + timeline-tool.hpp - Implementation of the Tool class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + 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 "timeline-tool.hpp" + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +Tool::Tool() +{ + +} + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + diff --git a/src/gui/widgets/timeline/timeline-tool.hpp b/src/gui/widgets/timeline/timeline-tool.hpp new file mode 100644 index 000000000..1007aace6 --- /dev/null +++ b/src/gui/widgets/timeline/timeline-tool.hpp @@ -0,0 +1,58 @@ +/* + timeline-tool.hpp - Declaration of the Tool class + + Copyright (C) Lumiera.org + 2008, Joel Holdsworth + + 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-tool.hpp + ** This file contains the definition of base class for timeline + ** tool objects + */ + +#ifndef TIMELINE_TOOL_HPP +#define TIMELINE_TOOL_HPP + +#include + +namespace lumiera { +namespace gui { +namespace widgets { +namespace timeline { + +enum ToolType +{ + None, + Arrow, + IBeam +}; + +class Tool +{ +public: + Tool(); + + virtual ToolType get_type() const = 0; +}; + + +} // namespace timeline +} // namespace widgets +} // namespace gui +} // namespace lumiera + +#endif // TIMELINE_TOOL_HPP diff --git a/src/gui/widgets/timeline/track.hpp b/src/gui/widgets/timeline/track.hpp index 3abbf036d..b5f193019 100644 --- a/src/gui/widgets/timeline/track.hpp +++ b/src/gui/widgets/timeline/track.hpp @@ -34,22 +34,22 @@ namespace widgets { namespace timeline { class Track - { - public: - Track(); +{ +public: + Track(); - Glib::ustring get_title(); + Glib::ustring get_title(); - Gtk::Widget& get_header_widget(); + Gtk::Widget& get_header_widget(); - int get_height(); + int get_height(); - void draw_track(Cairo::RefPtr cairo); + void draw_track(Cairo::RefPtr cairo); - protected: - Gtk::VBox headerWidget; - Gtk::Label label; - }; +protected: + Gtk::VBox headerWidget; + Gtk::Label label; +}; } // namespace timeline diff --git a/src/gui/workspace/actions.cpp b/src/gui/workspace/actions.cpp index deade71fa..64bc6bb07 100644 --- a/src/gui/workspace/actions.cpp +++ b/src/gui/workspace/actions.cpp @@ -95,37 +95,65 @@ void Actions::register_stock_items() { RefPtr factory = IconFactory::create(); - add_stock_item(factory, "assets-panel.png", "assets_panel", _("_Assets")); - add_stock_item(factory, "timeline-panel.png", "timeline_panel", _("_Timeline")); - add_stock_item(factory, "viewer-panel.png", "viewer_panel", _("_Viewer")); + + add_stock_item_set(factory, "assets-panel.png", "assets_panel", _("_Assets")); + add_stock_item_set(factory, "timeline-panel.png", "timeline_panel", _("_Timeline")); + add_stock_item_set(factory, "viewer-panel.png", "viewer_panel", _("_Viewer")); + + add_stock_item_set(factory, "arrow.png", "arrow", _("_Arrow")); + add_stock_item_set(factory, "i-beam.png", "i_beam", _("_I-Beam")); + factory->add_default(); //Add factory to list of factories. } -void -Actions::add_stock_item(const Glib::RefPtr& factory, - const Glib::ustring& filepath, - const Glib::ustring& id, const Glib::ustring& label) +bool +Actions::add_stock_item_set(const Glib::RefPtr& factory, + const Glib::ustring& filename, + const Glib::ustring& id, + const Glib::ustring& label) +{ + Gtk::IconSet icon_set; + + add_stock_icon_source(icon_set, 16, filename); + add_stock_icon_source(icon_set, 22, filename); + add_stock_icon_source(icon_set, 24, filename); + add_stock_icon_source(icon_set, 32, filename); + add_stock_icon_source(icon_set, 48, filename); + + if(!icon_set.get_sizes().empty()) + { + const Gtk::StockID stock_id(id); + factory->add(stock_id, icon_set); + Gtk::Stock::add(Gtk::StockItem(stock_id, label)); + return true; + } + + return false; +} + +bool +Actions::add_stock_icon_source(Gtk::IconSet &icon_set, + int size, const Glib::ustring& filename) { Gtk::IconSource source; + try { //This throws an exception if the file is not found: - source.set_pixbuf( Gdk::Pixbuf::create_from_file(filepath) ); + source.set_pixbuf( Gdk::Pixbuf::create_from_file( + Glib::ustring::compose("icons/%1x%1/%2", size, filename) ) ); } catch(const Glib::Exception& ex) { - g_message(ex.what().c_str()); + return false; } - source.set_size(Gtk::ICON_SIZE_SMALL_TOOLBAR); - source.set_size_wildcarded(); //Icon may be scaled. + source.set_size(IconSize(size)); + //source.set_size_wildcarded(); // Icon may be scaled. - Gtk::IconSet icon_set; - icon_set.add_source(source); //More than one source per set is allowed. + icon_set.add_source(source); - const Gtk::StockID stock_id(id); - factory->add(stock_id, icon_set); - Gtk::Stock::add(Gtk::StockItem(stock_id, label)); + return true; } void diff --git a/src/gui/workspace/actions.hpp b/src/gui/workspace/actions.hpp index 235ae29ef..c3b21c384 100644 --- a/src/gui/workspace/actions.hpp +++ b/src/gui/workspace/actions.hpp @@ -53,9 +53,14 @@ class WorkspaceWindow; * labels associated with IDs */ static void register_stock_items(); - static void add_stock_item(const Glib::RefPtr& factory, - const Glib::ustring& filepath, - const Glib::ustring& id, const Glib::ustring& label); + static bool add_stock_item_set( + const Glib::RefPtr& factory, + const Glib::ustring& filename, + const Glib::ustring& id, + const Glib::ustring& label); + + static bool add_stock_icon_source(Gtk::IconSet &icon_set, + int size, const Glib::ustring& filename); /** * Updates the state of the menu/toolbar actions From 04320ae794132665cb26b401f05d9a084d38bd34 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 4 Aug 2008 12:06:24 +0100 Subject: [PATCH 06/12] Added code to render icons as part of the build process --- Makefile.am | 4 + icons/render-icons.py => admin/render-icon.py | 122 ++++++++++++------ icons/Makefile.am | 53 ++++++++ icons/svg/i-beam.svg | 16 +-- src/gui/Makefile.am | 17 +-- 5 files changed, 153 insertions(+), 59 deletions(-) rename icons/render-icons.py => admin/render-icon.py (53%) create mode 100644 icons/Makefile.am diff --git a/Makefile.am b/Makefile.am index 379d36803..3cf851c55 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ # Copyright (C) Lumiera.org # 2007, Christian Thaeter +# 2008, Joel Holdsworth # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -44,6 +45,9 @@ include $(top_srcdir)/src/gui/Makefile.am # plugins #include $(top_srcdir)/src... +# resources +include $(top_srcdir)/icons/Makefile.am + # tests include $(top_srcdir)/tests/common/Makefile.am include $(top_srcdir)/tests/components/Makefile.am diff --git a/icons/render-icons.py b/admin/render-icon.py similarity index 53% rename from icons/render-icons.py rename to admin/render-icon.py index 4ebbd3fc4..9bf4c7dc5 100755 --- a/icons/render-icons.py +++ b/admin/render-icon.py @@ -19,12 +19,16 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +import sys +import getopt from xml.dom import minidom import os import shutil +import cairo +import rsvg -svgDir = "svg" -prerenderedDir = "prerendered" +#svgDir = "svg" +#prerenderedDir = "prerendered" inkscapePath = "/usr/bin/inkscape" artworkLayerPrefix = "artwork:" @@ -63,7 +67,6 @@ def parsePlateLayer( layer ): height = float(node.getAttribute("height")) rectangles.append([x, y, width, height]) return rectangles - def parseSVG( file_path ): print "Rendering " + file_path @@ -82,46 +85,91 @@ def parseSVG( file_path ): return artwork_name, size, parsePlateLayer( plate ) return None -def renderSVGIcons(): - listing = os.listdir(svgDir) - for file_path in listing: - [root, extension] = os.path.splitext(file_path) - if extension.lower() == ".svg": - file_path = os.path.join(svgDir, file_path) - artwork_name, doc_size, rectangles = parseSVG(file_path) - for rectangle in rectangles: - x1 = rectangle[0] - y1 = doc_size[1] - rectangle[1] - rectangle[3] - x2 = x1 + rectangle[2] - y2 = y1 + rectangle[3] - os.spawnlp(os.P_WAIT, inkscapePath, inkscapePath, - file_path, - "-z", - "-a %g:%g:%g:%g" % (x1, y1, x2, y2), - "-w %g" % (rectangle[2]), "-h %g" % (rectangle[3]), - "--export-png=%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name)) +def renderSvgInkscape(file_path, out_dir, artwork_name, rectangle, doc_size): -def copyPrerenderedIcons(): - listing = os.listdir(prerenderedDir) - for list_item in listing: - src_dir = os.path.join(prerenderedDir, list_item) - copyMergeDirectory(src_dir, list_item) + # Calculate the rendering rectangle + x1 = rectangle[0] + y1 = doc_size[1] - rectangle[1] - rectangle[3] + x2 = x1 + rectangle[2] + y2 = y1 + rectangle[3] + + # Call Inkscape to do the render + os.spawnlp(os.P_WAIT, inkscapePath, inkscapePath, + file_path, + "-z", + "-a %g:%g:%g:%g" % (x1, y1, x2, y2), + "-w %g" % (rectangle[2]), "-h %g" % (rectangle[3]), + "--export-png=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name))) + +def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size): + # Prepare a Cairo context + width = int(rectangle[2]) + height = int(rectangle[3]) + + surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) + context = cairo.Context(surface) + context.translate(-rectangle[0], -rectangle[1]) -def main(): + # Load an render the SVG + svg = rsvg.Handle(file=file_path) + svg.render_cairo(context) + + # Output a PNG file + surface.write_to_png(os.path.join(out_dir, + "%ix%i/%s.png" % (width, height, artwork_name))) + +def renderSvgIcon(file_path, out_dir): + artwork_name, doc_size, rectangles = parseSVG(file_path) + for rectangle in rectangles: + renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size) + +#def renderSvgIcons(): +# listing = os.listdir(svgDir) +# for file_path in listing: +# [root, extension] = os.path.splitext(file_path) +# if extension.lower() == ".svg": +# renderSvgIcon(os.path.join(svgDir, file_path)) + +#def copyPrerenderedIcons(): +# listing = os.listdir(prerenderedDir) +# for list_item in listing: +# src_dir = os.path.join(prerenderedDir, list_item) +# copyMergeDirectory(src_dir, list_item) + +def printHelp(): + print "render-icon.py - An icon rendering utility script for lumiera" + +def parseArguments(argv): + optlist, args = getopt.getopt(argv, "") + + if len(args) == 2: + return args[0], args[1] + + printHelp() + return None, None + +def main(argv): + in_path, out_dir = parseArguments(argv) + + if in_path == None or out_dir == None: + return + + if os.path.exists(out_dir) == False: + print "Directory not found: " + out_dir + return # Create the icons folders - createDirectory("48x48") - createDirectory("32x32") - createDirectory("24x24") - createDirectory("22x22") - createDirectory("16x16") - - # Render the SVG icons - renderSVGIcons() + createDirectory(os.path.join(out_dir, "48x48")) + createDirectory(os.path.join(out_dir, "32x32")) + createDirectory(os.path.join(out_dir, "24x24")) + createDirectory(os.path.join(out_dir, "22x22")) + createDirectory(os.path.join(out_dir, "16x16")) + renderSvgIcon(in_path, out_dir) + # Copy in prerendered icons - copyPrerenderedIcons() + #copyPrerenderedIcons() if __name__=="__main__": - main() + main(sys.argv[1:]) diff --git a/icons/Makefile.am b/icons/Makefile.am new file mode 100644 index 000000000..d3adca1fa --- /dev/null +++ b/icons/Makefile.am @@ -0,0 +1,53 @@ +# Copyright (C) Lumiera.org +# 2008, Joel Holdsworth +# +# 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. + +svgdir = $(top_srcdir)/icons/svg +prerendereddir = $(top_srcdir)/icons/prerendered +icondir = $(top_builddir) +iconcommand = python $(top_srcdir)/admin/render-icon.py + +16x16 = $(icondir)/16x16 +22x22 = $(icondir)/22x22 +24x24 = $(icondir)/24x24 +32x32 = $(icondir)/32x32 +48x48 = $(icondir)/48x48 + +16x16pre = $(prerendereddir)/16x16 +22x22pre = $(prerendereddir)/22x22 +24x24pre = $(prerendereddir)/24x24 +32x32pre = $(prerendereddir)/32x32 +48x48pre = $(prerendereddir)/48x48 + +lumigui_DEPENDENCIES += \ + $(16x16)/arrow.png $(22x22)/arrow.png $(24x24)/arrow.png $(32x32)/arrow.png $(48x48)/arrow.png \ + $(16x16)/i-beam.png $(22x22)/i-beam.png $(24x24)/i-beam.png $(32x32)/i-beam.png $(48x48)/i-beam.png \ + $(16x16)/assets-panel.png \ + $(16x16)/timeline-panel.png \ + $(16x16)/viewer-panel.png + +$(16x16)/arrow.png $(22x22)/arrow.png $(24x24)/arrow.png $(32x32)/arrow.png $(48x48)/arrow.png : $(svgdir)/arrow.svg + $(iconcommand) $< $(icondir) +$(16x16)/i-beam.png $(22x22)/i-beam.png $(24x24)/i-beam.png $(32x32)/i-beam.png $(48x48)/i-beam.png : $(svgdir)/i-beam.svg + $(iconcommand) $< $(icondir) + +$(16x16)/assets-panel.png: + cp $(16x16pre)/assets-panel.png $(16x16) +$(16x16)/timeline-panel.png: + cp $(16x16pre)/timeline-panel.png $(16x16) +$(16x16)/viewer-panel.png: + cp $(16x16pre)/viewer-panel.png $(16x16) + diff --git a/icons/svg/i-beam.svg b/icons/svg/i-beam.svg index 2f4e82f27..250f087c0 100644 --- a/icons/svg/i-beam.svg +++ b/icons/svg/i-beam.svg @@ -554,9 +554,9 @@ objecttolerance="10" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="5.6568543" - inkscape:cx="79.400744" - inkscape:cy="54.133354" + inkscape:zoom="32" + inkscape:cx="135.70823" + inkscape:cy="18.300078" inkscape:document-units="px" inkscape:current-layer="layer4" showgrid="true" @@ -565,9 +565,9 @@ inkscape:snap-global="true" showguides="true" inkscape:guide-bbox="true" - inkscape:window-width="1679" - inkscape:window-height="977" - inkscape:window-x="1281" + inkscape:window-width="1670" + inkscape:window-height="973" + inkscape:window-x="1285" inkscape:window-y="48"> Date: Mon, 4 Aug 2008 12:15:42 +0100 Subject: [PATCH 07/12] Temporarily bodged the icon source directory --- src/gui/workspace/actions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/workspace/actions.cpp b/src/gui/workspace/actions.cpp index 64bc6bb07..f3ebcd450 100644 --- a/src/gui/workspace/actions.cpp +++ b/src/gui/workspace/actions.cpp @@ -141,7 +141,7 @@ Actions::add_stock_icon_source(Gtk::IconSet &icon_set, { //This throws an exception if the file is not found: source.set_pixbuf( Gdk::Pixbuf::create_from_file( - Glib::ustring::compose("icons/%1x%1/%2", size, filename) ) ); + Glib::ustring::compose("%1x%1/%2", size, filename) ) ); } catch(const Glib::Exception& ex) { From fdab62a5d8c9045cb4c884fe4b5dc6fdd9347c87 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 4 Aug 2008 12:20:13 +0100 Subject: [PATCH 08/12] Added a separator between tool groups --- src/gui/panels/timeline-panel.cpp | 1 + src/gui/panels/timeline-panel.hpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/gui/panels/timeline-panel.cpp b/src/gui/panels/timeline-panel.cpp index ea46da0a0..905a7b035 100644 --- a/src/gui/panels/timeline-panel.cpp +++ b/src/gui/panels/timeline-panel.cpp @@ -45,6 +45,7 @@ TimelinePanel::TimelinePanel() : &TimelinePanel::on_arrow_tool)); toolbar.append(iBeamTool, mem_fun(this, &TimelinePanel::on_ibeam_tool)); + toolbar.append(seperator1); toolbar.append(zoomIn, mem_fun(this, &TimelinePanel::on_zoom_in)); toolbar.append(zoomOut, mem_fun(this, &TimelinePanel::on_zoom_out)); diff --git a/src/gui/panels/timeline-panel.hpp b/src/gui/panels/timeline-panel.hpp index 06e71ff71..dc228403c 100644 --- a/src/gui/panels/timeline-panel.hpp +++ b/src/gui/panels/timeline-panel.hpp @@ -64,6 +64,8 @@ private: Gtk::ToggleToolButton arrowTool; Gtk::ToggleToolButton iBeamTool; + Gtk::SeparatorToolItem seperator1; + Gtk::ToolButton zoomIn; Gtk::ToolButton zoomOut; From 2ee6f6be62cfc6858e24bef8cc2df4cb4a2e9cda Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 4 Aug 2008 16:39:36 +0100 Subject: [PATCH 09/12] 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 From 45ca590c38535e044de2bfb3ca6814a6152fd07c Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Mon, 4 Aug 2008 16:40:38 +0100 Subject: [PATCH 10/12] Reinstated a small efficiency --- src/gui/widgets/timeline-widget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index 6b9d83be2..faea874ff 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -179,8 +179,8 @@ TimelineWidget::set_tool(ToolType tool_type) if(tool != NULL) { // Do we need to change tools? - //if(tool->get_type() == tool_type) - // return; + if(tool->get_type() == tool_type) + return; delete tool; } From 2082f0843b8091e9218e4209010f319d76e02a87 Mon Sep 17 00:00:00 2001 From: Joel Holdsworth Date: Thu, 7 Aug 2008 20:27:41 +0100 Subject: [PATCH 11/12] Initial implementation of I-Beam tool. Needs more work --- src/gui/widgets/timeline-widget.cpp | 108 ++++++++++------- src/gui/widgets/timeline-widget.hpp | 31 ++++- .../widgets/timeline/timeline-arrow-tool.cpp | 22 +++- .../widgets/timeline/timeline-arrow-tool.hpp | 7 +- src/gui/widgets/timeline/timeline-body.cpp | 112 +++++++++++++++++- src/gui/widgets/timeline/timeline-body.hpp | 18 ++- .../widgets/timeline/timeline-ibeam-tool.cpp | 54 ++++++++- .../widgets/timeline/timeline-ibeam-tool.hpp | 14 ++- src/gui/widgets/timeline/timeline-ruler.cpp | 106 +++++++++++------ src/gui/widgets/timeline/timeline-ruler.hpp | 35 +++--- src/gui/widgets/timeline/timeline-tool.cpp | 35 ++++-- src/gui/widgets/timeline/timeline-tool.hpp | 19 +-- 12 files changed, 428 insertions(+), 133 deletions(-) diff --git a/src/gui/widgets/timeline-widget.cpp b/src/gui/widgets/timeline-widget.cpp index faea874ff..867595ad3 100644 --- a/src/gui/widgets/timeline-widget.cpp +++ b/src/gui/widgets/timeline-widget.cpp @@ -21,8 +21,6 @@ * *****************************************************/ #include "timeline-widget.hpp" -#include "timeline/timeline-arrow-tool.hpp" -#include "timeline/timeline-ibeam-tool.hpp" #include @@ -46,14 +44,17 @@ TimelineWidget::TimelineWidget() : totalHeight(0), horizontalAdjustment(0, 0, 0), verticalAdjustment(0, 0, 0), + selectionStart(0), + selectionEnd(0), horizontalScroll(horizontalAdjustment), - verticalScroll(verticalAdjustment), - tool(NULL) + verticalScroll(verticalAdjustment) { body = new TimelineBody(this); ENSURE(body != NULL); headerContainer = new HeaderContainer(this); ENSURE(headerContainer != NULL); + ruler = new TimelineRuler(this); + ENSURE(ruler != NULL); horizontalAdjustment.signal_value_changed().connect( sigc::mem_fun( this, &TimelineWidget::on_scroll) ); @@ -63,9 +64,10 @@ TimelineWidget::TimelineWidget() : this, &TimelineWidget::on_motion_in_body_notify_event) ); set_time_scale(GAVL_TIME_SCALE / 200); + set_selection(2000000, 4000000); attach(*body, 1, 2, 1, 2, FILL|EXPAND, FILL|EXPAND); - attach(ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); + attach(*ruler, 1, 2, 0, 1, FILL|EXPAND, SHRINK); attach(*headerContainer, 0, 1, 1, 2, SHRINK, FILL|EXPAND); attach(horizontalScroll, 1, 2, 2, 3, FILL|EXPAND, SHRINK); attach(verticalScroll, 2, 3, 1, 2, SHRINK, FILL|EXPAND); @@ -87,10 +89,10 @@ TimelineWidget::~TimelineWidget() REQUIRE(headerContainer != NULL); if(headerContainer != NULL) headerContainer->unreference(); - - REQUIRE(tool != NULL); - if(tool != NULL) - delete tool; + + REQUIRE(ruler != NULL); + if(ruler != NULL) + ruler->unreference(); } gavl_time_t @@ -102,9 +104,11 @@ TimelineWidget::get_time_offset() const void TimelineWidget::set_time_offset(gavl_time_t time_offset) { + REQUIRE(ruler != NULL); + timeOffset = time_offset; horizontalAdjustment.set_value(time_offset); - ruler.set_time_offset(time_offset); + ruler->update_view(); } int64_t @@ -116,11 +120,14 @@ TimelineWidget::get_time_scale() const void TimelineWidget::set_time_scale(int64_t time_scale) { + REQUIRE(ruler != NULL); + timeScale = time_scale; - ruler.set_time_scale(time_scale); const int view_width = body->get_allocation().get_width(); horizontalAdjustment.set_page_size(timeScale * view_width); + + ruler->update_view(); } void @@ -163,49 +170,56 @@ TimelineWidget::shift_view(int shift_size) shift_size * timeScale * view_width / 16); } +gavl_time_t +TimelineWidget::get_selection_start() const +{ + return selectionStart; +} + +gavl_time_t +TimelineWidget::get_selection_end() const +{ + return selectionEnd; +} + +void +TimelineWidget::set_selection(gavl_time_t start, gavl_time_t end) +{ + if(start < end) + { + selectionStart = start; + selectionEnd = end; + } + else + { + // The selection is back-to-front, flip it round + selectionStart = end; + selectionEnd = start; + } + + ruler->queue_draw(); + body->queue_draw(); +} + ToolType TimelineWidget::get_tool() const { - REQUIRE(tool != NULL); - if(tool != NULL) - return tool->get_type(); - return None; + REQUIRE(body != NULL); + return body->get_tool(); } void 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; - } - - // Create the new tool - switch(tool_type) - { - case timeline::Arrow: - tool = new timeline::ArrowTool(this); - break; - - case timeline::IBeam: - tool = new timeline::IBeamTool(this); - break; - } - - // Apply the cursor if possible - tool->apply_cursor(); + REQUIRE(body != NULL); + body->set_tool(tool_type); } void TimelineWidget::on_scroll() { timeOffset = horizontalAdjustment.get_value(); - ruler.set_time_offset(timeOffset); + ruler->update_view(); } void @@ -216,6 +230,18 @@ TimelineWidget::on_size_allocate(Allocation& allocation) update_scroll(); } +int +TimelineWidget::time_to_x(gavl_time_t time) const +{ + return (int)((time - timeOffset) / timeScale); +} + +gavl_time_t +TimelineWidget::x_to_time(int x) const +{ + return (gavl_time_t)((int64_t)x * timeScale + timeOffset); +} + void TimelineWidget::update_tracks() { @@ -282,7 +308,7 @@ bool TimelineWidget::on_motion_in_body_notify_event(GdkEventMotion *event) { REQUIRE(event != NULL); - ruler.set_mouse_chevron_offset(event->x); + ruler->set_mouse_chevron_offset(event->x); return true; } diff --git a/src/gui/widgets/timeline-widget.hpp b/src/gui/widgets/timeline-widget.hpp index e5e90fe92..ca6be76ec 100644 --- a/src/gui/widgets/timeline-widget.hpp +++ b/src/gui/widgets/timeline-widget.hpp @@ -31,6 +31,8 @@ #include "timeline/timeline-body.hpp" #include "timeline/timeline-ruler.hpp" #include "timeline/timeline-tool.hpp" +#include "timeline/timeline-arrow-tool.hpp" +#include "timeline/timeline-ibeam-tool.hpp" #include "timeline/track.hpp" namespace lumiera { @@ -96,18 +98,30 @@ public: **/ void shift_view(int shift_size); + gavl_time_t get_selection_start() const; + + gavl_time_t get_selection_end() const; + + void set_selection(gavl_time_t start, gavl_time_t end); + timeline::ToolType get_tool() const; void set_tool(timeline::ToolType tool_type); - + /* ===== Events ===== */ protected: void on_scroll(); void on_size_allocate(Gtk::Allocation& allocation); + + /* ===== Utilities ===== */ +protected: + int time_to_x(gavl_time_t time) const; + + gavl_time_t x_to_time(int x) const; /* ===== Internals ===== */ -protected: +private: void update_tracks(); @@ -118,8 +132,14 @@ protected: bool on_motion_in_body_notify_event(GdkEventMotion *event); protected: + + // View State gavl_time_t timeOffset; int64_t timeScale; + + // Selection State + gavl_time_t selectionStart; + gavl_time_t selectionEnd; int totalHeight; @@ -129,13 +149,11 @@ protected: timeline::HeaderContainer *headerContainer; timeline::TimelineBody *body; - timeline::TimelineRuler ruler; + timeline::TimelineRuler *ruler; Gtk::Adjustment horizontalAdjustment, verticalAdjustment; Gtk::HScrollbar horizontalScroll; Gtk::VScrollbar verticalScroll; - - timeline::Tool *tool; /* ===== Constants ===== */ public: @@ -148,7 +166,10 @@ protected: friend class timeline::TimelineBody; friend class timeline::HeaderContainer; + friend class timeline::TimelineRuler; friend class timeline::Tool; + friend class timeline::ArrowTool; + friend class timeline::IBeamTool; }; } // namespace widgets diff --git a/src/gui/widgets/timeline/timeline-arrow-tool.cpp b/src/gui/widgets/timeline/timeline-arrow-tool.cpp index 4e65165f5..109d6190e 100644 --- a/src/gui/widgets/timeline/timeline-arrow-tool.cpp +++ b/src/gui/widgets/timeline/timeline-arrow-tool.cpp @@ -27,8 +27,8 @@ namespace gui { namespace widgets { namespace timeline { -ArrowTool::ArrowTool(TimelineWidget *timeline_widget) : - Tool(timeline_widget) +ArrowTool::ArrowTool(TimelineBody *timeline_body) : + Tool(timeline_body) { } @@ -45,6 +45,24 @@ ArrowTool::get_cursor() const return Gdk::Cursor(Gdk::ARROW); } +void +ArrowTool::on_button_press_event(GdkEventButton* event) +{ + Tool::on_button_press_event(event); +} + +void +ArrowTool::on_button_release_event(GdkEventButton* event) +{ + Tool::on_button_release_event(event); +} + +void +ArrowTool::on_motion_notify_event(GdkEventMotion *event) +{ + Tool::on_motion_notify_event(event); +} + } // 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 05f4ef562..b7bfb6138 100644 --- a/src/gui/widgets/timeline/timeline-arrow-tool.hpp +++ b/src/gui/widgets/timeline/timeline-arrow-tool.hpp @@ -37,12 +37,17 @@ namespace timeline { class ArrowTool : public Tool { public: - ArrowTool(TimelineWidget *timeline_widget); + ArrowTool(TimelineBody *timeline_body); ToolType get_type() const; protected: Gdk::Cursor get_cursor() const; + +protected: + void on_button_press_event(GdkEventButton* event); + void on_button_release_event(GdkEventButton* event); + void on_motion_notify_event(GdkEventMotion *event); }; } // namespace timeline diff --git a/src/gui/widgets/timeline/timeline-body.cpp b/src/gui/widgets/timeline/timeline-body.cpp index 63edb6a1a..50da41348 100644 --- a/src/gui/widgets/timeline/timeline-body.cpp +++ b/src/gui/widgets/timeline/timeline-body.cpp @@ -27,6 +27,9 @@ #include "../timeline-widget.hpp" #include "../../window-manager.hpp" +#include "timeline-arrow-tool.hpp" +#include "timeline-ibeam-tool.hpp" + using namespace Gtk; using namespace std; using namespace lumiera::gui; @@ -38,8 +41,10 @@ namespace gui { namespace widgets { namespace timeline { -TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget) : +TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget + *timeline_widget) : Glib::ObjectBase("TimelineBody"), + tool(NULL), dragType(None), mouseDownX(0), mouseDownY(0), @@ -63,6 +68,51 @@ TimelineBody::TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widge GDK_TYPE_COLOR, G_PARAM_READABLE)); } +TimelineBody::~TimelineBody() +{ + REQUIRE(tool != NULL); + if(tool != NULL) + delete tool; +} + +ToolType +TimelineBody::get_tool() const +{ + REQUIRE(tool != NULL); + if(tool != NULL) + return tool->get_type(); + return lumiera::gui::widgets::timeline::None; +} + +void +TimelineBody::set_tool(timeline::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; + } + + // Create the new tool + switch(tool_type) + { + case timeline::Arrow: + tool = new ArrowTool(this); + break; + + case timeline::IBeam: + tool = new IBeamTool(this); + break; + } + + // Apply the cursor if possible + tool->apply_cursor(); +} + void TimelineBody::on_realize() { @@ -76,7 +126,7 @@ TimelineBody::on_realize() Gdk::BUTTON_RELEASE_MASK); // Apply the cursor if possible - timelineWidget->tool->apply_cursor(); + tool->apply_cursor(); } void @@ -138,7 +188,12 @@ TimelineBody::on_button_press_event(GdkEventButton* event) default: dragType = None; break; - } + } + + // Forward the event to the tool + tool->on_button_press_event(event); + + return true; } bool @@ -146,11 +201,16 @@ TimelineBody::on_button_release_event(GdkEventButton* event) { // Terminate any drags dragType = None; + + // Forward the event to the tool + tool->on_button_release_event(event); + + return true; } bool TimelineBody::on_motion_notify_event(GdkEventMotion *event) -{ +{ REQUIRE(event != NULL); switch(dragType) @@ -168,6 +228,9 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event) } } + // Forward the event to the tool + tool->on_motion_notify_event(event); + // false so that the message is passed up to the owner TimelineWidget return false; } @@ -175,6 +238,8 @@ TimelineBody::on_motion_notify_event(GdkEventMotion *event) bool TimelineBody::on_expose_event(GdkEventExpose* event) { + Cairo::Matrix view_matrix; + REQUIRE(event != NULL); REQUIRE(timelineWidget != NULL); @@ -196,6 +261,7 @@ TimelineBody::on_expose_event(GdkEventExpose* event) // Translate the view by the scroll distance cairo->translate(0, -get_vertical_offset()); + cairo->get_matrix(view_matrix); // Interate drawing each track BOOST_FOREACH( Track* track, timelineWidget->tracks ) @@ -217,8 +283,44 @@ TimelineBody::on_expose_event(GdkEventExpose* event) // Shift for the next track cairo->translate(0, height + TimelineWidget::TrackPadding); - } + } + + //----- Draw the selection -----// + const int start_x = timelineWidget->time_to_x( + timelineWidget->get_selection_start()); + const int end_x = timelineWidget->time_to_x( + timelineWidget->get_selection_end()); + cairo->set_matrix(view_matrix); + + // Draw the cover + if(end_x > 0 && start_x < allocation.get_width()) + { + cairo->set_source_rgba(1.0, 0, 0, 0.5); + cairo->rectangle(start_x + 0.5, 0, + end_x - start_x, allocation.get_height()); + cairo->fill(); + } + + cairo->set_source_rgb(1.0, 0, 0); + cairo->set_line_width(1); + + // Draw the start + if(start_x >= 0 && start_x < allocation.get_width()) + { + cairo->move_to(start_x + 0.5, 0); + cairo->line_to(start_x + 0.5, allocation.get_height()); + cairo->stroke_preserve(); + } + + // Draw the end + if(end_x >= 0 && end_x < allocation.get_width()) + { + cairo->move_to(end_x + 0.5, 0); + cairo->line_to(end_x + 0.5, allocation.get_height()); + cairo->stroke_preserve(); + } + return true; } diff --git a/src/gui/widgets/timeline/timeline-body.hpp b/src/gui/widgets/timeline/timeline-body.hpp index 86ce40a47..cebe4d5e1 100644 --- a/src/gui/widgets/timeline/timeline-body.hpp +++ b/src/gui/widgets/timeline/timeline-body.hpp @@ -27,6 +27,7 @@ #define TIMELINE_BODY_HPP #include "../../gtk-lumiera.hpp" +#include "timeline-tool.hpp" namespace lumiera { namespace gui { @@ -40,6 +41,12 @@ class TimelineBody : public Gtk::DrawingArea { public: TimelineBody(lumiera::gui::widgets::TimelineWidget *timeline_widget); + + ~TimelineBody(); + + ToolType get_tool() const; + + void set_tool(ToolType tool_type); /* ===== Events ===== */ protected: @@ -76,15 +83,20 @@ private: Shift }; - // UI State Data - DragType dragType; + timeline::Tool *tool; double mouseDownX, mouseDownY; + + // Scroll State + DragType dragType; gavl_time_t beginShiftTimeOffset; - int beginShiftVerticalOffset; + int beginShiftVerticalOffset; GdkColor background; lumiera::gui::widgets::TimelineWidget *timelineWidget; + + friend class ArrowTool; + friend class IBeamTool; }; } // namespace timeline diff --git a/src/gui/widgets/timeline/timeline-ibeam-tool.cpp b/src/gui/widgets/timeline/timeline-ibeam-tool.cpp index 8225ced80..1940a04b1 100644 --- a/src/gui/widgets/timeline/timeline-ibeam-tool.cpp +++ b/src/gui/widgets/timeline/timeline-ibeam-tool.cpp @@ -21,14 +21,15 @@ * *****************************************************/ #include "timeline-ibeam-tool.hpp" +#include "../timeline-widget.hpp" namespace lumiera { namespace gui { namespace widgets { namespace timeline { -IBeamTool::IBeamTool(TimelineWidget *timeline_widget) : - Tool(timeline_widget) +IBeamTool::IBeamTool(TimelineBody *timeline_body) : + Tool(timeline_body) { } @@ -44,6 +45,55 @@ IBeamTool::get_cursor() const return Gdk::Cursor(Gdk::XTERM); } +void +IBeamTool::on_button_press_event(GdkEventButton* event) +{ + Tool::on_button_press_event(event); + + REQUIRE(timelineBody != NULL); + lumiera::gui::widgets::TimelineWidget *timeline_widget = + timelineBody->timelineWidget; + REQUIRE(timeline_widget != NULL); + + if(event->button == 1) + { + drag_start_time = timeline_widget->x_to_time(event->x); + timeline_widget->set_selection(drag_start_time, drag_start_time); + } +} + +void +IBeamTool::on_button_release_event(GdkEventButton* event) +{ + Tool::on_button_release_event(event); + + if(event->button == 1) + set_leading_x(event->x); +} + +void +IBeamTool::on_motion_notify_event(GdkEventMotion *event) +{ + Tool::on_motion_notify_event(event); + + if(isDragging) + set_leading_x(event->x); +} + +void IBeamTool::set_leading_x(const int x) +{ + REQUIRE(timelineBody != NULL); + lumiera::gui::widgets::TimelineWidget *timeline_widget = + timelineBody->timelineWidget; + REQUIRE(timeline_widget != NULL); + + const gavl_time_t time = timeline_widget->x_to_time(x); + if(time > drag_start_time) + timeline_widget->set_selection(drag_start_time, time); + else + timeline_widget->set_selection(time, drag_start_time); +} + } // 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 79eb36c8c..fa0021ce1 100644 --- a/src/gui/widgets/timeline/timeline-ibeam-tool.hpp +++ b/src/gui/widgets/timeline/timeline-ibeam-tool.hpp @@ -38,12 +38,24 @@ namespace timeline { class IBeamTool : public Tool { public: - IBeamTool(TimelineWidget *timeline_widget); + IBeamTool(TimelineBody *timeline_body); ToolType get_type() const; protected: Gdk::Cursor get_cursor() const; + +protected: + void on_button_press_event(GdkEventButton* event); + void on_button_release_event(GdkEventButton* event); + void on_motion_notify_event(GdkEventMotion *event); + +private: + void set_leading_x(const int x); + +protected: + //----- Internals -----// + gavl_time_t drag_start_time; }; } // namespace timeline diff --git a/src/gui/widgets/timeline/timeline-ruler.cpp b/src/gui/widgets/timeline/timeline-ruler.cpp index 44cf4e307..0b28472b9 100644 --- a/src/gui/widgets/timeline/timeline-ruler.cpp +++ b/src/gui/widgets/timeline/timeline-ruler.cpp @@ -23,6 +23,7 @@ #include #include "timeline-ruler.hpp" +#include "../timeline-widget.hpp" #include "../../window-manager.hpp" extern "C" { @@ -41,39 +42,24 @@ namespace gui { namespace widgets { namespace timeline { -TimelineRuler::TimelineRuler() : +TimelineRuler::TimelineRuler( + lumiera::gui::widgets::TimelineWidget *timeline_widget) : Glib::ObjectBase("TimelineRuler"), - timeOffset(-1), - timeScale(1), mouseChevronOffset(0), annotationHorzMargin(0), annotationVertMargin(0), majorTickHeight(0), minorLongTickHeight(0), minorShortTickHeight(0), - minDivisionWidth(100) -{ + minDivisionWidth(100), + timelineWidget(timeline_widget) +{ + REQUIRE(timelineWidget != NULL); + // Install style properties register_styles(); } -void -TimelineRuler::set_time_offset(gavl_time_t time_offset) -{ - timeOffset = time_offset; - rulerImage.clear(); - queue_draw(); -} - -void -TimelineRuler::set_time_scale(int64_t time_scale) -{ - REQUIRE(time_scale > 0); - timeScale = time_scale; - rulerImage.clear(); - queue_draw(); -} - void TimelineRuler::set_mouse_chevron_offset(int offset) { @@ -81,6 +67,13 @@ TimelineRuler::set_mouse_chevron_offset(int offset) queue_draw(); } +void +TimelineRuler::update_view() +{ + rulerImage.clear(); + queue_draw(); +} + void TimelineRuler::on_realize() { @@ -132,8 +125,9 @@ TimelineRuler::on_expose_event(GdkEventExpose* event) cairo->set_source(rulerImage, 0, 0); cairo->paint(); - // Draw the mouse chevron + // Draw the overlays draw_mouse_chevron(cairo, allocation); + draw_selection(cairo, allocation); return true; } @@ -168,11 +162,15 @@ TimelineRuler::on_size_allocate(Gtk::Allocation& allocation) void TimelineRuler::draw_ruler(Cairo::RefPtr cairo, - Gdk::Rectangle ruler_rect) + const Gdk::Rectangle ruler_rect) { REQUIRE(cairo); REQUIRE(ruler_rect.get_width() > 0); REQUIRE(ruler_rect.get_height() > 0); + REQUIRE(timelineWidget != NULL); + + const gavl_time_t left_offset = timelineWidget->timeOffset; + const int64_t time_scale = timelineWidget->timeScale; // Preparation steps const int height = ruler_rect.get_height(); @@ -187,7 +185,7 @@ TimelineRuler::draw_ruler(Cairo::RefPtr cairo, cairo->clip(); // Make sure we don't have impossible zoom - if(timeScale <= 0) + if(time_scale <= 0) return; // Render ruler annotations @@ -196,16 +194,16 @@ TimelineRuler::draw_ruler(Cairo::RefPtr cairo, const gavl_time_t major_spacing = calculate_major_spacing(); const gavl_time_t minor_spacing = major_spacing / 10; - int64_t time_offset = timeOffset - timeOffset % major_spacing; - if(timeOffset < 0) + int64_t time_offset = left_offset - left_offset % major_spacing; + if(left_offset < 0) time_offset -= major_spacing; int x = 0; - const int64_t x_offset = timeOffset / timeScale; + const int64_t x_offset = left_offset / time_scale; do { - x = (int)(time_offset / timeScale - x_offset); + x = (int)(time_offset / time_scale - x_offset); cairo->set_line_width(1); @@ -241,7 +239,7 @@ TimelineRuler::draw_ruler(Cairo::RefPtr cairo, void TimelineRuler::draw_mouse_chevron(Cairo::RefPtr cairo, - Gdk::Rectangle ruler_rect) + const Gdk::Rectangle ruler_rect) { REQUIRE(cairo); REQUIRE(ruler_rect.get_width() > 0); @@ -258,19 +256,55 @@ TimelineRuler::draw_mouse_chevron(Cairo::RefPtr cairo, cairo->move_to(mouseChevronOffset + 0.5, ruler_rect.get_height()); - cairo->line_to(mouseChevronOffset + mouseChevronSize + 0.5, - ruler_rect.get_height() - mouseChevronSize); - cairo->line_to(mouseChevronOffset - mouseChevronSize + 0.5, - ruler_rect.get_height() - mouseChevronSize); + cairo->rel_line_to(-mouseChevronSize, -mouseChevronSize); + cairo->rel_line_to(2 * mouseChevronSize, 0); cairo->fill(); } +void +TimelineRuler::draw_selection(Cairo::RefPtr cairo, + const Gdk::Rectangle ruler_rect) +{ + REQUIRE(cairo); + REQUIRE(ruler_rect.get_width() > 0); + REQUIRE(ruler_rect.get_height() > 0); + REQUIRE(timelineWidget != NULL); + + Glib::RefPtr