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:
Fischlurch 2016-11-01 23:20:43 +01:00
parent 6fd0045a65
commit 1fbade3a67
4 changed files with 151 additions and 65 deletions

View file

@ -128,7 +128,7 @@ namespace panel {
scroller_.set_border_width(10); scroller_.set_border_width(10);
scroller_.add(canvas_); scroller_.add(canvas_);
adjustToNecessaryCanvasSize(); canvas_.adjustSize();
// show everything.... // show everything....
this->add(twoParts_); 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 void
TimelinePanel::experiment_1() TimelinePanel::experiment_1()
@ -178,7 +160,7 @@ namespace panel {
uint y = rand() % 500; uint y = rand() % 500;
canvas_.put(*chld, x, y); canvas_.put(*chld, x, y);
chld->show(); chld->show();
adjustToNecessaryCanvasSize(); canvas_.adjustSize();
} }
@ -197,7 +179,7 @@ namespace panel {
canvas_.move (*chld, x,y); canvas_.move (*chld, x,y);
} }
adjustToNecessaryCanvasSize(); canvas_.adjustSize();
} }
@ -214,7 +196,7 @@ namespace panel {
int width = chld->get_allocated_width(); int width = chld->get_allocated_width();
pos += 0.6 * 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 { namespace {
_Fmt debugAdj(" | Adj-%s(%3d<%5.2f<%3d)"); _Fmt debugAdj(" | Adj-%s(%3d<%5.2f<%3d)");
} }
bool bool
Canvas::on_draw(Cairo::RefPtr<Cairo::Context> const& cox) Canvas::on_draw(Cairo::RefPtr<Cairo::Context> const& cox)
{ {
@ -269,8 +283,8 @@ namespace panel {
{ {
int h = get_allocation().get_width(); int h = get_allocation().get_width();
int v = get_allocation().get_height(); int v = get_allocation().get_height();
uint extH=20, extV=20;
uint extH, extV; determineExtension();
get_size (extH, extV); get_size (extH, extV);
auto adjH = get_hadjustment(); auto adjH = get_hadjustment();
@ -295,8 +309,10 @@ namespace panel {
cox->stroke(); cox->stroke();
cox->restore(); cox->restore();
// cause child widgets to be redrawn
Gtk::Layout::on_draw(cox); Gtk::Layout::on_draw(cox);
// any drawing which follows happens on top of child widgets...
cox->save(); cox->save();
cox->translate(-offH, -offV); cox->translate(-offH, -offV);

View file

@ -75,12 +75,16 @@ namespace panel {
: public Gtk::Layout : public Gtk::Layout
{ {
bool shallDraw_; bool shallDraw_;
bool recalcExtension_ = false;
public: public:
void enableDraw (bool); void enableDraw (bool);
void adjustSize();
private: private:
virtual bool on_draw (Cairo::RefPtr<Cairo::Context> const&) override; virtual bool on_draw (Cairo::RefPtr<Cairo::Context> const&) override;
void determineExtension();
}; };
@ -138,8 +142,6 @@ namespace panel {
using ChildV = std::vector<ChildEx*>; using ChildV = std::vector<ChildEx*>;
ChildV childz_; ChildV childz_;
void adjustToNecessaryCanvasSize();
void experiment_1(); void experiment_1();
void experiment_2(); void experiment_2();
void experiment_3(); void experiment_3();

View file

@ -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. 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> </pre>
</div> </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// <pre>//This is the canvas widget of ~GTK-3//
It allows not only custom drawing, but also to embed other widgets at defined coordinates. 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 !test setup
we need a test setup for this investigation. we need a test setup for this investigation.
* easy to launch * easy to launch
* don't waste much time, it is disposable * don't waste much time, it is disposable
* realistic: shall reflect the situation in our actual UI * realistic: shall reflect the situation in our actual UI
</pre> </pre>
</div> </div>
<div title="GuiCommandBinding" creator="Ichthyostega" modifier="Ichthyostega" created="201511272246" modified="201609091641" tags="design decision operational GuiPattern GuiIntegration draft discuss" changecount="26"> <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
&amp;rarr; important question: how to [[organise the widgets|GuiTimelineWidgetStructure]] &amp;rarr; important question: how to [[organise the widgets|GuiTimelineWidgetStructure]]
</pre> </pre>
</div> </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. <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). 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 :** 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.&lt;br/&gt;It is //not// the extension of the virtual canvas. :* the {{{Gtk::Allocation}}} is precisely the visible screen area reserved for the widget.&lt;br/&gt;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. &amp;rarr; see [[here|GtkCustomDrawing]] :* ...consequently, if our drawing shall be stitched to the canvas, we need to care for translation and for clipping ourselves. &amp;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
= [&amp;](Gtk::Widget&amp; chld)
{
cout &lt;&lt; &quot;hoya &quot;&lt;&lt;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> </pre>
</div> </div>
<div title="HighLevelModel" modifier="Ichthyostega" created="200808152311" modified="201505310109" tags="Model spec design discuss img" changecount="2"> <div title="HighLevelModel" modifier="Ichthyostega" created="200808152311" modified="201505310109" tags="Model spec design discuss img" changecount="2">

View file

@ -57,8 +57,7 @@
und welchen Teil des Verhaltens &#252;berlassen wir GTK und welchen Teil des Verhaltens &#252;berlassen wir GTK
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="help"/> <icon BUILTIN="help"/>
</node> </node>
<node CREATED="1477600216950" ID="ID_1935952349" MODIFIED="1477600219202" TEXT="focus"> <node CREATED="1477600216950" ID="ID_1935952349" MODIFIED="1477600219202" TEXT="focus">
@ -119,8 +118,7 @@
mehr als ein top-level Fenster offen mehr als ein top-level Fenster offen
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1477342868574" ID="ID_679226593" MODIFIED="1477342875681" TEXT="WorkspaceWindow"> <node CREATED="1477342868574" ID="ID_679226593" MODIFIED="1477342875681" TEXT="WorkspaceWindow">
@ -142,8 +140,7 @@
which reference actions from one or more action groups. which reference actions from one or more action groups.
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1477343041295" ID="ID_1874325062" MODIFIED="1477343048450" TEXT="PanelManager"> <node CREATED="1477343041295" ID="ID_1874325062" MODIFIED="1477343048450" TEXT="PanelManager">
<node CREATED="1477343244428" ID="ID_513688853" MODIFIED="1477343252255" TEXT="managed die Docks"/> <node CREATED="1477343244428" ID="ID_513688853" MODIFIED="1477343252255" TEXT="managed die Docks"/>
@ -162,8 +159,7 @@
realisiert Vererbung <i>zu fu&#223;</i> realisiert Vererbung <i>zu fu&#223;</i>
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
<head> <head>
@ -182,8 +178,7 @@
AUA! AUA!
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1477347390430" HGAP="46" ID="ID_138529757" MODIFIED="1477347400283" TEXT="Panel" VSHIFT="31"> <node CREATED="1477347390430" HGAP="46" ID="ID_138529757" MODIFIED="1477347400283" TEXT="Panel" VSHIFT="31">
@ -227,8 +222,7 @@
auch nicht im Application-Shutdown! auch nicht im Application-Shutdown!
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1477617185582" ID="ID_634277803" MODIFIED="1477617217049" TEXT="PanelManager::createPanels()"> <node CREATED="1477617185582" ID="ID_634277803" MODIFIED="1477617217049" TEXT="PanelManager::createPanels()">
<richcontent TYPE="NOTE"><html> <richcontent TYPE="NOTE"><html>
@ -243,8 +237,7 @@
dock_.add_item(timelinePanel-&gt;getDockItem(),Gdl::DOCK_BOTTOM); dock_.add_item(timelinePanel-&gt;getDockItem(),Gdl::DOCK_BOTTOM);
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="info"/> <icon BUILTIN="info"/>
</node> </node>
</node> </node>
@ -260,8 +253,7 @@
Helper to build the menu and for&#160;registering and handling of user action events Helper to build the menu and for&#160;registering and handling of user action events
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1477344354329" ID="ID_1683945104" MODIFIED="1477344359708" TEXT="createUi()"> <node CREATED="1477344354329" ID="ID_1683945104" MODIFIED="1477344359708" TEXT="createUi()">
@ -287,8 +279,7 @@
aber es kann davon mehrere geben aber es kann davon mehrere geben
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1477343152288" ID="ID_1267678981" MODIFIED="1477343164378" TEXT="Vermengung von Fenster und Workspace"/> <node CREATED="1477343152288" ID="ID_1267678981" MODIFIED="1477343164378" TEXT="Vermengung von Fenster und Workspace"/>
</node> </node>
@ -9277,8 +9268,7 @@
...nicht mehr das <i>klassische</i>&#160;gtk::Main ...nicht mehr das <i>klassische</i>&#160;gtk::Main
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1477785704584" ID="ID_528329491" MODIFIED="1477785711408" TEXT="event handling"> <node CREATED="1477785704584" ID="ID_528329491" MODIFIED="1477785711408" TEXT="event handling">
@ -9314,8 +9304,7 @@
Siehe Beschreibung im Beispiel/Tutorial Siehe Beschreibung im Beispiel/Tutorial
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="info"/> <icon BUILTIN="info"/>
</node> </node>
</node> </node>
@ -9337,8 +9326,7 @@
und auch ein Signal f&#252;r Parse-Fehler anschlie&#223;t und auch ein Signal f&#252;r Parse-Fehler anschlie&#223;t
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1810760662" ENDARROW="Default" ENDINCLINATION="1846;-61;" ID="Arrow_ID_1610122569" SOURCE="ID_1164942946" STARTARROW="None" STARTINCLINATION="-227;-646;"/> <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"/> <icon BUILTIN="info"/>
</node> </node>
@ -9434,12 +9422,11 @@
i.e. the enclosing parent widget also gets a chance to redraw itself i.e. the enclosing parent widget also gets a chance to redraw itself
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
<node CREATED="1477791881630" ID="ID_1823256674" MODIFIED="1477843569686" TEXT="coordinates"> <node CREATED="1477791881630" ID="ID_1823256674" MODIFIED="1478038049036" TEXT="coordinates">
<icon BUILTIN="pencil"/> <icon BUILTIN="button_ok"/>
<node CREATED="1477791885614" ID="ID_380369648" MODIFIED="1477791916343"> <node CREATED="1477791885614" ID="ID_380369648" MODIFIED="1477791916343">
<richcontent TYPE="NODE"><html> <richcontent TYPE="NODE"><html>
<head> <head>
@ -9450,8 +9437,7 @@
<font color="#bd0053">Warning</font>: allocation is the <i>visible</i>&#160;area <font color="#bd0053">Warning</font>: allocation is the <i>visible</i>&#160;area
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
</node> </node>
<node CREATED="1477791921953" ID="ID_555455740" MODIFIED="1477791952896" TEXT="...not the extension of the canvas!"/> <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 by printing values from the on_draw() callback
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
<node CREATED="1477841809741" ID="ID_1400891730" MODIFIED="1477841816024" TEXT="context-&gt;translate"> <node CREATED="1477841809741" ID="ID_1400891730" MODIFIED="1477841816024" TEXT="context-&gt;translate">
<node CREATED="1477841816516" ID="ID_642580279" MODIFIED="1477841841348" TEXT="by -value"/> <node CREATED="1477841816516" ID="ID_642580279" MODIFIED="1477841841348" TEXT="by -value"/>
@ -9506,8 +9491,7 @@
causing us to adjust too much causing us to adjust too much
</p> </p>
</body> </body>
</html> </html></richcontent>
</richcontent>
</node> </node>
</node> </node>
</node> </node>
@ -9515,6 +9499,68 @@
<node CREATED="1477843534095" ID="ID_1261380784" MODIFIED="1477843541259" TEXT="Problem: widget extension"> <node CREATED="1477843534095" ID="ID_1261380784" MODIFIED="1477843541259" TEXT="Problem: widget extension">
<icon BUILTIN="messagebox_warning"/> <icon BUILTIN="messagebox_warning"/>
<node CREATED="1477843543126" ID="ID_1096450231" MODIFIED="1477843556632" TEXT="seems to be defined only after drawing it"/> <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&#252;rden,
</p>
<p>
sind nur f&#252;r den Fall, da&#223; 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&#xfc;ck"/>
<node CREATED="1478038020338" ID="ID_541293489" MODIFIED="1478038026524" TEXT="Layout-&gt;set_size()"/>
</node>
</node> </node>
</node> </node>
<node CREATED="1477784943797" ID="ID_298493039" MODIFIED="1477791972306" TEXT="layering"> <node CREATED="1477784943797" ID="ID_298493039" MODIFIED="1477791972306" TEXT="layering">