Commit Graph

31 Commits

Author SHA1 Message Date
Elias Naur 2782436ffc ui/layout: add common state to Context
Almost every layout and widget need the ui.Config for its environment,
an ui.Ops to store operations. Stateful widgets need an input.Queue
for events.

Add all these common objects to Context, greatly simplifying the
function signatures for Gio programs.

Fixes gio#33

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-24 21:44:33 +02:00
Elias Naur ce9bcee62b ui/layout: introduce Context
Context keeps the current Constraints and Dimensions so the layout
function scopes don't have to.

With

	ctx := new(layout.Context)

a label with margins and alignment goes from

	return al.Layout(ops, cs, func(cs layout.Constraints) layout.Dimensions {
		in := layout.Inset{...}
		return in.Layout(c, ops, cs, func(cs layout.Constraints) layout.Dimensions {
			return text.Label{...}.Layout(ops, cs)
		})
	})

to

	al.Layout(ops, ctx, func() {
		in := layout.Inset{...}
		in.Layout(c, ops, ctx, func() {
		       text.Label{...}.Layout(ops, ctx)
		})
	})

It was a difficult trade-off between the verbose functional approach
and the shorter but more complex Context.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-24 19:06:07 +02:00
Elias Naur 29639565cd ui/layout: replace implicit begin/end scopes with explicit function scopes
Before this change, layout objects followed a pattern where a
begin method would set up the layout and return a tweaked set
of constraints, and a end method would take the widget dimensions
and return the tweaked dimensions.

As has been pointed out, this process is error prone, because the
scope of the layout objects are not clear and because it is easy
to swap two begins or two ends.

It turns out that it is possible to implement layout with function
scopes in garbage free way. A typical layout changes from

        al := layout.Align{Alignment: layout.NE}
	cs = al.Begin(ops, cs)
	in := layout.Inset{Top: ui.Dp(16)}
	cs = in.Begin(c, ops, cs)
	txt := fmt.Sprintf("m: %d %s", mallocs, u.profile.Timings)
	dims := text.Label{Material: theme.text, Face: u.face(fonts.mono, 10), Text: txt}.Layout(ops, cs)
	dims = in.End(dims)
	return al.End(dims)

to

        al := layout.Align{Alignment: layout.NE}
	return al.Layout(ops, cs, func(cs layout.Constraints) layout.Dimensions {
	       in := layout.Inset{Top: ui.Dp(16)}
	       return in.Layout(c, ops, cs, func(cs layout.Constraints) layout.Dimensions {
		       txt := fmt.Sprintf("m: %d %s", mallocs, u.profile.Timings)
		       return text.Label{Material: theme.text, Face: u.face(fonts.mono, 10), Text: txt}.Layout(ops, cs)
	       })
	})

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-18 19:31:36 +02:00
Elias Naur 5766a8d226 ui/layout: avoid accumulating rounding errors from Flexible
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-30 21:15:18 +02:00
Elias Naur 12089ea62a all: rename layout.Dimens to layout.Dimensions
Dimens is only 4 characters shorter and not worth the abbreviation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-30 15:00:17 +02:00
Elias Naur ba3a952af2 ui/layout: document List, Stack
Tweak Flex documentation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-10 16:49:02 +02:00
Elias Naur 8f17163a13 ui/layout: rename List.Elem to End to match Stack and Flex
Add more documentation while we're here.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-10 16:26:39 +02:00
Elias Naur 6d1339733a apps: update gioui.org/ui
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-10 12:34:58 +02:00
Elias Naur 1a15d7241a ui/layout: rename and sanitize enums
Rename MainAxisAlignment to Spacing and CrossAxisAlignment to just
Alignment.

Drop the untyped Start, End, Center values and add them as Spacing
and Direction values. Center is both a Direction and Alignment, so
use the synonym "Middle" for the alignment.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-10 12:29:17 +02:00
Elias Naur 3d9861011e ui/layout: restore Flex.Rigid behaviour
Broken by 5f2adf9b2f.

Clamp to 0 while we're here.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-30 15:25:23 +02:00
Elias Naur 5f2adf9b2f ui: get rid of Inf
It's not worth the special cases. Use a large value where needed
(layout.List, text.Editor...) instead.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-29 12:12:51 +02:00
Elias Naur 5e1f078b12 ui: merge Transform into TransformOp
The separate Transform type is not worth its weight.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-29 02:50:55 -07:00
Elias Naur 586d33c26e ui: replace PushOp, PopOp with a StackOp
Before this change, there was no guarantee that a PopOp matched
the intended PushOp. With a single stack operation, the client is
forced to match pop with the right push.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-16 13:49:32 +02:00
Elias Naur 94a913a371 ui: move macro recording from Ops to MacroOp
Move the Record and Stop methods from Ops to MacroOp itself.

Before this change, Ops.Stop stopped the recording of the most
recent macro, which could be a different macro than intended.
After this change, there is no such confusion.

As a bonus, the Ops API becomes less cluttered.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-16 13:21:51 +02:00
Elias Naur eb9c2896cd ui/layout: round, not truncate, flex sizes in Flex.Flexible
Without proper rounding, a pixel could be left uncovered at the end
of the flex layout.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-15 21:43:53 +02:00
Elias Naur 3b5fcfe2bb ui: rename block to macro
It is a more precise name.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-15 20:36:17 +02:00
Elias Naur 0d49eb3f4b ui/layout: drop CrossAxisAlignment value Stretch
It doesn't carry its own weight; client can just as easily adjust
the Constraints themselves.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-11 20:13:10 +02:00
Elias Naur 10ef4576e7 ui/layout: drop Flex.MainAxisSize setting and MainAxisSize type
The setting doesn't bear its own weight; it's simpler for the client
to adjust the constraints itself.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-11 19:15:17 +02:00
Elias Naur c7e85efc27 ui/layout: ensure that flex weights add to 1
Before this change, the weight applied to the space left, not the
total space available after rigid children.

While here, ensure that weight sums > 1 are capped to the available
space.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-11 19:06:27 +02:00
Elias Naur 449c2b844a ui/layout: drop FlexMode
The type and argument to Flex.Flexible does not carry its weight;
It is just as easy to expand the constraint directly.

While we're here, rename the flex argument to weight which is clearer.
2019-07-11 18:44:44 +02:00
Elias Naur f44ccec043 ui/pointer: simplify pointer pass through
Get rid of the confused LayerOp and the transparent property from
AreaOp. Add an explicit PassOp to specify whether pointer events
pass-through the current area.

Let AreaOp swallow events even when no handlers are active for the
area. That behaviour is less surprising and allow clients to disable
a widget by keeping its areas but leave out its handlers.

Simplify the pointer.HitResult enum to just a bool: hit or no hit.

Finally, simplify the pointer queue by tracking parent areas and
node with indices.
2019-07-10 22:43:03 +02:00
Elias Naur 683df6345b ui/layout: fix Flex spacing
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-07-01 19:22:06 +02:00
Elias Naur ef9384ceee ui/layout: allow one-line initialization of Flex and Stack
Returning itself from the Init methods allows the client to
initialize the layout instance on one line.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-06-27 12:44:15 +02:00
Elias Naur 7aa7bb3be4 ui: rename ops to have Op suffixed, not prefixed
Match Go's FooError name pattern.

While we're here, rename RedrawOp to InvalidateOp.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-06-21 17:01:45 +02:00
Elias Naur df791f2e9b ui: remove ui.Ops parameters from layouts and path builder structs
Layouts and path builders are transient and need an ops list for
operation. However, instead of passing the ops list to every method,
pass the list in an init method and store it for subsequent methods.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-06-03 16:08:38 +02:00
Elias Naur 9142345fd4 ui: make OpPush and OpPop explicit
We're about to allow OpBlock for invoking ops from multiple (cached)
Ops containers. To allow for drawing state changes to stick after
invoking such a cached block, we can't let OpBlock perform an implicit
save and restore of drawing state.

Instead, introduce OpPush and OpPop for explicit drawing state stack
management.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-06-02 19:37:34 +02:00
Elias Naur 9b3429d6da ui: switch to (more) explicit layout
The layout package switched from interfaces to functions for
composing layouts. The switch made sure that no garbage is
generated for transient layouts such as Align, Inset, Stack, Flex.

Unfortunately, that left the stateful widgets and layouts: as soon
as their layout methods are embedded in a transient layout, a
closure is generated that escapes to the heap.

To avoid garbage for both transient as well as stateful widgets,
replace the functional approach with explicit begin/end methods.

A begin method generally starts an op block and returns the adjusted
constraints. An end method takes computed dimensions, ends its op
block and returns adjusted dimensions.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-05-30 21:39:00 +02:00
Elias Naur e436dce0e7 ui/layout: make layout API explicit
With layout.Widget a function instead of an interface, the amount
of per-frame garbage can be drastically reduced.

The layout code ends up slightly more explicit.

As a side benefit, the awkward ordering indexing for Flex and Stack
fit nicely into their new explicit Layout methods.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-05-16 11:44:17 +02:00
Elias Naur 252e058766 all: serialize ops
Pros:
- Much less per-frame garbage
- Allow future preprocessing of ops while building it
- Much fewer interface calls and pointer chasing
- Allow future serialization of ops for remote rendering

Cons:
- Slightly clumsier API

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-04-27 22:19:34 +02:00
Elias Naur 48b6a73753 all: run goimports
gioui.org/ui was renamed from gioui.org/ui/ui before the release,
but the import order wasn't changed accordingly.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-04-02 17:09:06 +02:00
Elias Naur 0f05231c35 all: initial import
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-03-31 10:47:22 +02:00