Skip to content

Dropdown popup height does not match its content #57

Description

@Vmarcelo49

A dropdown with one or two options shows a vertical scrollbar, and one with three to nine options is taller than its content.

The popup height is computed from defaultHeight + padding + 1:

https://github.com/ebitengine/debugui/blob/85357fb/dropdown.go#L103-L104

optionHeight := c.style().defaultHeight + c.style().padding + 1
totalHeight := len(options) * optionHeight

The popup body is a grid of defaultHeight rows separated by spacing, inset by padding, so the content height is len(options)*(defaultHeight+spacing) - spacing + padding*2 (22n + 6 with the default style), not 24n. The + 1 does not correspond to anything.

Measured with a 300x300 window, reading what the widget actually lays out:

options popup height content height vertical scrollbar
1 24 28 yes
2 48 50 yes
3 72 72 no
5 120 116 no (4px of empty space)
9 216 204 no (12px of empty space)
10 216 226 yes (expected, the popup is capped)

Repro:

package main

import (
	"image"

	"github.com/ebitengine/debugui"
	"github.com/hajimehoshi/ebiten/v2"
)

const (
	screenWidth  = 320
	screenHeight = 240
)

type Game struct {
	ui       debugui.DebugUI
	selected int
}

func (g *Game) Update() error {
	_, err := g.ui.Update(func(ctx *debugui.Context) error {
		ctx.Window("test", image.Rect(10, 10, 310, 160), func(layout debugui.ContainerLayout) {
			ctx.Text("Two options")
			// The popup is len(options) * (defaultHeight + padding + 1) = 2 * 24 = 48px
			// tall, but the two buttons need 2*18 + 4 + 2*5 = 50px, so the popup runs
			// out of room and a vertical scrollbar appears.
			ctx.Dropdown(&g.selected, []string{"Option 1", "Option 2"})
		})
		return nil
	})
	return err
}

func (g *Game) Draw(screen *ebiten.Image) {
	g.ui.Draw(screen)
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return screenWidth, screenHeight
}

func main() {
	ebiten.SetWindowSize(screenWidth, screenHeight)
	ebiten.SetWindowTitle("debugui: dropdown popup height")
	if err := ebiten.RunGame(&Game{}); err != nil {
		panic(err)
	}
}

Clicking the dropdown shows the problem: the popup is 48px tall, the two buttons need 50px, and a scrollbar appears that scrolls 2px of padding.

Using the real row pitch and including the body padding fixes it (checked with 1 to 20 options: the popup matches the content up to 9 options, and the scrollbar is kept from 10 on):

st := c.style()
optionHeight := st.defaultHeight + st.spacing
totalHeight := len(options)*optionHeight - st.spacing + st.padding*2

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions