| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- package giu
- import (
- "image/color"
- "github.com/AllenDang/imgui-go"
- )
- // SplitDirection represents a direction (vertical/horizontal) of splitting layout.
- type SplitDirection uint8
- const (
- // DirectionHorizontal is a horizontal line.
- DirectionHorizontal SplitDirection = 1 << iota
- // DirectionVertical is a vertical line.
- DirectionVertical
- )
- var _ Disposable = &splitLayoutState{}
- type splitLayoutState struct {
- delta float32
- sashPos float32
- }
- // Dispose implements disposable interface.
- func (s *splitLayoutState) Dispose() {
- // noop
- }
- // SplitLayoutWidget creates two childs with a line between them.
- // This line can be moved by the user to adjust child sizes.
- type SplitLayoutWidget struct {
- id string
- direction SplitDirection
- layout1 Widget
- layout2 Widget
- originItemSpacingX float32
- originItemSpacingY float32
- originFramePaddingX float32
- originFramePaddingY float32
- sashPos float32
- border bool
- }
- // SplitLayout creates split layout widget.
- func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Widget) *SplitLayoutWidget {
- return &SplitLayoutWidget{
- direction: direction,
- sashPos: sashPos,
- layout1: layout1,
- layout2: layout2,
- border: true,
- id: GenAutoID("SplitLayout"),
- }
- }
- // Border sets if childs should have borders.
- func (s *SplitLayoutWidget) Border(b bool) *SplitLayoutWidget {
- s.border = b
- return s
- }
- // ID allows to manually set splitter's id.
- func (s *SplitLayoutWidget) ID(id string) *SplitLayoutWidget {
- s.id = id
- return s
- }
- // Build implements widget interface.
- func (s *SplitLayoutWidget) Build() {
- splitLayoutState := s.getState()
- s.originItemSpacingX, s.originItemSpacingY = GetItemInnerSpacing()
- s.originFramePaddingX, s.originFramePaddingY = GetFramePadding()
- var layout Layout
- splitLayoutState.sashPos += splitLayoutState.delta
- if splitLayoutState.sashPos < 1 {
- splitLayoutState.sashPos = 1
- }
- switch s.direction {
- case DirectionHorizontal:
- availableW, _ := GetAvailableRegion()
- if splitLayoutState.sashPos >= availableW {
- splitLayoutState.sashPos = availableW
- }
- layout = Layout{
- Row(
- s.buildChild(splitLayoutState.sashPos, 0, s.layout1),
- VSplitter(&(splitLayoutState.delta)).Size(s.originItemSpacingX, 0),
- s.buildChild(Auto, Auto, s.layout2),
- ),
- }
- case DirectionVertical:
- _, availableH := GetAvailableRegion()
- if splitLayoutState.sashPos >= availableH {
- splitLayoutState.sashPos = availableH
- }
- layout = Layout{
- Column(
- s.buildChild(Auto, splitLayoutState.sashPos, s.layout1),
- HSplitter(&(splitLayoutState.delta)).Size(0, s.originItemSpacingY),
- s.buildChild(Auto, Auto, s.layout2),
- ),
- }
- }
- PushItemSpacing(0, 0)
- layout.Build()
- PopStyle()
- }
- func (s *SplitLayoutWidget) restoreItemSpacing(layout Widget) Layout {
- return Layout{
- Custom(func() {
- PushItemSpacing(s.originItemSpacingX, s.originItemSpacingY)
- PushFramePadding(s.originFramePaddingX, s.originFramePaddingY)
- // Restore Child bg color
- bgColor := imgui.CurrentStyle().GetColor(imgui.StyleColorChildBg)
- PushStyleColor(StyleColorChildBg, Vec4ToRGBA(bgColor))
- }),
- layout,
- Custom(func() {
- PopStyleColor()
- PopStyleV(2)
- }),
- }
- }
- // Build Child panel. If layout is a SplitLayout, set the frame padding to zero.
- func (s *SplitLayoutWidget) buildChild(width, height float32, layout Widget) Widget {
- return Layout{
- Custom(func() {
- _, isSplitLayoutWidget := layout.(*SplitLayoutWidget)
- hasFramePadding := isSplitLayoutWidget || !s.border
- hasBorder := !isSplitLayoutWidget && s.border
- if hasFramePadding {
- PushFramePadding(0, 0)
- }
- PushStyleColor(StyleColorChildBg, color.RGBA{R: 0, G: 0, B: 0, A: 0})
- Child().
- Border(hasBorder).
- Size(width, height).
- Layout(s.restoreItemSpacing(layout)).
- Build()
- PopStyleColor()
- if hasFramePadding {
- PopStyle()
- }
- }),
- }
- }
- func (s *SplitLayoutWidget) getState() (state *splitLayoutState) {
- if st := Context.GetState(s.id); st == nil {
- state = &splitLayoutState{delta: 0.0, sashPos: s.sashPos}
- Context.SetState(s.id, state)
- } else {
- var isOk bool
- state, isOk = st.(*splitLayoutState)
- Assert(isOk, "SplitLayoutWidget", "Build", "got unexpected type of widget's state")
- }
- return state
- }
|