Timeline: add the typical framework for custom drawing on the canvas
see gtk-canvas-experiment.cpp
This commit is contained in:
parent
615796d812
commit
ad9043ae1d
6 changed files with 125 additions and 23 deletions
|
|
@ -77,12 +77,12 @@ namespace timeline {
|
||||||
this->property_expand() = true; // dynamically grab any available additional space
|
this->property_expand() = true; // dynamically grab any available additional space
|
||||||
this->add(canvas_);
|
this->add(canvas_);
|
||||||
|
|
||||||
{ // for the initial empty canvas -- use space the enclosing scrolled window got.
|
{ // for the initial empty canvas -- use all space the enclosing scrolled window got.
|
||||||
auto currSize = get_allocation();
|
auto currSize = get_allocation();
|
||||||
canvas_.set_size (currSize.get_width(), currSize.get_height());
|
canvas_.set_size (currSize.get_width(), currSize.get_height());
|
||||||
}
|
}
|
||||||
|
|
||||||
// show everything....
|
// realise all initially configured elements....
|
||||||
this->show_all();
|
this->show_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,7 +101,103 @@ namespace timeline {
|
||||||
{
|
{
|
||||||
canvas_.rootBody_ = &rootTrackBody;
|
canvas_.rootBody_ = &rootTrackBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom drawing of the timeline content area.
|
||||||
|
* The inherited `Gtk::Layout::on_raw(Context)` handles all drawing of child widgets placed onto the virtual canvas.
|
||||||
|
* Thus we need to fill in the structure of the tracks in the timeline background, and any non-standard overlay elements,
|
||||||
|
* including tags and markers, indicators, locators (edit point and playhead) and (semi-transparent) range selections.
|
||||||
|
* @todo according to the documentation for `signal_draw()`, the framework passes the actually visible area as clipping
|
||||||
|
* region. In theory, this information could be used to reduce the load of canvas painting and repainting, which
|
||||||
|
* becomes crucial for responsiveness on large sessions ////////////////////////////////////TICKET #1191
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
TimelineCanvas::on_draw (Cairo::RefPtr<Cairo::Context> const& cox)
|
||||||
|
{
|
||||||
|
// draw track structure behind all widgets
|
||||||
|
openCanvas (cox);
|
||||||
|
drawGrounding (cox);
|
||||||
|
closeCanvas (cox);
|
||||||
|
|
||||||
|
// cause child widgets to be redrawn
|
||||||
|
bool event_is_handled = Gtk::Layout::on_draw(cox);
|
||||||
|
|
||||||
|
// draw dynamic markers and locators on top
|
||||||
|
openCanvas (cox);
|
||||||
|
drawOverlays (cox);
|
||||||
|
closeCanvas (cox);
|
||||||
|
|
||||||
|
return event_is_handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare the drawing canvas to work within our virtual canvas coordinate system.
|
||||||
|
* @remarks GTK passes a context related to the actual window area; however, we need to create
|
||||||
|
* a uniform virtual canvas, shared by the child widgets, the backgrounding and any overlays.
|
||||||
|
* To make this work, we have to connect to the scrollbar adjustments, since GTK does this
|
||||||
|
* only for the child widgets on the canvas, not for any custom painting.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TimelineCanvas::openCanvas (Cairo::RefPtr<Cairo::Context> const& cox)
|
||||||
|
{
|
||||||
|
auto adjH = get_hadjustment();
|
||||||
|
auto adjV = get_vadjustment();
|
||||||
|
double offH = adjH->get_value();
|
||||||
|
double offV = adjV->get_value();
|
||||||
|
|
||||||
|
cox->save();
|
||||||
|
cox->translate(-offH, -offV);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish and close the virtual drawing canvas established by #openCanvas().
|
||||||
|
* Discard any coordinate offsets, stroke and drawing settings applied within.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TimelineCanvas::closeCanvas (Cairo::RefPtr<Cairo::Context> const& cox)
|
||||||
|
{
|
||||||
|
cox->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Establish and render the structure of (possibly nested) tracks and overview rulers.
|
||||||
|
* @param cox cairo drawing context for custom drawing, adjusted for our virtual canvas.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TimelineCanvas::drawGrounding (Cairo::RefPtr<Cairo::Context> const& cox)
|
||||||
|
{
|
||||||
|
/////////////////////////////////////////////TICKET #1139 : placeholder drawing
|
||||||
|
cox->set_source_rgb(0.8, 0.0, 0.0);
|
||||||
|
cox->set_line_width (5.0);
|
||||||
|
cox->rectangle(0,0, 80, 40);
|
||||||
|
cox->stroke();
|
||||||
|
/////////////////////////////////////////////TICKET #1139 : placeholder drawing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param cox cairo drawing context of the virtual canvas for custom drawing.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TimelineCanvas::drawOverlays (Cairo::RefPtr<Cairo::Context> const& cox)
|
||||||
|
{
|
||||||
|
/////////////////////////////////////////////TICKET #1139 : placeholder drawing
|
||||||
|
auto alloc = get_allocation();
|
||||||
|
int w = alloc.get_width();
|
||||||
|
int h = alloc.get_height();
|
||||||
|
int rad = MIN (w,h) / 2;
|
||||||
|
|
||||||
|
cox->set_source_rgb(0.2, 0.4, 0.9); // blue
|
||||||
|
cox->set_line_width (2.0);
|
||||||
|
cox->arc(rad, rad, rad, 0.0, 2.0*M_PI); // full circle
|
||||||
|
cox->stroke();
|
||||||
|
/////////////////////////////////////////////TICKET #1139 : placeholder drawing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@
|
||||||
** on top of Gtk::Layout, allows to combine _custom drawing_ with the placement of
|
** 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
|
** 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
|
** by the toolkit set. This approach allows us to circumvent some of the perils of
|
||||||
** custom drawing, where we might forfeit several of the benefits of using a toolkit
|
** custom drawing, where we might forfeit several of the benefits of using a toolkit,
|
||||||
** unintentionally, and create an UI which feels foreign and brittle in comparison
|
** unintentionally of course, and create an UI which feels foreign and brittle
|
||||||
** to standard software.
|
** in comparison to standard software.
|
||||||
**
|
**
|
||||||
** # Layout management
|
** # Layout management
|
||||||
**
|
**
|
||||||
** To create a consistent layout of the timeline, header pane and body need to react
|
** To create a consistent timeline layout, the header pane and body need to react
|
||||||
** to the same scrolling adjustments, and use the same vertical size allocations for
|
** to the same scrolling adjustments, and use the same vertical size allocations for
|
||||||
** each embedded track. Such a consistent global layout needs to be built up in a
|
** each embedded track. Such a consistent global layout needs to be built up in a
|
||||||
** *display evaluation pass*, carried out collaboratively between the building blocks
|
** *display evaluation pass*, carried out collaboratively between the building blocks
|
||||||
|
|
@ -45,8 +45,8 @@
|
||||||
** as (view) model entities, visited by the timeline::LayoutManager to establish
|
** as (view) model entities, visited by the timeline::LayoutManager to establish
|
||||||
** coherent display parameters. From within this evaluation pass, the individual
|
** coherent display parameters. From within this evaluation pass, the individual
|
||||||
** presenters communicate with their _slave widgets,_ which are inserted into the
|
** presenters communicate with their _slave widgets,_ which are inserted into the
|
||||||
** display context of the track header pane or this body widget respectively. As
|
** display context of the track header pane or into this body widget respectively.
|
||||||
** a result, some new widgets may be injected, existing widgets may be removed or
|
** As result, some new widgets may be injected, existing widgets might be removed or
|
||||||
** hidden, and other widgets may be relocated to different virtual canvas coordinates.
|
** hidden, and other widgets may be relocated to different virtual canvas coordinates.
|
||||||
**
|
**
|
||||||
** @todo WIP-WIP-WIP as of 12/2016
|
** @todo WIP-WIP-WIP as of 12/2016
|
||||||
|
|
@ -79,6 +79,15 @@ namespace timeline {
|
||||||
TrackBody* rootBody_;
|
TrackBody* rootBody_;
|
||||||
|
|
||||||
TimelineCanvas();
|
TimelineCanvas();
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool on_draw (Cairo::RefPtr<Cairo::Context> const&) override;
|
||||||
|
|
||||||
|
void openCanvas (Cairo::RefPtr<Cairo::Context> const&);
|
||||||
|
void closeCanvas (Cairo::RefPtr<Cairo::Context> const&);
|
||||||
|
|
||||||
|
void drawGrounding (Cairo::RefPtr<Cairo::Context> const&);
|
||||||
|
void drawOverlays (Cairo::RefPtr<Cairo::Context> const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,8 @@
|
||||||
** Thus we strive to break up the whole process of controlling the layout into several
|
** Thus we strive to break up the whole process of controlling the layout into several
|
||||||
** local concerns, each of which can be made self contained. The backbone is formed by
|
** local concerns, each of which can be made self contained. The backbone is formed by
|
||||||
** a recursive collaboration between two abstractions (interfaces)
|
** a recursive collaboration between two abstractions (interfaces)
|
||||||
** - the building blocks of the timeline expose the interface timeline::Element
|
** - the building blocks of the timeline expose the interface timeline::Element (TODO 12/18 really?)
|
||||||
** - the global timeline widget implements a timeline::LayoutManager interface
|
** - the global timeline widget implements a timeline::LayoutManager interface (TODO 12/18 work out the crucial point of that interface!)
|
||||||
**
|
**
|
||||||
** ## Display evaluation pass
|
** ## Display evaluation pass
|
||||||
**
|
**
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ namespace timeline {
|
||||||
|
|
||||||
TrackBody::TrackBody()
|
TrackBody::TrackBody()
|
||||||
: overviewHeight_{DEFAULT_OVERVIEW_HEIGHT_px}
|
: overviewHeight_{DEFAULT_OVERVIEW_HEIGHT_px}
|
||||||
, contentHeight_{DEFAULT_OVERVIEW_HEIGHT_px}
|
, contentHeight_{DEFAULT_CONTENT_HEIGHT_px}
|
||||||
, subTracks_{}
|
, subTracks_{}
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ namespace timeline {
|
||||||
* A given TrackBody works with coordinates relative to its vertical starting point;
|
* A given TrackBody works with coordinates relative to its vertical starting point;
|
||||||
* coordinates on the TimelineCanvas operate from top downwards. The fundamental
|
* coordinates on the TimelineCanvas operate from top downwards. The fundamental
|
||||||
* task of a TrackBody is to find out about its own overall height, including the
|
* task of a TrackBody is to find out about its own overall height, including the
|
||||||
* overall height require by all its nesting children. Moreover, the height of
|
* overall height required by all its nested children. Moreover, the height of
|
||||||
* the content area needs to be negotiated with the actual content elements.
|
* the content area needs to be negotiated with the actual content elements.
|
||||||
* @todo WIP-WIP as of 10/2018
|
* @todo WIP-WIP as of 10/2018
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -19423,8 +19423,7 @@
|
||||||
...in dem der Timeline body-canvas nämlich liegt
|
...in dem der Timeline body-canvas nämlich liegt
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
<icon BUILTIN="idea"/>
|
<icon BUILTIN="idea"/>
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -19577,7 +19576,7 @@
|
||||||
<icon BUILTIN="flag-yellow"/>
|
<icon BUILTIN="flag-yellow"/>
|
||||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1540640109628" ID="ID_147809215" MODIFIED="1540640128945" TEXT="TODO: TimelineGui (proxy) muß kaskadieren">
|
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1540640109628" ID="ID_147809215" MODIFIED="1540640128945" TEXT="TODO: TimelineGui (proxy) muß kaskadieren">
|
||||||
<icon BUILTIN="flag-pink"/>
|
<icon BUILTIN="flag-pink"/>
|
||||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1544135984042" ID="ID_429363053" MODIFIED="1544310842213" TEXT="Grund für den Fehler im Nexus?">
|
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1544135984042" ID="ID_429363053" MODIFIED="1544136004274" TEXT="Grund für den Fehler im Nexus?">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
|
|
@ -21297,7 +21296,7 @@
|
||||||
<node CREATED="1541860174509" ID="ID_983216306" MODIFIED="1541860194622" TEXT="position within window">
|
<node CREATED="1541860174509" ID="ID_983216306" MODIFIED="1541860194622" TEXT="position within window">
|
||||||
<node CREATED="1541860195426" ID="ID_1143510761" MODIFIED="1541860197638" TEXT="relative"/>
|
<node CREATED="1541860195426" ID="ID_1143510761" MODIFIED="1541860197638" TEXT="relative"/>
|
||||||
<node CREATED="1541860198222" ID="ID_847832000" MODIFIED="1541860200197" TEXT="absolute">
|
<node CREATED="1541860198222" ID="ID_847832000" MODIFIED="1541860200197" TEXT="absolute">
|
||||||
<node CREATED="1544126105472" ID="ID_1636490570" MODIFIED="1544310842664" TEXT="relative-absolute">
|
<node CREATED="1544126105472" ID="ID_1636490570" MODIFIED="1544126149549" TEXT="relative-absolute">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
|
|
@ -21319,7 +21318,7 @@
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1542384160498" ID="ID_1252241860" MODIFIED="1542384163677" TEXT="TimeWindow">
|
<node CREATED="1542384160498" ID="ID_1252241860" MODIFIED="1542384163677" TEXT="TimeWindow">
|
||||||
<node CREATED="1542384165737" ID="ID_705415129" MODIFIED="1542384177115" TEXT="die konkret sichbare TimeSpan"/>
|
<node CREATED="1542384165737" ID="ID_705415129" MODIFIED="1542384177115" TEXT="die konkret sichbare TimeSpan"/>
|
||||||
<node CREATED="1542384188438" ID="ID_444895141" MODIFIED="1544310842677" TEXT="stets in realem relativem Zeitmaß">
|
<node CREATED="1542384188438" ID="ID_444895141" MODIFIED="1542384280140" TEXT="stets in realem relativem Zeitmaß">
|
||||||
<richcontent TYPE="NOTE"><html>
|
<richcontent TYPE="NOTE"><html>
|
||||||
<head>
|
<head>
|
||||||
|
|
||||||
|
|
@ -21334,8 +21333,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1541859633805" ID="ID_304890799" MODIFIED="1541859637628" TEXT="Scale">
|
<node CREATED="1541859633805" ID="ID_304890799" MODIFIED="1541859637628" TEXT="Scale">
|
||||||
|
|
@ -21383,7 +21381,7 @@
|
||||||
<node CREATED="1541860828603" ID="ID_111513506" MODIFIED="1541860839002" TEXT="Zeit"/>
|
<node CREATED="1541860828603" ID="ID_111513506" MODIFIED="1541860839002" TEXT="Zeit"/>
|
||||||
<node CREATED="1541860831875" ID="ID_1775831703" MODIFIED="1541860835311" TEXT="Extension"/>
|
<node CREATED="1541860831875" ID="ID_1775831703" MODIFIED="1541860835311" TEXT="Extension"/>
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1541860818012" FOLDED="true" ID="ID_814200290" MODIFIED="1541860825864" TEXT="vertikale Dimension stets topologisch">
|
<node CREATED="1541860818012" FOLDED="true" ID="ID_814200290" MODIFIED="1544127129504" TEXT="vertikale Dimension stets topologisch">
|
||||||
<node CREATED="1544127119809" ID="ID_431805088" MODIFIED="1544127122858" TEXT="nicht immer...."/>
|
<node CREATED="1544127119809" ID="ID_431805088" MODIFIED="1544127122858" TEXT="nicht immer...."/>
|
||||||
<node CREATED="1544127123803" ID="ID_1360167609" MODIFIED="1544127127665" TEXT="Ausnahme: Kurven"/>
|
<node CREATED="1544127123803" ID="ID_1360167609" MODIFIED="1544127127665" TEXT="Ausnahme: Kurven"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
@ -40734,8 +40732,7 @@
|
||||||
...also <i>abzüglich</i> Dekoration und Margin
|
...also <i>abzüglich</i> Dekoration und Margin
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html></richcontent>
|
||||||
</richcontent>
|
|
||||||
</node>
|
</node>
|
||||||
<node CREATED="1542308990570" ID="ID_1371068296" MODIFIED="1542309000371" TEXT="stets komplett in der zugewiesenen Allocation enthalten"/>
|
<node CREATED="1542308990570" ID="ID_1371068296" MODIFIED="1542309000371" TEXT="stets komplett in der zugewiesenen Allocation enthalten"/>
|
||||||
</node>
|
</node>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue