From 3e9aae30b3acd95a6f7ca9965e6f6ddc596af5b7 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 13 May 2021 16:14:11 +0200 Subject: [PATCH] Clip-Drag: switch implementation to the new observer/adapter --- src/lib/opaque-holder.hpp | 8 + src/stage/interact/cmd-context.hpp | 10 +- .../interact/drag-relocate-controller.hpp | 31 +++- src/stage/timeline/clip-presenter.hpp | 37 ++-- wiki/thinkPad.ichthyo.mm | 170 +++++++++++------- 5 files changed, 154 insertions(+), 102 deletions(-) diff --git a/src/lib/opaque-holder.hpp b/src/lib/opaque-holder.hpp index db5f2539b..85330578c 100644 --- a/src/lib/opaque-holder.hpp +++ b/src/lib/opaque-holder.hpp @@ -705,6 +705,14 @@ namespace lib { } } + DEFAULT& + reset() + { + destroy(); + placeDefault(); + return static_cast (getObj()); + } + diff --git a/src/stage/interact/cmd-context.hpp b/src/stage/interact/cmd-context.hpp index 97312b95d..509c27bd7 100644 --- a/src/stage/interact/cmd-context.hpp +++ b/src/stage/interact/cmd-context.hpp @@ -102,7 +102,6 @@ namespace interact { public: virtual ~GestureObserver(); ///< this is an interface - GestureObserver () : cmdID_(Symbol::BOTTOM){ } GestureObserver (Symbol cmdID) : cmdID_(cmdID) { } GestureObserver (GestureObserver&&) = default; @@ -122,6 +121,8 @@ namespace interact { { void updateOffset (double, double) override { /*NOOP*/ } void markGestureCompleted() override { /*NOOP*/ } + public: + InactiveObserver() : GestureObserver(Symbol::BOTTOM) { } }; @@ -139,12 +140,9 @@ namespace interact { virtual ~Subject(); ///< this is an interface public: - virtual Gtk::Widget& exposeWidget() =0; - virtual void fireGesture (Symbol cmdID) =0; - virtual void gestureOffset (Symbol cmdID, double deltaX, double deltaY) =0; - using Buffer = lib::PlantingHandle; - virtual void buildGestureObserver (Symbol cmdID, Buffer) =0; + virtual void buildGestureObserver (Symbol cmdID, Buffer) =0; ///< prompt the Subject to build an Observer for the gesture in formation + virtual Gtk::Widget& exposeWidget() =0; ///< the exposed widget can be used for wiring signal handlers }; diff --git a/src/stage/interact/drag-relocate-controller.hpp b/src/stage/interact/drag-relocate-controller.hpp index 0d686e0f3..41d3760a2 100644 --- a/src/stage/interact/drag-relocate-controller.hpp +++ b/src/stage/interact/drag-relocate-controller.hpp @@ -50,6 +50,7 @@ #include "stage/gtk-base.hpp" #include "stage/interact/interaction-state.hpp" #include "stage/interact/cmd-context.hpp" +#include "lib/opaque-holder.hpp" #include "lib/format-string.hpp"//////////////////////////////////TODO #include "lib/format-cout.hpp" //////////////////////////////////TODO //#include "lib/idi/entry-id.hpp" @@ -71,6 +72,12 @@ namespace interact { namespace { const gdouble DISTANCE_THRESHOLD = 5.0; + + /** heuristics for sizing the inline buffer + where the Subject will construct its Observer/Adapter */ + const size_t OBSERVER_BUFF_SIZ = sizeof(void*) + + sizeof(Symbol) + + 4 * sizeof(void*); } @@ -99,12 +106,15 @@ namespace interact { : public InteractionState { bool buttonPressed_ = false; - Symbol cmdID_ = Symbol::BOTTOM; Subject* subject_ = nullptr; bool isInFormation_ = false; gdouble anchorX_ = 0.0; gdouble anchorY_ = 0.0; + using Observer = lib::InPlaceBuffer; + + Observer observer_; + void linkTrigger (Subject& subject, Symbol cmdID) override { @@ -158,6 +168,8 @@ namespace interact { if (not isActive()) { probeActivation (motion_event); + if (isActive()) + initGestureTracking(cmdID, subject); return false; } else @@ -186,14 +198,13 @@ namespace interact { anchor (Symbol cmdID, Subject& subject, GdkEventMotion* motion_event) { REQUIRE (motion_event); - this->cmdID_ = cmdID; this->subject_ = & subject; this->anchorX_ = motion_event->x; this->anchorY_ = motion_event->y; std::cerr << _Fmt{"ANCHOR at x=%3.1f y=%3.1f ('%s')"} % anchorX_ % anchorY_ - % cmdID_ + % cmdID << std::endl; } @@ -204,6 +215,12 @@ namespace interact { or DISTANCE_THRESHOLD < abs (motion_event->y - anchorY_); } + void + initGestureTracking(Symbol cmdID, Subject& subject) + { + subject.buildGestureObserver (cmdID, Observer::Handle{observer_}); + } + void doTrackGesture (GdkEventMotion* motion_event) { @@ -211,28 +228,28 @@ namespace interact { gdouble deltaX = motion_event->x - this->anchorX_; gdouble deltaY = motion_event->y - this->anchorY_; // notify Subject to feed current delta - subject_->gestureOffset (cmdID_, deltaX, deltaY); + observer_->updateOffset (deltaX, deltaY); } void doCompleteGesture() { - subject_->fireGesture (cmdID_); + observer_->markGestureCompleted(); } void resetState() { isInFormation_ = false; - cmdID_ = Symbol::BOTTOM; anchorX_ = anchorY_ = 0.0; subject_ = nullptr; + observer_.reset(); } public: DragRelocateController() -// : + : observer_{} { } private: diff --git a/src/stage/timeline/clip-presenter.hpp b/src/stage/timeline/clip-presenter.hpp index 8c266478a..d939bb952 100644 --- a/src/stage/timeline/clip-presenter.hpp +++ b/src/stage/timeline/clip-presenter.hpp @@ -221,29 +221,6 @@ namespace timeline { private:/* ===== Subject-Interface ===== */ - Gtk::Widget& - exposeWidget() override - { - return ClipDelegate::expect_and_expose_Widget (widget_); - } - - void - fireGesture (Symbol cmdID) override - { - std::cerr << _Fmt{"!!BANG!! Gesture-Cmd '%s'"} - % cmdID - << std::endl; - } - - void - gestureOffset (Symbol cmdID, double deltaX, double deltaY) override - { - std::cerr << _Fmt{"Gesture(%s) --> Δ := (%3.1f,%3.1f)"} - % cmdID - % deltaX - % deltaY - << std::endl; - } class DragRelocateObserver : public interact::GestureObserver @@ -269,17 +246,25 @@ namespace timeline { } public: - DragRelocateObserver(ClipPresenter& clipPresenter) - : subject_{clipPresenter} + DragRelocateObserver(Symbol cmdID, ClipPresenter& clipPresenter) + : interact::GestureObserver{cmdID} + , subject_{clipPresenter} { } }; void buildGestureObserver (Symbol cmdID, Buffer buffer) override { - buffer.create (*this); + buffer.create (cmdID, *this); } + Gtk::Widget& + exposeWidget() override + { + return ClipDelegate::expect_and_expose_Widget (widget_); + } + + private:/* ===== Internals ===== */ /** diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 3910ec885..21aa77a9c 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -32602,8 +32602,8 @@ - - + + @@ -32684,42 +32684,9 @@ - - - - - - - - - - -

- Beispiel: das "grab" von Blender ist ein praktisches Konzept. Dort kann man ein Element überhaupt nur bewegen, wenn man vorher die "g"-Taste gedrückt hatte. So etwas will ich in Lumiera auch haben... ist aber nicht so ganz einfach -

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

- Hierarchische Gesten-Controller -

- -
- -
-
@@ -32811,22 +32778,6 @@ - - - - - - - - -

- es ist total an das Framework gebunden -

- -
- -
-
@@ -32945,7 +32896,7 @@ - + @@ -33261,6 +33212,9 @@ + + + @@ -33345,8 +33299,8 @@ - - + + @@ -33385,12 +33339,13 @@ - + + - - + + @@ -33445,8 +33400,8 @@ - - + + @@ -33616,8 +33571,38 @@ - - + + + + + + + + + + + + + + +

+ ...und das ist eleganter, als jede der denkbaren Alternativen +

+
    +
  • + stattdessen eine virtuelle Funktion für diesen State verwenden
    +
  • +
  • + stattdessen einen "magischen wert" in den Anker-Koordinaten speichern +
  • +
  • +
    +
  • +
+ +
+
+
@@ -33710,6 +33695,65 @@
+ + + + + + + + + +

+ es ist total an das Framework gebunden +

+ +
+ +
+
+
+
+ + + + + + + + + + + + + + +

+ Beispiel: das "grab" von Blender ist ein praktisches Konzept. Dort kann man ein Element überhaupt nur bewegen, wenn man vorher die "g"-Taste gedrückt hatte. So etwas will ich in Lumiera auch haben... ist aber nicht so ganz einfach +

+ +
+ + + + + + + + + + + + + +

+ Hierarchische Gesten-Controller +

+ +
+ +
+