Timeline: draft solution to interconnect ZoomWindow and scrollbar
After quite some tinkering, instead of extending the DisplayManager interface, I now prefer to treat this connection rather as an intricate implementation detail: The TimelineLayout implementatino now provides two translation functions, which are directly wired as slots from the Signals emitted by moving the hand of the scrollbar; the idea is that these functions mutate the ZoomWindow, which then triggers a DisplayEvaltuation, which in turn causes the drawing code to pick up and translate back the new metric and position. Results look promising, insofar the DisplayEvaluation is now triggered repeatedly, and the actual window width in pixel is propagated; however, the response of the layout code is seemingly random at times, the allocated height grows monontonously and the code Segfaults when moving the scrollbar...
This commit is contained in:
parent
941d3088d5
commit
09714cfe28
6 changed files with 193 additions and 19 deletions
|
|
@ -276,7 +276,11 @@ namespace model {
|
|||
/* === Mutators === */
|
||||
|
||||
/**
|
||||
* define the extension of the window in pixels.
|
||||
* Define the extension of the window in pixels.
|
||||
* The existing logical scale factor is retained, meaning that
|
||||
* the logical duration of the actually visible window is adjusted
|
||||
* alongside to match the new given pixel size, if necessary, also
|
||||
* the canvas is expanded to fit.
|
||||
* @note all other manipulations will always retain this value
|
||||
*/
|
||||
void
|
||||
|
|
@ -362,6 +366,13 @@ namespace model {
|
|||
fireChangeNotification();
|
||||
}
|
||||
|
||||
void
|
||||
setVisibleStart (TimeValue start)
|
||||
{
|
||||
mutateWindow (TimeSpan{start, Duration(afterWin_-startWin_)});
|
||||
fireChangeNotification();
|
||||
}
|
||||
|
||||
/**
|
||||
* explicitly set the visible window,
|
||||
* possibly expanding the canvas to fit.
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ namespace timeline {
|
|||
* Find out the extension in pixels currently allocated for the content display.
|
||||
* @return number of pixels reasonably representing the actual visible with in the window
|
||||
*/
|
||||
int
|
||||
uint
|
||||
BodyCanvasWidget::getEffectiveHorizontalSize() const
|
||||
{
|
||||
int widthForDebug = contentArea_.get_allocated_width();
|
||||
|
|
@ -529,7 +529,7 @@ namespace timeline {
|
|||
auto hadj = contentArea_.get_hadjustment();
|
||||
cout<<"|?| win::width="<<widthForDebug<<"("<<alloW<<") hadj="<<hadj->get_value()<<"/"<<hadj->get_upper()<<endl;
|
||||
widthForDebug = util::max (widthForDebug - 100, 100); ////////////////////////////////////////TODO: visual debugging
|
||||
return widthForDebug;
|
||||
return uint(widthForDebug);
|
||||
}
|
||||
void
|
||||
BodyCanvasWidget::on_size_allocate(Gtk::Allocation& allocation)
|
||||
|
|
|
|||
|
|
@ -167,13 +167,10 @@ namespace timeline {
|
|||
void disable();
|
||||
|
||||
/** @internal allow the header pane to follow our vertical scrolling movement */
|
||||
auto
|
||||
get_vadjustment()
|
||||
{
|
||||
return contentArea_.get_vadjustment();
|
||||
}
|
||||
auto get_vadjustment() { return contentArea_.get_vadjustment(); }
|
||||
auto get_hadjustment() { return contentArea_.get_hadjustment(); }
|
||||
|
||||
int getEffectiveHorizontalSize() const;
|
||||
uint getEffectiveHorizontalSize() const;
|
||||
|
||||
protected: /* ==== Interface: CanvasHook ===== */
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,13 @@ namespace timeline {
|
|||
topLevelContainer.add2 (bodyCanvas_);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////TICKET #1264 : how to pick up initial zoom settings
|
||||
zoomWindow_.attachChangeNotification (signalStructureChange_);
|
||||
// make the ZoomWindow react on changes to the horizontal scrollbar pos
|
||||
bodyCanvas_.get_hadjustment()->property_value().signal_changed().connect(
|
||||
sigc::bind(sigc::mem_fun(*this, &TimelineLayout::syncZoomWindow)
|
||||
,bodyCanvas_.get_focus_hadjustment()));
|
||||
// make the ZoomWindow react on changes to the window geometry
|
||||
bodyCanvas_.signal_size_allocate().connect(
|
||||
sigc::mem_fun(*this, &TimelineLayout::sizeZoomWindow));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -143,18 +150,53 @@ namespace timeline {
|
|||
void
|
||||
TimelineLayout::establishLayout (DisplayEvaluation&)
|
||||
{
|
||||
int contentWidthPx = bodyCanvas_.getEffectiveHorizontalSize();
|
||||
if (contentWidthPx != zoomWindow_.pxWidth())
|
||||
{////////////////////////////////////////////////////////////////TODO
|
||||
cout<<"|!| zoom-calibrateExtension("<<zoomWindow_.pxWidth()<<" ⟶ "<<contentWidthPx<<")"<<endl;
|
||||
zoomWindow_.calibrateExtension (contentWidthPx);
|
||||
}////////////////////////////////////////////////////////////////TODO
|
||||
Time windowStart = zoomWindow_.visible().start();
|
||||
int pxOffset = translateTimeToPixels (windowStart);
|
||||
cout<<"|↯| establishLayout time="<<windowStart<<" ->offset="<<pxOffset<<endl;
|
||||
bodyCanvas_.get_hadjustment()->set_value(pxOffset);
|
||||
}
|
||||
|
||||
void
|
||||
TimelineLayout::completeLayout (DisplayEvaluation&)
|
||||
{
|
||||
/* noting to do for the collect-phase */
|
||||
/* nothing to do for the collect-phase */
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal receiver (slot) to react on scrollbar changes.
|
||||
* Changes the logical window position in the ZoomWindow to reflect
|
||||
* the given #scrollPos, which is interpreted relative to the implicitly
|
||||
* known size of the timeline canvas in pixels.
|
||||
* @remark changes to ZoomWindow parameters cause notification of the listener,
|
||||
* thereby triggering a new DisplayEvaluation; this in turn will invoke
|
||||
* TimelineLayout::establishLayout() eventually, accommodating changes.
|
||||
*/
|
||||
void
|
||||
TimelineLayout::syncZoomWindow (PAdjustment hadj)
|
||||
{
|
||||
double pos = hadj->get_value();
|
||||
TimeValue windowStart = applyScreenDelta(zoomWindow_.overallSpan().start(), pos);
|
||||
cout<<"|!| zoom-scroll pos="<<pos<<" start="<<windowStart<<" zoomWin="<<zoomWindow_.visible()<<endl;
|
||||
zoomWindow_.setVisibleStart (windowStart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal receiver (slot) to react on changes of the window screen space allocation.
|
||||
* Whenever an actual change to the usable window width in pixels is detected,
|
||||
* the ZoomWindow will be re-calibrated, in turn leading to a DisplayEvaluation.
|
||||
*/
|
||||
void
|
||||
TimelineLayout::sizeZoomWindow (Gtk::Allocation& alloc)
|
||||
{
|
||||
int contentWidthPx = alloc.get_width();
|
||||
cout<<"|V| sigAlloc width="<<contentWidthPx<<endl;
|
||||
contentWidthPx = util::max (contentWidthPx - 100, 100); ////////////////////////////////////////TODO: visual debugging
|
||||
if (contentWidthPx != zoomWindow_.pxWidth())
|
||||
{////////////////////////////////////////////////////////////////TODO
|
||||
cout<<"|!| zoom-calibrateExtension("<<zoomWindow_.pxWidth()<<" ⟶ "<<contentWidthPx<<")"<<endl;
|
||||
zoomWindow_.calibrateExtension (contentWidthPx);
|
||||
cout<<"|=| zoom-calibrateExtension(canvas"<<zoomWindow_.overallSpan()<<" window="<<zoomWindow_.visible()<<" scale="<<zoomWindow_.px_per_sec()<<")"<<endl;
|
||||
}////////////////////////////////////////////////////////////////TODO
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,8 @@ namespace timeline {
|
|||
void rehook (TrackBody&) noexcept override;
|
||||
|
||||
private:/* ===== Internals ===== */
|
||||
|
||||
void syncZoomWindow (PAdjustment);
|
||||
void sizeZoomWindow (Gtk::Allocation&);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25126,7 +25126,7 @@
|
|||
<node CREATED="1672787342676" ID="ID_1189311522" MODIFIED="1672787960019" TEXT="aber auch: ZoomWindow selber muß von Geometrie-Änderungen erfahren">
|
||||
<arrowlink COLOR="#4c7ef4" DESTINATION="ID_973993644" ENDARROW="Default" ENDINCLINATION="-1199;-155;" ID="Arrow_ID_1196387900" STARTARROW="None" STARTINCLINATION="2666;104;"/>
|
||||
<linktarget COLOR="#4a449e" DESTINATION="ID_1189311522" ENDARROW="Default" ENDINCLINATION="785;29;" ID="Arrow_ID_1573433988" SOURCE="ID_650213030" STARTARROW="None" STARTINCLINATION="241;10;"/>
|
||||
<linktarget COLOR="#4a449e" DESTINATION="ID_1189311522" ENDARROW="Default" ENDINCLINATION="1548;60;" ID="Arrow_ID_751989601" SOURCE="ID_37048779" STARTARROW="None" STARTINCLINATION="1439;55;"/>
|
||||
<linktarget COLOR="#4a449e" DESTINATION="ID_1189311522" ENDARROW="Default" ENDINCLINATION="1548;60;" ID="Arrow_ID_751989601" SOURCE="ID_37048779" STARTARROW="None" STARTINCLINATION="1439;57;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1672787636743" ID="ID_1344084462" MODIFIED="1672797005517" TEXT="Flexibilisierung Display-Evaluation">
|
||||
|
|
@ -43389,8 +43389,112 @@
|
|||
<node COLOR="#338800" CREATED="1672708802759" ID="ID_412094029" MODIFIED="1672708819294" TEXT="Interface DisplayMetric implementiert durch Rückgriff auf das ZoomWindow">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1672883648918" ID="ID_1140551016" MODIFIED="1672883762952" TEXT="Zugangsweg schaffen für ZoomWindow-Aktuatoren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1672883866721" ID="ID_265373712" MODIFIED="1672883891409" TEXT="jeweils anzubinden...">
|
||||
<node CREATED="1672883669691" ID="ID_233898229" MODIFIED="1672883705186" TEXT="horizontale Scrollbar"/>
|
||||
<node CREATED="1672883684145" ID="ID_1407291054" MODIFIED="1672883701874" TEXT="Ermittlung der realen Pixel-Weite"/>
|
||||
</node>
|
||||
<node CREATED="1672883854586" ID="ID_676447060" MODIFIED="1672952350546" TEXT="Interface/Architektur">
|
||||
<node CREATED="1672883916450" ID="ID_624038632" MODIFIED="1672883920077" TEXT="Möglichkeiten">
|
||||
<node CREATED="1672883927393" ID="ID_137422584" MODIFIED="1672883937611" TEXT="ZoomWindow& per DI">
|
||||
<node CREATED="1672884659498" ID="ID_183190051" MODIFIED="1672952301593" TEXT="konzeptionell sauber">
|
||||
<icon BUILTIN="up"/>
|
||||
</node>
|
||||
<node CREATED="1672884699265" ID="ID_1546365198" MODIFIED="1672884715498" TEXT="jeweils ein zusätzliches (Referenz)-Feld">
|
||||
<icon BUILTIN="down"/>
|
||||
</node>
|
||||
<node CREATED="1672942812195" ID="ID_113255429" MODIFIED="1672942843359" TEXT=" Zugang zu low-level-Funktionalität (breites Interface)">
|
||||
<icon BUILTIN="down"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1672883940990" ID="ID_545229135" MODIFIED="1672883957585" TEXT="Proxy-Interface auf dem DisplayManager">
|
||||
<node CREATED="1672884731013" ID="ID_648800678" MODIFIED="1672942853799" TEXT="typischerweise genau da wo auch DisplayManager ohnehin verdrahtet ist">
|
||||
<icon BUILTIN="up"/>
|
||||
<node CREATED="1672884819665" ID="ID_593694932" MODIFIED="1672884824476" TEXT="BodyCanvasWidget"/>
|
||||
<node CREATED="1672884832528" ID="ID_202520630" MODIFIED="1672884839611" TEXT="AbstractTrackRenderer"/>
|
||||
<node CREATED="1672884991017" ID="ID_1411622586" MODIFIED="1672884996861" TEXT="CanvasHook::getMetric">
|
||||
<node CREATED="1672885022278" ID="ID_224159108" MODIFIED="1672885039960" TEXT="ClipPresenter::DragRelocateObserver"/>
|
||||
<node CREATED="1672885043371" ID="ID_419966736" MODIFIED="1672885045903" TEXT="ClipWidget"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1672942888477" ID="ID_344109754" MODIFIED="1672957304300" TEXT="notwendigerweise virtual calls (2 Indirektionen)">
|
||||
<icon BUILTIN="down"/>
|
||||
</node>
|
||||
<node CREATED="1672949981338" ID="ID_1962786517" MODIFIED="1672949994745" TEXT="überdehnt die Bedeutung des DisplayManager">
|
||||
<icon BUILTIN="down"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1672956771420" ID="ID_593557107" MODIFIED="1672956799788" TEXT="Update-Signal(s) auf dem DisplayManager">
|
||||
<node CREATED="1672957191000" ID="ID_76359433" MODIFIED="1672957382867" TEXT="explizit zweckgebunden">
|
||||
<linktarget COLOR="#485dbf" DESTINATION="ID_76359433" ENDARROW="Default" ENDINCLINATION="-176;17;" ID="Arrow_ID_167764533" SOURCE="ID_1233770503" STARTARROW="None" STARTINCLINATION="77;-6;"/>
|
||||
<icon BUILTIN="up"/>
|
||||
</node>
|
||||
<node CREATED="1672957201677" ID="ID_358714069" MODIFIED="1672957257339" TEXT="ZoomWindow selber bleibt Implementierungs-Detail">
|
||||
<icon BUILTIN="up"/>
|
||||
</node>
|
||||
<node CREATED="1672957271741" ID="ID_1521993338" MODIFIED="1672957286257" TEXT="nur ein einfach-indirekter (funtion-pointer) call">
|
||||
<icon BUILTIN="up"/>
|
||||
</node>
|
||||
<node CREATED="1672957315863" ID="ID_934216010" MODIFIED="1672957330972" TEXT="Komplexer und Gesamt-Funktion ist undurchsichtig">
|
||||
<icon BUILTIN="down"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1672957336020" ID="ID_1233770503" MODIFIED="1672959113510" TEXT="Entscheidung: Signale!">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Ja!!!<br />Hat lange gedauert, bis ich da drauf gekommen bin; aber das ist so eindeutig die richtige und angemessene Lösung, daß ich jetzt ausgesprochen erleichtert bin.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#485dbf" DESTINATION="ID_76359433" ENDARROW="Default" ENDINCLINATION="-176;17;" ID="Arrow_ID_167764533" STARTARROW="None" STARTINCLINATION="77;-6;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1672952339119" ID="ID_27417257" MODIFIED="1672952344269" TEXT="Art der Einbindung">
|
||||
<node CREATED="1672952358471" ID="ID_577116696" MODIFIED="1672952449076" TEXT="spezieller Twist hier: Aktuatoren arbeiten pixel-basiert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
alle Steuersignale aus dem GUI kommen in Pixel-Einheiten, entweder absolut oder relativ; das ZoomWindow selber aber arbeitet in Zeit-Einheiten (und das ist auch seine Aufgabe).
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1672952474418" ID="ID_1703019039" MODIFIED="1672952486547" TEXT="unnötige Umwege über Zeit-Werte möglichst vermeiden">
|
||||
<node CREATED="1672952510381" ID="ID_557400282" MODIFIED="1672952543555" TEXT="insofern die Rechnungen als präzise gelten"/>
|
||||
<node CREATED="1672952549168" ID="ID_1479986541" MODIFIED="1672952631231" TEXT="aber die Werte-Begrenzungen berücksichtigen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
in Grenzbereichen greift das ZoomWindow ein und begrenzt Ausschläge; selbst wenn der angeschlossene Code direkt die Pixel-Werte verwendet, muß trotzdem auf solche Eingriffe geprüft werden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1672952644887" ID="ID_393917969" MODIFIED="1672952661568" TEXT="ggfs aber Stellung der Scrollbars prüfen und rekalibrieren"/>
|
||||
<node CREATED="1672956427506" ID="ID_1572841890" MODIFIED="1672956430600" TEXT="Struktur">
|
||||
<node CREATED="1672956446738" ID="ID_419294832" MODIFIED="1672960594911" TEXT="Adjustment::valueChanged() ⟼ syncZoomWindow(Adjustment&)"/>
|
||||
<node CREATED="1672956504172" ID="ID_1390665381" MODIFIED="1672960626188" TEXT="BodyCanvasWidget::on_size_allocate() ⟼ sizeZoomWindow()">
|
||||
<node CREATED="1672960628748" ID="ID_31432666" MODIFIED="1672960671941" TEXT="Display-Evaluation ⟶ update Adjustment based on ZoomWindow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1672787519757" ID="ID_37048779" MODIFIED="1672787852442" TEXT="Pixel-Weite kalibrieren: zu Beginn der Display-Evaluation einschleifen">
|
||||
<arrowlink COLOR="#4a449e" DESTINATION="ID_1189311522" ENDARROW="Default" ENDINCLINATION="1548;60;" ID="Arrow_ID_751989601" STARTARROW="None" STARTINCLINATION="1439;55;"/>
|
||||
<arrowlink COLOR="#4a449e" DESTINATION="ID_1189311522" ENDARROW="Default" ENDINCLINATION="1548;60;" ID="Arrow_ID_751989601" STARTARROW="None" STARTINCLINATION="1439;57;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1672798860387" ID="ID_981451006" MODIFIED="1672798872066" TEXT="Feedback auf Scrolling">
|
||||
|
|
@ -43398,6 +43502,21 @@
|
|||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1672798873057" ID="ID_133007183" MODIFIED="1672799054739" TEXT="horizontale Canvas-Breite kommt nicht korrekt an">
|
||||
<arrowlink COLOR="#ac3f80" DESTINATION="ID_1699842831" ENDARROW="Default" ENDINCLINATION="-1384;79;" ID="Arrow_ID_927325344" STARTARROW="None" STARTINCLINATION="-1848;-74;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node COLOR="#338800" CREATED="1672969399236" ID="ID_105188286" MODIFIED="1672969452360" TEXT="Logik überarbeitet: Werte kommmen jetzt an">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1672969412314" ID="ID_128441040" MODIFIED="1672969448542" TEXT="Fehler: horizontale Ausdehnung instabil">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1672969457755" ID="ID_1145571154" MODIFIED="1672969483227" TEXT="Fehler: run-away in der Höhe bei wiederholter Display-Evaluation">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1672969484624" ID="ID_1370033195" MODIFIED="1672969500955" TEXT="die allozierte Content-Höhe wächst monoton">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1672969501989" ID="ID_1513242412" MODIFIED="1672969532573" TEXT="Verdacht: da nun erstmals re-Evaluationen stattfinden, wird ein Init-Fehler sichtbar">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -43405,6 +43524,10 @@
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1672708648699" ID="ID_1985216414" MODIFIED="1672708769250" TEXT="#1264 fully integrate ZoomWindow mutators into Timeline display">
|
||||
<linktarget COLOR="#954368" DESTINATION="ID_1985216414" ENDARROW="Default" ENDINCLINATION="1507;68;" ID="Arrow_ID_1698932113" SOURCE="ID_1466789019" STARTARROW="None" STARTINCLINATION="-35;216;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1672883774136" HGAP="85" ID="ID_135908111" MODIFIED="1672883794675" TEXT="anzubinden" VSHIFT="21">
|
||||
<edge COLOR="#976c6c"/>
|
||||
<node CREATED="1672883797610" ID="ID_1763437884" MODIFIED="1672883807253" TEXT="Canvas-Scrollbar"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1667488193842" ID="ID_1347640673" MODIFIED="1667488208549" TEXT="Invarianten">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="14"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue