Skip to content

Commit

Permalink
Merge pull request #925 from gucio321/split-layout-ref
Browse files Browse the repository at this point in the history
feat(SplitLayout): support different sashPos interpretations
  • Loading branch information
gucio321 authored Dec 4, 2024
2 parents c97a822 + 6f0e327 commit 3d9187d
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 17 deletions.
91 changes: 80 additions & 11 deletions SplitLayout.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ const (
DirectionVertical
)

// SplitRefType describes how sashPos argument to the SplitLayout should be interpreted.
type SplitRefType byte

const (
// SplitRefLeft is the default. Splitter placed counting from left/top layout's edge.
SplitRefLeft SplitRefType = iota
// SplitRefRight splitter placed counting from right/bottom layout's edge.
SplitRefRight
// SplitRefProc sashPos will be clamped in range [0, 1]. Then the position is considered a percent of GetAvailableRegion.
SplitRefProc
)

var _ Disposable = &splitLayoutState{}

type splitLayoutState struct {
Expand All @@ -40,6 +52,7 @@ type SplitLayoutWidget struct {
originFramePaddingY float32
sashPos *float32
border bool
splitRefType SplitRefType
}

// SplitLayout creates split layout widget.
Expand All @@ -66,42 +79,75 @@ func (s *SplitLayoutWidget) ID(id ID) *SplitLayoutWidget {
return s
}

// SplitRefType allows to set how sashPos should be interpreted.
// Default is counting from left/top layout's edge in px.
func (s *SplitLayoutWidget) SplitRefType(refType SplitRefType) *SplitLayoutWidget {
s.splitRefType = refType
return s
}

// Build implements widget interface.
func (s *SplitLayoutWidget) Build() {
splitLayoutState := s.getState()
s.originItemSpacingX, s.originItemSpacingY = GetItemInnerSpacing()
s.originFramePaddingX, s.originFramePaddingY = GetFramePadding()
availableW, availableH := GetAvailableRegion()

var layout Layout

*s.sashPos += splitLayoutState.delta
if *s.sashPos < 1 {
*s.sashPos = 1
var sashPos float32

switch s.splitRefType {
case SplitRefLeft:
sashPos = *s.sashPos
case SplitRefRight:
switch s.direction {
case DirectionHorizontal:
sashPos = availableH - *s.sashPos
case DirectionVertical:
sashPos = availableW - *s.sashPos
}
case SplitRefProc:
if *s.sashPos < 0 {
*s.sashPos = 0
} else if *s.sashPos > 1 {
*s.sashPos = 1
}

switch s.direction {
case DirectionHorizontal:
sashPos = availableH * *s.sashPos
case DirectionVertical:
sashPos = availableW * *s.sashPos
}
}

sashPos += splitLayoutState.delta
if sashPos < 1 {
sashPos = 1
}

switch s.direction {
case DirectionHorizontal:
_, availableH := GetAvailableRegion()
if *s.sashPos >= availableH {
*s.sashPos = availableH
if sashPos >= availableH {
sashPos = availableH
}

layout = Layout{
Column(
s.buildChild(Auto, *s.sashPos, s.layout1),
s.buildChild(Auto, sashPos, s.layout1),
Splitter(DirectionHorizontal, &(splitLayoutState.delta)).Size(0, s.originItemSpacingY),
s.buildChild(Auto, Auto, s.layout2),
),
}
case DirectionVertical:
availableW, _ := GetAvailableRegion()
if *s.sashPos >= availableW {
*s.sashPos = availableW
if sashPos >= availableW {
sashPos = availableW
}

layout = Layout{
Row(
s.buildChild(*s.sashPos, Auto, s.layout1),
s.buildChild(sashPos, Auto, s.layout1),
Splitter(DirectionVertical, &(splitLayoutState.delta)).Size(s.originItemSpacingX, 0),
s.buildChild(Auto, Auto, s.layout2),
),
Expand All @@ -111,6 +157,29 @@ func (s *SplitLayoutWidget) Build() {
PushItemSpacing(0, 0)
layout.Build()
PopStyle()

s.encodeSashPos(sashPos, availableW, availableH)
}

func (s *SplitLayoutWidget) encodeSashPos(sashPos, availableW, availableH float32) {
switch s.splitRefType {
case SplitRefLeft:
*s.sashPos = sashPos
case SplitRefRight:
switch s.direction {
case DirectionHorizontal:
*s.sashPos = availableH - sashPos
case DirectionVertical:
*s.sashPos = availableW - sashPos
}
case SplitRefProc:
switch s.direction {
case DirectionHorizontal:
*s.sashPos = sashPos / availableH
case DirectionVertical:
*s.sashPos = sashPos / availableW
}
}
}

func (s *SplitLayoutWidget) restoreItemSpacing(layout Widget) Layout {
Expand Down
17 changes: 11 additions & 6 deletions examples/splitter/splitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

var (
sashPos1 float32 = 200
sashPos2 float32 = 200
sashPos3 float32 = 200
sashPos2 float32 = 400
sashPos3 float32 = 0.5
sashPos4 float32 = 100
)

Expand All @@ -18,17 +18,22 @@ func loop() {
g.Layout{
g.Label("Left panel"),
g.Row(g.Button("Button1"), g.Button("Button2")),
g.Label("Info: These SplitLayouts have different SplitRefTypes. Try to resize MasterWindow and see what happens."),
},
g.SplitLayout(g.DirectionVertical, &sashPos2,
g.Layout{},
g.Layout{
g.Label("This split is counted from right edge."),
},
g.SplitLayout(g.DirectionHorizontal, &sashPos3,
g.Layout{},
g.Layout{
g.Label("This starts from 50%"),
},
g.SplitLayout(g.DirectionVertical, &sashPos4,
g.Layout{},
g.Layout{},
),
),
),
).SplitRefType(g.SplitRefProc),
).SplitRefType(g.SplitRefRight),
),
)
}
Expand Down

0 comments on commit 3d9187d

Please sign in to comment.