Before this change, the middle alignment would align according to
the widest child. This change aligns according to the widest child
or minimum constraint, whichever is largest.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
The unit.Value is a struct and thus more inconvenient to use than its
underlying float32 type. In addition, most uses don't need a general
value, but rather a specific unit given by the context. This change
replaces unit.Value with two float32 units, Dp and Sp. It also changes
variables and parameters of unit.Value to a specific unit type matching
the context. That is, unit.Dp everywhere except for text sizes which are
in Sp.
Switching to typed float32s has multiple advantages
- They can be constants:
const touchSlop = unit.Dp(16)
- Casting untyped constants is no longer necessary:
insets := layout.UniformInset(16)
- Calculation with values is natural:
func (s ScrollbarStyle) Width() unit.Dp {
return s.Indicator.MinorWidth + s.Track.MinorPadding + s.Track.MinorPadding
}
The main API change is that calls to gtx.Px must be replaced with either
gtx.Dp or gtx.Sp depending on the unit.
Idea by Christophe Meessen.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
op.Offset is a convenience function most often used by layouts. Layouts
usually operate in integer coordinates, and the float32 version of op.Offset
needlessly force conversions from int to float32. This change makes op.Offset
take integer coordinates, to better match its intended use.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Updated the documentation for layout.List to include the details about how
drawing is performed for items in it. This gives the user an understanding about
how so many items can be drawn for performance.
Signed-off-by: Thomas Mathews <thomas.c.mathews@gmail.com>
Clipping all children once to the entire List area is enough. The
change was motivated by #389 where individual child clips would
make it harder for focus scroll heuristics to work.
References: https://todo.sr.ht/~eliasnaur/gio/389
Signed-off-by: Elias Naur <mail@eliasnaur.com>
A recent change added automatic scrolling to move focused widgets
into view. This change modifies List to layout an extra child at
each of its ends, to enable focus to move to them and trigger
automatic scrolling of the list.
For https://github.com/tailscale/tailscale/issues/4278.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Before, List would only report the remaining scrollable area of the visible
children when positioned close to either end. Now, List always report infinite
scroll bounds *unless* it is positioned at an extremum.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
When the Min constraints are set but the list
has no item to display, use those as the list
returned dimensions.
Signed-off-by: Pierre Curto <pierre.curto@gmail.com>
The op.Save and Load methods exist to support the need for
transformation, clip, pointer area state to behave as stacks. For
example, layout needs to apply an offset to its children but not
subsequent operations.
Before this change, op.Save and Load were used to save and restore the
state:
ops := new(op.Ops)
// Save state.
state := op.Save(ops)
// Apply offset.
op.Offset(...).Add(ops)
// Draw with offset applied.
draw(ops)
// Restore state.
state.Load()
A drawback with the op.Save mechanism is that there is no direct
connection between the state change and the saving and loading of state.
This causes confusion as to when a Save/Load is needed and who is
responsible for performing them, which leads to subtle bugs and over-use
of Save/Loads.
This change gets rid of the general state stack and replaces it with
per-state stacks. There is now a stack for transformation, clip, pointer
areas, and they can only be restored by the code pushing state to them.
The example above now becomes:
ops := new(op.Ops)
// Push offset to the transformation stack.
stack := op.Offset(...).Push(ops)
// Draw with offset applied.
draw(ops)
// Restore state.
stack.Pop()
For convenience, transformation also be Add'ed if the stack operation is
not required.
Simple state such as the current material no longer has a way to be
restored; it is assumed the client of a PaintOp adds their desired
material operation before it.
API change: replace op.Save/Load with explicit Push/Pop scopes for
op.TransformOps, pointer.AreaOps, clip.Ops.
To ease porting, this change retains a version of op.Save/Load that
saves and restores the transformation and clip stacks. It also retains
an Add method for clip.Op.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit adds a Length field to the
layout.Position. This field contains an approximation
of the overall length of the list's contents.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
This creates a floating-point analog to layout.Axis.Convert
for converting from (x,y) coordinate space to (main,cross)
coordinate space.
Signed-off-by: Chris Waldon <christopher.waldon.dev@gmail.com>
For example, ButtonLeft may be the right-most button for a left-handed user.
Rename the button names to match their intended use.
This is an API change. Use the following commands to update your
projects:
$ gofmt -r 'pointer.ButtonLeft -> pointer.ButtonPrimary' -w .
$ gofmt -r 'pointer.ButtonRight -> pointer.ButtonSecondary' -w .
$ gofmt -r 'pointer.ButtonMiddle -> pointer.ButtonTertiary' -w .
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Currently every user needs to manually adjust for system insets.
This is rather verbose and most don't need to deviate from this behavior.
To disable the automatic adjustment, use:
e.Insets = system.Insets{}
ctx := layout.NewContext(ops, e)
Signed-off-by: Egon Elbre <egonelbre@gmail.com>
The semantics were relaxed in a previous commit; this change renames
to operations accordingly.
API change. Use gofmt to adjust your code accordingly:
gofmt -r 'op.Push(a).Pop() -> op.Save(a).Load()'
gofmt -r 'op.Push(a) -> op.Save(a)'
gofmt -r 'v.Pop() -> v.Load()'
gofmt -r 'op.StackOp -> op.StateOp'
Signed-off-by: Elias Naur <mail@eliasnaur.com>
Added comment on the use of Dimension.Baseline and Direction.Layout constraint minimum clearing.
Also, renamed the Direction receiver for consistency and removed unnecessary conversions.
Signed-off-by: Pierre.Curto <pierre.curto@gmail.com>
I found the interplay of List's Layout/init/next/more/end methods
somewhat confusing and hard to reason about, so I refactored them.
Signed-off-by: Larry Clapp <larry@theclapp.org>
Use op.Offset instead, or create and manipulate a f32.Affine2D.
API change. Update your code with a gofmt rule:
gofmt -r 'op.TransformOp{}.Offset -> op.Offset'
Signed-off-by: Elias Naur <mail@eliasnaur.com>
An interface for scaling dp and sp is overkill, at least for all
current uses. Make it a concrete struct type, and rename it to the
shorter and more precise Metric.
Signed-off-by: Elias Naur <mail@eliasnaur.com>
It's more intuitive to specify the weight as a ratio of the total
weight of all Flexed children than to specify the ratio of the
flexable space.
Signed-off-by: Elias Naur <mail@eliasnaur.com>