Clip-Drag: switch implementation to the new observer/adapter
This commit is contained in:
parent
aad4087e26
commit
3e9aae30b3
5 changed files with 154 additions and 102 deletions
|
|
@ -705,6 +705,14 @@ namespace lib {
|
|||
}
|
||||
}
|
||||
|
||||
DEFAULT&
|
||||
reset()
|
||||
{
|
||||
destroy();
|
||||
placeDefault();
|
||||
return static_cast<DEFAULT&> (getObj());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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<GestureObserver, InactiveObserver>;
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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<GestureObserver, OBSERVER_BUFF_SIZ, InactiveObserver>;
|
||||
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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<DragRelocateObserver> (*this);
|
||||
buffer.create<DragRelocateObserver> (cmdID, *this);
|
||||
}
|
||||
|
||||
Gtk::Widget&
|
||||
exposeWidget() override
|
||||
{
|
||||
return ClipDelegate::expect_and_expose_Widget (widget_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:/* ===== Internals ===== */
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32602,8 +32602,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617568275423" ID="ID_705403474" MODIFIED="1617568293029" TEXT="Trigger-Bedingung formulieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1617568275423" ID="ID_705403474" MODIFIED="1620913868535" TEXT="Trigger-Bedingung formulieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1617568301466" ID="ID_1738730292" MODIFIED="1617568534103" TEXT="inhaltlich...">
|
||||
<node CREATED="1617568311385" ID="ID_120327257" MODIFIED="1617568327148" TEXT=""klicken und ziehen""/>
|
||||
<node CREATED="1617568432466" ID="ID_1992031404" MODIFIED="1617568445795" TEXT="der Klick war im Bereich des zu ziehenden Objekts"/>
|
||||
|
|
@ -32684,42 +32684,9 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617569687944" ID="ID_109351275" MODIFIED="1617569696784" TEXT="Modifier sollten konfigurierbar sein">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1617569722132" ID="ID_1004932792" MODIFIED="1617569729653" TEXT="Einschränkung der Maustaste"/>
|
||||
<node CREATED="1617569730283" ID="ID_1098298417" MODIFIED="1617569798116" TEXT="Modifier-Key auf der Tastatur"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617569873288" ID="ID_32172316" MODIFIED="1617569973233" TEXT="Modus durch Tastenfolge aktiviert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617569687944" ID="ID_109351275" MODIFIED="1620913776693" TEXT="Modifier sollten konfigurierbar sein">
|
||||
<arrowlink COLOR="#d54526" DESTINATION="ID_914526002" ENDARROW="Default" ENDINCLINATION="-19;-306;" ID="Arrow_ID_1156051405" STARTARROW="None" STARTINCLINATION="-130;185;"/>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1617570608516" ID="ID_1536648683" MODIFIED="1617570619960" TEXT="Vorsicht: das ist ein Riesen-Thema">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node CREATED="1617570633938" ID="ID_1636227122" MODIFIED="1617570654929" TEXT="Stichwort: globale und konsistente Tasenkürzel">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1618499304789" ID="ID_636470529" MODIFIED="1618499325642" TEXT="das sollte besser durch Komposition gelöst werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Hierarchische Gesten-Controller
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1617570674708" ID="ID_1037850042" MODIFIED="1617570685158" TEXT="Zugang / Definitionen">
|
||||
<node CREATED="1617570694344" ID="ID_752689969" MODIFIED="1617570698161" TEXT="gdkevents.h">
|
||||
|
|
@ -32811,22 +32778,6 @@
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1617913172095" ID="ID_389454227" MODIFIED="1617919654631" TEXT="Callbacks für Button-Events">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617919674980" ID="ID_1535616039" MODIFIED="1617919704165" TEXT="TODO: spezielle Buttons und Modifier konfigurierbar machen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1618499388465" ID="ID_540657197" MODIFIED="1618499424481" TEXT="Problem: wie kann man dies einkapseln?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
es ist total an das Framework gebunden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1617913205146" ID="ID_1972128766" MODIFIED="1618690918521" TEXT="Callback für Motion-Events">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -32945,7 +32896,7 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1619104748998" ID="ID_1862152665" MODIFIED="1619106836504" TEXT="zu Klären: Skala für Screen-Koordinaten und/oder Pixel">
|
||||
<arrowlink COLOR="#6084b9" DESTINATION="ID_206049495" ENDARROW="Default" ENDINCLINATION="-1698;230;" ID="Arrow_ID_1554039358" STARTARROW="None" STARTINCLINATION="-5472;269;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node CREATED="1619104774025" ID="ID_1244834056" MODIFIED="1619105073946" TEXT="habe mir darüber nie Gedanken gemacht">
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
|
|
@ -33261,6 +33212,9 @@
|
|||
</node>
|
||||
<node CREATED="1619132645927" ID="ID_3614055" MODIFIED="1619696704275" TEXT="Umgang mit Zeit-Werten (immutable)">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1620913903207" ID="ID_236784465" MODIFIED="1620913912953" TEXT="Lösung time::Control (Mutator)">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1618753085285" ID="ID_560686142" MODIFIED="1618753216324" TEXT="noch keinerlei Infrastruktur für die vertikale Anordnung">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
|
|
@ -33345,8 +33299,8 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1618691013997" ID="ID_429908834" MODIFIED="1618691021757" TEXT="Delta an das Subject weitergeben">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1619887175393" ID="ID_54981427" MODIFIED="1619887223546" TEXT="Problem: Aufwand für Gesten-Verfolgung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1619887175393" FOLDED="true" ID="ID_54981427" MODIFIED="1619887223546" TEXT="Problem: Aufwand für Gesten-Verfolgung">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1619887230011" ID="ID_1178141750" MODIFIED="1619887552418" TEXT="Push von low-Level-Events erzeugt Übersetzungsaufwand">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -33385,12 +33339,13 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1619887730416" ID="ID_915000313" MODIFIED="1619887745442" TEXT="Lösung: Subject zu einem Protokoll ausbauen">
|
||||
<node COLOR="#338800" CREATED="1619887730416" FOLDED="true" ID="ID_915000313" MODIFIED="1620913945733" TEXT="Lösung: Subject zu einem Protokoll ausbauen">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node COLOR="#338800" CREATED="1619887769934" ID="ID_15885968" MODIFIED="1620565933367" TEXT="Schnittstelle zum Verdrahten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1619887785265" ID="ID_194430924" MODIFIED="1620565819404" TEXT="ein Adapter für die Gesten-Instanz">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1619887785265" ID="ID_194430924" MODIFIED="1620913562059" TEXT="ein Adapter für die Gesten-Instanz">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1619887907477" ID="ID_580784250" MODIFIED="1619887914507" TEXT="wird vom Subject konkret bereitgestellt"/>
|
||||
<node CREATED="1619887915592" ID="ID_1016019139" MODIFIED="1619887925546" TEXT="wird in der Storage des Gesten-Controllers abgelegt"/>
|
||||
<node CREATED="1619887926542" ID="ID_234628540" MODIFIED="1619887933409" TEXT="lebt bis zum Ende der Geste"/>
|
||||
|
|
@ -33445,8 +33400,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1619967216789" ID="ID_1503155358" MODIFIED="1619967554656" TEXT="aber an der Idee mit dem Adapter halte ich fest...">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1619967216789" ID="ID_1503155358" MODIFIED="1620913547263" TEXT="aber an der Idee mit dem Adapter halte ich fest...">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1619967266842" ID="ID_1478677945" MODIFIED="1619967373917">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
|
@ -33616,8 +33571,38 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1620565789665" ID="ID_515994897" MODIFIED="1620565795370" TEXT="Implementierung schwenken">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1620565789665" ID="ID_515994897" MODIFIED="1620913405382" TEXT="Implementierung schwenken">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1620913417225" ID="ID_1322371180" MODIFIED="1620913542016" TEXT="cmd-ID kann in den Observer verlegt werden">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1620913426512" ID="ID_1802612620" MODIFIED="1620913444069" TEXT="Pointer auf das Subject könne eigentlich auch dorthin">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1620913445509" ID="ID_1831141576" MODIFIED="1620913451984" TEXT="bringt aber nix"/>
|
||||
<node CREATED="1620913452692" ID="ID_339655971" MODIFIED="1620913529933" TEXT="und außerdem benutze ich den Pointer auch als Flag">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...und das ist eleganter, als jede der denkbaren Alternativen
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
stattdessen eine virtuelle Funktion für diesen State verwenden<br />
|
||||
</li>
|
||||
<li>
|
||||
stattdessen einen "magischen wert" in den Anker-Koordinaten speichern
|
||||
</li>
|
||||
<li>
|
||||
<br />
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -33710,6 +33695,65 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1618575194230" ID="ID_144431144" MODIFIED="1618575227970" TEXT="Planung: State-Machine für Gesten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617919674980" ID="ID_1535616039" MODIFIED="1620913818152" TEXT="TODO: spezielle Buttons und Modifier konfigurierbar machen">
|
||||
<linktarget COLOR="#eb4353" DESTINATION="ID_1535616039" ENDARROW="Default" ENDINCLINATION="-48;51;" ID="Arrow_ID_695007412" SOURCE="ID_914526002" STARTARROW="None" STARTINCLINATION="275;0;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1618499388465" ID="ID_540657197" MODIFIED="1618499424481" TEXT="Problem: wie kann man dies einkapseln?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
es ist total an das Framework gebunden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1620913676837" ID="ID_1104135051" MODIFIED="1620913687082" TEXT="Weiterungen(ungelöst)">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617569687944" ID="ID_914526002" MODIFIED="1620913823880" TEXT="Modifier sollten konfigurierbar sein">
|
||||
<arrowlink COLOR="#eb4353" DESTINATION="ID_1535616039" ENDARROW="Default" ENDINCLINATION="-48;51;" ID="Arrow_ID_695007412" STARTARROW="None" STARTINCLINATION="275;0;"/>
|
||||
<linktarget COLOR="#d54526" DESTINATION="ID_914526002" ENDARROW="Default" ENDINCLINATION="-19;-306;" ID="Arrow_ID_1156051405" SOURCE="ID_109351275" STARTARROW="None" STARTINCLINATION="-130;185;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1617569722132" ID="ID_1004932792" MODIFIED="1617569729653" TEXT="Einschränkung der Maustaste"/>
|
||||
<node CREATED="1617569730283" ID="ID_1098298417" MODIFIED="1617569798116" TEXT="Modifier-Key auf der Tastatur"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1617569873288" ID="ID_32172316" MODIFIED="1617569973233" TEXT="Modus durch Tastenfolge aktiviert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
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
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1617570608516" ID="ID_1536648683" MODIFIED="1617570619960" TEXT="Vorsicht: das ist ein Riesen-Thema">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
<node CREATED="1617570633938" ID="ID_1636227122" MODIFIED="1617570654929" TEXT="Stichwort: globale und konsistente Tasenkürzel">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1618499304789" ID="ID_636470529" MODIFIED="1618499325642" TEXT="das sollte besser durch Komposition gelöst werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Hierarchische Gesten-Controller
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue