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 @@

- + + + + - + + + + + + + + + + + +