Lumiera  0.pre.03
»edit your freedom«
clip-widget.hpp File Reference

Go to the source code of this file.

Description

This widget provides the concrete rendering of a clip-like entity.

Such can appear in various contexts within the UI, be it a media bin in the asset management section, or rather the timeline display proper, which is at the heart of the Lumiera UI. Moreover, such a "clip" might represent a media clip as a whole, or just recursively some part of it. It might be a channel, or even an effect attached to some clip. Combined with the various temporal zoom levels, we thus need the ability to adapt this display to a wide variety of clip appearance styles. And another consequence is that the ClipWidget itself needs to be mostly passive, supervised by a dedicated ClipPresenter.

Appearance styles

According to the requirements of the given context, the ClipWidget is able to conform to several styles of appearance. All of these can be implemented from a single common base structure, and thus it is possible to switch those styles dynamically, so to expand or collapse the visible entity in place

abridged form
To start with, a clip can be rendered in abridged form, which means that the content is stylised and the temporal extension does not matter. In this form, the clip is reduced to an icon, an expand widget and a ID label. This is the standard representation encountered within the media bins. The intent of this representation is to save on screen estate, especially to minimise vertical extension. But as a derivative of this layout style, a clip may be shown in abridged form, but in fact with proper representation of the temporal extension; to this end, the enclosing box is extended horizontally as needed, while the compound of icon, control and label is aligned such as to remain in sight.
compact form
The next step in a series of progressively more detailed clip representations is the compact form, which still focuses on handling the clip as an unit, while at least indicating some of the inherent structuring. Essentially, the clip here is represented as a strip of rendered preview content, decorated with some overlays. One of these overlays is the ID pane, which resembles the arrangement known from the abridged form: The icon here is always the placement icon, followed by the expand widget and the ID label. Again, this pane is aligned such as to remain in sight. Then, there is a pair of overlays, termed the boundary panes, which indicate the begin and the end of the clip respectively. Graphically, these overlays should be rendered in a more subtle way, just enough to be recognisable. The boundary panes are the attachment areas for trimming gestures, as opposed to moving and dragging the whole clip or shuffle editing of the content. Moreover, these boundary panes compensate for the alignment of the ID pane, which mostly keeps the latter in sight. As this might counterfeit the visual perception of scrolling, the boundary panes serve to give a clear visual clue when reaching the boundary of an extended clip. Optionally, another overlay is rendered at the upper side of the clip's area, to indicate attached effect(s). It is quite possible for these effect decorations not to cover the whole temporal span of the clip.
expanded form
A yet more detailed display of the clip's internals is exposed in the expanded form. Here, the clip is displayed as an window pane holding nested clip displays, which in turn might again be abridged, compact or _(TODO not sure 11/16)_ even expanded. This enclosing clip window pane should be rendered semi transparent, just to indicate the enclosing whole. The individual clip displays embedded therein serve to represent individual media parts or channels, or individual attached effects. Due to the recursive nature of Lumiera's High-Level-Model, each of these parts exposes essentially the same controls, allowing to control the respective aspects of the part in question
degraded form
Finally, there can be a situation where it is just not possible to render any of the aforementioned display styles properly, due to size constraints. Especially, this happens when zooming out such as to show a whole sequence or even timeline in overview. We need to come up with a scheme of ''graceful display degradation'' to deal with this situation – just naively attempting to render any form might easily send our UI thread into a minute long blocking render state, for no good reason. Instead, in such cases display should fall back to
  • showing just a placeholder rectangle, when the clip (or any other media element) will cover a temporal span relating to at least 1 pixel width (configurable trigger condition)
  • even further collapsing several entities into a strike of elements, to indicate at least that some content is present in this part of the timeline.

Structure of the clip representation

Obviously, managing all these wildly different appearance styles incurs a lot of complexity, which needs to be decomposed to keep it manageable. Thus, we introduce several responsibilities

  • the ClipPresenter is what formally corresponds to the session::Clip, i.e. in a birds eyes view, it "is" the clip. However, in fact the ClipPresenter only manages the desired properties and delegates the actual realisation to "some widget"
  • and this "widget" is in fact a "PImpl", the ClipDelegate, which foremost exposes an interface to adapt and control the appearance style, while the actual clip widget remains a private detail and is only accessible through the ClipDelegate interface
  • behind the scenes, within the implementation, several implementation subclasses are available, to be installed and exchanged to accommodate the desired appearance style. These are managed semi-automatically and hooked into the appropriate display framework as required. And this attachment is itself again abstracted as CanvasHook – which means the actual clip widget implements the interaction mechanics, and can draw itself on demand, while remaining agnostic about details regarding zoom management, scrolling and visibility of timeline contents, or the actual allocation of display extension, which happens within the stage::timeline::DisplayEvaluation pass.
Todo:
WIP-WIP as of 1/2021

Definition in file clip-widget.hpp.

#include "stage/gtk-base.hpp"
#include "stage/model/canvas-hook.hpp"
#include "lib/time/timevalue.hpp"
#include <optional>
#include <memory>
#include <string>

Classes

class  ClipDelegate
 

Typedefs

using PDelegate = std::unique_ptr< ClipDelegate >
 
using WidgetHook = model::CanvasHook< Gtk::Widget >
 

Namespaces

 stage
 Lumiera GTK UI implementation root.
 
 stage::timeline
 The timeline display and editing operations.