Lumiera  0.pre.03
»edit your freedom«
zoom-window.hpp File Reference

Go to the source code of this file.

Description

Abstraction: the current zoom- and navigation state of a view, possibly in multiple dimensions.

This is a generic component to represent and handle the zooming and positioning of views within an underlying model space. This model space is conceived to be two fold:

  • it is a place or excerpt within the model topology (e.g. the n-th track in the fork)
  • it has a temporal extension within a larger temporal frame (e.g. some seconds within the timeline) This component is called »Zoom Window«, since it represents a window-like local visible interval, embedded into a larger time span covering a complete timeline.
    Note
    as of 10/2022 this component is in an early stage of development and just used to coordinate the horizontal extension of the timeline view.

Rationale

Working with and arranging media requires a lot of navigation and changes of zoom detail level. More specifically, the editor is required to repeatedly return to the same locations and show arrangements at the same alternating scale levels. Most existing editing applications approach this topic naively, by just responding to some coarse grained interaction controls — thereby creating the need for a lot of superfluous and tedious search and navigation activities, causing constant grind for the user. And resolving these obnoxious shortcomings turns out as a never ending task, precisely due to the naive and ad-hoc approach initially taken. Based on these observations, the design of the Lumiera UI calls for centralisation of all zoom- and navigation handling into a single component, instantiated once for every visible context, outfitted with the ability to capture and maintain a history of zoom and navigation activities. The current zoom state is thus defined by

  • the overall TimeSpan of the timeline, defining a start and end time
  • the visible interval („window“), likewise modelled as time::TimeSpan
  • the scale defined as pixels per second
    Todo:
    as of 12/2022 it rather seems the more general navigation should be abstracted at a higher level, leaving ZoomWindow mostly focused on time scale handling.

Interactions

The basic parameters can be changed and adjusted through various setters, dedicated to specific usage scenarios. After invoking any setter, one of the mutating functions is invoked to adjust the base parameters and then re-establish the invariant

  • visible window lies completely within the overall range
  • scale factor and visible window line up logically
  • scale factor produces precise reproducible values

Safety Guards

Most setters require lib::time::TimeSpan or lib::time::Duration as value arguments; based on those entities internal definition, they can be assumed to be sanitised, within TimeValue bounds and properly oriented. Other setters taking possibly negative numbers are prepared to handle these (e.g. as offset). Range checks are in place to prevent possibly dangerous numbers from infesting the calculations.

Note
rational integral arithmetics can be insidious, since normalisation requires frequent multiplications, and large denominators might cause numeric overflow.

Change listener

A single change listener lambda can be installed (as of 10/2022 this is considered sufficient, since only the TimelineLayout was identified as collaborator requiring push notification). This callback will be invoked after any effective change and serves as notification; the receiver is expected to read the current settings by invoking the getters.

Todo:
WIP-WIP as of 10/2022 the usage is just emerging, while the actual meaning of this interface still remains somewhat nebulous...
See also
ZoomWindow_test

Definition in file zoom-window.hpp.

#include "lib/error.hpp"
#include "lib/rational.hpp"
#include "lib/time/timevalue.hpp"
#include "lib/nocopy.hpp"
#include "lib/util.hpp"
#include <limits>
#include <functional>
#include <array>

Classes

class  ZoomWindow
 A component to ensure uniform handling of zoom scale and visible interval on the timeline. More...
 

Functions

FSecs _FSecs (TimeValue const &timeVal)
 
double approx (Rat r)
 
bool isMicroGridAligned (FSecs duration)
 
TimeVar operator+ (Time const &tval, TimeVar const &tvar)
 
TimeVar operator- (Time const &tval, TimeVar const &tvar)
 
int toxicDegree (Rat poison, const int64_t THRESHOLD=HAZARD_DEGREE)
 

Variables

const FSecs DEFAULT_CANVAS {23}
 
const Rat DEFAULT_METRIC {25}
 
const int64_t HAZARD_DEGREE {util::ilog2(LIM_HAZARD)}
 
const int64_t LIM_HAZARD {int64_t{1} << 40 }
 Maximum quantiser to be handled in fractional arithmetics without hazard. More...
 
const uint MAX_PX_WIDTH {100000}
 
const FSecs MAX_TIMESPAN {_FSecs(Duration::MAX)}
 
const int64_t MAXDIM {util::ilog2 (std::numeric_limits<int64_t>::max())}
 
const FSecs MICRO_TICK {1_r/Time::SCALE}
 
const Rat ZOOM_MAX_RESOLUTION = 2 * TimeValue::SCALE
 the deepest zoom is to use 2px per micro-tick
 

Namespaces

 stage
 Lumiera GTK UI implementation root.
 
 stage::model
 The Lumiera GTK-GUI uses a thin proxy layer data model on top of the actual "high-level-model", which lives in the Steam-Layer below.