Timeline: complete integration of bracket drawing into the Layout
- pick up all relevant values from CSS - also control the width of the StaveBracket - observe the given overall height Moreover, complete documentation drawing in Inkscape and add a page to the TiddlyWiki, describing the principles underlying this design and construction.
This commit is contained in:
parent
47108fa2d8
commit
fc74fbcd4f
7 changed files with 415 additions and 183 deletions
|
|
@ -10,7 +10,7 @@
|
|||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="100mm"
|
||||
height="100mm"
|
||||
height="120mm"
|
||||
viewBox="0 0 100 100"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
|
|
@ -19,7 +19,21 @@
|
|||
<title
|
||||
id="title815">StaveBracket</title>
|
||||
<defs
|
||||
id="defz" />
|
||||
id="defz">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mend"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path896"
|
||||
style="fill:#004d83;stroke:#004d83;stroke-width:0.5;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) rotate(180) translate(0,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
|
|
@ -27,12 +41,12 @@
|
|||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="2.2436667"
|
||||
inkscape:cx="-134.23558"
|
||||
inkscape:cy="420.39176"
|
||||
inkscape:zoom="1.8697222"
|
||||
inkscape:cx="188.97638"
|
||||
inkscape:cy="226.77165"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="svg8"
|
||||
showgrid="true"
|
||||
showgrid="false"
|
||||
width="100mm"
|
||||
inkscape:window-width="1680"
|
||||
inkscape:window-height="1031"
|
||||
|
|
@ -47,7 +61,7 @@
|
|||
id="snapgrid"
|
||||
units="mm"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
spacingy="0.83333334"
|
||||
visible="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
|
|
@ -95,51 +109,96 @@
|
|||
inkscape:label="Drawing:Bracket"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:none;stroke:teal;stroke-width:0.1"
|
||||
id="rect821"
|
||||
width="10"
|
||||
height="10"
|
||||
x="77"
|
||||
y="61" />
|
||||
<g
|
||||
id="phi_pos"
|
||||
transform="translate(20,50)">
|
||||
<g
|
||||
id="phi">
|
||||
<rect
|
||||
id="phiMaj"
|
||||
y="0"
|
||||
x="0"
|
||||
height="10"
|
||||
width="10"
|
||||
style="fill:none;stroke:teal;stroke-width:0.1" />
|
||||
<rect
|
||||
id="phiMin"
|
||||
y="0"
|
||||
x="0"
|
||||
height="6.1803398"
|
||||
width="6.1803398"
|
||||
style="fill:none;stroke:teal;stroke-width:0.1" />
|
||||
<rect
|
||||
id="phiMinI"
|
||||
y="3.8196602"
|
||||
x="3.8196602"
|
||||
height="6.1803398"
|
||||
width="6.1803398"
|
||||
style="fill:none;stroke:teal;stroke-width:0.1" />
|
||||
<text
|
||||
id="phisym"
|
||||
x="3.8193359"
|
||||
y="6.0935059"
|
||||
style="font-size:3px;font-family:Sans;fill:teal;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
id="phispan"
|
||||
sodipodi:role="line"
|
||||
x="3.8193359"
|
||||
y="6.0935059">Φ</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
id="cap_u"
|
||||
transform="matrix(10,0,0,10,50,70)"
|
||||
style="fill:#a0a0a0;stroke:none;stroke-width:0.01"
|
||||
d="M 2.2360679,-2.6180343 C 1.5784391,-1.5539685 0.68209953,-0.65762901 -0.38196626,-2.438908e-7 l 9e-8,-0.9999998561092 C 0.60447706,-1.3288145 1.5008166,-1.8827827 2.236068,-2.6180341"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
id="dubline"
|
||||
transform="matrix(10,0,0,10,50,69.999999)"
|
||||
style="fill:#787878;stroke:none;stroke-width:0.01"
|
||||
d="M 0.47213596,0 H 0.61803399 V 3.9 H 0.47213596 Z M -0.38196602,-1 H 0 v 4.9000001 h -0.38196602 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccc" />
|
||||
<text
|
||||
id="phisym"
|
||||
x="73.087059"
|
||||
y="55.067478"
|
||||
style="font-size:3px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
id="phispan"
|
||||
sodipodi:role="line"
|
||||
x="73.087059"
|
||||
y="55.067478">Φ</tspan></text>
|
||||
<text
|
||||
id="phisym2"
|
||||
x="50.139442"
|
||||
y="69.676567"
|
||||
style="font-size:3px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan9"
|
||||
sodipodi:role="line"
|
||||
x="50.139442"
|
||||
y="69.676567">Φ</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:3px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
y="44.16069"
|
||||
x="73.087059"
|
||||
id="text851"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan853"
|
||||
x="73.087059"
|
||||
y="44.16069">Φ²</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:1.40999997px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
y="47.16256"
|
||||
x="73.287186"
|
||||
id="text857"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan859"
|
||||
x="73.287186"
|
||||
y="47.16256">square_minor</tspan></text>
|
||||
<text
|
||||
id="text863"
|
||||
x="36.264141"
|
||||
y="61.371403"
|
||||
style="font-size:1.40999997px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
y="61.371403"
|
||||
x="36.264141"
|
||||
id="tspan861"
|
||||
sodipodi:role="line">square_minor</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:1.40999997px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
y="71.477699"
|
||||
x="46.370426"
|
||||
id="text867"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan869"
|
||||
x="46.370426"
|
||||
y="71.477699">base width</tspan></text>
|
||||
<text
|
||||
id="text862"
|
||||
x="39.266003"
|
||||
y="67.275085"
|
||||
style="font-size:1.40999997px;font-family:Sans;fill:#004d83;stroke:none"
|
||||
xml:space="preserve"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan864"
|
||||
x="39.266003"
|
||||
y="67.275085">origin</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#004d83;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;marker-end:url(#Arrow2Mend)"
|
||||
d="m 42.251299,67.623625 c 0,0 4.62788,-0.12508 7.179468,1.951212"
|
||||
id="orgptr"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
|
|
@ -147,7 +206,7 @@
|
|||
inkscape:label="Construction" >
|
||||
<g
|
||||
id="r_trans"
|
||||
transform="scale(10)">
|
||||
transform="matrix(10,0,0,10,50,70)">
|
||||
<g
|
||||
id="r_ref"
|
||||
style="fill:none;stroke:teal;stroke-width:0.01">
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -22,57 +22,69 @@
|
|||
|
||||
|
||||
/** @file stave-bracket-widget.cpp
|
||||
** Implementation of drawing code to indicate the structure of nested tracks
|
||||
** in the header area of the Timleline UI.
|
||||
** Implementation of drawing code to indicate the structure of nested tracks.
|
||||
** The design of the drawing is inspired by classical score notation, where braces
|
||||
** are used to group the staves (or stems) for one instrument (e.g. grand piano, organ),
|
||||
** while brackets are used to group the staves of an ensemble (e.g. string quartet, symphony orchestra)
|
||||
** The usual typesetting of musical notation relies much on classical design principles, based on the
|
||||
** golden ratio Φ, which is known to be perceived as _balanced, neutral and unobtrusive._
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 2/2023
|
||||
** The design implemented here is built around a vertical double bar line, and the width of this line
|
||||
** is used as reference for size calculations; the curved top and bottom cap is enclosed within a
|
||||
** bounding box of size Φ², when defining the _base width_ to be 1. The inner tangent of the curved
|
||||
** cap will point towards the end of the smaller (inner) vertical line. While this design is quite
|
||||
** simple in structure, and rather easy to construct geometrically, deriving all necessary coordinates
|
||||
** numerically can be a challenge. To build this implementation, the constraint system of *FreeCAD*
|
||||
** was used to define the relations, and the resulting numbers were picked directly from the resulting
|
||||
** XML document, and used both to build a SVG for documentation, and for the constants in this source file.
|
||||
** Using the Gtk::StyleContext and the given Cairo::Context, the drawing code derives the size of the
|
||||
** defined standard font in device units, and uses this _em_ size as reference to derive a _scale_ factor,
|
||||
** which is then applied to the drawing as a whole — taking into account any given vertical size limitations
|
||||
** as imposed by the general nested trade head structure.
|
||||
** - the FreeCAD document can be found at `doc/devel/draw/StaveBracket.FCStd`
|
||||
** - see also the SVG image `doc/devel/draw/StaveBracket.svg` for explanation of geometry
|
||||
**
|
||||
** @todo WIP as of 3/2023
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "stage/timeline/stave-bracket-widget.hpp"
|
||||
//#include "stage/style-scheme.hpp" /////////////////////TODO needed?
|
||||
#include "stage/style-scheme.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <algorithm>
|
||||
//#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
|
||||
using util::min;
|
||||
using util::max;
|
||||
//using util::_Fmt;
|
||||
//using util::isnil;
|
||||
//using util::contains;
|
||||
//using Gtk::Widget;
|
||||
//using sigc::mem_fun;
|
||||
//using sigc::ptr_fun;
|
||||
//using std::cout;
|
||||
//using std::endl;
|
||||
using std::ceil;
|
||||
|
||||
|
||||
namespace stage {
|
||||
namespace timeline {
|
||||
|
||||
namespace {
|
||||
const uint REQUIRED_WIDTH_px = 30;
|
||||
namespace {//---------Implementation-details--Stave-Bracket-design-----------------------
|
||||
|
||||
const uint FALLBACK_FONT_SIZE_px = 12.5; // (assuming 96dpi and 10 Point font)
|
||||
const uint POINT_PER_INCH = 72; // typographic point ≔ 1/72 inch
|
||||
|
||||
const double BASE_WIDTH_PER_EM = 0.5; // scale factor: width of double line relative to font size
|
||||
|
||||
const double ORG = 0.0;
|
||||
const double PHI = (1.0 + sqrt(5)) / 2.0; // Golden Ratio Φ = 1.6180339887498948482
|
||||
const double PHI = (1.0 + sqrt(5)) / 2.0; // Golden Ratio Φ ≔ ½(1+√5) ≈ 1.6180339887498948482
|
||||
const double PHI_MAJOR = PHI - 1.0; // 1/Φ = Φ-1
|
||||
const double PHI_MINOR = 2.0 - PHI; // 1-1/Φ = 2-Φ
|
||||
const double PHISQUARE = 1.0 + PHI; // Φ² = 1+Φ
|
||||
const double PHI_MINSQ = 5.0 - 3*PHI; // Φ-minor of Φ-minor : (2-Φ)²= 2 ²-4Φ + Φ²
|
||||
const double PHISQUARE = 1.0 + PHI; // Φ² = Φ+1
|
||||
const double PHI_MINSQ = 5.0 - 3*PHI; // Φ-minor of Φ-minor : (2-Φ)²= 2²-4Φ + Φ²
|
||||
|
||||
const double BAR_WIDTH = PHI_MINOR; // the main (bold) bar is right aligned to axis
|
||||
const double BAR_WIDTH = PHI_MINOR; // the main (bold) vertical bar line is right aligned to axis
|
||||
const double BAR_LEFT = -BAR_WIDTH;
|
||||
const double LIN_WIDTH = PHI_MINSQ; // thin line is Φ-minor or bold line (which itself is Φ-minor)
|
||||
const double LIN_WIDTH = PHI_MINSQ; // thin line is Φ-minor of bold line (which itself is Φ-minor)
|
||||
const double LIN_LEFT = PHI_MAJOR - LIN_WIDTH; // main line and thin line create a Φ-division
|
||||
|
||||
const double SQUARE_TIP_X = 2.2360679774997880;
|
||||
const double SQUARE_TIP_X = PHISQUARE - PHI_MINOR;
|
||||
const double SQUARE_TIP_Y = -PHISQUARE;
|
||||
const double SQUARE_MINOR = 1.0;
|
||||
|
||||
|
|
@ -128,11 +140,50 @@ namespace timeline {
|
|||
* @return scale factor to apply to the base layout
|
||||
*/
|
||||
double
|
||||
determineScale (StyleC style)
|
||||
baseWidth (StyleC style)
|
||||
{
|
||||
return BASE_WIDTH_PER_EM * getAbsoluteFontSize (style);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine the base metric, taking into account the available canvas size.
|
||||
* @param style CSS style context where this calculation shall apply
|
||||
* @param givenHeight the allocated vertical space for the drawing
|
||||
* @return scale factor to apply to the design of the bracket
|
||||
* @remark the design is anchored at the line width, and other parts
|
||||
* are related by golden ratio Φ. Notably the bounding box of the
|
||||
* top and bottom cap is defined as Φ² times the base width.
|
||||
* Consequently the drawing requires a minimum height of two times
|
||||
* this bounding box (for top and bottom cap); in case the given
|
||||
* height allocation is not sufficient, the whole design will be
|
||||
* scaled down to fit.
|
||||
* @see #baseWidth(StyleC) the desired base width, as derived from font size
|
||||
*/
|
||||
double
|
||||
determineScale (StyleC style, int givenHeight)
|
||||
{
|
||||
auto maxScale = givenHeight / (2*PHISQUARE);
|
||||
return min (maxScale, baseWidth (style));
|
||||
}
|
||||
|
||||
/** @return width in pixels required to realise the bracket construction,
|
||||
* taking into account the possible vertical limitation
|
||||
* @param givenHeight vertical limitation in (device) pixels
|
||||
* @remark actually #determineScale is responsible to observe limitations
|
||||
*/
|
||||
int
|
||||
calcRequiredWidth (StyleC style, int givenHeight)
|
||||
{
|
||||
return ceil (PHISQUARE * determineScale (style,givenHeight));
|
||||
}
|
||||
|
||||
/** @return width for the drawing, without considering height limitation */
|
||||
int
|
||||
calcDesiredWidth (StyleC style)
|
||||
{
|
||||
return ceil (PHISQUARE * baseWidth (style));
|
||||
}
|
||||
|
||||
/** place left anchor reference line to right side of bold bar.
|
||||
* @remark taking into account the scale and padding
|
||||
*/
|
||||
|
|
@ -177,12 +228,15 @@ namespace timeline {
|
|||
* @remark See `doc/devel/draw/StaveBracket.svg` for explanation
|
||||
*/
|
||||
void
|
||||
drawCap (CairoC cox, double ox, double oy, double scale, bool upside=true)
|
||||
drawCap (CairoC cox, Gdk::RGBA colour, double ox, double oy, double scale, bool upside=true)
|
||||
{
|
||||
cox->save();
|
||||
cox->translate (ox,oy);
|
||||
cox->scale (scale, upside? scale:-scale);
|
||||
cox->set_source_rgb(0.0, 0.0, 0.8); ///////TICKET #1168 : retrieve colour from stylesheet
|
||||
cox->set_source_rgba(colour.get_red()
|
||||
,colour.get_green()
|
||||
,colour.get_blue()
|
||||
,colour.get_alpha());
|
||||
// draw the inner contour of the bracket cap,
|
||||
// which is the outer arc from left top of the bar to the tip point
|
||||
cox->move_to(BAR_LEFT, ORG);
|
||||
|
|
@ -199,12 +253,15 @@ namespace timeline {
|
|||
|
||||
/** draw the double bar to fit between upper and lower cap */
|
||||
void
|
||||
drawBar (CairoC cox, double leftX, double upperY, double lowerY, double scale)
|
||||
drawBar (CairoC cox, Gdk::RGBA colour, double leftX, double upperY, double lowerY, double scale)
|
||||
{
|
||||
cox->save();
|
||||
cox->translate (leftX, upperY);
|
||||
cox->scale (scale, scale);
|
||||
cox->set_source_rgb(0.0, 0.0, 0.8); ///////TICKET #1168 : retrieve colour from stylesheet
|
||||
cox->set_source_rgba(colour.get_red()
|
||||
,colour.get_green()
|
||||
,colour.get_blue()
|
||||
,colour.get_alpha());
|
||||
//
|
||||
double height = max (0.0, (lowerY - upperY)/scale);
|
||||
cox->rectangle(BAR_LEFT, -SQUARE_MINOR, BAR_WIDTH, height + 2*SQUARE_MINOR);
|
||||
|
|
@ -214,7 +271,10 @@ namespace timeline {
|
|||
//
|
||||
cox->restore();
|
||||
}
|
||||
}
|
||||
|
||||
}//(End)Implementation details (drawing design)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -229,39 +289,36 @@ namespace timeline {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/** */
|
||||
/**
|
||||
* Custom drawing: a »stave bracket« to indicate track scope.
|
||||
* The layout is controlled by settings in the CSS style context
|
||||
* - a _base width_ (which is the width of the vertical double bar)
|
||||
* is based on current font settings, with scale #BASE_WIDTH_PER_EM
|
||||
* - this base width also defines the width requirement reported to
|
||||
* GTK through #get_preferred_width_for_height_vfunc
|
||||
* - possible padding is picket up from CSS
|
||||
* - current text colour is used for drawing
|
||||
*/
|
||||
bool
|
||||
StaveBracketWidget::on_draw (CairoC cox)
|
||||
{
|
||||
// invoke (presumably empty) base implementation....
|
||||
bool event_is_handled = _Base::on_draw (cox);
|
||||
|
||||
/////////////////////////////////////////////TICKET #1018 : placeholder drawing
|
||||
//
|
||||
int w = get_width();
|
||||
int h = get_allocated_height();
|
||||
cox->set_source_rgb(0.8, 0.0, 0.0);
|
||||
cox->set_line_width (5.0);
|
||||
cox->move_to(0, 0);
|
||||
cox->line_to(w, h);
|
||||
cox->move_to(w, 0);
|
||||
cox->line_to(0, h);
|
||||
cox->stroke();
|
||||
/////////////////////////////////////////////TICKET #1018 : placeholder drawing
|
||||
|
||||
REQUIRE (1.0 == deviceUnitsPerUserUnit (cox)
|
||||
,"Cairo surface in device coordinates assumed");
|
||||
|
||||
StyleC style = this->get_style_context();
|
||||
double scale = determineScale (style);
|
||||
double left = anchorLeft (style, scale);
|
||||
auto colour = style->get_color (Gtk::STATE_FLAG_NORMAL);
|
||||
int height = this->get_allocated_height();
|
||||
double scale = determineScale (style, height);
|
||||
double left = anchorLeft (style, scale);
|
||||
double upper = anchorUpper (style,scale);
|
||||
double lower = anchorLower (style, scale, h);
|
||||
double lower = anchorLower (style, scale, height);
|
||||
|
||||
drawCap (cox, left, upper, scale, true);
|
||||
drawCap (cox, left, lower, scale, false);
|
||||
drawBar (cox, left, upper, lower, scale);
|
||||
drawCap (cox, colour, left, upper, scale, true);
|
||||
drawCap (cox, colour, left, lower, scale, false);
|
||||
drawBar (cox, colour, left, upper, lower, scale);
|
||||
|
||||
return event_is_handled;
|
||||
}
|
||||
|
|
@ -276,21 +333,22 @@ namespace timeline {
|
|||
|
||||
/**
|
||||
* The structural outline adapts flexible in vertical direction,
|
||||
* but requires a fixed horizontal size for proper drawing.
|
||||
* but requires a proportional horizontal size for proper drawing.
|
||||
* The horizontal requisition is based on the font in CSS style context.
|
||||
*/
|
||||
void
|
||||
StaveBracketWidget::get_preferred_width_for_height_vfunc (int givenHeight, int& minimum_width, int& natural_width) const
|
||||
{
|
||||
StyleC style = this->get_style_context();
|
||||
minimum_width = natural_width = calcRequiredWidth (style, givenHeight);
|
||||
}
|
||||
|
||||
void
|
||||
StaveBracketWidget::get_preferred_width_vfunc (int& minimum_width, int& natural_width) const
|
||||
{
|
||||
minimum_width = natural_width = REQUIRED_WIDTH_px;
|
||||
StyleC style = this->get_style_context();
|
||||
minimum_width = natural_width = calcDesiredWidth (style);
|
||||
}
|
||||
|
||||
void
|
||||
StaveBracketWidget::get_preferred_width_for_height_vfunc (int, int& minimum_width, int& natural_width) const
|
||||
{
|
||||
get_preferred_width (minimum_width, natural_width);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}}// namespace stage::timeline
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@
|
|||
**
|
||||
** \par styling
|
||||
** - styling is controlled via CSS, using the marker class \ref CLASS_fork_bracket
|
||||
** - the »base width« of the vertical double line is based on the font's `em` setting
|
||||
** - padding and colour attributes from CSS are observed
|
||||
**
|
||||
** @todo WIP-WIP-WIP as of 2/2023
|
||||
** @todo WIP as of 3/2023
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@ -43,13 +45,6 @@
|
|||
#define STAGE_TIMELINE_STAVE_BRACKET_WIDGET_H
|
||||
|
||||
#include "stage/gtk-base.hpp"
|
||||
//#include "stage/model/controller.hpp"
|
||||
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
//#include <memory>
|
||||
//#include <vector>
|
||||
|
||||
|
||||
|
||||
namespace stage {
|
||||
|
|
@ -57,8 +52,6 @@ namespace timeline {
|
|||
|
||||
using CairoC = PCairoContext const&;
|
||||
using StyleC = PStyleContext const&;
|
||||
|
||||
// class TrackPresenter;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
BIN
wiki/draw/StaveBracket.png
Normal file
BIN
wiki/draw/StaveBracket.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
wiki/draw/TrackHeadNesting.png
Normal file
BIN
wiki/draw/TrackHeadNesting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.6 KiB |
|
|
@ -3701,7 +3701,7 @@ Now, since we build our UI on the notion of mapping session contents via a messa
|
|||
|
||||
In any case, this is an advanced topic, and nowhere near trivial. It seems reasonable to reject opening duplicate timeline presentations as a first step, and then address this topic way later, when we've gained sufficient knowledge regarding all the subtleties of timeline presentation and editing.</pre>
|
||||
</div>
|
||||
<div title="GuiTimelineView" creator="Ichthyostega" modifier="Ichthyostega" created="201410160100" modified="202210281524" tags="GuiPattern design decision draft img" changecount="66">
|
||||
<div title="GuiTimelineView" creator="Ichthyostega" modifier="Ichthyostega" created="201410160100" modified="202303042311" tags="GuiPattern design decision draft img" changecount="68">
|
||||
<pre>Within the Lumieara GUI, the [[Timeline]] structure(s) from the HighLevelModel are arranged and presented according to the following principles and conventions.
|
||||
Several timeline views may be present at the same time -- and there is not necessarily a relation between them, since »a Timeline« is the top-level concept within the [[Session]]. Obviously, there can also be several //views// based on the same »Timeline« model element, and in this latter case, these //coupled views// behave according to a linked common state. An entity »Timeline« as represented through the GUI, emerges from the combination of several model elements
|
||||
* a root level [[Binding|BindingMO]] acts as framework
|
||||
|
|
@ -3714,7 +3714,7 @@ Several timeline views may be present at the same time -- and there is not neces
|
|||
Session, Binding and Sequence are the mandatory ingredients.
|
||||
|
||||
!Basic layout
|
||||
[>img[Clip presentation control|draw/UI-TimelineLayout-1.png]]The representation is split into a ''Header pane'' exposing structure and configuration, and a ''Content pane'' extending in time. The ''Time ruler'' ( &rarr; [[Rulers|TrackRuler]]) running alongside the top of the content pane represents the //position in time.// Beyond this temporal dimension, the content area is conceived as a flexible working space. This working space //can// be structured hierarchically -- when interacting with the GUI, hierarchical nesting will be created and collapsed on demand. Contrast this with conventional editing applications which are built upon the rigid notion of "Tracks": Lumiera is based on //Pipes// and //Scopes// rather than Tracks.
|
||||
[>img[Clip presentation control|draw/UI-TimelineLayout-1.png]]The representation is split into a ''Header pane'' exposing structure and configuration ( &rarr; [[Patchbay|TimelinePatchbay]]), and a ''Content pane'' extending in time. The ''Time ruler'' ( &rarr; [[Rulers|TrackRuler]]) running alongside the top of the content pane represents the //position in time.// Beyond this temporal dimension, the content area is conceived as a flexible working space. This working space //can// be structured hierarchically -- when interacting with the GUI, hierarchical nesting will be created and collapsed on demand. Contrast this with conventional editing applications which are built upon the rigid notion of "Tracks": Lumiera is based on //Pipes// and //Scopes// rather than Tracks.
|
||||
|
||||
In the temporal dimension, there is the usual [[scrolling and zooming|ZoomWindow]] of content, and possibly a selected time range, and after establishing a ViewerPlayConnection, there is an effective playback location featured as a "Playhead"
|
||||
The workspace dimension (vertical layout) is more like a ''Fork'', which can be expanded recursively. More specifically, each strip or layer or "track" can be featured in //collapsed// or //expanded state.//
|
||||
|
|
@ -3731,6 +3731,7 @@ The workspace dimension (vertical layout) is more like a ''Fork'', which can be
|
|||
@@
|
||||
This collapsed, expanded and possibly nested workspace structure is always exactly paralleled in the header pane. In addition, it allows to configure specific placement properties for each nested scope, which especially means to display faders and some toggles, depending on what kind of placement was added. Of course, this placement configuration needs to be collapsible too. Effects and markers can appear at various different scopes, sometimes requiring an abridged display
|
||||
&rarr; more about [[the actual drawing code|GuiTimelineDraw]]
|
||||
&rarr; the [[Track Head display|TrackHead]]
|
||||
|
||||
|
||||
!!!lifecycle and instances
|
||||
|
|
@ -3760,7 +3761,7 @@ In the most general case, there can be per-track content and nested content at t
|
|||
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiTimelineWidgetStructure" creator="Ichthyostega" modifier="Ichthyostega" created="201410250002" modified="202210281525" tags="GuiPattern discuss decision impl" changecount="110">
|
||||
<div title="GuiTimelineWidgetStructure" creator="Ichthyostega" modifier="Ichthyostega" created="201410250002" modified="202303042308" tags="GuiPattern discuss decision impl" changecount="112">
|
||||
<pre>The Timeline is probably the most prominent place in the GUI where we need to come up with a custom UI design.
|
||||
Instead of combining standard components in one of the well-known ways, here we need to come up with our own handling solution -- which also involves to build several custom GTK widgets. Thus the question of layout and screen space division and organisation becomes a crucial design decision. The ~GTK-2 UI, as implemented during the initial years of the Lumiera project, did already take some steps along this route, which was was valuable as foundation for assessment and further planning.
|
||||
|
||||
|
|
@ -3769,7 +3770,7 @@ As it stands, this topic touches a tricky design and architectural challenge: th
|
|||
In a nutshell, ~GTKmm offers several degrees of customisation, namely to build a custom widget class, to build a custom container widget, and to use the [[Gtk::Layout "canvas widget"|GtkLayoutWidget]], possibly combined with //custom drawing.// In addition to assembling a timeline widget class by combining several nested panes, the timeline display needs to rely on the latter approach to allow for the necessary flexible arrangement of [[clip widgets|GuiClipWidget]] within the [[track fork|Fork]].
|
||||
|
||||
!the header pane problem
|
||||
Based on principles of //conventional UI design,// we derive the necessity to have a track header pane area, always visible to the left, and scrolling vertically in sync with the actual track display to the right of the timeline area. This insight brings about several consequences. For one this means that our top level widget organisation in the timeline will be a horizontal split. And furthermore this means that we get two distinct sub widgets, whose vertical layout needs to be kept in sync. And even more so, presumably the most adequate implementation technique is different in both parts: the header pane looks like a classical fit for the paradigm of nested boxes and grid layout within those boxes, while the right part -- the actual track contents -- impose very specific layout constraints, not served by any of the pre-existing layout containers -- which means we have to resort to custom drawing on a canvas widget. Following this line of thought, we need an overarching layout manager to coordinate these two disjoint technologies. Any viable alternatives?
|
||||
Based on principles of //conventional UI design,// we derive the necessity to have a [[track header pane area|TimelinePatchbay]], always visible to the left, and scrolling vertically in sync with the actual track display to the right of the timeline area. This insight brings about several consequences. For one this means that our top level widget organisation in the timeline will be a horizontal split. And furthermore this means that we get two distinct sub widgets, whose vertical layout needs to be kept in sync. And even more so, presumably the most adequate implementation technique is different in both parts: the header pane looks like a classical fit for the paradigm of nested boxes and grid layout within those boxes, while the right part -- the actual track contents -- impose very specific layout constraints, not served by any of the pre-existing layout containers -- which means we have to resort to custom drawing on a canvas widget. Following this line of thought, we need an overarching layout manager to coordinate these two disjoint technologies. Any viable alternatives?
|
||||
|
||||
!!!considering a table grid layout
|
||||
The layout mechanics we try to establish here by explicit implementation would be more or less a given, if instead we'd build the whole timeline display from one base widget, which needs to be a table layout, i.e. {{{Gtk::Grid}}}. We'd use two columns, one for the header pane area, one for the timeline display, and we'd use N+1 rows, with the head row holding the time ruler and the additional rows holding individual tracks. But to get the specific UI mechanics desirable for a timeline display, we had to introduce some twists:
|
||||
|
|
@ -3781,7 +3782,7 @@ The layout mechanics we try to establish here by explicit implementation would b
|
|||
* this problem is mitigated once we add a track with //automation data// linked to the mentioned controls. Yet still, this is not the default situation...
|
||||
On the other hand, what would be the //obvious benefits...?//
|
||||
* we just have to add stuff in both the left / right part of the display and get the vertical space management sorted out by framework code
|
||||
While the special setup for scrolling doesn't really count (since it is necessary anyway), after this initial investigation it seems clear that a global grid layout doesn't yield enough benefit to justify all the quirks and limitations its use would impose.
|
||||
While the special setup for scrolling doesn't really count (since it is necessary anyway), after this initial investigation it seems clear that a global grid layout doesn't yield enough benefit to justify all the quirks and limitations its use would impose -- however, //we can indeed benefit// from GTK's automatic layout management when it comes to building the [[nested Track Head controls|TrackHead]], which can be implemented as nested {{{Gtk::Grid}}}.
|
||||
|
||||
!!!follow-up to the obvious choices
|
||||
We came to this point of re-considering the overall organisation of widgets, after having to re-write the initial version of our timeline widget. This initial version was developed until 2011 by Joel Holdsworth, and it followed a similar reasoning, involving a global timeline layout manager. The distinction between the two panes was not so clear though, and the access to the model code was awkward at places, so the necessity to re-write the timeline widget due to the transition to ~GTK-3 looks like a good opportunity to re-do the same basic reasoning a second time, verify decisions taken and improve matters turning out as difficult on first attempt.
|
||||
|
|
@ -3798,7 +3799,7 @@ The handling of objects structured into nested scopes is a hallmark of the very
|
|||
The structure of the display is extended or altered under two circumstances:
|
||||
# some component receives a [[diff mutation message|MutationMessage]], prompting to add or remove a //child component.//
|
||||
# the display (style) of some component is expanded or collapsed.
|
||||
Here, the "component" relevant for such structural changes is always the UI representation of a track. Beyond that, the layout can also be changed //without changing the display structure,// when some embedded component, be it placement (in the track heads / the patchbay) or a clip, effect or transition, is expanded or collapsed. In such a case, a resizing challenge needs to be directed towards the next enclosing track container.
|
||||
Here, the "component" relevant for such structural changes is always the UI representation of a track. Beyond that, the layout can also be changed //without changing the display structure,// when some embedded component, be it placement (in the [[track heads|TrackHead]] / the [[patchbay|TimelinePatchbay]]) or a clip, effect or transition, is expanded or collapsed. In such a case, a resizing challenge needs to be directed towards the next enclosing track container.
|
||||
|
||||
From these observations we can draw the conclusion, that we'll build a ''local structural model'', to reflect the logical relations between the parts comprising the timeline display. More precisely, these structuring components are not mere model objects, rather they are mediating entities used to guide and organise the actual view entities, which in turn are passive. They are more like a view model, while also bearing some local controller responsibilities. For this reason, we prefer to term these as ''presenters'' -- i.e. TrackPresenter and ClipPresenter. And each of these local representation components holds onto a ''display context'', which generally links it //into two different display widget stacks// within the two parts of the actual timeline display. Adding a child component thus becomes a rather tricky operation, involving to link possibly two child widgets into two disjoint parent widgets, thereby forming a similar display context for the child presenter. Overall, the guiding idea is that of self similarity: on each level, we have to reproduce the same relations and collaborations as present in the parent level.
|
||||
|
||||
|
|
@ -9293,6 +9294,15 @@ Another, closely related topic, handled within this context, is the mapping from
|
|||
By principle, //widgets always work exclusively in pixel coordinates// -- thus we need the help of a coordinating entity to find out where some entity shall be located on the GTK drawing canvas. This becomes especially relevant for the timeline body, since there we're relying on a GuiCustomWidget to perform and control some of the UI drawing by specific custom rules and procedures. And to add to this complexity, several structures are //nested,// thus anchoring their coordinates relative to the parent entity. These challenges are resolved by the introduction of yet another abstraction, the [[»canvas interface«|GuiCanvasInterface]], allowing to attach widgets relative to a //reference canvas// and to maintain uniform coordinates and a [[zoom metric|ZoomWindow]] used for a properly calibrated timeline display.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TimelineNavigator" creator="Ichthyostega" modifier="Ichthyostega" created="202303042301" modified="202303042302" tags="def GuiPattern draft" changecount="3">
|
||||
<pre>//The TimelineNavigator is a small widget at the left top side of the timeline display and allows to jump and control the current location.//
|
||||
|
||||
{{red{Unspecified and implementation postponed for later, as of 2/2023}}}</pre>
|
||||
</div>
|
||||
<div title="TimelinePatchbay" creator="Ichthyostega" modifier="Ichthyostega" created="202303042259" modified="202303050008" tags="def GuiPattern draft" changecount="8">
|
||||
<pre>//The »''Patchbay''« at the left of the timeline provides controls to influence the scopes within the fork of tracks, most notably levels, mix-mode and routing.//
|
||||
Structurally, it reflects the nesting of scopes in the ''Fork'' of tracks; each track is represented as a TrackHead widget, with sub-Tracks displayed recursively.</pre>
|
||||
</div>
|
||||
<div title="TimelineSequences" modifier="Ichthyostega" created="200811011836" modified="201505310138" tags="design decision img" changecount="4">
|
||||
<pre>There is a three-level hierarchy: [[Project|Session]], [[Timeline]], [[Sequence]]. Each project can contain ''multiple timelines'', to be viewed and rendered independently. But, being the top-level entities, these timelines may not be combined further. You can always just render (or view) one specific timeline. Each of those timelines refers to a Sequence, which is a bunch of [[media objects|MObject]] placed to a [[fork ("tree of tracks")|Fork]]. Of course it is possible to use ~sub-sequences within the top-level sequence within a timeline to organize a movie into several scenes or chapters.
|
||||
|
||||
|
|
@ -9366,6 +9376,19 @@ Matters are quite different for the placement of a Track within the tree of trac
|
|||
* obviously, one wants the __edit function__ used to create such an overlapping placement&nbsp; also to create an [[transition|TransitionsHandling]] between the overlapping objects. Meaning this edit function will automatically create an transition processor object and provide it with a placement such as to attach it to the region of overlap.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TrackHead" creator="Ichthyostega" modifier="Ichthyostega" created="202303042255" modified="202303050005" tags="def GuiPattern draft" changecount="11">
|
||||
<pre>//The TrackHead display is always visible to the left of the timeline and provides controls for a Track's scope, including all nested sub track//
|
||||
In Lumiera, »Tracks« are arranged as a system of nested scopes, starting top-down from the root-track of the Timeline. For each Track, there is a {{{timeline::TrackBody}}} element in the //content area// of the Timeline display, and a corresponding {{{timeline::TrackHeadWidget}}}, arranged at apropriate level within the [[»Patchbay«|TimelinePatchbay]] area to the left. The //model entity »Track«// corresponds to a TrackPresenter in the timeline display, which in turn manages and synchronises both related display zones in the body and header space.
|
||||
|
||||
!Structure of the Track Head display
|
||||
While the //content area// is rendered by [[custom drawing onto a canvas widget|GuiTimelineDraw]], the //header display// is built up „conventionally“ -- <br/>based on nested {{{Gtk::Grid}}} widgets (i.e. the {{{TrackHeadWidget}}} inherits from {{{Gtk::Grid}}}).
|
||||
* For any track, this grid is comprised of two columns and will initially be populated with three rows:
|
||||
**a row holding the Track Header label and menu (actually an [[ElementBoxWidget|GuiElementBoxWidget]])
|
||||
**a row corresponding to the //content// of the track itself, to hold the controls to govern this track's scope,<br/>i.e. the track //together with all nested sub-tracks.//
|
||||
** a padding row to help synchronising track head and track body display.
|
||||
*Additional sub-Tracks are added as additional lines to the grid, while nested sub-Tracks will be handled by nested TrackHead widgets
|
||||
*The column to the left side will be increased accordingly to display the nested fork structure in the form of [[nested brackets|TrackStaveBracket]]</pre>
|
||||
</div>
|
||||
<div title="TrackPipeSequence" modifier="Ichthyostega" created="200711300405" modified="201505310138" tags="design def decision Builder rewrite" changecount="2">
|
||||
<pre>''towards a definition of »Track«''. We don't want to tie ourself to some naive and overly simplistic definition, just because it is convenient. For classical (analogue) media, tracks are physical entities dictated by the nature of the process by which the media works. Especially, Tape machines have read/writing heads, which creates fixed tracks to which to route the signals. This is a practical geometric necessity. For digital media, there is no such necessity. We are bound primarily by the editor's habits of working.
|
||||
|
||||
|
|
@ -9394,12 +9417,12 @@ Placements are __resolved__ resulting in an ExplicitPlacement. In most cases thi
|
|||
&rarr; [[Definition|Pipe]] and [[handling of Pipes|PipeHandling]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="TrackPresenter" creator="Ichthyostega" modifier="Ichthyostega" created="201611280207" modified="201912061629" tags="def GuiPattern" changecount="13">
|
||||
<div title="TrackPresenter" creator="Ichthyostega" modifier="Ichthyostega" created="201611280207" modified="202303042253" tags="def GuiPattern" changecount="15">
|
||||
<pre>//mediating entity used to guide and control the track-like nested working space in the timeline display of the UI.//
|
||||
|
||||
Similar to the ClipPresenter, judged from a global angle, this element fulfils a model-like role, while at the same time guiding and controlling a mostly passive view component, implemented as GTK widget. Here, the authority of the presenter over the widget must be total, since display management //needs to work automatically,// due to model updates and mutations arriving as [[diff messages|MutationMessage]]. In addition, this structure is prerequisite for (possibly) implementing UI rendering optimisations, since it allows us to leave out widgets entirely, when it is clear they won't become visible: A ''display evaluation pass'', which is effectively a //tree walk,// consecutively visits each part of the timeline structure, to negotiate its concrete display properties in collaboration with a global TimelineDisplayManager. As a result, the presenter knows where to show its corresponding view, and it knows if to show it at all, allowing to either adjust, create or destroy actual GTK widgets within its local reference frame.
|
||||
|
||||
A special twist arises from the fact that track display has to happen aligned and in sync within the two display panes of the timeline at the same time. This means that each TrackPresenter has to hold and manage //two slave display elements,// each of which is inserted within a disjoint hierarchy of display elements. For one, there is the {{{timeline::TrackHeadWidget}}} which in turn renders a {{{PatchbayWidget}}}, and on the other side there is a {{{TrackBody}}} element, which is not strictly a widget of itself, but inserted into our custom drawing {{{timeline::BodyCanvasWidget}}} to manage the custom drawing of the respective track working area.
|
||||
A special twist arises from the fact that track display has to happen aligned and in sync within the two display panes of the timeline at the same time. This means that each TrackPresenter has to hold and manage //two slave display elements,// each of which is inserted within a disjoint hierarchy of display elements. For one, there is the {{{timeline::HeaderPaneWidget}}} which in turn renders a [[Navigation Control|TimelineNavigator]] and below the [[»Patchbay«|TimelinePatchbay]], holding a [[timeline::TrackHeadWidget|TrackHead]] for each track -- while on the other side there is a {{{TrackBody}}} element, which is not strictly a widget of itself, but inserted into our custom drawing {{{timeline::BodyCanvasWidget}}} to manage the custom drawing of the respective track working area.
|
||||
|
||||
To deal with this typical problem of recursive programming, we introduce a binding element, the {{{DisplayFrame}}}
|
||||
* the TrackPresenter holds a {{{DisplayFrame}}} member, which in turn houses the two head and body widgets. So basically the widgets are allocated within the presenter.
|
||||
|
|
@ -9429,6 +9452,25 @@ The actual presentation of ruler elements is a fusion of parametrisation, track
|
|||
** the ruler of an //expanded fork// (a track with nested child tracks) will typically give a summary of effective content, but can also be hidden, or feature other content
|
||||
** the ruler of an //expanded leaf track// (no child tracks) will typically be hidden, but can likewise be configured to show specific data</pre>
|
||||
</div>
|
||||
<div title="TrackStaveBracket" creator="Ichthyostega" modifier="Ichthyostega" created="202303050037" modified="202303050303" tags="def GuiPattern img" changecount="39">
|
||||
<pre>//Graphical representation of the nested Track scopes as part of the TrackHead display.//
|
||||
The design (and the name) of this graphical display is inspired by musical notation, where it is customary to indicate with a bracket the grouping of stems (or staves) forming an ensemble, while a brace typically groups the staves to be played on a single instrument, e.g. a grand piano or organ.
|
||||
|
||||
In the Lumiera Timeline UI, »Tracks« are arranged into a ''Fork'' of nested scopes; the Timeline has a single root Track, which in turn might hold several nested sub-Tracks, and the nesting can be continued recursively. In the [[»Patchbay«|TimelinePatchbay]], settings and properties can be controlled to influence a specific part of the scope hierarchy, and this part is always represented by the TrackHead of the specific track forming this scope. [>img[Nested Track Heads grouped by stave brackets|draw/TrackHeadNesting.png]] In this {{{TrackHeadWidget}}}, there is a cell holding the actual controls, while further grid cells below possibly hold further nested sub-Track heads -- while the left side of this Track head arrangement is used to indicate the grouping of scopes with the aforementioned brackets.
|
||||
|
||||
!Design
|
||||
The design of the grouping Bracket in the graphical display is based on proportions governed by the ''Golden Ratio'' Φ = ½·(1+√5)
|
||||
Relying on those proportions has much tradition, and often leads to a design perceived as natural and unobtrusive.
|
||||
|
||||
The Golden Ratio creates a division into a larger part and smaller part, denoted as Φ-major and Φ-minor -- and the defining property of Φ is that these divisions can be extended or subdivided endlessly, always reproducing the same ratio Φ: A distance divided by Golden ratio gan be //extended// by adding the Φ-minor, with the surprising result that the now extended distance and the original distance are again governed by the Golden Ratio, leading to geometric structures intricately interwoven.
|
||||
[<img[Stave Bracket construction|draw/StaveBracket.png]]
|
||||
|
||||
This way, the size and shape of the Stave Bracket is determined by choosing a single ''base width'', which in this case is the horizontal extension of the double vertical line. This base width is divided by Φ, and the smaller part, the Φ-minor is used as the filled bold vertical bar, while the larger distance, the Φ-major is used to define the spacing to the smaller vertical line. The right side of the bold vertical bar is used as anchor line, with the origin of the coordinate system at the top end, just below the top cap.
|
||||
|
||||
The cap is enclosed into a bounding box, which is again defined through the Golden Ratio, by using the //base width// as it's Φ-minor. Consequently, the size of this bounding square is thus Φ². The curved contour of the cap is inscribed into that bounding square, along the main diagonal, and with a tangent at the tip pointing down to the end of the smaller line (and thus at Φ-minor of the bounding square's lower base). To find the centre of this curved arc, a perpendicular is erected in the middle of the main diagonal (since the arc can be assumed to be symmetrical to this line); furthermore the radius of this arc must touch the tangent at the tip of the figure, and thus a perpendicular attached at the tip to the tangent will subtend the symmetry line and yield the centre point. By a similar construction, the inner arc -- which forms the outer side of the cap -- can be constructed along the „upper diagonal“, running down from the tip to the Φ-minor at the left side.
|
||||
|
||||
__''Implementation''__: while rather simple in geometrical terms, obtaining the coordinates by trigonometric calculations can be challenging. To simplify this tedious task, the ''Constraint'' system of ''~FreeCAD'' was used to directly define the geometric relations outlined above; the resulting coordinates were then be picked from the ~FreeCAD XML document, and embedded as hard wired constants into the {{{timeline::StaveBracketWidget}}} code. For the purpose of this construction, the base width was defined as 1 Unit -- yet for the actual drawing code, an //uniform scaling factor// is applied, based on the font size available in the CSS style context of the widget. As GTK uses the vector graphics libary ''Cairo'' for drawing, the outline of the shape can be directly translated into path instructions, and the resulting contour will then be filled with a solid colour, as defined by the foreground {{{color}}} attribute of CSS. For the curved arcs, a slight adaptation is necessary, since ~FreeCAD defines circle segments in mathematical orientation ↶, while SVG and libCairo use a clockwise ↻ orientation starting at +X axis.</pre>
|
||||
</div>
|
||||
<div title="TransitionsHandling" modifier="Ichthyostega" created="200712080417" modified="200805300100" tags="def design">
|
||||
<pre>Transitions combine the data from at least two processing chains and do this combining in a time varying fashion. So, any transition has
|
||||
* N input connections
|
||||
|
|
|
|||
|
|
@ -28077,8 +28077,10 @@
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1676156477801" ID="ID_772056246" MODIFIED="1676156487723" TEXT="Grundstruktur zeichnen: Klammer">
|
||||
<node CREATED="1676156693199" ID="ID_1410623513" MODIFIED="1676156728537" TEXT="geschwungene Kappen">
|
||||
<node COLOR="#338800" CREATED="1676156477801" ID="ID_772056246" MODIFIED="1677851184706" TEXT="Grundstruktur zeichnen: Klammer">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1676156693199" FOLDED="true" ID="ID_1410623513" MODIFIED="1677851190441" TEXT="geschwungene Kappen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1676156831767" FOLDED="true" ID="ID_1352090582" MODIFIED="1677284185352" TEXT="Problem: wie konstruieren?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1676156890344" ID="ID_324278944" MODIFIED="1676156912279" TEXT="Geheimwissen — wie so oft in der Typographie"/>
|
||||
|
|
@ -28507,14 +28509,17 @@
|
|||
</node>
|
||||
<node CREATED="1677365153860" ID="ID_1720144005" MODIFIED="1677365157523" TEXT="Breite">
|
||||
<node CREATED="1677366839611" ID="ID_1835454334" MODIFIED="1677366839611" TEXT="0.3819660112501033"/>
|
||||
<node CREATED="1677861231484" ID="ID_1930167405" MODIFIED="1677861233712" TEXT="Φ-minor"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677365163942" ID="ID_1262283150" MODIFIED="1677365167810" TEXT="Linie">
|
||||
<node CREATED="1677365150864" ID="ID_786192191" MODIFIED="1677365152884" TEXT="links">
|
||||
<node CREATED="1677366744194" ID="ID_576965784" MODIFIED="1677366744194" TEXT="0.4721359549995793"/>
|
||||
<node CREATED="1677861270767" ID="ID_1949339527" MODIFIED="1677861283377" TEXT="Φ-major - Breite"/>
|
||||
</node>
|
||||
<node CREATED="1677365153860" ID="ID_595356019" MODIFIED="1677365157523" TEXT="Breite">
|
||||
<node CREATED="1677366786332" ID="ID_1751894187" MODIFIED="1677366789785" TEXT="0.1458980337503155"/>
|
||||
<node CREATED="1677861251177" ID="ID_211146367" MODIFIED="1677861259039" TEXT="(Φ-minor)²"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677366276186" ID="ID_457752414" MODIFIED="1677366882793" TEXT="rechts">
|
||||
|
|
@ -28532,21 +28537,42 @@
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1677365024897" ID="ID_1080324350" MODIFIED="1677365030156" TEXT="Spitze">
|
||||
<node CREATED="1677366042929" ID="ID_861341963" MODIFIED="1677366058947" TEXT="2.2360679774997880"/>
|
||||
<node CREATED="1677366091306" ID="ID_1245813830" MODIFIED="1677366094102" TEXT="2.6180339887498931"/>
|
||||
<node CREATED="1677366042929" ID="ID_931394195" MODIFIED="1677861076642" TEXT="Φ² - Φ-minor">
|
||||
<node CREATED="1677366042929" ID="ID_861341963" MODIFIED="1677861104342" TEXT="2.2360679774997880"/>
|
||||
</node>
|
||||
<node CREATED="1677366091306" ID="ID_1220515657" MODIFIED="1677861059471" TEXT="Φ²">
|
||||
<node CREATED="1677366091306" ID="ID_1245813830" MODIFIED="1677861105707" TEXT="2.6180339887498931"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677365057285" ID="ID_1262105297" MODIFIED="1677365060840" TEXT="Mitte">
|
||||
<node CREATED="1677861431937" ID="ID_734498141" MODIFIED="1677861482575" TEXT="Φ²/2 - Φ-minor">
|
||||
<node CREATED="1677366380685" ID="ID_1473309857" MODIFIED="1677366382633" TEXT="0.9270509831248426"/>
|
||||
<node CREATED="1677366414197" ID="ID_980628298" MODIFIED="1677366414197" TEXT="1.3090169943749477"/>
|
||||
</node>
|
||||
<node CREATED="1677366530209" ID="ID_1369679680" MODIFIED="1677366544687" TEXT="Auge">
|
||||
<node CREATED="1677861472620" ID="ID_462202557" MODIFIED="1677861478375" TEXT="Φ²/2">
|
||||
<node CREATED="1677366414197" ID="ID_980628298" MODIFIED="1677861494360" TEXT="1.3090169943749477"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677366530209" ID="ID_1369679680" MODIFIED="1677861872506" TEXT="Auge">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Mitte der »Oberdiogonalen«, d.h die Diagonale durch das obere Rechteck mit Höhe Φ-major und voller Breite
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1677366380685" ID="ID_1234225514" MODIFIED="1677366604271" TEXT="0.9270509831248426"/>
|
||||
<node CREATED="1677366596379" ID="ID_888978877" MODIFIED="1677366596379" TEXT="1.8090169943749466"/>
|
||||
<node CREATED="1677861748026" ID="ID_686856800" MODIFIED="1677861797202" TEXT="1 + (Φ²-1)/2 = 1+Φ/2"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677365073270" ID="ID_1583254932" MODIFIED="1677365077542" TEXT="Außenbogen">
|
||||
<node CREATED="1677365085156" ID="ID_653816127" MODIFIED="1677365088556" TEXT="Zentrum">
|
||||
<node CREATED="1677861176926" ID="ID_1292417077" MODIFIED="1677861194492" TEXT="-(Φ+3)">
|
||||
<node CREATED="1677366982576" ID="ID_1594210270" MODIFIED="1677366982576" TEXT="-4.6180339887498949"/>
|
||||
</node>
|
||||
<node CREATED="1677366993247" ID="ID_712675731" MODIFIED="1677366993247" TEXT="6.8541019662496847"/>
|
||||
</node>
|
||||
<node CREATED="1677365089489" ID="ID_1183768368" MODIFIED="1677365092867" TEXT="Radius">
|
||||
|
|
@ -28600,8 +28626,8 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1677284189119" ID="ID_848175311" MODIFIED="1677336300812" TEXT="Dokumentation im SVG darstellen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1677284189119" ID="ID_848175311" MODIFIED="1677984956527" TEXT="Dokumentation im SVG darstellen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1677285339149" ID="ID_622350527" MODIFIED="1677373894578" TEXT="manuell die Koordinaten ins SVG reinschreiben">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1677336149759" ID="ID_436410709" MODIFIED="1677336194334" TEXT="Konstruktion vollständig anlegen">
|
||||
|
|
@ -28622,13 +28648,26 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1677285356443" ID="ID_1264869426" MODIFIED="1677285395543" TEXT="von diesen Eckpunkten ausgehend die Konstruktion rekonstruieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1677285356443" ID="ID_1264869426" MODIFIED="1677969711023" TEXT="von diesen Eckpunkten ausgehend die Konstruktion rekonstruieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1677373881642" ID="ID_1218195679" MODIFIED="1677373890994" TEXT="skalieren mit Faktor 10">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677969712922" ID="ID_1925495036" MODIFIED="1677969746070" TEXT="platzieren nach (50, 70)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1677285374042" ID="ID_597185643" MODIFIED="1677285392527" TEXT="Maßgabe: jemand anders soll diese Konstruktion verstehen können">
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677969764690" ID="ID_1467582175" MODIFIED="1677969832530" TEXT="Beschriftung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677969777393" ID="ID_1079168037" MODIFIED="1677969793058" TEXT="Φ und Φ² anzeigen"/>
|
||||
<node CREATED="1677969815402" ID="ID_1142467839" MODIFIED="1677969819526" TEXT="square_minor"/>
|
||||
<node CREATED="1677969794531" ID="ID_36594722" MODIFIED="1677969823012" TEXT="base_width"/>
|
||||
<node CREATED="1677969824779" ID="ID_1673607654" MODIFIED="1677969829494" TEXT="origin"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677984963525" ID="ID_1359201455" MODIFIED="1677984979078" TEXT="die Konstruktion textuell beschreiben (im TiddlyWiki)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1677285374042" ID="ID_597185643" MODIFIED="1677984959942" TEXT="Maßgabe: jemand anders soll diese Konstruktion verstehen können">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -28735,29 +28774,29 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1677426582635" ID="ID_78847857" MODIFIED="1677718435058" TEXT="Balken zeichnen">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1677426794738" ID="ID_270081654" MODIFIED="1677426873746" TEXT="dicker Balken">
|
||||
<node COLOR="#338800" CREATED="1677426582635" ID="ID_78847857" MODIFIED="1677861018300" TEXT="Balken zeichnen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1677426794738" ID="ID_270081654" MODIFIED="1677861020212" TEXT="dicker Balken">
|
||||
<arrowlink DESTINATION="ID_231769096" ENDARROW="Default" ENDINCLINATION="-186;54;" ID="Arrow_ID_1647326271" STARTARROW="None" STARTINCLINATION="120;19;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1677426794738" ID="ID_1333503744" MODIFIED="1677426884359" TEXT="dünne Linie">
|
||||
<node COLOR="#338800" CREATED="1677426794738" ID="ID_1333503744" MODIFIED="1677861022079" TEXT="dünne Linie">
|
||||
<arrowlink DESTINATION="ID_1111801677" ENDARROW="Default" ENDINCLINATION="-186;54;" ID="Arrow_ID_1520723305" STARTARROW="None" STARTINCLINATION="71;13;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1677426603105" ID="ID_243044944" MODIFIED="1677426609439" TEXT="Gesamtanordnung steuern">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1677458294653" ID="ID_1105975491" MODIFIED="1677718415331" TEXT="brauche Zugriff auf Layout-Steuerung">
|
||||
<arrowlink COLOR="#8255b2" DESTINATION="ID_883997565" ENDARROW="Default" ENDINCLINATION="108;-242;" ID="Arrow_ID_1785981386" STARTARROW="None" STARTINCLINATION="-291;20;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1677426726852" ID="ID_1196135559" MODIFIED="1677718407222" TEXT="Klammer sinnvoll positionieren">
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1677426603105" ID="ID_243044944" MODIFIED="1677861011227" TEXT="Gesamtanordnung steuern">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1677426763414" ID="ID_591151065" MODIFIED="1677775763826" TEXT="Balken-Länge">
|
||||
<node COLOR="#338800" CREATED="1677458294653" ID="ID_1105975491" MODIFIED="1677851113897" TEXT="brauche Zugriff auf Layout-Steuerung">
|
||||
<arrowlink COLOR="#5586b2" DESTINATION="ID_883997565" ENDARROW="Default" ENDINCLINATION="108;-242;" ID="Arrow_ID_1785981386" STARTARROW="None" STARTINCLINATION="-291;20;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1677718715763" ID="ID_354383908" MODIFIED="1677775372224" TEXT="Balken ist unten zu kurz">
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677426726852" ID="ID_1196135559" MODIFIED="1677861006427" TEXT="Klammer sinnvoll positionieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1677426763414" FOLDED="true" ID="ID_591151065" MODIFIED="1677775763826" TEXT="Balken-Länge">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1677718715763" FOLDED="true" ID="ID_354383908" MODIFIED="1677775372224" TEXT="Balken ist unten zu kurz">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -28816,7 +28855,7 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1677775374922" ID="ID_758069702" MODIFIED="1677775760407" TEXT="Zweifel: verwenden Gtk und Cairo die gleichen »device units«?">
|
||||
<node COLOR="#435e98" CREATED="1677775374922" FOLDED="true" ID="ID_758069702" MODIFIED="1677775760407" TEXT="Zweifel: verwenden Gtk und Cairo die gleichen »device units«?">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1677775564913" ID="ID_933287576" MODIFIED="1677775585136" TEXT="Beobachte Höhe = 12, allerdings nur im ersten Durchlauf"/>
|
||||
<node CREATED="1677775586262" ID="ID_712638262" MODIFIED="1677775598515" TEXT="im zweiten Durchlauf ist die kleinste Höhe = 62"/>
|
||||
|
|
@ -28895,12 +28934,47 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1675902536517" ID="ID_827367364" MODIFIED="1677451616418" TEXT="Anpassung an Allocation">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1675902536517" ID="ID_827367364" MODIFIED="1677860993690" TEXT="Anpassung an Allocation">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1677851231787" ID="ID_989353390" MODIFIED="1677851251627" TEXT="Höhe wird fest vorgegeben">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1677451786789" ID="ID_883997565" MODIFIED="1677458321599" TEXT="Styling per CSS">
|
||||
<linktarget COLOR="#8255b2" DESTINATION="ID_883997565" ENDARROW="Default" ENDINCLINATION="108;-242;" ID="Arrow_ID_1785981386" SOURCE="ID_1105975491" STARTARROW="None" STARTINCLINATION="-291;20;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1677851253034" ID="ID_534111962" MODIFIED="1677860992436" TEXT="notwendige Breite aus CSS + Konstruktion ermitteln">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677851285924" ID="ID_452245483" MODIFIED="1677860991136" TEXT="Realisierbarkeit sicherstellen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677851305897" ID="ID_724109318" MODIFIED="1677851357078" TEXT="es gibt eine Minimal-Höhe">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...denn es muß die obere und die untere Kappe gezeichnet werden, und deren Höhe ergibt sich qua Konstruktion aus der Basisbreite
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677851359498" ID="ID_1131290489" MODIFIED="1677860989026" TEXT="⟹ notfalls Basisbreite reduzieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
➩ Skala für gesamte Klammer verkleinern
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677451786789" ID="ID_883997565" MODIFIED="1677860999220" TEXT="Styling per CSS">
|
||||
<linktarget COLOR="#5586b2" DESTINATION="ID_883997565" ENDARROW="Default" ENDINCLINATION="108;-242;" ID="Arrow_ID_1785981386" SOURCE="ID_1105975491" STARTARROW="None" STARTINCLINATION="-291;20;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1677451800420" ID="ID_1164109956" MODIFIED="1677457558599" TEXT="Entscheidung: Modell?">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node COLOR="#435e98" CREATED="1677451818657" FOLDED="true" ID="ID_1508791771" MODIFIED="1677457503784" TEXT="global oder individuell?">
|
||||
|
|
@ -29194,8 +29268,10 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677457832609" ID="ID_1478500520" MODIFIED="1677457839466" TEXT="Festzulegende Eigenschaften">
|
||||
<node CREATED="1677458010560" ID="ID_1003264563" MODIFIED="1677545992545" TEXT="Basisgröße (=Linienbreite)">
|
||||
<node COLOR="#435e98" CREATED="1677457832609" ID="ID_1478500520" MODIFIED="1677864414871" TEXT="Festzulegende Eigenschaften">
|
||||
<icon BUILTIN="info"/>
|
||||
<node COLOR="#338800" CREATED="1677458010560" ID="ID_1003264563" MODIFIED="1677851081064" TEXT="Basisgröße (=Linienbreite)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677458053102" ID="ID_1614036555" MODIFIED="1677458063936" TEXT="könnte man erst mal am DPI-Wert festmachen"/>
|
||||
<node CREATED="1677458064756" ID="ID_1912408866" MODIFIED="1677458088765" TEXT="man könnte es zusätzlich auch an einer default-Schriftgröße festmachen"/>
|
||||
<node CREATED="1677458115914" ID="ID_1725640561" MODIFIED="1677458124777" TEXT="alternativ wäre ein spezial-Setting denkbar"/>
|
||||
|
|
@ -29213,20 +29289,37 @@
|
|||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1677457850153" ID="ID_1305504262" MODIFIED="1677457863755" TEXT="Bezugsachse horizontal">
|
||||
<node COLOR="#338800" CREATED="1677457850153" ID="ID_1305504262" MODIFIED="1677851083066" TEXT="Bezugsachse horizontal">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677458156264" ID="ID_857815456" MODIFIED="1677458189479" TEXT="ergbit sich aus Padding, Scale und dem Design selber (Φ-minor)"/>
|
||||
</node>
|
||||
<node CREATED="1677457867207" ID="ID_1126720758" MODIFIED="1677457876146" TEXT="Ankerpunkt obere/untere Kappe">
|
||||
<node COLOR="#338800" CREATED="1677457867207" ID="ID_1126720758" MODIFIED="1677851085119" TEXT="Ankerpunkt obere/untere Kappe">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677458198238" ID="ID_1920467800" MODIFIED="1677458213788" TEXT="ganz analog, Padding + Scale"/>
|
||||
</node>
|
||||
<node CREATED="1677457975185" ID="ID_1711981540" MODIFIED="1677457995178" TEXT="Farbe der Klammer">
|
||||
<node COLOR="#338800" CREATED="1677457975185" ID="ID_1711981540" MODIFIED="1677860996817" TEXT="Farbe der Klammer">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677458102355" ID="ID_1926644285" MODIFIED="1677458115114" TEXT="könnte man an default-Schriftfarbe festmachen"/>
|
||||
<node CREATED="1677458115914" ID="ID_829449840" MODIFIED="1677458124777" TEXT="alternativ wäre ein spezial-Setting denkbar"/>
|
||||
</node>
|
||||
<node CREATED="1677457971241" ID="ID_716437219" MODIFIED="1677458024907" TEXT="Padding">
|
||||
<node COLOR="#338800" CREATED="1677457971241" ID="ID_716437219" MODIFIED="1677851087182" TEXT="Padding">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1677458131835" ID="ID_1560054657" MODIFIED="1677458143628" TEXT="direkt aus CSS entnehmen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677864417723" ID="ID_692056392" MODIFIED="1677864442889">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Style-Klasse: <b><font face="Monospaced">.fork__bracket</font></b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -29297,19 +29390,6 @@
|
|||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1677864417723" ID="ID_692056392" MODIFIED="1677864442889">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Style-Klasse: <b><font face="Monospaced">.fork__bracket</font></b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1554996492819" ID="ID_1391546845" MODIFIED="1557498707227" TEXT="Konfig laut systematischem Modell">
|
||||
<arrowlink COLOR="#3e63c5" DESTINATION="ID_433238862" ENDARROW="Default" ENDINCLINATION="-612;-125;" ID="Arrow_ID_1858329997" STARTARROW="None" STARTINCLINATION="-747;0;"/>
|
||||
|
|
@ -70870,8 +70950,8 @@
|
|||
<node CREATED="1554476956084" ID="ID_541824716" LINK="https://www.cairographics.org/documentation/cairomm/reference/classCairo_1_1Context.html" MODIFIED="1557498707239" TEXT="CairoContext(C++)"/>
|
||||
</node>
|
||||
<node CREATED="1561412911257" ID="ID_1173541827" LINK="https://www.cairographics.org/tutorial/" MODIFIED="1677771875029" TEXT="Zusammenfassung: Cairo-Konzepte">
|
||||
<linktarget COLOR="#5579dd" DESTINATION="ID_1173541827" ENDARROW="Default" ENDINCLINATION="-2465;188;" ID="Arrow_ID_1216025940" SOURCE="ID_1322665426" STARTARROW="None" STARTINCLINATION="-2437;323;"/>
|
||||
<linktarget COLOR="#6460c9" DESTINATION="ID_1173541827" ENDARROW="Default" ENDINCLINATION="-1791;132;" ID="Arrow_ID_1651743539" SOURCE="ID_711895669" STARTARROW="None" STARTINCLINATION="-2602;211;"/>
|
||||
<linktarget COLOR="#5579dd" DESTINATION="ID_1173541827" ENDARROW="Default" ENDINCLINATION="-2465;188;" ID="Arrow_ID_1216025940" SOURCE="ID_1322665426" STARTARROW="None" STARTINCLINATION="-2437;323;"/>
|
||||
<node CREATED="1561412945044" FOLDED="true" ID="ID_1336013492" MODIFIED="1677772243199" TEXT="»Source«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
|
|
|||
Loading…
Reference in a new issue