Fit the photograph clear of the roll and the floating row while composing
A crop handle straddles the picture's edge. With the photograph fitted to the whole canvas, the bottom handles sat in the photo roll's band, whose swipe handler takes every press inside it, and the bottom-left one under the "Done Composing" row, which is declared after the overlay and whose buttons press 44px tall. Both were drawn and could not be grabbed: on a laptop-shaped window, one or the other for nearly any photograph. While composing, the canvas box is inset 16px from its clip and stops above the band, the row's margin and the row's hit height. The band is measured once, on the canvas, and the row reads it from there.
This commit is contained in:
+55
-17
@@ -1823,8 +1823,10 @@ in property <bool> panel-visible: true;
|
||||
clip: true;
|
||||
|
||||
canvas-image := Image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
x: parent.fit-x;
|
||||
y: parent.fit-y;
|
||||
width: parent.fit-w;
|
||||
height: parent.fit-h;
|
||||
source: root.canvas;
|
||||
image-fit: contain;
|
||||
// TRACES: FR-UI-4
|
||||
@@ -1872,8 +1874,10 @@ in property <bool> panel-visible: true;
|
||||
// original straight away, and the last draft of the edit
|
||||
// fades out over it rather than vanishing.
|
||||
previous-frame := Image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
x: canvas-image.x;
|
||||
y: canvas-image.y;
|
||||
width: canvas-image.width;
|
||||
height: canvas-image.height;
|
||||
source: root.canvas-previous;
|
||||
image-fit: contain;
|
||||
image-rendering: canvas-image.image-rendering;
|
||||
@@ -1941,15 +1945,54 @@ in property <bool> panel-visible: true;
|
||||
// The overlay is placed against *this*, not against the whole
|
||||
// area — otherwise the crop rect drifts off the picture on any
|
||||
// window whose shape differs from the image's.
|
||||
//
|
||||
// **While composing, the box is inset and stops above the
|
||||
// photo roll.** A crop handle straddles the picture's edge,
|
||||
// half of it outside, and a photograph fitted to the full
|
||||
// box puts that half under this area's clip — and, along
|
||||
// the bottom, under the roll's band, whose swipe handler
|
||||
// takes every press inside it (see `PhotoRoll`). The bottom
|
||||
// corners were drawn there, lit up, and could not be
|
||||
// grabbed. Fitting the picture clear of both is the only
|
||||
// fix: the handler has to be where it is, and moving the
|
||||
// handles inward would leave them off the corner they
|
||||
// move.
|
||||
property <length> roll-band:
|
||||
Library.library-total > 0
|
||||
? (root.roll-open
|
||||
? Theme.roll-strip + Theme.roll-reach
|
||||
: Theme.roll-reach)
|
||||
: 0px;
|
||||
// The roll's own travel, so what stands on it rises with
|
||||
// the strip rather than jumping ahead of it.
|
||||
animate roll-band { duration: 180ms; easing: ease-out; }
|
||||
//
|
||||
// The floating "Done Composing" row stands on that band,
|
||||
// and is declared after the crop overlay so it takes a
|
||||
// press first: a photograph filling the width put the
|
||||
// bottom-left handle under it. So the reserve is the band,
|
||||
// the row's 12px margin, and the row's hit height — a
|
||||
// `Button`'s press area is the touch target, not its ink.
|
||||
// Every other side keeps half a handle and a finger's
|
||||
// slop clear of this area's clip.
|
||||
property <length> fit-inset: Develop.cropping ? 16px : 0px;
|
||||
property <length> fit-below: Develop.cropping
|
||||
? self.roll-band + 12px + Theme.touch-target
|
||||
: 0px;
|
||||
property <length> fit-x: self.fit-inset;
|
||||
property <length> fit-y: self.fit-inset;
|
||||
property <length> fit-w: max(1px, self.width - 2 * self.fit-inset);
|
||||
property <length> fit-h: max(1px, self.height - 2 * self.fit-inset - self.fit-below);
|
||||
|
||||
property <float> src-w: root.canvas.width > 0 ? root.canvas.width : 1;
|
||||
property <float> src-h: root.canvas.height > 0 ? root.canvas.height : 1;
|
||||
property <float> box-w: self.width / 1px;
|
||||
property <float> box-h: self.height / 1px;
|
||||
property <float> box-w: self.fit-w / 1px;
|
||||
property <float> box-h: self.fit-h / 1px;
|
||||
property <float> fit-scale: min(self.box-w / self.src-w, self.box-h / self.src-h);
|
||||
property <length> shown-w: self.src-w * self.fit-scale * 1px;
|
||||
property <length> shown-h: self.src-h * self.fit-scale * 1px;
|
||||
property <length> shown-x: (self.width - self.shown-w) / 2;
|
||||
property <length> shown-y: (self.height - self.shown-h) / 2;
|
||||
property <length> shown-x: self.fit-x + (self.fit-w - self.shown-w) / 2;
|
||||
property <length> shown-y: self.fit-y + (self.fit-h - self.shown-h) / 2;
|
||||
|
||||
// Empty and error states say what happened rather than
|
||||
// showing a blank canvas.
|
||||
@@ -2904,15 +2947,10 @@ in property <bool> panel-visible: true;
|
||||
// the thing that could not be reached. They stack
|
||||
// instead — the controls ride on top of the roll's
|
||||
// band, at whatever height it currently stands.
|
||||
property <length> roll-clear:
|
||||
Library.library-total > 0
|
||||
? (root.roll-open
|
||||
? Theme.roll-strip + Theme.roll-reach
|
||||
: Theme.roll-reach)
|
||||
: 0px;
|
||||
// The roll's own travel, so they rise with the strip
|
||||
// rather than jumping ahead of it.
|
||||
animate roll-clear { duration: 180ms; easing: ease-out; }
|
||||
// The canvas's measure of the band, animated there
|
||||
// with the roll's own travel so these rise with the
|
||||
// strip rather than jumping ahead of it.
|
||||
property <length> roll-clear: canvas-area.roll-band;
|
||||
|
||||
x: 12px;
|
||||
y: parent.height - self.preferred-height - 12px
|
||||
|
||||
Reference in New Issue
Block a user