~eliasnaur/gio#198: 
layout Rigid with cross constraint

I have run into a case where I need to display Flex items with a separator running between them. The separator cross size should match the longest cross size of all Rigids. Although doable with the existing FlexChilds, would it make sense to introduce a new RigidCross which would have its cross constraint set by all Rigids and Flexes and be displayed last?

Status
REPORTED
Submitter
~pierrec
Assigned to
No-one
Submitted
7 days ago
Updated
6 days ago
Labels
No labels applied.

~eliasnaur 6 days ago

Probably not. Unless I misunderstood, RigidCross seems hard to explain, in particular its influence on the layout ordering.

I wonder how a copy of Flex, specialized for this use looks like. It may even be quite small, comparable to Egon's Split view widget.

~pierrec 6 days ago

This is what I currently use. Not perfect esp. since it cannot work with Flex children. Any better option welcome!

// Flex wraps a layout.Flex to support cross constraint rigids.
type Flex struct {
	layout.Flex
	cross int
}

func (f *Flex) Rigid(w layout.Widget) layout.FlexChild {
	return layout.Rigid(func(gtx layout.Context) layout.Dimensions {
		dims := w(gtx)
		f.cross = max(f.cross, f.Flex.Axis.Convert(dims.Size).Y)
		return dims
	})
}

// RigidCross returns a Rigid which cross axis constraint is set to the
// largest one from other non RigidCross.
func (f *Flex) RigidCross(w layout.Widget) layout.FlexChild {
	// Use a Flexed so that they are run after Rigids have been evaluated.
	return layout.Flexed(1, func(gtx layout.Context) layout.Dimensions {
		if f.Flex.Axis == layout.Horizontal {
			gtx.Constraints.Max.Y = f.cross
		} else {
			gtx.Constraints.Max.X = f.cross
		}
		return w(gtx)
	})
}

~eliasnaur 6 days ago

On Wed Feb 24, 2021 at 13:29, ~pierrec wrote:

This is what I currently use. Not perfect esp. since it cannot work with Flex children. Any better option welcome!

// Flex wraps a 
layout.Flex to support cross constraint rigids.
type Flex struct {
	
layout.Flex
	cross int
}

func (f *Flex) Rigid(w layout.Widget) 
layout.FlexChild {
	return layout.Rigid(func(gtx layout.Context) 
layout.Dimensions {
		dims := w(gtx)
		f.cross = max(f.cross, 
f.Flex.Axis.Convert(dims.Size).Y)
		return dims
	})
}

// 
RigidCross returns a Rigid which cross axis constraint is set to the
//
 largest one from other non RigidCross.
func (f *Flex) RigidCross(w 
layout.Widget) layout.FlexChild {
	// Use a Flexed so that they are run
 after Rigids have been evaluated.
	return layout.Flexed(1, func(gtx 
layout.Context) layout.Dimensions {
		if f.Flex.Axis == 
layout.Horizontal {
			gtx.Constraints.Max.Y = f.cross
		} else {
			
gtx.Constraints.Max.X = f.cross
		}
		return w(gtx)
	})
}

I meant to say whether your case is specialized enough that a custom replacement layout for Flex would be warranted. In other words, why wrap Flex rather than replacing it?

Elias

Register here or Log in to comment, or comment via email.