Commit Graph

371 Commits

Author SHA1 Message Date
Elias Naur 22cd88df9f all: rename the gioui.org/ui module to gioui.org
The "ui" is redundant and stutters.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-30 12:37:06 +02:00
Elias Naur ce74bc0cba ui/layout,ui/app: fix tests, go fmt, update comments
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-26 19:15:58 +02:00
Elias Naur bdd6b32711 ui/app/internal/input: schedule an extra frame after event delivery
A program might choose to process events that affect UI state already laid out.
For example, a button click might switch to a completely different UI page, but
the click might be processed during the drawing of the current page.

Avoiding that require either processing events very early during layout or
adding InvalidateOps whenever events are handled late.

Early event processing is awkward and InvalidateOps are easy to forget and
their absence masked by any other cause of redraw.

This change adds an implicit InvalidateOp for each frame where events have been
delivered to the program, allowing late event handling without use of
InvalidateOps.

In the worst case we waste a frame, increasing power use. I hope that future
optimizations will detect and discard the duplicate frame before it reaches
the GPU.

A similar situation applies to the delayed delivery of Editor events, but
since Editor.Layout flushes remaining events, extra InvalidateOps are not
required. Add a comment.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-26 18:58:25 +02:00
Elias Naur dc6fedc163 ui: change Queue to return all events at once
The Queue interface was changed from

	type Queue interface {
		Events(k Key) []Event
	}

to the more complex single-step protocol

	type Queue interface {
		Next(k Key) (Event, bool)
	}

to cater for a particular use case: Editor's SubmitEvent. When a
SubmitEvent is passed to a caller of Editor.Next, the Editor state,
in particular the current text, must not have changed by edits
later in the command stream. For example, pressing the keys <E>,
<Enter>, <E> should result in a SubmitEvent where the Editor has
a single 'e' in Text(), not two.

However, there is no reason to push the more complex Queue to every user.
Rather, store remaining input events inside Editor and process them as
Editor.Event (or Layout) is called.

Finally, revert the Queue interface to the simpler Events method.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-26 18:41:03 +02:00
Elias Naur 578b169279 ui/app: (wayland) pack related field in structs
No functional changes.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-26 13:42:09 +02:00
Elias Naur 51cfb4e5c2 ui/app: (linux) separate xkb logic from wayland backend
Makes the Wayland backend more clean, and X11 might be able to reuse
the xkb code.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-26 13:01:51 +02:00
Elias Naur bbc0cebacf ui/layout: reset Dimensions in Context.Reset
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-25 10:38:06 +02:00
Elias Naur 9c33550644 all: rename more *layout.Context names to gtx
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-25 09:43:15 +02:00
Elias Naur a89c6d1c33 all: rename c to gtx for *layout.Context parameters
Short like `ctx` but not as easily confused with context.Context
values.

Suggested by Larry Clapp.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-25 09:34:12 +02:00
Elias Naur 3944ef4b2e ui: merge package input
Event handling is as fundamental as operations, so move the input
package declarations to package ui.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-24 22:24:10 +02:00
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 2f878fe154 ui/layout: make Align a Direction
Removes the stutter by simplifying

	layout.Align{Alignment: layout.NE}

to

	layout.Align(layout.NE)

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-24 20:32:14 +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 64add13d28 ui/app: (wayland) wait for xdg_shell configure event before drawing
According to the xdg_shell documentation, the xdg_surface must be
configured before use.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-24 17:28:04 +02:00
Elias Naur 736692a725 ui/app: (windows) process all events before redrawing
While here, make sure the DestroyEvent is sent after exiting the
event loop.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-23 20:49:51 +01:00
Elias Naur 5c9d35c186 ui/app,ui/app/internal/gl: work around golang.org/issue/34474
Apparently, the (*syscall.LazyProc).Call does not keep its arguments
alive across calls.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-23 20:26:52 +01:00
Elias Naur 5c87437542 ui/app: (windows) don't unregister window class
It silently fails because the Gio window is using it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-23 19:17:14 +01:00
Elias Naur 8e41c8a0be ui/app: (windows) don't cast syscall.Handle to unsafe.Pointer
The cast is not necessary and a syscall.Handle is not a pointer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-23 10:25:11 +02:00
Elias Naur 2d8072fbbb ui/layout: replace "interface element" with "widget" in documentation
Now that we have a Widget type, use it in the documentation.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-22 16:19:07 +02:00
Elias Naur 4a1e0a30cb ui/layout: fix typo
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-19 18:53:45 +02:00
Elias Naur 3817b19bbe ui/layout: update documentation to reflect the function scope changes
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-18 22:57:14 +02:00
Elias Naur 31f7f04181 ui/layout: clean up after function scope change
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-18 22:03:08 +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 816f0e901f ui/app: scale touch events by surface scale
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-18 19:28:08 +02:00
Drew DeVault dcddd9a84a os_wayland: transform pointer events by scale
Fixes #37
2019-09-18 19:15:17 +02:00
Drew DeVault c5a6ca2aba ui/app/egl.go: on failure, try again without sRGB
Signed-off-by: Drew DeVault <sir@cmpwn.com>
2019-09-18 18:44:35 +02:00
Elias Naur ee89d643cc ui: panic if a StackOp does not Pop in the same macro as Push
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-17 11:56:42 +02:00
Elias Naur bae2e0ecf2 ui/app: (wayland) restore discrete scrolling behaviour
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-16 15:39:31 +02:00
Elias Naur 37d5b947eb ui/app: (wayland) reset fling emulation on key press
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-13 21:13:02 +02:00
Elias Naur 2ea9fd9983 ui/app: (wayland) reset fling emulation of pointer motion
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-13 20:11:14 +02:00
Elias Naur 81f935f69b ui/app: go fmt
Sigh.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-13 19:09:05 +02:00
Elias Naur 5bdb1d9e54 ui/app: (wayland) emulate fling behaviour for touchpads
Unlike macOS, Wayland leaves it up to the client to animate the
implied fling gesture when scrolling on a touchpad.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-13 18:35:38 +02:00
Elias Naur e6f0e0582d ui/gesture,ui/internal/fling: extract fling logic into its own package
We're going to re-use fling extrapolation and animation for Wayland touchpads.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-13 18:35:38 +02:00
Elias Naur 86b231ca28 ui: add Max, Add for Values
Finding the maximum or adding Values are particularly for adjusting
margins for the safe area insets returned in app.UpdateEvent.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-09 17:50:13 +02:00
Elias Naur 5eef85f5cd ui/app: note that Window.Invalidate is safe for concurrent use
Invalidate is intended to be called as a result of external events,
which might very well be from a different goroutine than the one
driving the window.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-09 14:51:55 +02:00
Elias Naur 93409a784d ui: fill out the MacroOp opcode in Record to support unfinished macros
Before this change MacroOp.Record simply reserved enough space for Stop to fill
out. If a user Record but never Stop'ed a MacroOp, the resulting Ops buffer
would end up with a zero, invalid opcode and panic at decode.

Fill out an empty MacroOp at Record, ensuring the Ops remains valid.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-08 21:27:25 +02:00
Daniel Martí 85843f1f29 all: update go.mod files to target Go 1.13
Since the main README recommends Go 1.13 or later, let's make the go.mod
files reflect that. This will enable starting to use new language
features.

Modules that still build on 1.12 will continue to work on that version
just fine; this line is just a hint to enable new language features for
versions of Go new enough.

Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
2019-09-07 11:18:37 +02:00
Elias Naur b4433da21b ui/app: (iOS) use UIView's safeAreaInsets for window insets if available
Unlike UIView's layoutMargins, safeAreaInsets only includes the space
actually taken up by system UI.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-06 13:09:59 +02:00
Elias Naur 6ad154419b ui/layout: rename List.Invert to ScrollToEnd
Much clearer.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-05 21:15:37 +02:00
Elias Naur 7d93a2790c ui/layout: delete List.Distance field
Distance was meant to be used for implementing nested scrollers, but
I don't think the API is right. For example, Distance doesn't report
residual fling scrolling.

Delete the field while we wait for a better approach.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-05 20:41:09 +02:00
Elias Naur 1529f20eb7 ui/layout: rewrite List
Inverted lists used to behave as if its top and bottom edges were
flipped. That was easy but also wrong: when the underlying children
changed size, they would move relative to the top edge of the list.

As illustrated by issue gio#34, Invert should only do two things:

- End lign lists smaller than the containing area.
- Scroll to end, but only as long as the user hasn't scrolled away.

List also had a bug where it didn't handle shrinking lists, so
this change rewrites List to fix that bug, fix Invert behaviour and
hopefully be a little simpler.

Fixes gio#34
2019-09-05 20:27:08 +02:00
Kenshi Kamata 82b0563c8b README, ui/layout: fix typos
Signed-off-by: Kenshi Kamata <kenshi.kamata@gmail.com>
2019-09-03 19:26:00 +02:00
Elias Naur 7ad60e0878 ui/app: print sRGB flag for eglCreateWindowSurface failure
For gio#35

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-02 15:17:29 +02:00
Elias Naur 52dd762405 ui/app: (wayland) define WL_EGL_PLATFORM=1 to force EGL in Wayland mode
Including wayland-egl.h will also set WL_EGL_PLATFORM, but generic
egl code in egl_linux.go cannot do that.

For gio#35

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-02 15:13:36 +02:00
Elias Naur dc62058bce ui/app: (wayland) ensure DestroyEvent is the last event
A ToplevelClose event could end in the same batch of events as
another event, which will result in the other event being sent
after a DestroyEvent. Window assumes no event will arrive after
DestroyEvent, so ensure that property for the Wayland backend.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-01 14:33:33 +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 110da804a0 ui/app: (wayland) expand comments for double server roundtrip
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-30 13:38:58 +02:00
Kenshi Kamata ea2ee1abcc ui/app: fix example code in document
Signed-off-by: Kenshi Kamata <kenshi.kamata@gmail.com>
2019-08-29 17:49:27 +02:00
Elias Naur 069bb0e7cd ui/app: merge goString implementations and add test
Fixes gio#30

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-08-26 21:19:58 +01:00