Skip to content

Three-way split containers #72

@nullst

Description

@nullst

Checklist

  • I have searched the issue tracker for open issues that relate to the same feature, before opening a new one.
  • This issue only relates to a single feature. I will open new issues for any other features.

Is your feature request related to a problem?

In some cases an analogue of Split container that could handle more than two widgets inside would improve user experience. My use case is explained below.

I am writing an application with a three-pane window (i.e., the widgets are organized into three columns). Users should be able to change the sizes of the three columns. Currently I organize the window as a sequence of two HSplit containers:

hsplit(hsplit(COLUMN1, COLUMN2), COLUMN3)

This works, but the two "splitter" widgets that appear between the columns do not have the same behavior and this leads to an inconsistent user interface. Moving the first splitter preserves the size of the third column and changes only the sizes of the first two columns. But moving the second splitter, which visually is between COLUMN2 and COLUMN3, changes the sizes of all three columns:

three-way-split.webm

As a user, given such an interface I would certainly expect the two splitter widgets to behave in the same way. It would be nice to have a way to build this using standard fyne containers.

For completeness, here's the code for the minimal example:

package main

import (
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/widget"
)

func main() {
	application := app.NewWithID("three-way-split")
	window := application.NewWindow("Three-way-split")

	label1 := widget.NewLabel("First")
	label2 := widget.NewLabel("Second")
	label3 := widget.NewLabel("Third")

	split1 := container.NewHSplit(label1, label2)
	split2 := container.NewHSplit(split1, label3)

	window.SetContent(split2)
	window.Resize(fyne.NewSize(float32(400), float32(100)))

	window.ShowAndRun()
}

Is it possible to construct a solution with the existing API?

Yes, it's possible to write an alternative Split container that could handle an arbitrary list of subordinate widgets. It shouldn't be very difficult, but I didn't do this since my goal of making three resizable columns was reached.

Describe the solution you'd like to see.

A new container, for example called SplitN, with APIs like

  • container.NewHSplitN(objects []fyne.CanvasObject) and similarly container.NewVSplitN
  • func (s *SplitN) SetWeights (weights []float32): after computing the minimal sizes for each object in the split container, divide the remaining free space available in the container among widgets according to the float values in the weights slice. Negative or zero weights should hide the corresponding widget. Positive weights do not have to sum to one, only their ratios matter.

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