Commit graph

5816 commits

Author SHA1 Message Date
8b5f6b0dea DOC: update and rework documentation regarding command access
In 2017, I did a first design draft, followed by a design critique,
which partially obsoleted some ideas regarding command binding.

Mostly, the reason to abandon parts of that initial design was
due to the fact, that to many actual construction details of the
UI framework were not worked out at that time.

Thus I rather focussed on (re)-building a backbone for the timeline display,
in order to support that kind of flexibility aspired within the session model.


Now, when re-visiting the topic of an UI gesture (using simple dragging
of a clip in the timeline as an example for a first draft), I picked up
some of those planned structures, but tend to bind them together in
a slightly different way -- more akin to a state machine and less
in the way of an LR-parser.

This chagneset updates the relevant part within the TiddlyWiki
and the corresponding UML drawing to better reflect my actual thinking.
2021-04-16 18:14:33 +02:00
e8d29b8093 Tooling: Upgrade to Umbrello 4.17 (UML drawing tool)
..just open the existing uml/Lumiera.xmi and store it again
2021-04-16 15:50:22 +02:00
9796a8ebd0 Clip-Drag: requirements analysis in wider scope
...because this is a prototype, but should fit in
with a future frameworks to handle complex interactions and gestures.

And no, we can not afford to rely on a UI toolkit for such a core concern
It is impossible that a framework like e.g. GTK will allow us to
support a custom made hardware controller and integrate it seamlessly
into getsture handling, thereby following a design philosophy that
is in accordance with our fundamental decisions.
2021-04-15 18:46:49 +02:00
0e98a1a940 Clip-Drag: investigate how to deal with motion events
...found out that GTK already implements an "implicit grab",
and thus the tricky situation that the mouse slides off the widget
can not happen at all; so in the end it's rather easy to build a trigger
for a dragging gesture.

The demo code is now activated only after the button is down
and just prints the position...


PS: did some research regarding the new Coroutines in C++
2021-04-09 00:18:38 +02:00
b1f739115b move some common helpers into central UI headers 2021-04-04 15:46:40 +02:00
e72df5c02d Clip-Drag: successfully hook up a signal binding for the trigger condition
Setup the scaffolding necessary to get at the actual clip widget
and to establish a signal connection to the button_pressed signal.
The intention is to watch this in conjunction with mouse movements
for detection of the actual gesture.

At the moment, I am using button widgets as placeholder for the actual
clip widgets (not yet implemented...). And, as a tiny little success,
these buttons now invoke the gesture controller on right click
(left click is seemingly consumed by the button itself)
2021-04-03 19:49:30 +02:00
1187a81943 Clip-Drag: hook up the access point to the gesture definition
thus far my implementation concept seems to work as intended....


note: when populating the timeline with actual Clips,
the not-yet implemented linkSubject()-Function of the DragRelocateController
gets invoked (as it should), thereby killing Lumiera
2021-04-02 17:39:42 +02:00
6578b3cf1c Clip-Drag: wire access to the actual InteractionState for dragging 2021-04-02 16:57:18 +02:00
91273e5931 Clip-Drag: consider translation of command ctxID into a InteractionState implementation
...actually postpone to build a generic translation system and use hard wired relations for now;
it is acknowledged that we'll need some kind of translation system eventually,
once the GUI has to handle a lot of possibly configurable gestures.
2021-03-28 18:03:40 +02:00
65f16d54fa Clip-Drag: setup access-front-end via dependency injection
Decision to use a dedicated holder service (GestureState),
maintained as sub-service within InteractionDirector
2021-03-27 16:47:22 +01:00
451673dd09 Clip-Drag: now able to detect creation of a new clip widget
..and thus there is now one dedicated source location,
where configuration of new clip widgets can be done reliably.

So all prerequisites are solved and we can start
building a prototypical drag-gesture implementation
2021-03-27 14:42:08 +01:00
d4b1735013 define the ClipPresenter header-only (no change)
A separate translation unit turns out to be unnecessary here,
since this is implementation level code included into one single
other translation unit (timeline-controller.cpp). In such a situation,
having the whole class definition at one code location improves
readability.

Moreover, there clearly is now another abstraction barrier,
insofar all of the clip widget's implementation technicalities
are buried within clip-widget.cpp
2021-03-27 13:47:43 +01:00
98a675e54c Clip-Drag: refactoring to establish prerequisites for dragging support
The specific twist with the clip display lies in the fact
that there might or might not be a dedicated clip widget,
based on the current presentation style and zoom level.

Consequently we need hook up the widget for dragging,
only when, and whenever a new clip widget is actually created.
This boils down to the requirement to detect whenever a state change
creates a dedicated widget -- and this can only be sensibly implemented
when all display state transitions are handled by a single function.

Previously, we had two specialised functions for this purpose:
one to initially create the delegate and one to switch the
implementation type for an already existing delegate.

This refactoring attempts to merge all this logic into a single function,
which now unfortunately became quite complex and hard to understand.
2021-03-27 01:30:06 +01:00
e2292e0239 Clip-Drag: start prototypical implementation of a gesture controller (see #1218)
My planning thus far seems solid enough to start fleshing out one concrete gesture handling,
which can serve as a blueprint for a generic scheme to be worked out later.
Moreover, the implementation is limited to mouse interaction for the time being,
while the goal remains to treat "gestures" in a way to span several
Interaction-Schemes eventually (mouse, key sequence, pen...).
2021-03-26 01:21:46 +01:00
e3f64d1c3c Clip-Drag: reshape that solution to avoid abundance of cross-links
...since it would be problematic, so store the prospective context data
for any conceivable gesture within each Widget possibly addressed by that gesture.

After some mulling over, today it finally occurred to me,
that I already solved a similar problem for the layout management,
and the very structure of ViewModel vs. Widget vs. Canvas settles
around that solution. Thus we could try to expand that structure --
which means that the gesture context is only created *late*, when the
gesture starts; and then the *subject* should be reponsible to collect
and establish the context for the gesture and feed it to the
gesture-controller, not the other way round
2021-03-12 16:54:19 +01:00
a64dc9c05f Clip-Drag: draft a solution for handling gestures
...even while keeping the focus to the actual problem at hand,
this solution must be built with the larger goal in mind, which
is the ability to support various editing gestures, transmitted
possibly through several control-systems (mouse, keybindings, pen...)

It is obvious that we'll need a dedicated controller for each kind of gesture;
what turns out as tricky is to maintain and bind a stateful context
and find the correct participants while a specific gesture is under way.
2021-02-28 23:04:06 +01:00
154868e8e2 Clip-Drag: reconsider the state of the command invocation scheme
As it turned out, I drafted a rather elaborate vision in 2017,
leading to the conclusion to better just implement the very simple
"point and shot" command invocation and to postpone anything more
advanced to a later point, when the properties of the actual UI
are defined more clearly.

Thus, what I have to build now is a first step in the direction
of the more elaborate vision, but only that, namely a first draft,
which should fit into the more complete solution later.
2021-02-22 00:21:53 +01:00
7e946fa1cc Clip-Drag: investigate the problem...
Can we build a simple feature to allow dragging clips in the timeline display?

Well... not really, at least not "simple".
As it turns out, the GTK-framework only supports classic "drag-n-drop",
which translates into sending an action to a drag target to receive a "document".

And, even worse, dragging clips must be implemented as a UI gesture,
and as such overlaps with the other gestures for editing, trimming.

In 2017, I did an comprehensive analysis of this problem, and then
concluded to postpone it. Thus the task now would be to build a
*simplified preview*, while being aware of the danger of creating
oversimplified structures, and the danger to hamper a complete
solution for implementing UI gestures...
2021-02-21 15:40:08 +01:00
ab718ed6aa DisplayEvaluation: get corrdinated vertical size roughly to work
Now basically the header labels are aligned with the start of the corresponding body area.

However, there still seems to be some minor glitch hidden somewhere,
and the labels seem to be off by one pixel per track. Also the allocated
canvas size is to small after first evaluation, but somehow gets
corrected whenever the window is resized.
2021-02-08 01:09:16 +01:00
8f572fc122 DisplayEvaluation: draft coordinated vertical layout (see #1211)
a first rather simplistic attempt to establish a vertically
synchronised layout between track header and body.

TODO: doesn't yet work as intended
2021-02-07 20:45:28 +01:00
34725afaa8 Clip: try out some solution to enforce a fixed extension
..now this more or less works and indeed crops the button widget
used here for a proof-of concept; however the label within that button
emits a lot of layout warnings on each event handling and drawing routine,
indicating that we violated its fundamental assumptions.

Not sure how to proceed from here; also not sure if this actually
becomes turns into a relevant issue in practice, since maybe in most cases
we'll rather increase the size, and all we really have to do is handle
the Clip's textual label properly. A clip smaller than some drop-down icon
should probably not be rendered explicitly, just as overview
2021-02-06 15:30:59 +01:00
453ee08803 Clip: investigate how to enforce a fixed horizontal extension
GTK doesn't expose a first-class API for this,
since -- by design -- the extension of a widget is negotiated.
Thus I'm looking for some kind of workaround for our specific use-case,
where a clip widget must be rendered with a well defined horizontal size,
corresponding to its length.

Thus far, we're only able to increase the size of the Button widget
used as placeholder, but we can not forcibly shrink that button,
probably because the embedded Gtk::Lable requires additional extension.
2021-02-05 00:21:08 +01:00
5570850377 Clip: review ClipDelegate creation
implement the special convention for Time::NEVER to hide such clips
2021-01-30 19:36:47 +01:00
c4634837a3 DisplayEvaluation: further testing and bugfixes
- fix a regression introduced with the 3rd DisplayEvaluation pass
- use references to pass the timings more efficiently to the ClipDelegate
- DisplayEvalutation in fact has a real LifeCycle and is not disposable
- generate the population diff for this test in canonical form
2021-01-30 19:01:56 +01:00
4451d5bfc9 Clip: implement re-attachment after layout change
with these changes, essentially the clip is moved to the
new position established in the preceding DisplayEvaluation.

...there is still some problem when this DisplayEvaluation itself
is triggered from within draw(), because then GTK still uses the old
sub-widget coordinates within this draw code, pretty much as if
they were cached somewhere. The next draw() call then uses the
proper new coordinates.
2021-01-30 16:29:06 +01:00
2e4cd56f4f Relative-Hook: rectify the design
Partially as a leftover from the way more ambitious initial design,
we ended up with CanvasHook as an elaboration/specialisation of the
ViewHook abstraction. However, as it stands, this design is tilted,
since CanvasHook is not just an elaboration, but rather a variation
of the same basic idea.

And this is now more like a building pattern and less of a generic
framework, it seems adequate to separate these two variations completely,
even if this incurs a small amount of code duplication.


Actually this refactoring is necessary to resolve a bug, where
we ended up with the same Clip widgets attached two times to the
same Canvas control, one time through the ViewHook baseclass,
and a second time by the ctor of the "derived" CanvasHook
2021-01-30 13:29:50 +01:00
e175805481 Clip: rearrange storage of clip presentation data
This can only be a preliminary solution, since we do not know
the actual usage pattern of the ClipDelegate object yet.
We only know there will typically be a huge amount of clips
to represent in the UI, and we need to be careful to avoid
unneccesary reallocations.

Thus for now we use a data record as base class, and we
move the data record into the new allocation when switching gears.
However, this could easily be converted into a data delegate,
where we'd only transfer ownership without reallocation,
in case this turns out to be more efficient.
2021-01-29 23:08:53 +01:00
96dfbf7d96 DisplayEvaluation: introduce a 3rd pass to adjust widget positions
After some in-depth analysis, it seems best to reattach the Clips and Marker
top-down through the control structure, rather than building some additional
magic callback into the CanvasHook. Thus the 3rd DisplayEvaluation pass
now not only has to rebalance track header and body, but also
reatach or move each attached widget within the body, using its
nominal coordinates. This should then pick up the changed
layout decoration size
2021-01-29 14:15:18 +01:00
5b33605469 Clip: fill in minimal implementation to make the clip appear 2021-01-25 03:06:27 +01:00
21f6e61fd3 Clip: evaluate state of the clip display implementation
...as it turns out, a first preliminary clip display should be working by now;
seemingly I was able to the tough theoretical problems last spring,
and was at the point of actually allocating display extension space
within the custom drawing area of the timeline.

Thus a simple placeholder widget based on a Gtk::Button should show up
at the right position, when sending a suitable diff message. The only
thing missing seems to be a first rough draft for the function
determineRequiredVerticalExtension()
2021-01-24 14:54:53 +01:00
acb674a9d2 Project: update and clean-up Doxygen configuration
...in an attempt to clarify why numerous cross links are not generated.
In the end, this attempt was not very successful, yet I could find some breadcrumbs...

- file comments generally seem to have a problem with auto link generation;
  only fully qualified names seem to work reliably

- cross links to entities within a namespace do not work,
  if the corresponding namespace is not documented in Doxygen

- documentation for entities within anonymous namespaces
  must be explicitly enabled. Of course this makes only sense
  for detailed documentation (but we do generate detailed
  documentation here, including implementation notes)

- and the notorious problem: each file needs a valid @file comment

- the hierarchy of Markdown headings must be consistent within each
  documentation section. This entails also to individual documented
  entities. Basically, there must be a level-one heading (prefix "#"),
  otherwise all headings will just disappear...

- sometimes the doc/devel/doxygen-warnings.txt gives further clues
2021-01-24 19:35:45 +01:00
06dbb9fad5 DiffFramework: simplify existing bindings
...by relying on the newly implemented automatic standard binding
Looks like a significant improvement for me, now the actual bindings
only details aspects, which are related to the target, and no longer
such technicalitis like how to place a Child-Mutator into a buffer handle
2021-01-23 12:55:10 +01:00
c52576ffc7 Diff-Framework: fill in the access variations
no metaprogramming since almost a year ... kindof missed that queer feeling
2021-01-22 15:06:43 +01:00
05b5ee9a7e Diff-Framework: investigate simplification for the most common case
After this long break during the "Covid Year 2020",
I pick this clean-up task as a means to fresh up my knowledge about the code base

The point to note is, when looking at all the existing diff bindings,
seemingly there is a lot of redundancy on some technical details,
which do not cary much meaining or relevance at the usage site:

- the most prominent case is binding to a collection of DiffMutables hold by smart-ptr
- all these objects expose an object identity (getID() function), which can be used as »Matcher«
- and all these objects can just delegate to the child's buildMutator() function
  for entering a recursive mutation.
2021-01-22 12:38:45 +01:00
657b94a4e3 ++ a strange year passed by ++
read the code, documentation and mindmap to find out
at what point I was when this story unfolded
2021-01-20 08:05:30 +01:00
28adf9a642 Clip: pondering about the representation of clip timings 2020-04-09 00:15:05 +02:00
ea3ea811bf Clip: sort out access to the canvas abstraction 2020-04-08 22:55:33 +02:00
765d124fff Clip: draft the decision logic for the clip presentation mode 2020-04-03 19:44:46 +02:00
cfa8e87931 Relative-Hook: now able to push down time->pixel translation (see #1213)
the actual translation is still TODO;
we should delegate the calculation to the DisplayManager,
which is in focus within the TrackBody, where the coordinate
translation hook is now located.
2020-03-23 04:29:06 +01:00
e33eae729b Relative-Hook: complete refactoring down to tracks and clips (see #1213)
...and the result was very much worth the effort,
leading to more focused and cleaner code.

 - all the concerns of moving widgets and translating coordinates
   are now confined to the second abstraction layer (CanvasHook)

 - while the ViewHook now deals exclusively with attachment, detachment
   and reordering of attachment sequence
2020-03-23 04:16:10 +01:00
f956f27ff4 Relative-Hook: build CanvasHook abstraction based on ViewHook
this refactoring was expedient, as the code becomes
way more legible within each of the two levels of abstraction
2020-03-23 02:02:06 +01:00
22bc2167f9 Relative-Hook: prepare to split the abstraction into two levels
Level-1 : generic attachment into some kind of view
Level-2 : attachment by coordinates onto some kind of canvas
2020-03-22 16:37:58 +01:00
030fbd74c4 Clip: next step to establish a Delegate and appearance style
while the actual selection logic for the appearance style still remains
to be coded, this changeset basically settles the tricky initialisation sequence
2020-03-16 01:49:53 +01:00
dd016667ad Diff-Listener: add a variant to trigger also on value assignment (see #1206)
As it turned out, it is rather easy to extend the existing listener
for structural changes to detect also value assignments. Actually
it seems we'd need both flavours, so be it.
2020-03-15 23:11:14 +01:00
31116fb079 Clip: draft state-switching operation 2020-03-15 17:26:13 +01:00
4015a98d23 Clip: wire the optional startpoint parameter
...to indicate how the setting up the delegate might decide upon the appearance style

WIP: this is more than half baked
 - for one it seems doubtful to pass a hidden hint regarding appearance through that optional argument
 - and then, most importantly, we should be passing a time::TimeSpan
2020-03-15 00:47:55 +01:00
0f6f09180e Lib: simplified optional access to nested record attributes
Yeah, C++17, finally!

...not totally sure if we want to go that route.
However, the noise reduction in terms of code size at call site looks compelling
2020-03-14 23:52:04 +01:00
a9ed0c01db Lib: minor indentation fix
by convention, braces for member functions are only indented within a class body,
not for a stand-alone function definition (even if just inline)
2020-03-14 23:04:52 +01:00
e4db0dbfd1 Clip: draft initialisation of display delegate (see #1038)
...first steps towards a solution to switch the appearence style of clips
2020-03-14 22:02:03 +01:00
f763e90d2d DisplayEvaluation: prefer simpler solution without templates
...while the first solution looked as a nice API, abstracting away
the actual collections (and in fact helped me to sport and fix a problem
with type substitution), in the end I prefer a simpler solution.
Since we're now passing in a lambda for transform anyway, it is
completely pointless to create an abstracted iterator type, just
for the sole purpose of dereferencing an unique_ptr.

As it stands now, this is all tightly interwoven implementation code,
and the DisplayFrame is no longer intended to become an important
interface on it's own (this role has been taken by the ViewHook /
ViewHooked types).

Note: as an asside, this solution also highlights, that our
TreeExplorer framework has gradually turned into a generic
pipeline building framework, rendering the "monadic use" just
one usage scenario amongst others. And since C++20 will bring
us a language based framework for building iteration pipelines,
very similar to what we have here, we can expect to retrofit
this framework eventually. For this reason, I now start using
the simple name `lib::explore(IT)` as a synonym.
2020-03-08 02:31:49 +01:00