From 7ee0baa241a9a9cd386ca701039fa5fe332aa400 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 13 Apr 2019 17:55:20 +0200 Subject: [PATCH] Timeline: reorganise widget structure within body pane to accommodate time ruler After thinking the whole concept over several times, it occurred to me that a separate implementation of a time ruler would be quite redundant with the envisioned feature of per-track overview rulers. Following this line of thought, the time ruler would just be some specifically configured overview ruler. This has the somewhat unfortunate consequence, that it becomes the responsibility of the body canvas to render the overview ruler, thereby somehow delegating to a common renderer implementation. Which makes the whole setup of the body canvas way more complex, because now we get *two* canvas like painting areas, one always visible at top, and the second one, the content area, fully scrollable within the lower part. --- src/stage/timeline/body-canvas-widget.cpp | 66 +++++++---- src/stage/timeline/body-canvas-widget.hpp | 38 +++++-- wiki/thinkPad.ichthyo.mm | 132 ++++++++++++++++++---- 3 files changed, 187 insertions(+), 49 deletions(-) diff --git a/src/stage/timeline/body-canvas-widget.cpp b/src/stage/timeline/body-canvas-widget.cpp index 51ba2a051..2527f45a0 100644 --- a/src/stage/timeline/body-canvas-widget.cpp +++ b/src/stage/timeline/body-canvas-widget.cpp @@ -39,7 +39,7 @@ //#include "lib/format-string.hpp" //#include "lib/format-cout.hpp" -//#include "lib/util.hpp" +#include "lib/util.hpp" //#include //#include @@ -48,6 +48,7 @@ //using util::_Fmt; +using util::max; //using util::contains; //using Gtk::Widget; using Gdk::Rectangle; @@ -65,6 +66,9 @@ namespace timeline { namespace { // details of track background painting + const int INITIAL_TIMERULER_HEIGHT_px = 30; + + class TrackGroundingRenderer : public ProfileInterpreter { @@ -142,11 +146,10 @@ namespace timeline { - TimelineCanvas::TimelineCanvas (DisplayManager& displayManager) + TimelineCanvas::TimelineCanvas (_RenderFactory groundingFac, _RenderFactory overlayFac) : Gtk::Layout{} - , layout_{displayManager} - , rootBody_{nullptr} - , profile_{} + , getGroundingRenderer_{groundingFac} + , getOverlayRenderer_{overlayFac} { } @@ -155,17 +158,29 @@ namespace timeline { BodyCanvasWidget::BodyCanvasWidget (DisplayManager& displayManager) - : Gtk::ScrolledWindow{} - , canvas_{displayManager} + : Gtk::Box{Gtk::ORIENTATION_VERTICAL} + , contentArea_{} + , rulerCanvas_{std::function(), std::function()} ///////////TODO dummy placeholder factories.... need to build the real thing + , mainCanvas_{std::function(), std::function()} + , layout_{displayManager} + , profile_{} + , rootBody_{nullptr} { - this->set_shadow_type(Gtk::SHADOW_IN); - this->set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_AUTOMATIC); // always need a horizontal scrollbar - this->property_expand() = true; // dynamically grab any available additional space - this->add(canvas_); + this->set_border_width (0); + this->property_expand() = true; // dynamically grab any available additional space + this->pack_start (rulerCanvas_); + this->pack_start (contentArea_); + + contentArea_.set_shadow_type (Gtk::SHADOW_NONE); + contentArea_.set_policy (Gtk::POLICY_ALWAYS, Gtk::POLICY_AUTOMATIC); // always need a horizontal scrollbar + contentArea_.property_expand() = true; // dynamically grab additional space + contentArea_.add (mainCanvas_); { // for the initial empty canvas -- use all space the enclosing scrolled window got. auto currSize = get_allocation(); - canvas_.set_size (currSize.get_width(), currSize.get_height()); + int height = currSize.get_height(); + rulerCanvas_.set_size (currSize.get_width(), INITIAL_TIMERULER_HEIGHT_px); + mainCanvas_.set_size (currSize.get_width(), max(0, height-INITIAL_TIMERULER_HEIGHT_px)); } // realise all initially configured elements.... @@ -185,7 +200,23 @@ namespace timeline { void BodyCanvasWidget::installForkRoot (TrackBody& rootTrackBody) { - canvas_.rootBody_ = &rootTrackBody; + rootBody_ = &rootTrackBody; + } + + + /** + * + */ + TrackProfile& + BodyCanvasWidget::establishTrackProfile() + { + if (rootBody_) + { + if (not profile_) + rootBody_->establishTrackSpace (profile_); + +// TrackGroundingRenderer renderer{cox, layout_.getPixSpan()}; //////////TODO TOD-oh + } } @@ -256,14 +287,7 @@ namespace timeline { void TimelineCanvas::drawGrounding (CairoC const& cox) { - if (rootBody_) - { - if (not profile_) - rootBody_->establishTrackSpace (profile_); - - TrackGroundingRenderer renderer{cox, layout_.getPixSpan()}; - profile_.performWith (renderer); - } +// profile_.performWith (renderer); /////////////////////////////////////////////TICKET #1039 : placeholder drawing cox->set_source_rgb(0.8, 0.0, 0.0); cox->set_line_width (5.0); diff --git a/src/stage/timeline/body-canvas-widget.hpp b/src/stage/timeline/body-canvas-widget.hpp index c35ac325d..e498eac39 100644 --- a/src/stage/timeline/body-canvas-widget.hpp +++ b/src/stage/timeline/body-canvas-widget.hpp @@ -64,6 +64,7 @@ //#include //#include +#include @@ -72,18 +73,27 @@ namespace timeline { class DisplayManager; class TrackBody; + class TimelineCanvas; + + class Renderer + { + public: + virtual ~Renderer() { } ///< this is an interface + + virtual void drawTo (TimelineCanvas&) =0; + }; class TimelineCanvas : public Gtk::Layout { - DisplayManager& layout_; + using _RenderFactory = std::function; + + _RenderFactory getGroundingRenderer_; + _RenderFactory getOverlayRenderer_; public: - TrackBody* rootBody_; - TrackProfile profile_; - - TimelineCanvas (DisplayManager&); + TimelineCanvas (_RenderFactory groundingFac, _RenderFactory overlayFac); private: virtual bool on_draw (Cairo::RefPtr const&) override; @@ -100,9 +110,15 @@ namespace timeline { * @todo WIP-WIP as of 12/2016 */ class BodyCanvasWidget - : public Gtk::ScrolledWindow + : public Gtk::Box { - TimelineCanvas canvas_; + Gtk::ScrolledWindow contentArea_; + TimelineCanvas rulerCanvas_; + TimelineCanvas mainCanvas_; + + DisplayManager& layout_; + TrackProfile profile_; + TrackBody* rootBody_; public: BodyCanvasWidget (DisplayManager&); @@ -111,8 +127,16 @@ namespace timeline { /** @internal Initially install the contents corresponding to the root track fork */ void installForkRoot (TrackBody& rootTrackBody); + /** @internal allow the header pane to follow our vertical scrolling movement */ + auto + get_vadjustment() + { + return contentArea_.get_vadjustment(); + } + private:/* ===== Internals ===== */ + TrackProfile& establishTrackProfile(); }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index cb6dc19ca..4399f079d 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -19448,7 +19448,7 @@ - + @@ -19513,6 +19513,46 @@ + + + + + + + + + +

+ Unterscheidung verschoben in die Darstellung +

+ + +
+ + + + + +

+ anstatt (konventionell) den Time-Ruler separat explizit auszuprogrammieren, +

+

+ bekommen wir nun eine gemeinsame Darstellungs-Mechanik, +

+

+ welche dann aber in zwei getrennten Bereichen jeweils anders parametrisiert +

+

+ zur Anwendung kommt +

+ + +
+
+ + + +
@@ -19525,10 +19565,73 @@ + + + + + + +

+ Problem: muß immer sichtbar sein +

+ + +
+ + + + + + + +

+ aber es bleibt bei diesem Prinzip. +

+

+ +

+

+ Des Genaueren, es gibt eine jeweils festgesetzte Menge von Elementen +

+

+ am Anfang des Track-Profils, welche immer sichtbar bleiben soll +

+ + +
+
+
+
+ + + + + + + + + - + + + + + + +

+ grundsätzlich: es zeichnet der Canvas +

+ + +
+ + + + + + @@ -19575,8 +19678,8 @@ - - + + @@ -19612,20 +19715,6 @@ - - - - - - -

- grundsätzlich: es zeichnet der Canvas -

- - -
- -
@@ -19765,7 +19854,8 @@ - + + @@ -22093,8 +22183,8 @@ - - + +