From 0dbdb2f3a4b33653c14be4f6e9d9ee4ee3492079 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 4 Dec 2024 07:39:25 +0100 Subject: [PATCH 1/3] feat(SplitLayout): support different sashPos interpretations until now the only and default behaviour was counting from left/top. I've added possibility to interpret sashPos from right/bottom or as percent (%) of availableRegion --- SplitLayout.go | 85 +++++++++++++++++++++++++++++++---- examples/splitter/splitter.go | 17 ++++--- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/SplitLayout.go b/SplitLayout.go index 21922749..37297c60 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -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 { @@ -40,6 +52,7 @@ type SplitLayoutWidget struct { originFramePaddingY float32 sashPos *float32 border bool + splitRefType SplitRefType } // SplitLayout creates split layout widget. @@ -66,42 +79,76 @@ 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), ), @@ -111,6 +158,26 @@ func (s *SplitLayoutWidget) Build() { PushItemSpacing(0, 0) layout.Build() PopStyle() + + // reencode sashPos + 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 { diff --git a/examples/splitter/splitter.go b/examples/splitter/splitter.go index f6cdf97d..92d94f36 100644 --- a/examples/splitter/splitter.go +++ b/examples/splitter/splitter.go @@ -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 ) @@ -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), ), ) } From 5922430e7b41584c828fde73e2bec9bb46680454 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 4 Dec 2024 07:40:03 +0100 Subject: [PATCH 2/3] SpltiLayout: reduce unnecessary calls to GetAvailableRegion --- SplitLayout.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/SplitLayout.go b/SplitLayout.go index 37297c60..3d8e13ac 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -128,7 +128,6 @@ func (s *SplitLayoutWidget) Build() { switch s.direction { case DirectionHorizontal: - _, availableH := GetAvailableRegion() if sashPos >= availableH { sashPos = availableH } @@ -141,7 +140,6 @@ func (s *SplitLayoutWidget) Build() { ), } case DirectionVertical: - availableW, _ := GetAvailableRegion() if sashPos >= availableW { sashPos = availableW } From 6f0e3273b1331894376aefd9db7dd4aa618e5f4f Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 4 Dec 2024 07:42:23 +0100 Subject: [PATCH 3/3] as always linting --- SplitLayout.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SplitLayout.go b/SplitLayout.go index 3d8e13ac..0c638ab4 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -96,6 +96,7 @@ func (s *SplitLayoutWidget) Build() { var layout Layout var sashPos float32 + switch s.splitRefType { case SplitRefLeft: sashPos = *s.sashPos @@ -157,7 +158,10 @@ func (s *SplitLayoutWidget) Build() { layout.Build() PopStyle() - // reencode sashPos + s.encodeSashPos(sashPos, availableW, availableH) +} + +func (s *SplitLayoutWidget) encodeSashPos(sashPos, availableW, availableH float32) { switch s.splitRefType { case SplitRefLeft: *s.sashPos = sashPos