From 3893968502b87888d4a6ead4e8393db61e99cdc1 Mon Sep 17 00:00:00 2001
From: Ichthyostega
Date: Fri, 16 Dec 2022 19:59:47 +0100
Subject: [PATCH] Timeline: improve handling of window size changes at extreme
positions
...again and again surprising how much inconsitencies can hide in just some lines of code...
---
src/stage/model/zoom-window.hpp | 9 ++--
tests/stage/model/zoom-window-test.cpp | 58 +++++++++++++++++++-------
wiki/thinkPad.ichthyo.mm | 56 +++++++++++++++++--------
3 files changed, 87 insertions(+), 36 deletions(-)
diff --git a/src/stage/model/zoom-window.hpp b/src/stage/model/zoom-window.hpp
index a9ae76510..f362c1619 100644
--- a/src/stage/model/zoom-window.hpp
+++ b/src/stage/model/zoom-window.hpp
@@ -171,7 +171,7 @@ namespace model {
/** the deepest zoom is to use 2px per micro-tick */
- const uint ZOOM_MAX_RESOLUTION = 2 * TimeValue::SCALE;
+ const Rat ZOOM_MAX_RESOLUTION = 2 * TimeValue::SCALE;
namespace {// initial values (rather arbitrary)
const FSecs DEFAULT_CANVAS{23};
@@ -982,8 +982,9 @@ namespace model {
duration = DEFAULT_CANVAS;
else if (duration > maxSaneWinExtension (px))
duration = maxSaneWinExtension (px);
- Rat changedMetric = Rat(px) / duration;
- conformWindowToMetric (changedMetric);
+ placeWindowRelativeToAnchor (duration);
+ establishWindowDuration (duration);
+ px_per_sec_ = conformMetricToWindow (px);
ensureInvariants (px);
}
@@ -1060,7 +1061,7 @@ namespace model {
FSecs
anchorPoint() const
{
- return startWin_ + scaleSafe (afterWin_-startWin_, relativeAnchor());
+ return startWin_ + Offset{scaleSafe (afterWin_-startWin_, relativeAnchor())};
}
/**
diff --git a/tests/stage/model/zoom-window-test.cpp b/tests/stage/model/zoom-window-test.cpp
index 4000d1019..da94eb45c 100644
--- a/tests/stage/model/zoom-window-test.cpp
+++ b/tests/stage/model/zoom-window-test.cpp
@@ -264,7 +264,7 @@ namespace test {
// so this is the deepest zoom possible....
CHECK (win.visible().duration() == TimeValue(640));
- CHECK (TimeValue(640) == _t(1280,ZOOM_MAX_RESOLUTION));
+ CHECK (TimeValue{640} == Time{Rat(1280)/ZOOM_MAX_RESOLUTION});
// and this the absolutely smallest possible zoom window
win.calibrateExtension(2);
@@ -818,26 +818,54 @@ namespace test {
CHECK (win.overallSpan().end() == Time::MAX);
/*--Test-3-----------*/
- win.setOverallDuration(Duration::MAX); // now use maximally expanded canvas
- Duration targetDur{99_r/100 * Duration::MAX};
- win.setVisibleDuration(targetDur); // and demand the duration be expanded to 99%
+ win.calibrateExtension(560);
+ CHECK (win.visible().duration() == TimeValue(280)); // effective window dimensions unchanged
+ CHECK (win.px_per_sec() == 2000000_r/1); // but zoom metric slightly adapted
- CHECK (win.visible().duration() > targetDur); // actual duration slightly more than requested,
- CHECK (win.visible().duration() < Duration::MAX);
+ win.setOverallDuration(Duration::MAX); // now use maximally expanded canvas
+ Duration targetDur{Duration::MAX - FSecs(23)};
+ win.setVisibleDuration(targetDur); // and demand the duration be expanded almost full size
+
+ CHECK (win.visible().duration() == targetDur); // actual duration is the value requested
+ CHECK (win.visible().duration() < Duration::MAX);
CHECK (win.visible().start() == Time::MIN); // expansion was anchored at previous position
CHECK (win.visible().start() < Time::MAX); // and thus the window now clings to the lower end
- CHECK (win.visible().end() == TimeValue(301415533658088775));
- CHECK (win.px_per_sec() == 2019_r/2199023255552); // effective zoom metric has been sanitised numerically
- CHECK (win.pxWidth() == 559); // but pixel count is matched precisely
+ CHECK (win.visible().end() == TimeValue(307445734538825860));
+ CHECK (Time::MAX - win.visible().end() == TimeValue(23*Time::SCALE));
+ CHECK (win.px_per_sec() == 2003_r/2199023255552); // effective zoom metric has been sanitised numerically
+ CHECK (win.pxWidth() == 560); // but pixel count is matched precisely
/*--Test-4-----------*/
win.setVisiblePos(Rat{std::numeric_limits::max()-23});
- SHOW_EXPR(_raw(win.overallSpan().duration()));
- SHOW_EXPR(_raw(win.visible().duration()));
- SHOW_EXPR(_raw(win.visible().start()));
- SHOW_EXPR(_raw(win.visible().end()));
- SHOW_EXPR(win.px_per_sec());
- SHOW_EXPR(win.pxWidth());
+ CHECK (win.visible().duration() == targetDur); // actual duration unchanged
+ CHECK (win.px_per_sec() == 2003_r/2199023255552);
+ CHECK (win.pxWidth() == 560);
+ CHECK (win.visible().end() == Time::MAX); // but window now slinged to the right extreme
+ CHECK (win.visible().start() > Time::MIN);
+ CHECK (win.visible().start() == TimeValue(-307445734538825860));
+
+ /*--Test-5-----------*/
+ win.calibrateExtension(561); // expand by 1 pixel
+ CHECK (win.visible().duration() > targetDur); // actual duration indeed increased
+ CHECK (win.visible().duration() == Duration::MAX); // and then capped at maximum
+ CHECK (win.visible().end() == Time::MAX); // but while initially the upper bound is increased...
+ CHECK (win.visible().start() == Time::MIN);
+ CHECK (win.px_per_sec() == 2007_r/2199023255552); // the smoothed nominal metric was also increased slightly
+ CHECK (win.pxWidth() == 561);
+
+ /*--Test-6-----------*/
+ win.setVisibleDuration(Duration::MAX - Duration(TimeValue(1))); // request slightly different window duration
+ CHECK (win.visible().end() == Time::MAX); // by arbitrary choice, the single µ-tick was removed at start
+ CHECK (win.visible().start() == Time::MIN + TimeValue(1));
+ CHECK (win.px_per_sec() == 2007_r/2199023255552); // the smoothed nominal metric was also increased slightly
+ CHECK (win.pxWidth() == 561);
+
+ win.setVisibleDuration(Duration(TimeValue(1))); // drastically zoom-in
+ CHECK (win.visible().duration() == TimeValue(281)); // ...but we get more than 1 µ-tick
+ CHECK (561_r/_FSecs(TimeValue(1)) > ZOOM_MAX_RESOLUTION); // because the requested window would exceed maximum zoom
+ CHECK (win.px_per_sec() == 561000000_r/281); // and this conflict was resolved by increasing the window
+ CHECK (win.visible().end() == Time::MAX); // while keeping it aligned to the end of the timeline
+ CHECK (win.pxWidth() == 561);
}
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index 12956ef77..129a4dc95 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -39613,7 +39613,7 @@
-
+
@@ -39774,11 +39774,11 @@
-
+
-
+
@@ -39868,9 +39868,9 @@
-
+
-
+
@@ -41244,27 +41244,32 @@
-
-
+
+
-
-
-
-
+
+
+
+
-
+
-
+
+
+
+
+
+
@@ -41285,8 +41290,11 @@
-
-
+
+
+
+
+
@@ -41297,14 +41305,28 @@
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+