core icon indicating copy to clipboard operation
core copied to clipboard

Layout Bug in Grid Frame

Open DapperMongoose opened this issue 7 months ago • 0 comments

Describe the bug

While attempting to build a regular pattern grid that holds two types of frame the layout becomes broken (grid out of alignment) if a border is added to one of the frame types. If you remove the contents of the other kind of frame the layout will work correctly again. But even an empty frame within that "container" frame will break the layout.

I suspect there are other cases based on my results in the real app, but I haven't narrowed down exactly the cases yet.

How to reproduce

  1. Run the example code - You should see a nice square grid.
  2. Un-comment the border width styler from newFrameHolder - You should see the frame holder widgets extend past the newTile widgets.
  3. Comment out internalButton - You should see the layout is fixed again
  4. Un-comment the empty frame in newTile - The layout is once again broken

Example code

package main

import (
	"cogentcore.org/core/colors"
	"cogentcore.org/core/core"
	"cogentcore.org/core/styles"
	"cogentcore.org/core/styles/units"
)

const GridXSize = 50
const GridYSize = 50

func main() {
	b := core.NewBody("Grid Repro")

	testGrid := core.NewFrame(b)
	testGrid.Styler(func(s *styles.Style) {
		s.Display = styles.Grid
		s.Columns = GridXSize
	})

	for range GridYSize {
		for index := range GridXSize {
			if index%2 == 0 {
				newFrameHolder(testGrid, units.Dp(100), units.Dp(75), "S")
			} else {
				newFrameHolder(testGrid, units.Dp(75), units.Dp(75), "D")
			}
		}

		for index := range GridXSize {
			if index%2 == 0 {
				newTile(testGrid, units.Dp(100), units.Dp(100), "F")
			} else {
				newFrameHolder(testGrid, units.Dp(75), units.Dp(100), "N")
			}
		}
	}

	b.RunMainWindow()
}

func newTile(parent *core.Frame, sizeX units.Value, sizeY units.Value, label string) {
	newFrame := core.NewFrame(parent)
	newFrame.Styler(func(s *styles.Style) {
		s.Min.Set(sizeX, sizeY)
		s.Max.Set(sizeX, sizeY)
	})

	// any child, an empty frame will do
	//core.NewFrame(newFrame)

	internalButton := core.NewButton(newFrame).SetText(label)
	internalButton.Styler(func(s *styles.Style) {
		s.Border.Radius.Zero()
		s.Grow.Set(1, 1)
	})
}

func newFrameHolder(parent *core.Frame, sizeX units.Value, sizeY units.Value, label string) {
	newFrame := core.NewFrame(parent)
	newFrame.Styler(func(s *styles.Style) {
		s.Min.Set(sizeX, sizeY)
		s.Max.Set(sizeX, sizeY)
		s.Background = colors.Scheme.Success.Base
		//s.Border.Width.Set(units.Dp(2))
	})

	core.NewText(newFrame).SetText(label)
}

Relevant output


Platform

Linux

DapperMongoose avatar May 03 '25 21:05 DapperMongoose