Skip to content

Commit

Permalink
Merge pull request #343 from gucio321/alignment-row-bug
Browse files Browse the repository at this point in the history
alignment consider a case when *RowWidget is a part of Layout
  • Loading branch information
AllenDang authored Sep 25, 2021
2 parents 5ef17df + 7539816 commit 36465fb
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 19 deletions.
89 changes: 70 additions & 19 deletions Alignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ type AlignmentSetter struct {
// Align sets widgets alignment.
// usage: see examples/align
//
// FIXME: DONOT put giu widgets inside of CustomWidget function in
// Align setter. CustomWidgets will be skip in alignment process
//
// BUG: DatePickerWidget doesn't work properly
// - BUG: DatePickerWidget doesn't work properly
// - BUG: there is some bug with SelectableWidget
// - BUG: ComboWidget and ComboCustomWidgets doesn't work properly
func Align(at AlignmentType) *AlignmentSetter {
return &AlignmentSetter{
alignType: at,
Expand All @@ -53,34 +52,28 @@ func (a *AlignmentSetter) Build() {
return
}

// WORKAROUND: get widgets widths rendering them with 100% transparency
// to align them later
a.layout.Range(func(item Widget) {
// if item is inil, just skip it
if item == nil {
return
}

// exclude some widgets from alignment process
// nolint:gocritic // could have more cases later
switch item.(type) {
// ok, it doesn't make sense to align again :-)
case *AlignmentSetter:
item.Build()
return
case *CustomWidget:
item.Build()
return
// there is a bug with selectables and combos, so skip them for now
case *SelectableWidget, *ComboWidget, *ComboCustomWidget:
item.Build()
return
}

// save cursor position before rendering
currentPos := GetCursorPos()

// render widget in `dry` mode
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, 0)
item.Build()
imgui.PopStyleVar()

// save widget's width
size := imgui.GetItemRectSize()
w := size.X

w := GetWidgetWidth(item)
availableW, _ := GetAvailableRegion()

// set cursor position to align the widget
Expand All @@ -99,3 +92,61 @@ func (a *AlignmentSetter) Build() {
item.Build()
})
}

// GetWidgetWidth returns a width of widget
// NOTE: THIS IS A BETA SOLUTION and may contain bugs
// in most cases, you may want to use supported by imgui GetItemRectSize.
// There is an upstream issue for this problem:
// https://github.com/ocornut/imgui/issues/3714
//
// This function is just a workaround used in giu.
//
// NOTE: user-definied widgets, which contains more than one
// giu widget will be processed incorrectly (only width of the last built
// widget will be processed)
//
// here is a list of known bugs:
// - BUG: Custom widgets are skipped, so if user put some widgets
// inside of CustomWidget, its sizes will not be returned
//
// if you find anything else, please report it on
// https://github.com/AllenDang/giu Any contribution is appreciated!
func GetWidgetWidth(w Widget) (result float32) {
// save cursor position before rendering
currentPos := GetCursorPos()
// enumerate some special cases
switch typed := w.(type) {
// Don't process custom widgets
case *CustomWidget:
return 0
// when row, sum all widget's sizes (adding spacing)
case *RowWidget:
isFirst := true
typed.widgets.Range(func(r Widget) {
result += GetWidgetWidth(r)
if !isFirst {
spacing, _ := GetItemSpacing()
result += spacing
} else {
isFirst = false
}
})
return result
// panic if layout - cannot calculate width of multiple widgets
case Layout, *Layout:
panic("GetWidgetWidth: requires Widget argument, but []Widget (Layout) got")
default:
// render widget in `dry` mode
imgui.PushStyleVarFloat(imgui.StyleVarAlpha, 0)
w.Build()
imgui.PopStyleVar()

// save widget's width
size := imgui.GetItemRectSize()
result = size.X
}

SetCursorPos(currentPos)

return result
}
7 changes: 7 additions & 0 deletions examples/align/align.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ func loop() {
},
giu.Label("I'm the last label"),
),
giu.Label("Buttons in row:"),
giu.Align(giu.AlignCenter).To(
giu.Row(
giu.Button("button 1"),
giu.Button("button 2"),
),
),
)
}

Expand Down

0 comments on commit 36465fb

Please sign in to comment.