~eliasnaur/gio

Gio news, January 2020

Details
Message ID
<BZMX52GW66KW.PH0XPNFWMU3I@testmac>
DKIM signature
pass
Download raw message
	Simpler Flex and Stack API

The Flex and Stack APIs were unnecessary complex because of a low level
issue blocking a garbage-free simpler API. The new CallOp operation
(described below) resolved that issue, and both layouts have been
reduced to just a single Layout call, similar to layout.List. In
particular, you no longer need to use temporary variables to hold Flex
and Stack children, and you don't need to mind the ordering between
rigid and flexed or stacked children.

For example:

   layout.Flex{}.Layout(gtx,
        layout.Flexed(0.5, func() { w2.Layout(gtx) }),
        layout.Rigid(func() { w1.Layout(gtx) }),
   }

is the simplified version of

	f := layout.Flex{}
	c2 := f.Rigid(gtx, func() { w1.Layout(gtx) })
	c1 := f.Flex(gtx, func() { w1.Layout(gtx) })
	f.Layout(gtx, c1, c2)

Notice that in the old API, rigid children (c2 in the example) had to be
first in the code, even when they were needed in a different order in
the Layout call. The new Stack and Flex APIs still lay out rigid
children first, but do so automatically.

The new unified Layout methods also avoid a common misuse of the old,
split API. For example, the following wrong way of insetting a Flex is
no longer possible:

	f := layout.Flex{}
	c2 := f.Rigid(gtx, func() { w1.Layout(gtx) })
	c1 := f.Flex(gtx, func() { w1.Layout(gtx) })
	layout.UniformInset(unit.Dp(8)).Layout(gtx, func() {
		f.Layout(gtx, c1, c2)
	})

(the Rigid and Flex calls had to be inside the Inset Layout method to work
correctly.)

See commits

    https://gioui.org/commit/7814da47a0ffdf00462fbd0095af5e3d23757ef2
    https://gioui.org/commit/f60a5c7ac342fe67638ae94fa332dfc743bc62a9

for the implementation and

   https://gioui.org/commit/0bfcac97344dce473bd7542480d65608cc582c24

for the updates to the examples.


 	New CallOp operation

It is sometimes useful to cache a list of operations for later re-use.
For example, text layouts use cached op.Ops lists to store their
computed layouts, in hope of re-using them when static text is redrawn
in a future frame.

It is also useful to be able to record a list of operations and replay
them after applying modifying operations. All non-trivial layouts do so:
record the layout of a widget, and use its dimensions to compute and
apply an offset before replaying its operations.

The old op.MacroOp did both: it records a list of operations, and the
resulting macro could be replayed from a different op.Ops list.

Unfortunately, the ability to invoke a different operations list also
made the macro escape to the heap when used, blocking the simpler and
garbage-free layout APIs described above.

The new specialized CallOp operation splits out the ability to replay an
operation list, leaving MacroOp with just the ability to record and
replay a particular range of operations on the same list.

See commit

	https://git.sr.ht/~eliasnaur/gio/commit/06217c532056c0bb3c5a808b403bdca108f84e74

for the implementation.


	New Sponsors

This month saw 4 new sponsors:

	Tom Ingleby (@tingleby)
	@ajwerner
	Roy E (@royge)
	Vitaliy F. (@funvit)

If you also find my work useful, please consider sponsoring me on

	https://eliasnaur.com/sponsor

or by reaching out to me directly.

My full-time work on Gio and related open source projects is 100% funded by
donations and sponsorships.