Timeline: complete the rework of UI backbone and Timeline (closes: #1014)
check private notes and mindmap and fix some remaining minor inconsistencies, notably the calculations in the overlay renderer in the `BodyCanvasWidget`.
This commit is contained in:
parent
8d9846837d
commit
28331f9f8a
8 changed files with 669 additions and 346 deletions
|
|
@ -36,10 +36,12 @@
|
|||
** timeline::TrackBody::establishTrackSpace(), based on specifications drawn from the real
|
||||
** CSS layout definitions. Here, within this translation unit, we define the corresponding
|
||||
** timeline::ProfileInterpreter implementations; these are the concrete visitors and are
|
||||
** invoked repeatedly to carry out the actual drawing requests.
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 6/2019
|
||||
** invoked repeatedly to carry out the actual drawing requests.
|
||||
**
|
||||
** @todo as of 3/2023 the foundation of this rewritten, highly flexible drawing code established,
|
||||
** and the layout seemingly behaves reasonably stable and visually as expected, yet with
|
||||
** some minor glitches. Any kind of dynamic adjustment in response to expanding/collapsing
|
||||
** or the content representation of clips is *not yet implemented*
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -50,34 +52,22 @@
|
|||
#include "stage/timeline/track-body.hpp"
|
||||
#include "stage/style-scheme.hpp"
|
||||
|
||||
//#include "stage/ui-bus.hpp"
|
||||
//#include "lib/format-string.hpp"
|
||||
#include "lib/format-cout.hpp"//////////////TODO
|
||||
|
||||
#include "common/advice.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <algorithm>
|
||||
//#include <vector>
|
||||
#include <utility>
|
||||
|
||||
|
||||
|
||||
//using util::_Fmt;
|
||||
using lib::time::Time;
|
||||
using util::max;
|
||||
using util::isnil;
|
||||
//using util::contains;
|
||||
//using Gtk::Widget;
|
||||
using Gdk::Rectangle;
|
||||
//using sigc::mem_fun;
|
||||
//using sigc::ptr_fun;
|
||||
//using std::cout;
|
||||
//using std::endl;
|
||||
using std::string;
|
||||
using std::move;
|
||||
|
||||
|
||||
|
||||
namespace stage {
|
||||
namespace timeline {
|
||||
|
||||
|
|
@ -147,7 +137,7 @@ namespace timeline {
|
|||
styleBody->add_class (slopeClassName(depth));
|
||||
|
||||
TrackBody::decoration.borders[depth] = styleBody->get_border().get_bottom();
|
||||
TrackBody::decoration.borders[0] = styleBody->get_border().get_top(); // Note: we use a common size for all opening borders
|
||||
TrackBody::decoration.borders[0] = styleBody->get_border().get_top(); // Note: we use a common size for all opening borders
|
||||
|
||||
styleBody->remove_class (slopeClassName(depth));
|
||||
// styleBody->context_restore(); // <<<---does not work...
|
||||
|
|
@ -167,15 +157,17 @@ namespace timeline {
|
|||
* mechanism to invoke a set of (virtual) drawing primitives, the
|
||||
* actual drawing code is in the two following subclasses,
|
||||
* separate for the background and for drawing overlays.
|
||||
* @note the *invariant* is: after processing a _verb_ from the profile,
|
||||
* all drawing including the current "water level" #line_ is complete.
|
||||
*/
|
||||
class AbstractTrackRenderer
|
||||
: public ProfileInterpreter
|
||||
{
|
||||
protected:
|
||||
CairoC cox_;
|
||||
StyleC style_;
|
||||
StyleC styleR_;
|
||||
PixSpan visible_;
|
||||
StyleC style_; // CSS style for the main track body
|
||||
StyleC styleR_; // CSS style for the an overview ruler
|
||||
PixSpan visible_; // vertical extension of the timeline
|
||||
|
||||
/** the current painting "water level".
|
||||
* To be updated while drawing top-down */
|
||||
|
|
@ -195,10 +187,18 @@ namespace timeline {
|
|||
public:
|
||||
AbstractTrackRenderer (CairoC currentDrawContext, DisplayManager& layout)
|
||||
: cox_{currentDrawContext}
|
||||
, style_{trackBodyStyle.getAdvice()} // storing a const& to the advice is potentially dangerous, but safe here, since it is not long-lived
|
||||
, style_{trackBodyStyle.getAdvice()}
|
||||
, styleR_{trackRulerStyle.getAdvice()}
|
||||
, visible_{layout.getPixSpan()}
|
||||
{ }
|
||||
/*
|
||||
* Note: we store a const& to the advice in the member fields.
|
||||
* This is potentially dangerous, but seems adequate here, since
|
||||
* the renderer instance does not outlive the BodyCanvasWidget,
|
||||
* and the style context accessed through the advice is created
|
||||
* once, at application startup. Please take into account that
|
||||
* this drawing code is invoked very frequently from GUI thread.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -299,14 +299,18 @@ namespace timeline {
|
|||
}
|
||||
|
||||
/** paint closing slope to finish nested sub tracks
|
||||
* @param n number of nested levels to close */
|
||||
* @param n number of nested levels to close
|
||||
* @note to get drawing of the border corners right,
|
||||
* we "set back" by the border width and draw some spurious
|
||||
* vertical part, hidden outside of the visible canvas area.
|
||||
*/
|
||||
void
|
||||
close (uint n) override
|
||||
{
|
||||
// style_->context_save(); // <<<---does not work. Asked on SO: https://stackoverflow.com/q/57342478
|
||||
style_->add_class (slopeClassName(n));
|
||||
int slopeWidth = style_->get_border().get_bottom();
|
||||
line_ -= slopeWidth; // set back to create room for the (invisible) top side of the frame
|
||||
line_ -= slopeWidth; // set back to create room for the (invisible) top side of the frame
|
||||
style_->render_frame_gap(cox_
|
||||
,visible_.b
|
||||
+30 ////////////////////////////////////////TODO: visual debugging
|
||||
|
|
@ -351,35 +355,60 @@ namespace timeline {
|
|||
}
|
||||
|
||||
/** draw overlays on top of overview/ruler track
|
||||
* @param h ruler track height */
|
||||
* @param contentHeight ruler track height */
|
||||
void
|
||||
ruler (uint h) override
|
||||
ruler (uint contentHeight) override
|
||||
{
|
||||
line_ += h;
|
||||
int marTop = styleR_->get_margin().get_top();
|
||||
int marBot = styleR_->get_margin().get_bottom();
|
||||
int padTop = styleR_->get_padding().get_top();
|
||||
int padBot = styleR_->get_padding().get_bottom();
|
||||
int frameT = styleR_->get_border().get_top();
|
||||
int frameB = styleR_->get_border().get_bottom();
|
||||
|
||||
int heightWithFrame = contentHeight + padTop+padBot + frameT+frameB;
|
||||
|
||||
/* nothing to paint */
|
||||
line_ += marTop
|
||||
+ heightWithFrame
|
||||
+ marBot;
|
||||
}
|
||||
|
||||
/** render overlays on top of padding/gap */
|
||||
void
|
||||
gap (uint h) override
|
||||
{
|
||||
UNIMPLEMENTED ("overlays for gap");
|
||||
/* nothing to paint */
|
||||
line_ += h;
|
||||
}
|
||||
|
||||
/** place overlays on top of of track content area,
|
||||
* @remark anything to show semi-transparent
|
||||
* on top of the content clips */
|
||||
void
|
||||
content (uint h) override
|
||||
content (uint contentHeight) override
|
||||
{
|
||||
int marTop = style_->get_margin().get_top();
|
||||
int marBot = style_->get_margin().get_bottom();
|
||||
int padTop = style_->get_padding().get_top();
|
||||
int padBot = style_->get_padding().get_bottom();
|
||||
int heightWithPadding = contentHeight + padTop+padBot;
|
||||
|
||||
/* nothing to paint */
|
||||
line_ += h;
|
||||
line_ += marTop
|
||||
+ heightWithPadding
|
||||
+ marBot;
|
||||
}
|
||||
|
||||
/** render overlays covering the opening slope towards nested tracks */
|
||||
void
|
||||
open() override
|
||||
{
|
||||
// style_->context_save(); // <<<---does not work. Asked on SO: https://stackoverflow.com/q/57342478
|
||||
style_->add_class (slopeClassName (1));
|
||||
int slopeWidth = style_->get_border().get_top();
|
||||
// style_->context_restore(); // <<<---does not work...
|
||||
style_->remove_class (slopeClassName(1));
|
||||
line_ += slopeWidth;
|
||||
}
|
||||
|
||||
|
|
@ -387,11 +416,12 @@ namespace timeline {
|
|||
void
|
||||
close (uint n) override
|
||||
{
|
||||
style_->context_save();
|
||||
style_->add_class(slopeClassName(n));
|
||||
// style_->context_save(); // <<<---does not work. Asked on SO: https://stackoverflow.com/q/57342478
|
||||
style_->add_class (slopeClassName(n));
|
||||
int slopeWidth = style_->get_border().get_bottom();
|
||||
// style_->context_restore(); // <<<---does not work...
|
||||
style_->remove_class (slopeClassName(n));
|
||||
line_ += slopeWidth;
|
||||
style_->context_restore();
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
** implemented with automatic layout by the UI toolkit set. Rather, we need to
|
||||
** control a precise temporal display grid, and we need to limit the actual widgets
|
||||
** added for display, since a given timeline may easily hold several hundred up to
|
||||
** thousands of elements. To ease such tasks, a _canvas control_ -- here implemented
|
||||
** thousands of elements. To ease such tasks, a _canvas control_ — here implemented
|
||||
** on top of Gtk::Layout, allows to combine _custom drawing_ with the placement of
|
||||
** embedded child widgets, where the latter's layout is again managed automatically
|
||||
** by the toolkit set. This approach allows us to circumvent some of the perils of
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
**
|
||||
** ## Coordinate systems
|
||||
** When drawing onto a canvas, we need to define the coordinate system. This task is
|
||||
** complicated here, since -- on implementation level -- we end up with several `Gtk::Layout`
|
||||
** complicated here, since — on implementation level — we end up with several `Gtk::Layout`
|
||||
** elements (the actual canvas widget). This is necessary to accommodate for the display
|
||||
** "mechanics": part of the timeline has to stay "pinned" on top, including the time
|
||||
** overview ruler and possible further marker displays. Based on practical considerations
|
||||
|
|
@ -66,8 +66,6 @@
|
|||
** So effectively, from the view point of (sub)widget management, we thus get virtual
|
||||
** canvas coordinates per (sub)track.
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 6/2019
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -137,7 +135,6 @@ namespace timeline {
|
|||
* On the other hand, for attachment of sub-widgets onto the canvas (Clips, Effects, Markers)
|
||||
* we use the Interface model::CanvasHook, which allows us to break down the access hierarchically.
|
||||
* Each sub-Track can be outfitted with its own "virtual canvas", exposed as delegating CanvasHook.
|
||||
* @todo WIP-WIP as of 6/2019
|
||||
*/
|
||||
class BodyCanvasWidget
|
||||
: public Gtk::Box
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@
|
|||
/** @file timeline-layout.cpp
|
||||
** Implementation details of global timeline layout management.
|
||||
**
|
||||
** @todo as of 10/2018 timeline display in the UI is rebuilt to match the architecture
|
||||
** @todo WIP-WIP-WIP as of 12/2019
|
||||
**
|
||||
** @see track-body.cpp for mapping individual tracks onto the common canvas
|
||||
** @see body-canvas-widget.cpp for painting track background and overlays
|
||||
**
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@
|
|||
** @see TrackBody::establishTrackSpace (TrackProfile&)
|
||||
** @see BodyCanvasWidget::maybeRebuildLayout() invocation
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 6/2019
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
** in the [header pane](\ref timeline::HeaderPaneWidget) and the display of the
|
||||
** timeline body; the latter is actually a canvas for custom drawing.
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 12/2016
|
||||
** @todo as of 3/2023 the reworked Timeline-UI is basically complete
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
** which serves to control such aspects relevant for all content contained within the scope
|
||||
** of this track, including the sub-tracks nested therein.
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 10/2018
|
||||
** @todo as of 3/2023 the reworked Timeline-UI is basically complete
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@
|
|||
** investigated when there is a sufficiently complete implementation available -- see #1254
|
||||
**
|
||||
** @todo as of 10/2018 timeline display in the UI is rebuilt to match the architecture
|
||||
** @todo still WIP as of 3/2020 -- yet the basic structure is settled by now.
|
||||
** @todo as of 3/2023, the basic structure is settled and the design validated
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue