so this seems to be the better approach for dealing with this insidious problem.
In some cases -- as here most prominently with the root track within the timeline --
we have to care within the domain model to prepare unique ids even for sub objects
treated as attributes. In the actual case, without that special attention,
all timelines would hold onto an attribute "fork" with the same ID, based
on the type of the nested object plus the string "fork". Thus all root track
representations in the GUI would end up listening to the same ID on the UI-Bus...
...rather extend the "object builder" DSL notation to allow passing in a given EntryID literally.
Rationale is, we should handle the problem of unique IDs on the level of the domain model.
If we attempt to "fix" this within GenNode, the price would be to make the ETD creation stateful
this is not a problem, strictly sepaking, locally.
But it becomes a problem once the GUI uses those attribute IDs
as Element-IDs for tangible UI entities, which need to be uniquely
addressable via the UI-Bus.
An obvious solution is to inject randomness into the Attribute ID hash
...otherwise we'll get several seemingly identical Timeline tabs in the UI,
since this fake function just sends an INS for each newly injected Timeline,
and there is no deduplication in the UI (we assume that in a real session
and timeline-IDs will be unique)
these recursively nested helper entities work together with the TimelineCanvas
and enable the latter to draw the track background in the Timeline Widget and
to find out about the vertical coordinates where to place content (Clip, Effects, Markers)
Gtk::Viewport allows to add the ability to scroll a partial view window
for a container larger than the available display area. The position
and movement of this window is controlled by Gtk::Adjustments,
which can be located elsewhere.
Here we use the existing Adjustments of the ScrolledWindow
holding the body canvas; this setup makes the header pane follow
the scroll movements of the body
bottom line is to do most autmatically, and to establish a slave-relation
navigation-area -> timeline-ruler
header-pane-content -> corresponding track-body
this can be accomplished mostly by connecting the aproprieate signals,
thus these widgets will live within the Layout-Manager, which consequently
is renamed into TimelineLayout
the solution idea is to use a helper frame, and an "anchor functor",
which is passed down from the respective parent context, and which
does the actual work of injecting the child widgets at the apropriate
position within the parent display.
This is an obsolete feature, since the JavaScript engine in modern browsers
is way faster than it used to be, and people are accustomed to some loading time
due to all those "single page applications".
I haven't seen this splash screen even on the old Firefox for quite some time;
moreover, the TiddlyWiki 2.9.1 now displays a "JavaScript is required" alert
anyway, so there is really no need for all this messing around.
The (very old and long abandoned) SplashScreenPlugin
was written in a very hackish style, as it injected a <div> with the splash screen into the <head> tag.
In those olde days when evil reigned, browsers just happily displayed such documents.
But our new gem, Firefox Quantum, now "sanitises" such a malformed document
by closing the Head right before the <div> and relocating the opening BODY tag
to this place. Which then causes the TiddlyWiki self-modification routine
to flounder, because the opening body tag is now in the middle of a "markup area",
which is replaced by existing tiddler content (in this case the "MarkupPreHead" tiddler).
So we end up without an opening Body tag, and this is what we save -- Resulting in a corrupted wiki!
The obvious fix is to use the MarkupPreBody instead
Firefox Quantum adopted the idiotic behaviour of Chrome and does no longer
retrieve Cookies for pages read from local file system. It stores the Cookie
data into its local cookies.sqlite, but it does not retrieve it anymore.
For aledged "security reasons", however it happily retrieves HTML 5 web storage
Since TiddlyWiki classic just accesses the document.cookie at 3 points,
it is easy to patch around that problem. Just check, if we're using a modern
browser with support for HTML5 web storage and branch accordingly.
Basically, TiddlyWiki "classic" is in maintenance mode, but it is still supported.
This minor upgarde brings some bugfixes, most notably a minor adjustment to work well
with the new Firefox Quantum, which switched to the more restricted WebExtensions
and discontinued support for the old-style XUL based plug-ins.
This bold move by the firefox project placed a lot of well established, mature
extensions on the brink of extinction. Especially TiddlyWiki has gradually lost
its original appeal of a low-ceremony guerrilla wiki. However, it is still
a sweet little gem for experienced users, albeit a bit brittle to use.
You are now either
- forced to enter the target destination on each save
- or forced to arrange tiddly wiki to reside within your default download folder
and use a firefox plug-in to automate the save process (I use at the moment
https://addons.mozilla.org/en-GB/firefox/addon/file-backups/
- or forced to install a 100 MB blurb of java-script based local server
to run TiddlyWikiDesktop
The bitter irony of the situation is, what still works more-or-less painless
is to place your TiddlyWiki into the cloud. Yikes, here we go.
seems to work surprisingly well...
the diff application poceeds in the GUI up to the point
where the TrackPresenter need to be inserted into a two-fold display context
To drive the timeline display in the UI ahead, the plan is to have
a faked action, which injects dummy population diff messages into the GUI,
resulting in the build-up of a typical simple session timeline
decision: for now we will represent *every* Timeline present in the Session.
Later it would also possible to skip some representation; however we'd need
a way to store such presentation state such that we'd be able to get at this
persisted stat right at this point here, when processing the Diff.
other than the regular way of building an object,
we do expect a minimal structure to be sent right within the INS message.
Rationale: the standard way would allow for too much leeway and created
unwanted intermediary states. The non-standard way decided upon here
is well within the limits of our diff language
As it turns out, using the functional-notation form conversion
with *parentheses* will fall back on a C-style (wild, re-interpret) cast
when the target type is *not* a class. As in the case in question here, where
it is a const& to a class. To the contrary, using *curly braces* will always
attempt to go through a constructor, and thus fail as expected, when there is
no conversion path available.
I wasn't aware of that pitfall. I noticed it since the recently introduced
class TimelineGui lacked a conversion operator to BareEntryID const& and just
happily used the TimelineGui object itself and did a reinterpret_cast into BareEntryID
Problem is, the InteractionDirector, being the representation of the model root,
needs to manage and maintain the collection of "timelines". However, these
can not be widgets, rather, they need to attach to widgets living within
the GUI widget structure proper, i.e. within the TimelinePanel
proposed solution is to build a smart handle based on WLink,
but also delegating the DiffMutable interface
This involves a fundamental decision about how to build structures in the Lumiera UI:
They shall be solely created in response to diff messages. Which leads us to
introduce a new (and quite challenging) concept: the »DiffConstituent«
...these magical strings are already spreading dangerously throughout the code base
PS: also fixup for c6b8811af0 (broken whitespace in test definition)
This marks start of actual work on this fundamental task.
Extensive planning from 2016 is available, together with an almost
complete diff binding for the entities involved into timeline display.
''a new hope''
This was quite a long way until we're back at the point of
re-building the timeline anew.
Stash the canvas research code to make room for new things to come
this turned out to be more tricky than expected.
When we initially configure the UI and invoke this->show_all(),
seemingly some draw-callbacks will be scheduled into the event loop.
Just set_visible(false) on the relevant buttons directly after that call
will have no effect (since the widget is still hidden at that point anyway,
it is not yet mapped and realised).
Thus we need to schedule a callback with the Glib::signal_idle(),
so our state detection runs after the initial mapping of the UI
NOTE: there is a minor itch, which I don't address right now:
when adding the error state and thus revealing the additional buttons,
the error log grabs some additional horizontal space, even while there
would be ample space for the additional buttons within the button bar.
When the error state is cleared and the buttons thus hidden again,
the additional horizontal space is dropped and the error log gets
narrower. Probably we'd need some special GTK call to re-allocate
the required space properly
solved by temporarily adding a CSS class.
Mostly this was an issue of writing the Stylesheet properly.
Hint: use the GTK+ inspector, i.e. run with
GTK_DEBUG=interactive target/lumiera
Even while we (still) have the goal to ship our own stylesheet and provide
the typical subdued media-aplication look, right now this porting and styling effort (#1023)
is unfinished and handled with rather low priority (writing code is more important
than toying with styles and looks).
This alternative stylesheet is meant to be used with a typical "light" desktop theme.
We'll add just the bare minimum of definitions to make lumiera work well in that setup.
And right now, I'll use that setup to continue with my development work
In GTK-2 you'd always use a theming engine.
During the transitional period, GTK-3 followed that path,
but at the point when the new CSS based system was mature enough,
this approach was discouraged, since it means to ship additional
executable code and defeats the purpose of configuring the look
of the application through one coherent set of rules.
As it turns out, debian continued to ship the 'adwaita' for some
extended transitional period, but in Stretch it is gone, which broke
our half-way ported stylesheet.
This changeset removes the use of a theming engine, and fixes tha
basic look by adding the background-color: inherit, which pushes aside
many (but not all) of the default theme definitions.
However, our stylesheet remains mostly broken and TODO for now
Basically we create a pair of marks, with left/right gravity and then
inject the content between. Unfortunately, when the insert position
is the very end of the buffer (which it always is), this trick
leads to nesting the marked regions into each other.
As a remedy, we first insert the trailing newline,
and then attach the insert position one step before
discard all other info log messages and retain only the entries marked as error.
This is also a proof-of-concept regarding position bookmarks and markup.
Implemented by populating a new buffer and swapping it into place.