Inv(#1020): find a reliable way to determine extension of the canvas
bottom line - seems we need to do that manually - must wait until in the on_draw() callback - use Container::foreach() to visit all child widgets - Layout::set_size()
This commit is contained in:
parent
6fd0045a65
commit
1fbade3a67
4 changed files with 151 additions and 65 deletions
|
|
@ -128,7 +128,7 @@ namespace panel {
|
|||
scroller_.set_border_width(10);
|
||||
scroller_.add(canvas_);
|
||||
|
||||
adjustToNecessaryCanvasSize();
|
||||
canvas_.adjustSize();
|
||||
|
||||
// show everything....
|
||||
this->add(twoParts_);
|
||||
|
|
@ -148,24 +148,6 @@ namespace panel {
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
TimelinePanel::adjustToNecessaryCanvasSize()
|
||||
{
|
||||
uint sizeX = 10;
|
||||
uint sizeY = 10;
|
||||
for (Widget* chld : childz_)
|
||||
{
|
||||
uint x = canvas_.child_property_x(*chld);
|
||||
uint y = canvas_.child_property_y(*chld);
|
||||
x += chld->get_allocated_width();
|
||||
y += chld->get_allocated_height();
|
||||
sizeX = max (sizeX, x);
|
||||
sizeY = max (sizeY, y);
|
||||
}
|
||||
|
||||
canvas_.set_size (sizeX, sizeY);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TimelinePanel::experiment_1()
|
||||
|
|
@ -178,7 +160,7 @@ namespace panel {
|
|||
uint y = rand() % 500;
|
||||
canvas_.put(*chld, x, y);
|
||||
chld->show();
|
||||
adjustToNecessaryCanvasSize();
|
||||
canvas_.adjustSize();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -197,7 +179,7 @@ namespace panel {
|
|||
|
||||
canvas_.move (*chld, x,y);
|
||||
}
|
||||
adjustToNecessaryCanvasSize();
|
||||
canvas_.adjustSize();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -214,7 +196,7 @@ namespace panel {
|
|||
int width = chld->get_allocated_width();
|
||||
pos += 0.6 * width;
|
||||
}
|
||||
adjustToNecessaryCanvasSize();
|
||||
canvas_.adjustSize();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -258,10 +240,42 @@ namespace panel {
|
|||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
Canvas::adjustSize()
|
||||
{
|
||||
recalcExtension_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
Canvas::determineExtension()
|
||||
{
|
||||
if (not recalcExtension_) return;
|
||||
|
||||
uint extH=20, extV=20;
|
||||
Gtk::Container::ForeachSlot callback
|
||||
= [&](Gtk::Widget& chld)
|
||||
{
|
||||
cout << "hoya "<<chld;
|
||||
auto allo = chld.get_allocation();
|
||||
uint x = allo.get_x();
|
||||
uint y = allo.get_y();
|
||||
x += allo.get_width();
|
||||
y += allo.get_height();
|
||||
extH = max (extH, x);
|
||||
extV = max (extV, y);
|
||||
cout << "x="<<x<<" y="<<y<<endl;
|
||||
};
|
||||
foreach(callback);
|
||||
recalcExtension_ = false;
|
||||
set_size (extH, extV);
|
||||
}
|
||||
|
||||
namespace {
|
||||
_Fmt debugAdj(" | Adj-%s(%3d<%5.2f<%3d)");
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Canvas::on_draw(Cairo::RefPtr<Cairo::Context> const& cox)
|
||||
{
|
||||
|
|
@ -269,8 +283,8 @@ namespace panel {
|
|||
{
|
||||
int h = get_allocation().get_width();
|
||||
int v = get_allocation().get_height();
|
||||
|
||||
uint extH, extV;
|
||||
uint extH=20, extV=20;
|
||||
determineExtension();
|
||||
get_size (extH, extV);
|
||||
|
||||
auto adjH = get_hadjustment();
|
||||
|
|
@ -295,8 +309,10 @@ namespace panel {
|
|||
cox->stroke();
|
||||
cox->restore();
|
||||
|
||||
// cause child widgets to be redrawn
|
||||
Gtk::Layout::on_draw(cox);
|
||||
|
||||
// any drawing which follows happens on top of child widgets...
|
||||
cox->save();
|
||||
cox->translate(-offH, -offV);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,12 +75,16 @@ namespace panel {
|
|||
: public Gtk::Layout
|
||||
{
|
||||
bool shallDraw_;
|
||||
bool recalcExtension_ = false;
|
||||
|
||||
public:
|
||||
void enableDraw (bool);
|
||||
void adjustSize();
|
||||
|
||||
private:
|
||||
virtual bool on_draw (Cairo::RefPtr<Cairo::Context> const&) override;
|
||||
|
||||
void determineExtension();
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -138,8 +142,6 @@ namespace panel {
|
|||
using ChildV = std::vector<ChildEx*>;
|
||||
ChildV childz_;
|
||||
|
||||
void adjustToNecessaryCanvasSize();
|
||||
|
||||
void experiment_1();
|
||||
void experiment_2();
|
||||
void experiment_3();
|
||||
|
|
|
|||
|
|
@ -2411,7 +2411,7 @@ Typically, when starting the draw operation, we retrieve our //allocation.// Thi
|
|||
Thus, if we want to use absolute canvas coordinates for our drawing, we need to adjust the cairo context prior to any drawing operations: we translate it in the opposite direction of the values retrieved from the scrollbar {{{Gtk::Adjustment}}}s. This causes the //user coordinates// to coincede with the absolute canvas coordinates.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GtkLayoutWidget" creator="Ichthyostega" modifier="Ichthyostega" created="201610141819" modified="201610141820" tags="GuiPattern impl" changecount="3">
|
||||
<div title="GtkLayoutWidget" creator="Ichthyostega" modifier="Ichthyostega" created="201610141819" modified="201611012211" tags="GuiPattern impl" changecount="4">
|
||||
<pre>//This is the canvas widget of ~GTK-3//
|
||||
It allows not only custom drawing, but also to embed other widgets at defined coordinates.
|
||||
|
||||
|
|
@ -2425,9 +2425,9 @@ In order to build a sensible plan for our timeline structure, we need to investi
|
|||
|
||||
!test setup
|
||||
we need a test setup for this investigation.
|
||||
* easy to launch
|
||||
* don't waste much time, it is disposable
|
||||
* realistic: shall reflect the situation in our actual UI
|
||||
* easy to launch
|
||||
* don't waste much time, it is disposable
|
||||
* realistic: shall reflect the situation in our actual UI
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiCommandBinding" creator="Ichthyostega" modifier="Ichthyostega" created="201511272246" modified="201609091641" tags="design decision operational GuiPattern GuiIntegration draft discuss" changecount="26">
|
||||
|
|
@ -2648,7 +2648,7 @@ In the most general case, there can be per-track content and nested content at t
|
|||
&rarr; important question: how to [[organise the widgets|GuiTimelineWidgetStructure]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="GuiTimelineWidgetStructure" creator="Ichthyostega" modifier="Ichthyostega" created="201410250002" modified="201610301605" tags="GuiPattern discuss decision impl" changecount="52">
|
||||
<div title="GuiTimelineWidgetStructure" creator="Ichthyostega" modifier="Ichthyostega" created="201410250002" modified="201611012218" tags="GuiPattern discuss decision impl" changecount="58">
|
||||
<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 means to write one or several custom GTK widgets. Thus the question of layout and screen space division and organisation becomes a crucial design decision. The ~GTK-2 Gui, as implemented currently, did already take some steps along this route, yet this kind of decision should be cast and documented explicitly (be it after the fact).
|
||||
|
||||
|
|
@ -2736,6 +2736,28 @@ In order to build a sensible plan for our timeline structure, we need to investi
|
|||
:** when invoked //after// our custom drawing, the embedded widgets stay on top
|
||||
:* the {{{Gtk::Allocation}}} is precisely the visible screen area reserved for the widget.<br/>It is //not// the extension of the virtual canvas.
|
||||
:* ...consequently, if our drawing shall be stitched to the canvas, we need to care for translation and for clipping ourselves. &rarr; see [[here|GtkCustomDrawing]]
|
||||
;determine canvas extension
|
||||
:when the extension of the (virtual) canvas area depends on position and size of child widgets, //we need to calculate this extension manually.//
|
||||
:* beware: the allocation for child widgets is not setup immediately, when adding or moving children
|
||||
:* rather, we need to wait until in the {{{on_draw()}}} callback for the {{{Gtk::Layout}}}
|
||||
:* at this point, we may use the //foreach// mechanism of the container
|
||||
{{{
|
||||
uint extH=20, extV=20;
|
||||
Gtk::Container::ForeachSlot callback
|
||||
= [&](Gtk::Widget& chld)
|
||||
{
|
||||
cout << "hoya "<<chld;
|
||||
auto allo = chld.get_allocation();
|
||||
uint x = allo.get_x();
|
||||
uint y = allo.get_y();
|
||||
x += allo.get_width();
|
||||
y += allo.get_height();
|
||||
extH = max (extH, x);
|
||||
extV = max (extV, y);
|
||||
};
|
||||
foreach(callback);
|
||||
set_size (extH, extV);
|
||||
}}}
|
||||
</pre>
|
||||
</div>
|
||||
<div title="HighLevelModel" modifier="Ichthyostega" created="200808152311" modified="201505310109" tags="Model spec design discuss img" changecount="2">
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@
|
|||
und welchen Teil des Verhaltens überlassen wir GTK
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node CREATED="1477600216950" ID="ID_1935952349" MODIFIED="1477600219202" TEXT="focus">
|
||||
|
|
@ -119,8 +118,7 @@
|
|||
mehr als ein top-level Fenster offen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477342868574" ID="ID_679226593" MODIFIED="1477342875681" TEXT="WorkspaceWindow">
|
||||
|
|
@ -142,8 +140,7 @@
|
|||
which reference actions from one or more action groups.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1477343041295" ID="ID_1874325062" MODIFIED="1477343048450" TEXT="PanelManager">
|
||||
<node CREATED="1477343244428" ID="ID_513688853" MODIFIED="1477343252255" TEXT="managed die Docks"/>
|
||||
|
|
@ -162,8 +159,7 @@
|
|||
realisiert Vererbung <i>zu fuß</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -182,8 +178,7 @@
|
|||
AUA!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477347390430" HGAP="46" ID="ID_138529757" MODIFIED="1477347400283" TEXT="Panel" VSHIFT="31">
|
||||
|
|
@ -227,8 +222,7 @@
|
|||
auch nicht im Application-Shutdown!
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1477617185582" ID="ID_634277803" MODIFIED="1477617217049" TEXT="PanelManager::createPanels()">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -243,8 +237,7 @@
|
|||
dock_.add_item(timelinePanel->getDockItem(),Gdl::DOCK_BOTTOM);
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -260,8 +253,7 @@
|
|||
Helper to build the menu and for registering and handling of user action events
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477344354329" ID="ID_1683945104" MODIFIED="1477344359708" TEXT="createUi()">
|
||||
|
|
@ -287,8 +279,7 @@
|
|||
aber es kann davon mehrere geben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1477343152288" ID="ID_1267678981" MODIFIED="1477343164378" TEXT="Vermengung von Fenster und Workspace"/>
|
||||
</node>
|
||||
|
|
@ -9277,8 +9268,7 @@
|
|||
...nicht mehr das <i>klassische</i> gtk::Main
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477785704584" ID="ID_528329491" MODIFIED="1477785711408" TEXT="event handling">
|
||||
|
|
@ -9314,8 +9304,7 @@
|
|||
Siehe Beschreibung im Beispiel/Tutorial
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -9337,8 +9326,7 @@
|
|||
und auch ein Signal für Parse-Fehler anschließt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1810760662" ENDARROW="Default" ENDINCLINATION="1846;-61;" ID="Arrow_ID_1610122569" SOURCE="ID_1164942946" STARTARROW="None" STARTINCLINATION="-227;-646;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
|
|
@ -9434,12 +9422,11 @@
|
|||
i.e. the enclosing parent widget also gets a chance to redraw itself
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477791881630" ID="ID_1823256674" MODIFIED="1477843569686" TEXT="coordinates">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1477791881630" ID="ID_1823256674" MODIFIED="1478038049036" TEXT="coordinates">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1477791885614" ID="ID_380369648" MODIFIED="1477791916343">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
|
@ -9450,8 +9437,7 @@
|
|||
<font color="#bd0053">Warning</font>: allocation is the <i>visible</i> area
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1477791921953" ID="ID_555455740" MODIFIED="1477791952896" TEXT="...not the extension of the canvas!"/>
|
||||
|
|
@ -9486,8 +9472,7 @@
|
|||
by printing values from the on_draw() callback
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1477841809741" ID="ID_1400891730" MODIFIED="1477841816024" TEXT="context->translate">
|
||||
<node CREATED="1477841816516" ID="ID_642580279" MODIFIED="1477841841348" TEXT="by -value"/>
|
||||
|
|
@ -9506,8 +9491,7 @@
|
|||
causing us to adjust too much
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -9515,6 +9499,68 @@
|
|||
<node CREATED="1477843534095" ID="ID_1261380784" MODIFIED="1477843541259" TEXT="Problem: widget extension">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1477843543126" ID="ID_1096450231" MODIFIED="1477843556632" TEXT="seems to be defined only after drawing it"/>
|
||||
<node CREATED="1478032584364" ID="ID_1961636905" MODIFIED="1478032597162" TEXT="need to find the right signal">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1478032598165" ID="ID_275509060" MODIFIED="1478032625203" TEXT="need to get foreach working">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1478032633704" ID="ID_1067159761" MODIFIED="1478032641714" TEXT="Hint: show_all_children"/>
|
||||
<node CREATED="1478032642310" ID="ID_246127915" LINK="https://developer.gnome.org/gtkmm-tutorial/stable/sec-custom-containers.html.en" MODIFIED="1478032658384" TEXT="Tutorial: custom container"/>
|
||||
<node CREATED="1478037794935" HGAP="41" ID="ID_614099643" MODIFIED="1478037886314" TEXT="geht doch" VSHIFT="38">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
<node CREATED="1478037802776" ID="ID_1706111079" MODIFIED="1478037817305" TEXT="keine Ahnung warums neulich einen SEGFAULT gab"/>
|
||||
<node CREATED="1478037818037" ID="ID_1257597772" MODIFIED="1478037846037" TEXT="wichtig: Funktor inline bestehen lassen"/>
|
||||
<node CREATED="1478037849449" ID="ID_171841689" MODIFIED="1478037859121" TEXT="habe diesmal sogar ein Lambda verwendet">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1478037888539" ID="ID_1261247197" MODIFIED="1478037996248" TEXT="wie">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1478037893658" ID="ID_1711061664" MODIFIED="1478037896669" TEXT="trigger-Variable"/>
|
||||
<node CREATED="1478037899458" ID="ID_132096735" MODIFIED="1478037907973" TEXT="im on_draw()-Callback">
|
||||
<node CREATED="1478037908465" ID="ID_1414994452" MODIFIED="1478037915835" TEXT="erst hier sind die Allokationen gesetzt"/>
|
||||
<node CREATED="1478037916303" ID="ID_1781865207" MODIFIED="1478037977495" TEXT="konnte keine anderen sinnvollen callbacks finden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...die anderen, die noch in Frage kommen würden,
|
||||
</p>
|
||||
<p>
|
||||
sind nur für den Fall, daß ein Widget neu instantiiert wird
|
||||
</p>
|
||||
<p>
|
||||
oder neu in das Window-System gemappt wird.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1478037986046" ID="ID_1293899679" MODIFIED="1478037990857">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
on_check_resize() wird nicht aufgerufen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1478038003892" ID="ID_477362495" MODIFIED="1478038010982" TEXT="rufe foreach mit inline-Lambda auf"/>
|
||||
<node CREATED="1478038011427" ID="ID_399044896" MODIFIED="1478038019797" TEXT="melde per max in die lokalen Variablen zurück"/>
|
||||
<node CREATED="1478038020338" ID="ID_541293489" MODIFIED="1478038026524" TEXT="Layout->set_size()"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1477784943797" ID="ID_298493039" MODIFIED="1477791972306" TEXT="layering">
|
||||
|
|
|
|||
Loading…
Reference in a new issue