Commit Graph

28 Commits

Author SHA1 Message Date
Elias Naur 162250392b layout: respect minimum constraint size in Flex.Layout
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2022-07-08 09:18:13 +02:00
Elias Naur a63e0cb44a all: [API] change op.Offset to take integer coordinates
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>
2022-05-31 10:24:09 +02:00
Elias Naur 936c266b03 all: [API] split operation stack into per-state stacks
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>
2021-10-08 17:21:56 +02:00
pierre e088833caf layout: simplified Axis methods
Removed the Main and Cross Axis methods in favor of Convert.

Signed-off-by: pierre <pierre.curto@gmail.com>
2021-01-14 11:04:06 +01:00
Elias Naur d331dd2de8 op: rename StackOp/Push/Pop to StateOp/Save/Load
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>
2021-01-12 21:28:59 +01:00
pierre 0e3e446393 layout: added Axis methods
Signed-off-by: pierre <pierre.curto@gmail.com>
2021-01-11 14:32:28 +01:00
pierre 33103593a1 layout: updated comment, avoid copying whole context in Flex
Signed-off-by: pierre <pierre.curto@gmail.com>
2020-12-29 01:00:53 +01:00
pierre e9cd8958de layout: fixed divisions by zero in Flex.Layout
Signed-off-by: pierre <pierre.curto@gmail.com>
2020-12-03 16:45:33 +01:00
Elias Naur 878131189b all: remove redundant op.TransformOp.Offset
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>
2020-06-21 22:41:56 +02:00
Elias Naur 3b54c665ca layout: add WeightSum to Flex for overriding the Flexed total weight
Updates gio#139

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-17 09:43:11 +02:00
Elias Naur 5272dc9fa5 layout: make Flexed weight a weight, not a ratio
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>
2020-06-10 11:25:25 +02:00
Elias Naur c19ed05342 op: change CallOp to be a return value from MacroOp.Stop
Converting

	macro := op.Record(ops)
	...
	macro.Stop()

	macro.Add()

to

	macro := op.Record(ops)
	...
	call := macro.Stop()

	call.Add(ops)

Which is more general (call.Add can take a different ops than the op.Record
that started it), and enforced the order between Stop and the subsequent Add.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-06-02 12:07:20 +02:00
Thomas Bruyelle ae8a377cda op: add op.Push and op.Record funcs
The funcs replace stack.Push and macro.Record, which become private.
This makes stack and macro faster to write, in particular for stacks
where you can just write the following line to save and restore the
state :

  defer op.Push(ops).Pop()

This usage requires Push to return a pointer (since Pop has a pointer
receiver), or else the code doesn't compile.

For consistancy, I tried to do the same for op.Record, but this implied
to turn all the MacroOp fields into pointers, and this caused some
panics. As a result, op.Record doesn't return a pointer.

An other side effect pointed by Larry Clapp: StackOp and MacroOp are not
re-usable any more, you have to allocate a new one for each usage, using
the described funcs above.

Signed-off-by: Thomas Bruyelle <thomas.bruyelle@gmail.com>
2020-06-02 10:39:56 +02:00
Elias Naur 3af01a3f43 layout: change Widget to take explicit Context and return explicit Dimensions
Change the definition of Widget from the implicit

        type Widget func()

to the explicit functional

        type Widget func(gtx layout.Context) layout.Dimensions

The advantages are numerous:

- Clearer connection between the incoming context and the output dimensions.
- Returning the Dimensions are impossible to omit.
- Contexts passed by value, so its fields can be exported
and freely mutated by the program.

The only disadvantage is the longer function literals and the many "returns".
What tipped the scales in favour of the explicit Widget variant is that type
aliases can dramatically shorten the literals:

	type (
		C = layout.Context
		D = layout.Dimensions
	)

	widget := func(gtx C) D {
		...
	}

Note that the aliases are not part of the Gio API and it is up to each user
whether they want to use them.

Finally the Go proposal for lightweight function literals,
https://github.com/golang/go/issues/21498, may remove the disadvantage
completely in future.

Context becomes a plain struct with only public fields, and its Reset is
replaced by a NewContext convenience constructor.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-23 22:28:49 +02:00
Elias Naur 013ea395b4 all: use new rectangle and point convenience functions
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-19 11:03:30 +02:00
Elias Naur 7bf3265ccd layout,widget: transpose Constraints to use image.Points for limits
Instead of

    type Contraints struct {
	    Width, Height Constraint
    }

use

    type Constraints struct {
	    Min, Max image.Point
    }

which leads to simpler use. For example, the Min method is trivally replaced by
the field, and the RigidConstraints constructor is no longer a net win.

API Change. Rewrites:

    gofmt -r 'gtx.Constraints.Min() -> gtx.Constraints.Min'
    gofmt -r 'gtx.Constraints.Width.Min -> gtx.Constraints.Min.X'
    gofmt -r 'gtx.Constraints.Height.Min -> gtx.Constraints.Min.Y'
    gofmt -r 'gtx.Constraints.Height.Max -> gtx.Constraints.Max.Y'
    gofmt -r 'gtx.Constraints.Width.Max -> gtx.Constraints.Max.X'

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-05-19 09:58:07 +02:00
Elias Naur bfb50cef5d all: remove unused fields, functions and add missing error handling
Credit to staticcheck.io.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2020-02-27 22:26:54 +01:00
Elias Naur f60a5c7ac3 layout: simplify Flex API to a single Layout call
With the simplification of MacroOp, it is now possible to simplify
the Flex API to just a single Layout method, similar to List:

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

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-12 00:45:36 +01:00
Elias Naur edc81ea0bb op: remove operation list argument from MacroOp.Add
The ability to invoke other operation lists belongs in the new CallOp.

While we're here, make MacroOp.Add use a pointer receiver to match the
other methods.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-12 00:45:36 +01:00
Elias Naur 65dc6797eb layout: don't allow overlapping Flex and Stack layouts
Overlapping layouts such as

	outer := layout.Flex{}
	inner := layout.Stack{}
	child := inner.Rigid(gtx, ...)
	outerChild := outer.Rigid(gtx, func() {
		inner.Layout(gtx, child)
	})
	outer.Layout(gtx, outerChild)

runs but result in a wrong layout.

This change use empty StackOps to ensure that the Stack and Flex
child layout methods are called in the same scope as their Layout
methods:

	outer := layout.Flex{}
	inner := layout.Stack{}
	outerChild := outer.Rigid(gtx, func() {
		child := inner.Rigid(gtx, ...)
		inner.Layout(gtx, child)
	})
	outer.Layout(gtx, outerChild)

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-12-02 18:54:35 +01:00
Elias Naur 759900902a layout: fix Flex baseline
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-16 20:35:24 +02:00
Elias Naur 7f07933eb3 layout: unexport Context.Layout and make it a function
Layout wasn't used outside package layout, so let's not export it.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-16 11:08:52 +02:00
Elias Naur e2d0b3cfca layout: invert baseline to measure positive distance from bottom
With an inverted baseline, the zero value results in the widget
baseline aligned to its bottom.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-16 00:49:52 +02:00
Elias Naur 45ccbbe571 layout: expand Flex children
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-15 23:33:31 +02:00
Elias Naur 529fd4d307 layout: rename Flex.Flexible to just Flex
Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-06 09:20:04 +02:00
Elias Naur 8d82a3eaa6 layout: delete Init methods from Flex and Stack
With Context containing all the necessary information, separate
Init methods no longer makes much sense. Delete them and thereby
remove a source of runtime panics.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-10-06 09:17:41 +02:00
Elias Naur 8cf35a1f97 op: add package op for operations
Extract operation types from package ui into package op.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2019-09-30 16:55:47 +02:00
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