From f11763c833719ea5fb3bac909f098a1856ac700b Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 9 Oct 2021 21:16:25 +0200 Subject: [PATCH 001/146] add comments in Popups.go --- .golangci.yml | 2 +- MasterWindow.go | 1 + Popups.go | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index b26b2451..2f0fd0fe 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,7 +73,7 @@ linters: - prealloc - predeclared - promlinter - #- revive + - revive - rowserrcheck - staticcheck - structcheck diff --git a/MasterWindow.go b/MasterWindow.go index ad541b08..45b7c711 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -13,6 +13,7 @@ import ( // MasterWindowFlags wrapps imgui.GLFWWindowFlags. type MasterWindowFlags imgui.GLFWWindowFlags +// master window flags const ( // Specifies the window will be fixed size. MasterWindowFlagsNotResizable MasterWindowFlags = MasterWindowFlags(imgui.GLFWWindowFlagsNotResizable) diff --git a/Popups.go b/Popups.go index fadfd1aa..0f511ed2 100644 --- a/Popups.go +++ b/Popups.go @@ -4,10 +4,14 @@ import ( "github.com/AllenDang/imgui-go" ) +// OpenPopup opens a popup with specified id. +// NOTE: you need to build this popup first (see Pop(Modal)Widget) func OpenPopup(name string) { imgui.OpenPopup(name) } +// CloseCurrentPopup closes currently opened popup. +// If no popups opened, no action will be taken. func CloseCurrentPopup() { imgui.CloseCurrentPopup() } From 2f44f8b3aede69eeda489baf2fcdc1a02822e68d Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 11:36:17 +0200 Subject: [PATCH 002/146] add comments in Flags.go --- Flags.go | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/Flags.go b/Flags.go index 73fc8252..ce9fc82b 100644 --- a/Flags.go +++ b/Flags.go @@ -2,8 +2,10 @@ package giu import "github.com/AllenDang/imgui-go" +// InputTextFlags represents input text flags type InputTextFlags int +// input text flags const ( // InputTextFlagsNone sets everything default. InputTextFlagsNone InputTextFlags = imgui.InputTextFlagsNone @@ -48,8 +50,10 @@ const ( InputTextFlagsCharsScientific InputTextFlags = imgui.InputTextFlagsCharsScientific ) +// WindowFlags represents a window flags (see (*WindowWidget).Flags type WindowFlags int +// window flags const ( // WindowFlagsNone default = 0. WindowFlagsNone WindowFlags = imgui.WindowFlagsNone @@ -112,8 +116,10 @@ const ( WindowFlagsNoInputs WindowFlags = imgui.WindowFlagsNoInputs ) +// ComboFlags represents imgui.ComboFlags type ComboFlags int +// combo flags list const ( // ComboFlagNone default = 0. ComboFlagNone ComboFlags = imgui.ComboFlagNone @@ -137,6 +143,7 @@ const ( // SelectableFlags represents imgui.SelectableFlags. type SelectableFlags int +// selectable flags list const ( // SelectableFlagsNone default = 0. SelectableFlagsNone SelectableFlags = imgui.SelectableFlagsNone @@ -153,6 +160,7 @@ const ( // TabItemFlags represents tab item flags. type TabItemFlags int +// tab item flags list const ( // TabItemFlagsNone default = 0. TabItemFlagsNone TabItemFlags = imgui.TabItemFlagsNone @@ -170,8 +178,10 @@ const ( TabItemFlagsNoPushID TabItemFlags = imgui.TabItemFlagsNoPushID ) +// TabBarFlags represents imgui.TabBarFlags type TabBarFlags int +// tab bar flags list const ( // TabBarFlagsNone default = 0. TabBarFlagsNone TabBarFlags = imgui.TabBarFlagsNone @@ -204,6 +214,7 @@ const ( // TreeNodeFlags represents tree node widget flags. type TreeNodeFlags int +// tree node flags list const ( // TreeNodeFlagsNone default = 0. TreeNodeFlagsNone TreeNodeFlags = imgui.TreeNodeFlagsNone @@ -250,6 +261,7 @@ const ( // FocusedFlags represents imgui.FocusedFlags. type FocusedFlags int +// focused flags list const ( // FocusedFlagsNone default FocusedFlags = 0. FocusedFlagsNone FocusedFlags = 0 @@ -266,6 +278,7 @@ const ( // HoveredFlags represents a hovered flags. type HoveredFlags int +// hovered flags list const ( // HoveredFlagsNone Return true if directly over the item/window, not obstructed by another window, // not obstructed by an active popup or modal blocking inputs under them. @@ -290,6 +303,7 @@ const ( // ColorEditFlags for ColorEdit3V(), etc. type ColorEditFlags int +// list of color edit flags const ( // ColorEditFlagsNone default = 0. ColorEditFlagsNone ColorEditFlags = imgui.ColorEditFlagsNone @@ -375,9 +389,10 @@ const ( TableFlagsScrollY TableFlags = TableFlags(imgui.TableFlags_ScrollY) TableFlagsSortMulti TableFlags = TableFlags(imgui.TableFlags_SortMulti) TableFlagsSortTristate TableFlags = TableFlags(imgui.TableFlags_SortTristate) - TableFlagsSizingMask_ TableFlags = TableFlags(imgui.TableFlags_SizingMask_) + TableFlagsSizingMask TableFlags = TableFlags(imgui.TableFlags_SizingMask_) ) +// TableRowFlags represents table row flags type TableRowFlags int // table row flags:. @@ -390,6 +405,7 @@ const ( // TableColumnFlags represents a flags for table column (see (*TableColumnWidget).Flags()). type TableColumnFlags int +// table column flags list const ( // Input configuration flags. TableColumnFlagsNone TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_None) @@ -417,14 +433,17 @@ const ( TableColumnFlagsIsHovered TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_IsHovered) // [Internal] Combinations and masks. - TableColumnFlagsWidthMask_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_WidthMask_) - TableColumnFlagsIndentMask_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_IndentMask_) - TableColumnFlagsStatusMask_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_StatusMask_) - TableColumnFlagsNoDirectResize_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_NoDirectResize_) + TableColumnFlagsWidthMask TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_WidthMask_) + TableColumnFlagsIndentMask TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_IndentMask_) + TableColumnFlagsStatusMask TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_StatusMask_) + TableColumnFlagsNoDirectResize TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_NoDirectResize_) ) +// SliderFlags represents imgui.SliderFlags +// TODO: Hard-reffer to these constants type SliderFlags int +// slider flags const ( SliderFlagsNone SliderFlags = 0 // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. @@ -441,8 +460,10 @@ const ( SliderFlagsInvalidMask SliderFlags = 0x7000000F ) +// PlotFlags represents imgui.ImPlotFlags type PlotFlags int +// plot flags const ( PlotFlagsNone = PlotFlags(imgui.ImPlotFlags_None) PlotFlagsNoTitle = PlotFlags(imgui.ImPlotFlags_NoTitle) @@ -461,8 +482,10 @@ const ( PlotFlagsCanvasOnly = PlotFlags(imgui.ImPlotFlags_CanvasOnly) ) +// PlotAxisFlags represents imgui.ImPlotAxisFlags type PlotAxisFlags int +// plot axis flags const ( PlotAxisFlagsNone PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_None) PlotAxisFlagsNoLabel PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_NoLabel) From fc35147e9c05d075ebde4e8559733f2da44b1a69 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 11:44:25 +0200 Subject: [PATCH 003/146] complete docs for Alignment.go --- Alignment.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Alignment.go b/Alignment.go index 96ee184f..0e290141 100644 --- a/Alignment.go +++ b/Alignment.go @@ -7,14 +7,30 @@ import ( "github.com/AllenDang/imgui-go" ) +// AlignmentType represents a bype of alignment to use with AlignSetter. type AlignmentType byte const ( + // AlignLeft is here just for clearity. + // if set, no action is taken so don't use it. AlignLeft AlignmentType = iota + // AlignCenter centers widget AlignCenter + // AlignRight aligns a widget to right side of window AlignRight ) +var _ Widget = &ALignSetter{} + +// AlignmentSetter allows to align to right / center a widget or widgets group. +// NOTE: Because of AlignSetter uses experimental GetWidgetWidth, +// it is experimantal too. +// usage: see examples/align +// +// list of known bugs: +// - BUG: DatePickerWidget doesn't work properly +// - BUG: there is some bug with SelectableWidget +// - BUG: ComboWidget and ComboCustomWidgets doesn't work properly. type AlignmentSetter struct { alignType AlignmentType layout Layout @@ -22,11 +38,6 @@ type AlignmentSetter struct { } // Align sets widgets alignment. -// usage: see examples/align -// -// - 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, @@ -40,13 +51,16 @@ func (a *AlignmentSetter) To(widgets ...Widget) *AlignmentSetter { return a } -// ID allows to manually set AlignmentSetter ID (it shouldn't be used -// in a normal conditions). +// ID allows to manually set AlignmentSetter ID +// NOTE: there isn't any known reason to use this method, however +// it is here for some random cases. YOU DON'T NEED TO USE IT +// in normal conditions func (a *AlignmentSetter) ID(id string) *AlignmentSetter { a.id = id return a } +// Build implements Widget interface func (a *AlignmentSetter) Build() { if a.layout == nil { return From 666eae9e011e8c5a9a64c054a248b94c4ade18c9 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 11:48:20 +0200 Subject: [PATCH 004/146] complete comments in CodeEditor.go --- Alignment.go | 2 +- CodeEditor.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Alignment.go b/Alignment.go index 0e290141..6906607b 100644 --- a/Alignment.go +++ b/Alignment.go @@ -20,7 +20,7 @@ const ( AlignRight ) -var _ Widget = &ALignSetter{} +var _ Widget = &AlignmentSetter{} // AlignmentSetter allows to align to right / center a widget or widgets group. // NOTE: Because of AlignSetter uses experimental GetWidgetWidth, diff --git a/CodeEditor.go b/CodeEditor.go index 366be398..30979c4a 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -39,6 +39,7 @@ type CodeEditorWidget struct { border bool } +// CodeEditor creates new code editor widget func CodeEditor() *CodeEditorWidget { return &CodeEditorWidget{ title: GenAutoID("##CodeEditor"), @@ -135,6 +136,7 @@ func (ce *CodeEditorWidget) GetCurrentLineText() string { } // GetCursorPos returns cursor position. +// (in characters) func (ce *CodeEditorWidget) GetCursorPos() (x, y int) { return ce.getState().editor.GetCursorPos() } @@ -159,10 +161,13 @@ func (ce *CodeEditorWidget) SelectWordUnderCursor() { ce.getState().editor.SelectWordUnderCursor() } +// IsTextChanged returns true if the editable text was changed in the frame. func (ce *CodeEditorWidget) IsTextChanged() bool { return ce.getState().editor.IsTextChanged() } +// GetScreenCursorPos returns cursor position on the screen. +// (in pixels) func (ce *CodeEditorWidget) GetScreenCursorPos() (x, y int) { return ce.getState().editor.GetScreenCursorPos() } From 87a008b2b232ec43d6fa17718c6bd8f2dd6e576c Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:31:55 +0200 Subject: [PATCH 005/146] add comments in ClickableWidgets.go --- ClickableWidgets.go | 199 +++++++++++++++++++++++------------- examples/widgets/widgets.go | 7 +- 2 files changed, 130 insertions(+), 76 deletions(-) diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 8f586578..1f22119a 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -20,16 +20,20 @@ type ButtonWidget struct { onClick func() } -// Build implements Widget interface. -func (b *ButtonWidget) Build() { - if b.disabled { - imgui.BeginDisabled(true) - defer imgui.EndDisabled() +// Button creates a new button widget. +func Button(label string) *ButtonWidget { + return &ButtonWidget{ + id: GenAutoID(label), + width: 0, + height: 0, + onClick: nil, } +} - if imgui.ButtonV(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { - b.onClick() - } +// Buttonf creates button with formated label +// NOTE: works like fmt.Sprintf (see `go doc fmt`). +func Buttonf(format string, args ...interface{}) *ButtonWidget { + return Button(fmt.Sprintf(format, args...)) } // OnClick sets callback called when button is clicked @@ -52,20 +56,16 @@ func (b *ButtonWidget) Size(width, height float32) *ButtonWidget { return b } -// Button creates a new button widget. -func Button(label string) *ButtonWidget { - return &ButtonWidget{ - id: GenAutoID(label), - width: 0, - height: 0, - onClick: nil, +// Build implements Widget interface. +func (b *ButtonWidget) Build() { + if b.disabled { + imgui.BeginDisabled(true) + defer imgui.EndDisabled() } -} -// Buttonf creates button with formated label -// NOTE: works like fmt.Sprintf (see `go doc fmt`). -func Buttonf(format string, args ...interface{}) *ButtonWidget { - return Button(fmt.Sprintf(format, args...)) + if imgui.ButtonV(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { + b.onClick() + } } var _ Widget = &ArrowButtonWidget{} @@ -77,12 +77,6 @@ type ArrowButtonWidget struct { onClick func() } -// OnClick adds callback called when button is clicked. -func (b *ArrowButtonWidget) OnClick(onClick func()) *ArrowButtonWidget { - b.onClick = onClick - return b -} - // ArrowButton creates ArrowButtonWidget. func ArrowButton(dir Direction) *ArrowButtonWidget { return &ArrowButtonWidget{ @@ -92,6 +86,12 @@ func ArrowButton(dir Direction) *ArrowButtonWidget { } } +// OnClick adds callback called when button is clicked. +func (b *ArrowButtonWidget) OnClick(onClick func()) *ArrowButtonWidget { + b.onClick = onClick + return b +} + // ID allows to manually set widget's id. func (b *ArrowButtonWidget) ID(id string) *ArrowButtonWidget { b.id = id @@ -107,16 +107,13 @@ func (b *ArrowButtonWidget) Build() { var _ Widget = &SmallButtonWidget{} +// SmallButtonWidget is like a button but without frame padding. type SmallButtonWidget struct { id string onClick func() } -func (b *SmallButtonWidget) OnClick(onClick func()) *SmallButtonWidget { - b.onClick = onClick - return b -} - +// SmallButton constructs a new small button widget func SmallButton(id string) *SmallButtonWidget { return &SmallButtonWidget{ id: GenAutoID(id), @@ -124,10 +121,18 @@ func SmallButton(id string) *SmallButtonWidget { } } +// SmallButtonf allows to set formated label for small button. +// It calls SmallButton(fmt.Sprintf(label, args...)) func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } +// OnClick adds OnClick event. +func (b *SmallButtonWidget) OnClick(onClick func()) *SmallButtonWidget { + b.onClick = onClick + return b +} + // Build implements Widget interface. func (b *SmallButtonWidget) Build() { if imgui.SmallButton(tStr(b.id)) && b.onClick != nil { @@ -137,6 +142,9 @@ func (b *SmallButtonWidget) Build() { var _ Widget = &InvisibleButtonWidget{} +// InvisibleButtonWidget is a clickable region. +// NOTE: you may want to display other widgets on this button. +// to do so, you may move drawing cursor back by Get/SetCursor(Screen)Pos type InvisibleButtonWidget struct { id string width float32 @@ -144,30 +152,34 @@ type InvisibleButtonWidget struct { onClick func() } +// InvisibleButton constructs a new invisible button widget. +func InvisibleButton() *InvisibleButtonWidget { + return &InvisibleButtonWidget{ + id: GenAutoID("InvisibleButton"), + width: 0, + height: 0, + onClick: nil, + } +} + +// Size sets button's size func (b *InvisibleButtonWidget) Size(width, height float32) *InvisibleButtonWidget { b.width, b.height = width, height return b } +// OnClick sets click event. func (b *InvisibleButtonWidget) OnClick(onClick func()) *InvisibleButtonWidget { b.onClick = onClick return b } +// ID allows to manually set widget's id (no need to use in normal conditions) func (b *InvisibleButtonWidget) ID(id string) *InvisibleButtonWidget { b.id = id return b } -func InvisibleButton() *InvisibleButtonWidget { - return &InvisibleButtonWidget{ - id: GenAutoID("InvisibleButton"), - width: 0, - height: 0, - onClick: nil, - } -} - // Build implements Widget interface. func (b *InvisibleButtonWidget) Build() { if imgui.InvisibleButton(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { @@ -177,6 +189,7 @@ func (b *InvisibleButtonWidget) Build() { var _ Widget = &ImageButtonWidget{} +// ImageButtonWidget is similar to ButtonWidget but with image texture instead of text label. type ImageButtonWidget struct { texture *Texture width float32 @@ -189,6 +202,21 @@ type ImageButtonWidget struct { onClick func() } +// ImageButton constructs image buton widget +func ImageButton(texture *Texture) *ImageButtonWidget { + return &ImageButtonWidget{ + texture: texture, + width: 50, + height: 50, + uv0: image.Point{X: 0, Y: 0}, + uv1: image.Point{X: 1, Y: 1}, + framePadding: -1, + bgColor: colornames.Black, + tintColor: colornames.White, + onClick: nil, + } +} + // Build implements Widget interface. func (b *ImageButtonWidget) Build() { if b.texture == nil && b.texture.id == 0 { @@ -206,58 +234,55 @@ func (b *ImageButtonWidget) Build() { } } +// Size sets BUTTONS size. +// NOTE: image size is button size - 2 * frame padding func (b *ImageButtonWidget) Size(width, height float32) *ImageButtonWidget { b.width, b.height = width, height return b } +// OnClick sets click event. func (b *ImageButtonWidget) OnClick(onClick func()) *ImageButtonWidget { b.onClick = onClick return b } +// UV sets image's uv func (b *ImageButtonWidget) UV(uv0, uv1 image.Point) *ImageButtonWidget { b.uv0, b.uv1 = uv0, uv1 return b } +// BgColor sets button's background color func (b *ImageButtonWidget) BgColor(bgColor color.Color) *ImageButtonWidget { b.bgColor = bgColor return b } +// TintColor sets tit color for image func (b *ImageButtonWidget) TintColor(tintColor color.Color) *ImageButtonWidget { b.tintColor = tintColor return b } +// FramePadding sets button's frame padding (set 0 to fit image to the frame) func (b *ImageButtonWidget) FramePadding(padding int) *ImageButtonWidget { b.framePadding = padding return b } -func ImageButton(texture *Texture) *ImageButtonWidget { - return &ImageButtonWidget{ - texture: texture, - width: 50, - height: 50, - uv0: image.Point{X: 0, Y: 0}, - uv1: image.Point{X: 1, Y: 1}, - framePadding: -1, - bgColor: colornames.Black, - tintColor: colornames.White, - onClick: nil, - } -} - var _ Widget = &ImageButtonWithRgbaWidget{} +// ImageButtonWithRgbaWidget does similar to ImageButtonWIdget, +// but implements image.Image instead of giu.Texture. It is probably +// more useful than the original ImageButtonWIdget. type ImageButtonWithRgbaWidget struct { *ImageButtonWidget rgba image.Image id string } +// ImageButtonWithRgba creates a new widget func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { return &ImageButtonWithRgbaWidget{ id: GenAutoID("ImageButtonWithRgba"), @@ -266,31 +291,37 @@ func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { } } +// Size sets button's size func (b *ImageButtonWithRgbaWidget) Size(width, height float32) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.Size(width, height) return b } +// OnClick sets click events. func (b *ImageButtonWithRgbaWidget) OnClick(onClick func()) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.OnClick(onClick) return b } +// UV sets image's uv color func (b *ImageButtonWithRgbaWidget) UV(uv0, uv1 image.Point) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.UV(uv0, uv1) return b } +// BgColor sets button's background color func (b *ImageButtonWithRgbaWidget) BgColor(bgColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.BgColor(bgColor) return b } +// TintColor sets image's tint color func (b *ImageButtonWithRgbaWidget) TintColor(tintColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.TintColor(tintColor) return b } +// FramePadding sets frame padding (see (*ImageButtonWidget).TintColor) func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.FramePadding(padding) return b @@ -323,10 +354,12 @@ type CheckboxWidget struct { onChange func() } -// Build implements Widget interface. -func (c *CheckboxWidget) Build() { - if imgui.Checkbox(tStr(c.text), c.selected) && c.onChange != nil { - c.onChange() +// Checkbox creates a new CheckboxWidget. +func Checkbox(text string, selected *bool) *CheckboxWidget { + return &CheckboxWidget{ + text: GenAutoID(text), + selected: selected, + onChange: nil, } } @@ -336,45 +369,50 @@ func (c *CheckboxWidget) OnChange(onChange func()) *CheckboxWidget { return c } -// Checkbox creates a new CheckboxWidget. -func Checkbox(text string, selected *bool) *CheckboxWidget { - return &CheckboxWidget{ - text: GenAutoID(text), - selected: selected, - onChange: nil, +// Build implements Widget interface. +func (c *CheckboxWidget) Build() { + if imgui.Checkbox(tStr(c.text), c.selected) && c.onChange != nil { + c.onChange() } } var _ Widget = &RadioButtonWidget{} +// RadioButtonWidget is a small, round button. +// It is common to use it for single-choice questions. +// see examples/widgets type RadioButtonWidget struct { text string active bool onChange func() } -// Build implements Widget interface. -func (r *RadioButtonWidget) Build() { - if imgui.RadioButton(tStr(r.text), r.active) && r.onChange != nil { - r.onChange() +// RadioButton creates a radio buton. +func RadioButton(text string, active bool) *RadioButtonWidget { + return &RadioButtonWidget{ + text: GenAutoID(text), + active: active, + onChange: nil, } } +// OnChange adds callback when button's state gets changed. func (r *RadioButtonWidget) OnChange(onChange func()) *RadioButtonWidget { r.onChange = onChange return r } -func RadioButton(text string, active bool) *RadioButtonWidget { - return &RadioButtonWidget{ - text: GenAutoID(text), - active: active, - onChange: nil, +// Build implements Widget interface. +func (r *RadioButtonWidget) Build() { + if imgui.RadioButton(tStr(r.text), r.active) && r.onChange != nil { + r.onChange() } } var _ Widget = &SelectableWidget{} +// SelectableWidget is a window-width button with a label which can get selected (highlighted). +// useful for certain lists. type SelectableWidget struct { label string selected bool @@ -385,6 +423,7 @@ type SelectableWidget struct { onDClick func() } +// Selectable constructs a selectable widget func Selectable(label string) *SelectableWidget { return &SelectableWidget{ label: GenAutoID(label), @@ -396,25 +435,30 @@ func Selectable(label string) *SelectableWidget { } } +// Selectablef creates a selectable widget with formated label. func Selectablef(format string, args ...interface{}) *SelectableWidget { return Selectable(fmt.Sprintf(format, args...)) } +// Selected sets if selectable widget is selected. func (s *SelectableWidget) Selected(selected bool) *SelectableWidget { s.selected = selected return s } +// Flags add flags func (s *SelectableWidget) Flags(flags SelectableFlags) *SelectableWidget { s.flags = flags return s } +// Size sets selectable's size func (s *SelectableWidget) Size(width, height float32) *SelectableWidget { s.width, s.height = width, height return s } +// OnClick sets on click event func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { s.onClick = onClick return s @@ -422,6 +466,7 @@ func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { // OnDClick handles mouse left button's double click event. // SelectableFlagsAllowDoubleClick will set once tonDClick callback is notnull. +// NOTE: IT IS DEPRECATED and could be removed. Use EventHandler instead. func (s *SelectableWidget) OnDClick(onDClick func()) *SelectableWidget { s.onDClick = onDClick return s @@ -445,6 +490,9 @@ func (s *SelectableWidget) Build() { var _ Widget = &TreeNodeWidget{} +// TreeNodeWidget is a a wide button with open/close state. +// if is opened, the `layout` is displayed below the widget. +// It can be used to create certain lists, advanced settings sections e.t.c. type TreeNodeWidget struct { label string flags TreeNodeFlags @@ -452,6 +500,7 @@ type TreeNodeWidget struct { eventHandler func() } +// TreeNode creates a new tree node widget func TreeNode(label string) *TreeNodeWidget { return &TreeNodeWidget{ label: tStr(label), @@ -461,10 +510,12 @@ func TreeNode(label string) *TreeNodeWidget { } } +// TreeNodef adds TreeNode with formatted label func TreeNodef(format string, args ...interface{}) *TreeNodeWidget { return TreeNode(fmt.Sprintf(format, args...)) } +// Flags sets flags. func (t *TreeNodeWidget) Flags(flags TreeNodeFlags) *TreeNodeWidget { t.flags = flags return t @@ -472,11 +523,13 @@ func (t *TreeNodeWidget) Flags(flags TreeNodeFlags) *TreeNodeWidget { // Event create TreeNode with eventHandler // You could detect events (e.g. IsItemClicked IsMouseDoubleClicked etc...) and handle them for TreeNode inside eventHandler. +// NOTE: DEPRECATED. use EventHandler instead! func (t *TreeNodeWidget) Event(handler func()) *TreeNodeWidget { t.eventHandler = handler return t } +// Layout sets layout to be displayed when tree node is opened. func (t *TreeNodeWidget) Layout(widgets ...Widget) *TreeNodeWidget { t.layout = Layout(widgets) return t diff --git a/examples/widgets/widgets.go b/examples/widgets/widgets.go index 8d192de6..b09cdc75 100644 --- a/examples/widgets/widgets.go +++ b/examples/widgets/widgets.go @@ -90,9 +90,10 @@ func loop() { fmt.Println(checked2) }), g.Dummy(30, 0), - g.RadioButton("Radio 1", radioOp == 0).OnChange(func() { radioOp = 0 }), - g.RadioButton("Radio 2", radioOp == 1).OnChange(func() { radioOp = 1 }), - g.RadioButton("Radio 3", radioOp == 2).OnChange(func() { radioOp = 2 }), + g.Label("Do you like giu?"), + g.RadioButton("Yes, of course", radioOp == 0).OnChange(func() { radioOp = 0 }), + g.RadioButton("I'm going to test it now", radioOp == 1).OnChange(func() { radioOp = 1 }), + g.RadioButton("No", false), ), g.ProgressBar(0.8).Size(g.Auto, 0).Overlay("Progress"), From d830a3275d7b72777097948cc906f3a7c7d46ae0 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:35:58 +0200 Subject: [PATCH 006/146] events.go - add comments --- Events.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Events.go b/Events.go index 502ef3d5..bc20016d 100644 --- a/Events.go +++ b/Events.go @@ -2,14 +2,17 @@ package giu import "github.com/AllenDang/imgui-go" +// MouseButton represents imgui.MoseButton type MouseButton int +// mouse buttons const ( MouseButtonLeft MouseButton = 0 MouseButtonRight MouseButton = 1 MouseButtonMiddle MouseButton = 2 ) +// IsItemHovered returns true if mouse is over the item func IsItemHovered() bool { return imgui.IsItemHovered() } From 3b367e38202478e01cfe82529307b3c8a4b4874e Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:39:12 +0200 Subject: [PATCH 007/146] complete comments in inputhandler.go --- InputHandler.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InputHandler.go b/InputHandler.go index e4090e00..c2321800 100644 --- a/InputHandler.go +++ b/InputHandler.go @@ -2,6 +2,7 @@ package giu // input menager is used to register a keyboard shortcuts in an app. +// Shortcut represents a keyboard shortcut type Shortcut struct { Key Key Modifier Modifier @@ -24,7 +25,7 @@ const ( // GlobalShortcut is registered for all the app. GlobalShortcut ShortcutType = true - // LocLShortcut is registered for current window only. + // LocalShortcut is registered for current window only. LocalShortcut ShortcutType = false ) From 9e30519e3a14615e9bd2bd9a35d6028d1cc6a491 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:47:54 +0200 Subject: [PATCH 008/146] masterWIndow.go: add missing comments --- MasterWindow.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MasterWindow.go b/MasterWindow.go index 45b7c711..549b435b 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -275,6 +275,7 @@ func (w *MasterWindow) SetCloseCallback(cb func() bool) { w.platform.SetCloseCallback(cb) } +// SetDropCallback sets callback when file was droppend into the window. func (w *MasterWindow) SetDropCallback(cb func([]string)) { w.platform.SetDropCallback(cb) } @@ -359,6 +360,8 @@ func (w *MasterWindow) SetShouldClose(v bool) { w.platform.SetShouldStop(v) } +// SetInputHandler allows to change default input handler. +// see InputHandler.go func (w *MasterWindow) SetInputHandler(handler InputHandler) { Context.InputHandler = handler w.platform.SetInputCallback(func(key glfw.Key, modifier glfw.ModifierKey, action glfw.Action) { From c0593eb387dba323a72a803b7196e261b5af63ce Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:56:18 +0200 Subject: [PATCH 009/146] complete comments in listclipper.go --- ListClipper.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ListClipper.go b/ListClipper.go index d9602c07..358aa4a2 100644 --- a/ListClipper.go +++ b/ListClipper.go @@ -13,15 +13,18 @@ type ListClipperWrapper struct { layout Layout } +// ListClipper creates list clipper func ListClipper() *ListClipperWrapper { return &ListClipperWrapper{} } +// Layout sets layout for list clipper func (l *ListClipperWrapper) Layout(layout ...Widget) *ListClipperWrapper { l.layout = layout return l } +// Build implements widget interface func (l *ListClipperWrapper) Build() { // read all the layout widgets and (eventually) split nested layouts var layout Layout From 372c886cd389d524f32dc1f3a1dd96d5201f7f3a Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:58:14 +0200 Subject: [PATCH 010/146] add missing comment on build method in StackWIdget.go --- StackWidget.go | 1 + 1 file changed, 1 insertion(+) diff --git a/StackWidget.go b/StackWidget.go index e2e5e4d5..1031f5f0 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -20,6 +20,7 @@ func Stack(visible int32, layouts ...Widget) *StackWidget { } } +// Build implements widget interface func (s *StackWidget) Build() { // save visible cursor position visiblePos := GetCursorScreenPos() From a6d05314828ad995f19a4d7c11197af0b9dc19e4 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 13:00:15 +0200 Subject: [PATCH 011/146] add missing comment in context.go --- Context.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Context.go b/Context.go index 4ff53811..2c208d26 100644 --- a/Context.go +++ b/Context.go @@ -9,6 +9,8 @@ import ( // Context represents a giu context. var Context context +// Disposable should be implemented by all states stored in context. +// Dispose method is called when state is removed from context. type Disposable interface { Dispose() } From 7c1787be266de8fcf150fe6ad3f7356810cdbb75 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 13:05:46 +0200 Subject: [PATCH 012/146] add comment in Texture.go --- Texture.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Texture.go b/Texture.go index f7ee73ce..be4a3eaa 100644 --- a/Texture.go +++ b/Texture.go @@ -9,6 +9,8 @@ import ( "github.com/faiface/mainthread" ) +// Texture represents imgui.TextureID. +// It is base unit of images in imgui. type Texture struct { id imgui.TextureID } From 61b9890862890b61fedd684909ca202d695538f7 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 13:08:07 +0200 Subject: [PATCH 013/146] add comment in window.go --- Window.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Window.go b/Window.go index 5a343c8d..89cc23ac 100644 --- a/Window.go +++ b/Window.go @@ -22,6 +22,7 @@ func SingleWindow() *WindowWidget { Size(size[0], size[1]) } +// SingleWindowWithMenuBar creates a SingleWindow and allows to add menubar on its top func SingleWindowWithMenuBar() *WindowWidget { size := Context.platform.DisplaySize() title := fmt.Sprintf("SingleWindow_%d", Context.GetWidgetIndex()) From dab7c5330dc89fc831f5d7312f8ac858adf81b63 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 14:42:03 +0200 Subject: [PATCH 014/146] add comments in TextWidgets.go --- TextWidgets.go | 83 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/TextWidgets.go b/TextWidgets.go index 1db4a483..dd51c6df 100644 --- a/TextWidgets.go +++ b/TextWidgets.go @@ -10,7 +10,7 @@ import ( var _ Widget = &InputTextMultilineWidget{} -// InputTextMultilineWidget represents multiline text input widget +// InputTextMultilineWidget is a large (multiline) text input // see examples/widgets/. type InputTextMultilineWidget struct { label string @@ -45,21 +45,6 @@ func (i *InputTextMultilineWidget) Labelf(format string, args ...interface{}) *I return i.Label(fmt.Sprintf(format, args...)) } -// Build implements Widget interface. -func (i *InputTextMultilineWidget) Build() { - if imgui.InputTextMultilineV( - tStr(i.label), - tStrPtr(i.text), - imgui.Vec2{ - X: i.width, - Y: i.height, - }, - int(i.flags), i.cb, - ) && i.onChange != nil { - i.onChange() - } -} - // Flags sets InputTextFlags (see Flags.go). func (i *InputTextMultilineWidget) Flags(flags InputTextFlags) *InputTextMultilineWidget { i.flags = flags @@ -84,6 +69,21 @@ func (i *InputTextMultilineWidget) Size(width, height float32) *InputTextMultili return i } +// Build implements Widget interface. +func (i *InputTextMultilineWidget) Build() { + if imgui.InputTextMultilineV( + tStr(i.label), + tStrPtr(i.text), + imgui.Vec2{ + X: i.width, + Y: i.height, + }, + int(i.flags), i.cb, + ) && i.onChange != nil { + i.onChange() + } +} + var _ Widget = &BulletWidget{} // BulletWidget adds a small, white dot (bullet). @@ -125,8 +125,20 @@ func (bt *BulletTextWidget) Build() { imgui.BulletText(bt.text) } +var _ Disposable = &inputTextState{} + +type inputTextState struct { + autoCompleteCandidates fuzzy.Matches +} + +// Dispose implements disposable interface +func (s *inputTextState) Dispose() { + s.autoCompleteCandidates = nil +} + var _ Widget = &InputTextWidget{} +// InputTextWidget is a single-line text iinput. type InputTextWidget struct { label string hint string @@ -138,14 +150,7 @@ type InputTextWidget struct { onChange func() } -type inputTextState struct { - autoCompleteCandidates fuzzy.Matches -} - -func (s *inputTextState) Dispose() { - s.autoCompleteCandidates = nil -} - +// InputText creates new input text widget func InputText(value *string) *InputTextWidget { return &InputTextWidget{ label: GenAutoID("##InputText"), @@ -158,11 +163,13 @@ func InputText(value *string) *InputTextWidget { } } +// Label adds label (alternatively you can use it to set widget's id) func (i *InputTextWidget) Label(label string) *InputTextWidget { i.label = tStr(label) return i } +// Labelf adds formatted label func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -174,26 +181,31 @@ func (i *InputTextWidget) AutoComplete(candidates []string) *InputTextWidget { return i } +// Hint sets hint text func (i *InputTextWidget) Hint(hint string) *InputTextWidget { i.hint = tStr(hint) return i } +// Size sets field's width func (i *InputTextWidget) Size(width float32) *InputTextWidget { i.width = width return i } +// Flags sets flags func (i *InputTextWidget) Flags(flags InputTextFlags) *InputTextWidget { i.flags = flags return i } +// Callback sets input text callback func (i *InputTextWidget) Callback(cb imgui.InputTextCallback) *InputTextWidget { i.cb = cb return i } +// OnChange sets callback when text was changed func (i *InputTextWidget) OnChange(onChange func()) *InputTextWidget { i.onChange = onChange return i @@ -258,6 +270,7 @@ func (i *InputTextWidget) Build() { var _ Widget = &InputIntWidget{} +// InputIntWidget is an input text field acceptiong intager values only type InputIntWidget struct { label string value *int32 @@ -266,6 +279,10 @@ type InputIntWidget struct { onChange func() } +// InputInt creates input int widget +// NOTE: value is int32, so its size is up to 10^32-1. +// to process greater values, you need to use InputTextWidget +// with InputTextFlagsCharsDecimal and strconv.ParseInt in OnChange callback. func InputInt(value *int32) *InputIntWidget { return &InputIntWidget{ label: GenAutoID("##InputInt"), @@ -276,25 +293,30 @@ func InputInt(value *int32) *InputIntWidget { } } +// Label sets label (id) func (i *InputIntWidget) Label(label string) *InputIntWidget { i.label = tStr(label) return i } +// Labelf sets formatted label func (i *InputIntWidget) Labelf(format string, args ...interface{}) *InputIntWidget { return i.Label(fmt.Sprintf(format, args...)) } +// Size sets input's width func (i *InputIntWidget) Size(width float32) *InputIntWidget { i.width = width return i } +// Flags sets flags func (i *InputIntWidget) Flags(flags InputTextFlags) *InputIntWidget { i.flags = flags return i } +// OnChange adds on change callback func (i *InputIntWidget) OnChange(onChange func()) *InputIntWidget { i.onChange = onChange return i @@ -314,6 +336,7 @@ func (i *InputIntWidget) Build() { var _ Widget = &InputFloatWidget{} +// InputFloatWidget does similar to InputIntWIdget, but accepts float numbers type InputFloatWidget struct { label string value *float32 @@ -323,6 +346,7 @@ type InputFloatWidget struct { onChange func() } +// InputFloat constructs InputFloatWidget func InputFloat(value *float32) *InputFloatWidget { return &InputFloatWidget{ label: GenAutoID("##InputFloatWidget"), @@ -334,30 +358,36 @@ func InputFloat(value *float32) *InputFloatWidget { } } +// Label sets label of input field func (i *InputFloatWidget) Label(label string) *InputFloatWidget { i.label = tStr(label) return i } +// Labelf sets formatted label func (i *InputFloatWidget) Labelf(format string, args ...interface{}) *InputFloatWidget { return i.Label(fmt.Sprintf(format, args...)) } +// Size sets input field's width func (i *InputFloatWidget) Size(width float32) *InputFloatWidget { i.width = width return i } +// Flags sets flags func (i *InputFloatWidget) Flags(flags InputTextFlags) *InputFloatWidget { i.flags = flags return i } +// Format sets data format (e.g. %.3f) func (i *InputFloatWidget) Format(format string) *InputFloatWidget { i.format = format return i } +// OnChange sets callback called when text is changed func (i *InputFloatWidget) OnChange(onChange func()) *InputFloatWidget { i.onChange = onChange return i @@ -377,12 +407,14 @@ func (i *InputFloatWidget) Build() { var _ Widget = &LabelWidget{} +// LabelWidget is a plain text label type LabelWidget struct { label string fontInfo *FontInfo wrapped bool } +// Label constructs label widget func Label(label string) *LabelWidget { return &LabelWidget{ label: tStr(label), @@ -390,15 +422,18 @@ func Label(label string) *LabelWidget { } } +// Labelf allows to add formatted label func Labelf(format string, args ...interface{}) *LabelWidget { return Label(fmt.Sprintf(format, args...)) } +// Wrapped determinates if label is frapped func (l *LabelWidget) Wrapped(wrapped bool) *LabelWidget { l.wrapped = wrapped return l } +// Font sets specific font (does like Style().SetFont) func (l *LabelWidget) Font(font *FontInfo) *LabelWidget { l.fontInfo = font return l From 3117c4875e058e3283df9dfdfd104a964b5bf07c Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 14:58:34 +0200 Subject: [PATCH 015/146] style.go: add missing coments --- Style.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Style.go b/Style.go index 79bb7c8b..4dccd05e 100644 --- a/Style.go +++ b/Style.go @@ -147,10 +147,17 @@ func PopItemWidth() { imgui.PopItemWidth() } +// PushTextWrapPos adds the position, where the text should be frapped. +// use PushTextWrapPos, render text. If text reaches frame end, +// rendering will be continued at the start pos in line below. +// NOTE: Don't forget to call PopWrapTextPos +// NOTE: it is done automatically in LabelWidget (see (*LabelWIdget).Wrapped()) func PushTextWrapPos() { imgui.PushTextWrapPos() } +// PopTextWrapPos should be caled as many times as PushTextWrapPos +// on each frame. func PopTextWrapPos() { imgui.PopTextWrapPos() } @@ -158,6 +165,7 @@ func PopTextWrapPos() { // MouseCursorType represents a type (layout) of mouse cursor. type MouseCursorType int +// cursor types const ( // MouseCursorNone no mouse cursor. MouseCursorNone MouseCursorType = -1 @@ -363,6 +371,9 @@ func (ss *StyleSetter) SetFont(font *FontInfo) *StyleSetter { return ss } +// SetFontSize sets size of the font. +// NOTE: Be aware, that StyleSetter needs to add a new font to font atlas for +// each font's size. func (ss *StyleSetter) SetFontSize(size float32) *StyleSetter { var font FontInfo if ss.font != nil { From aeca4ef8c473088ce55f4c07a754a4d19bcbea65 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 15:05:47 +0200 Subject: [PATCH 016/146] godot: fix lint errors --- Alignment.go | 8 +++---- ClickableWidgets.go | 48 +++++++++++++++++++------------------- CodeEditor.go | 6 ++--- Events.go | 6 ++--- Flags.go | 44 +++++++++++++++++------------------ InputHandler.go | 2 +- ListClipper.go | 6 ++--- MasterWindow.go | 4 ++-- Popups.go | 2 +- StackWidget.go | 2 +- Style.go | 4 ++-- TextWidgets.go | 56 ++++++++++++++++++++++----------------------- Window.go | 2 +- 13 files changed, 95 insertions(+), 95 deletions(-) diff --git a/Alignment.go b/Alignment.go index 6906607b..bcae0e78 100644 --- a/Alignment.go +++ b/Alignment.go @@ -14,9 +14,9 @@ const ( // AlignLeft is here just for clearity. // if set, no action is taken so don't use it. AlignLeft AlignmentType = iota - // AlignCenter centers widget + // AlignCenter centers widget. AlignCenter - // AlignRight aligns a widget to right side of window + // AlignRight aligns a widget to right side of window. AlignRight ) @@ -54,13 +54,13 @@ func (a *AlignmentSetter) To(widgets ...Widget) *AlignmentSetter { // ID allows to manually set AlignmentSetter ID // NOTE: there isn't any known reason to use this method, however // it is here for some random cases. YOU DON'T NEED TO USE IT -// in normal conditions +// in normal conditions. func (a *AlignmentSetter) ID(id string) *AlignmentSetter { a.id = id return a } -// Build implements Widget interface +// Build implements Widget interface. func (a *AlignmentSetter) Build() { if a.layout == nil { return diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 1f22119a..8869a996 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -113,7 +113,7 @@ type SmallButtonWidget struct { onClick func() } -// SmallButton constructs a new small button widget +// SmallButton constructs a new small button widget. func SmallButton(id string) *SmallButtonWidget { return &SmallButtonWidget{ id: GenAutoID(id), @@ -122,7 +122,7 @@ func SmallButton(id string) *SmallButtonWidget { } // SmallButtonf allows to set formated label for small button. -// It calls SmallButton(fmt.Sprintf(label, args...)) +// It calls SmallButton(fmt.Sprintf(label, args...)). func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } @@ -144,7 +144,7 @@ var _ Widget = &InvisibleButtonWidget{} // InvisibleButtonWidget is a clickable region. // NOTE: you may want to display other widgets on this button. -// to do so, you may move drawing cursor back by Get/SetCursor(Screen)Pos +// to do so, you may move drawing cursor back by Get/SetCursor(Screen)Pos. type InvisibleButtonWidget struct { id string width float32 @@ -162,7 +162,7 @@ func InvisibleButton() *InvisibleButtonWidget { } } -// Size sets button's size +// Size sets button's size. func (b *InvisibleButtonWidget) Size(width, height float32) *InvisibleButtonWidget { b.width, b.height = width, height return b @@ -174,7 +174,7 @@ func (b *InvisibleButtonWidget) OnClick(onClick func()) *InvisibleButtonWidget { return b } -// ID allows to manually set widget's id (no need to use in normal conditions) +// ID allows to manually set widget's id (no need to use in normal conditions). func (b *InvisibleButtonWidget) ID(id string) *InvisibleButtonWidget { b.id = id return b @@ -202,7 +202,7 @@ type ImageButtonWidget struct { onClick func() } -// ImageButton constructs image buton widget +// ImageButton constructs image buton widget. func ImageButton(texture *Texture) *ImageButtonWidget { return &ImageButtonWidget{ texture: texture, @@ -235,7 +235,7 @@ func (b *ImageButtonWidget) Build() { } // Size sets BUTTONS size. -// NOTE: image size is button size - 2 * frame padding +// NOTE: image size is button size - 2 * frame padding. func (b *ImageButtonWidget) Size(width, height float32) *ImageButtonWidget { b.width, b.height = width, height return b @@ -247,25 +247,25 @@ func (b *ImageButtonWidget) OnClick(onClick func()) *ImageButtonWidget { return b } -// UV sets image's uv +// UV sets image's uv. func (b *ImageButtonWidget) UV(uv0, uv1 image.Point) *ImageButtonWidget { b.uv0, b.uv1 = uv0, uv1 return b } -// BgColor sets button's background color +// BgColor sets button's background color. func (b *ImageButtonWidget) BgColor(bgColor color.Color) *ImageButtonWidget { b.bgColor = bgColor return b } -// TintColor sets tit color for image +// TintColor sets tit color for image. func (b *ImageButtonWidget) TintColor(tintColor color.Color) *ImageButtonWidget { b.tintColor = tintColor return b } -// FramePadding sets button's frame padding (set 0 to fit image to the frame) +// FramePadding sets button's frame padding (set 0 to fit image to the frame). func (b *ImageButtonWidget) FramePadding(padding int) *ImageButtonWidget { b.framePadding = padding return b @@ -282,7 +282,7 @@ type ImageButtonWithRgbaWidget struct { id string } -// ImageButtonWithRgba creates a new widget +// ImageButtonWithRgba creates a new widget. func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { return &ImageButtonWithRgbaWidget{ id: GenAutoID("ImageButtonWithRgba"), @@ -291,7 +291,7 @@ func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { } } -// Size sets button's size +// Size sets button's size. func (b *ImageButtonWithRgbaWidget) Size(width, height float32) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.Size(width, height) return b @@ -303,25 +303,25 @@ func (b *ImageButtonWithRgbaWidget) OnClick(onClick func()) *ImageButtonWithRgba return b } -// UV sets image's uv color +// UV sets image's uv color. func (b *ImageButtonWithRgbaWidget) UV(uv0, uv1 image.Point) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.UV(uv0, uv1) return b } -// BgColor sets button's background color +// BgColor sets button's background color. func (b *ImageButtonWithRgbaWidget) BgColor(bgColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.BgColor(bgColor) return b } -// TintColor sets image's tint color +// TintColor sets image's tint color. func (b *ImageButtonWithRgbaWidget) TintColor(tintColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.TintColor(tintColor) return b } -// FramePadding sets frame padding (see (*ImageButtonWidget).TintColor) +// FramePadding sets frame padding (see (*ImageButtonWidget).TintColor). func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.FramePadding(padding) return b @@ -380,7 +380,7 @@ var _ Widget = &RadioButtonWidget{} // RadioButtonWidget is a small, round button. // It is common to use it for single-choice questions. -// see examples/widgets +// see examples/widgets. type RadioButtonWidget struct { text string active bool @@ -423,7 +423,7 @@ type SelectableWidget struct { onDClick func() } -// Selectable constructs a selectable widget +// Selectable constructs a selectable widget. func Selectable(label string) *SelectableWidget { return &SelectableWidget{ label: GenAutoID(label), @@ -446,19 +446,19 @@ func (s *SelectableWidget) Selected(selected bool) *SelectableWidget { return s } -// Flags add flags +// Flags add flags. func (s *SelectableWidget) Flags(flags SelectableFlags) *SelectableWidget { s.flags = flags return s } -// Size sets selectable's size +// Size sets selectable's size. func (s *SelectableWidget) Size(width, height float32) *SelectableWidget { s.width, s.height = width, height return s } -// OnClick sets on click event +// OnClick sets on click event. func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { s.onClick = onClick return s @@ -500,7 +500,7 @@ type TreeNodeWidget struct { eventHandler func() } -// TreeNode creates a new tree node widget +// TreeNode creates a new tree node widget. func TreeNode(label string) *TreeNodeWidget { return &TreeNodeWidget{ label: tStr(label), @@ -510,7 +510,7 @@ func TreeNode(label string) *TreeNodeWidget { } } -// TreeNodef adds TreeNode with formatted label +// TreeNodef adds TreeNode with formatted label. func TreeNodef(format string, args ...interface{}) *TreeNodeWidget { return TreeNode(fmt.Sprintf(format, args...)) } diff --git a/CodeEditor.go b/CodeEditor.go index 30979c4a..cf3b3178 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -39,7 +39,7 @@ type CodeEditorWidget struct { border bool } -// CodeEditor creates new code editor widget +// CodeEditor creates new code editor widget. func CodeEditor() *CodeEditorWidget { return &CodeEditorWidget{ title: GenAutoID("##CodeEditor"), @@ -136,7 +136,7 @@ func (ce *CodeEditorWidget) GetCurrentLineText() string { } // GetCursorPos returns cursor position. -// (in characters) +// (in characters). func (ce *CodeEditorWidget) GetCursorPos() (x, y int) { return ce.getState().editor.GetCursorPos() } @@ -167,7 +167,7 @@ func (ce *CodeEditorWidget) IsTextChanged() bool { } // GetScreenCursorPos returns cursor position on the screen. -// (in pixels) +// (in pixels). func (ce *CodeEditorWidget) GetScreenCursorPos() (x, y int) { return ce.getState().editor.GetScreenCursorPos() } diff --git a/Events.go b/Events.go index bc20016d..6d5364a8 100644 --- a/Events.go +++ b/Events.go @@ -2,17 +2,17 @@ package giu import "github.com/AllenDang/imgui-go" -// MouseButton represents imgui.MoseButton +// MouseButton represents imgui.MoseButton. type MouseButton int -// mouse buttons +// mouse buttons. const ( MouseButtonLeft MouseButton = 0 MouseButtonRight MouseButton = 1 MouseButtonMiddle MouseButton = 2 ) -// IsItemHovered returns true if mouse is over the item +// IsItemHovered returns true if mouse is over the item. func IsItemHovered() bool { return imgui.IsItemHovered() } diff --git a/Flags.go b/Flags.go index ce9fc82b..f28f30f0 100644 --- a/Flags.go +++ b/Flags.go @@ -2,10 +2,10 @@ package giu import "github.com/AllenDang/imgui-go" -// InputTextFlags represents input text flags +// InputTextFlags represents input text flags. type InputTextFlags int -// input text flags +// input text flags. const ( // InputTextFlagsNone sets everything default. InputTextFlagsNone InputTextFlags = imgui.InputTextFlagsNone @@ -50,10 +50,10 @@ const ( InputTextFlagsCharsScientific InputTextFlags = imgui.InputTextFlagsCharsScientific ) -// WindowFlags represents a window flags (see (*WindowWidget).Flags +// WindowFlags represents a window flags (see (*WindowWidget).Flags. type WindowFlags int -// window flags +// window flags. const ( // WindowFlagsNone default = 0. WindowFlagsNone WindowFlags = imgui.WindowFlagsNone @@ -116,10 +116,10 @@ const ( WindowFlagsNoInputs WindowFlags = imgui.WindowFlagsNoInputs ) -// ComboFlags represents imgui.ComboFlags +// ComboFlags represents imgui.ComboFlags. type ComboFlags int -// combo flags list +// combo flags list. const ( // ComboFlagNone default = 0. ComboFlagNone ComboFlags = imgui.ComboFlagNone @@ -143,7 +143,7 @@ const ( // SelectableFlags represents imgui.SelectableFlags. type SelectableFlags int -// selectable flags list +// selectable flags list. const ( // SelectableFlagsNone default = 0. SelectableFlagsNone SelectableFlags = imgui.SelectableFlagsNone @@ -160,7 +160,7 @@ const ( // TabItemFlags represents tab item flags. type TabItemFlags int -// tab item flags list +// tab item flags list. const ( // TabItemFlagsNone default = 0. TabItemFlagsNone TabItemFlags = imgui.TabItemFlagsNone @@ -178,10 +178,10 @@ const ( TabItemFlagsNoPushID TabItemFlags = imgui.TabItemFlagsNoPushID ) -// TabBarFlags represents imgui.TabBarFlags +// TabBarFlags represents imgui.TabBarFlags. type TabBarFlags int -// tab bar flags list +// tab bar flags list. const ( // TabBarFlagsNone default = 0. TabBarFlagsNone TabBarFlags = imgui.TabBarFlagsNone @@ -214,7 +214,7 @@ const ( // TreeNodeFlags represents tree node widget flags. type TreeNodeFlags int -// tree node flags list +// tree node flags list. const ( // TreeNodeFlagsNone default = 0. TreeNodeFlagsNone TreeNodeFlags = imgui.TreeNodeFlagsNone @@ -261,7 +261,7 @@ const ( // FocusedFlags represents imgui.FocusedFlags. type FocusedFlags int -// focused flags list +// focused flags list. const ( // FocusedFlagsNone default FocusedFlags = 0. FocusedFlagsNone FocusedFlags = 0 @@ -278,7 +278,7 @@ const ( // HoveredFlags represents a hovered flags. type HoveredFlags int -// hovered flags list +// hovered flags list. const ( // HoveredFlagsNone Return true if directly over the item/window, not obstructed by another window, // not obstructed by an active popup or modal blocking inputs under them. @@ -303,7 +303,7 @@ const ( // ColorEditFlags for ColorEdit3V(), etc. type ColorEditFlags int -// list of color edit flags +// list of color edit flags. const ( // ColorEditFlagsNone default = 0. ColorEditFlagsNone ColorEditFlags = imgui.ColorEditFlagsNone @@ -392,7 +392,7 @@ const ( TableFlagsSizingMask TableFlags = TableFlags(imgui.TableFlags_SizingMask_) ) -// TableRowFlags represents table row flags +// TableRowFlags represents table row flags. type TableRowFlags int // table row flags:. @@ -405,7 +405,7 @@ const ( // TableColumnFlags represents a flags for table column (see (*TableColumnWidget).Flags()). type TableColumnFlags int -// table column flags list +// table column flags list. const ( // Input configuration flags. TableColumnFlagsNone TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_None) @@ -440,10 +440,10 @@ const ( ) // SliderFlags represents imgui.SliderFlags -// TODO: Hard-reffer to these constants +// TODO: Hard-reffer to these constants. type SliderFlags int -// slider flags +// slider flags. const ( SliderFlagsNone SliderFlags = 0 // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. @@ -460,10 +460,10 @@ const ( SliderFlagsInvalidMask SliderFlags = 0x7000000F ) -// PlotFlags represents imgui.ImPlotFlags +// PlotFlags represents imgui.ImPlotFlags. type PlotFlags int -// plot flags +// plot flags. const ( PlotFlagsNone = PlotFlags(imgui.ImPlotFlags_None) PlotFlagsNoTitle = PlotFlags(imgui.ImPlotFlags_NoTitle) @@ -482,10 +482,10 @@ const ( PlotFlagsCanvasOnly = PlotFlags(imgui.ImPlotFlags_CanvasOnly) ) -// PlotAxisFlags represents imgui.ImPlotAxisFlags +// PlotAxisFlags represents imgui.ImPlotAxisFlags. type PlotAxisFlags int -// plot axis flags +// plot axis flags. const ( PlotAxisFlagsNone PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_None) PlotAxisFlagsNoLabel PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_NoLabel) diff --git a/InputHandler.go b/InputHandler.go index c2321800..f951f773 100644 --- a/InputHandler.go +++ b/InputHandler.go @@ -2,7 +2,7 @@ package giu // input menager is used to register a keyboard shortcuts in an app. -// Shortcut represents a keyboard shortcut +// Shortcut represents a keyboard shortcut. type Shortcut struct { Key Key Modifier Modifier diff --git a/ListClipper.go b/ListClipper.go index 358aa4a2..c4e6e8c5 100644 --- a/ListClipper.go +++ b/ListClipper.go @@ -13,18 +13,18 @@ type ListClipperWrapper struct { layout Layout } -// ListClipper creates list clipper +// ListClipper creates list clipper. func ListClipper() *ListClipperWrapper { return &ListClipperWrapper{} } -// Layout sets layout for list clipper +// Layout sets layout for list clipper. func (l *ListClipperWrapper) Layout(layout ...Widget) *ListClipperWrapper { l.layout = layout return l } -// Build implements widget interface +// Build implements widget interface. func (l *ListClipperWrapper) Build() { // read all the layout widgets and (eventually) split nested layouts var layout Layout diff --git a/MasterWindow.go b/MasterWindow.go index 549b435b..e3977a44 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -13,7 +13,7 @@ import ( // MasterWindowFlags wrapps imgui.GLFWWindowFlags. type MasterWindowFlags imgui.GLFWWindowFlags -// master window flags +// master window flags. const ( // Specifies the window will be fixed size. MasterWindowFlagsNotResizable MasterWindowFlags = MasterWindowFlags(imgui.GLFWWindowFlagsNotResizable) @@ -361,7 +361,7 @@ func (w *MasterWindow) SetShouldClose(v bool) { } // SetInputHandler allows to change default input handler. -// see InputHandler.go +// see InputHandler.go. func (w *MasterWindow) SetInputHandler(handler InputHandler) { Context.InputHandler = handler w.platform.SetInputCallback(func(key glfw.Key, modifier glfw.ModifierKey, action glfw.Action) { diff --git a/Popups.go b/Popups.go index 0f511ed2..f46ca5eb 100644 --- a/Popups.go +++ b/Popups.go @@ -5,7 +5,7 @@ import ( ) // OpenPopup opens a popup with specified id. -// NOTE: you need to build this popup first (see Pop(Modal)Widget) +// NOTE: you need to build this popup first (see Pop(Modal)Widget). func OpenPopup(name string) { imgui.OpenPopup(name) } diff --git a/StackWidget.go b/StackWidget.go index 1031f5f0..b63cf3ea 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -20,7 +20,7 @@ func Stack(visible int32, layouts ...Widget) *StackWidget { } } -// Build implements widget interface +// Build implements widget interface. func (s *StackWidget) Build() { // save visible cursor position visiblePos := GetCursorScreenPos() diff --git a/Style.go b/Style.go index 4dccd05e..77628cee 100644 --- a/Style.go +++ b/Style.go @@ -151,7 +151,7 @@ func PopItemWidth() { // use PushTextWrapPos, render text. If text reaches frame end, // rendering will be continued at the start pos in line below. // NOTE: Don't forget to call PopWrapTextPos -// NOTE: it is done automatically in LabelWidget (see (*LabelWIdget).Wrapped()) +// NOTE: it is done automatically in LabelWidget (see (*LabelWIdget).Wrapped()). func PushTextWrapPos() { imgui.PushTextWrapPos() } @@ -165,7 +165,7 @@ func PopTextWrapPos() { // MouseCursorType represents a type (layout) of mouse cursor. type MouseCursorType int -// cursor types +// cursor types. const ( // MouseCursorNone no mouse cursor. MouseCursorNone MouseCursorType = -1 diff --git a/TextWidgets.go b/TextWidgets.go index dd51c6df..b279f583 100644 --- a/TextWidgets.go +++ b/TextWidgets.go @@ -131,7 +131,7 @@ type inputTextState struct { autoCompleteCandidates fuzzy.Matches } -// Dispose implements disposable interface +// Dispose implements disposable interface. func (s *inputTextState) Dispose() { s.autoCompleteCandidates = nil } @@ -150,7 +150,7 @@ type InputTextWidget struct { onChange func() } -// InputText creates new input text widget +// InputText creates new input text widget. func InputText(value *string) *InputTextWidget { return &InputTextWidget{ label: GenAutoID("##InputText"), @@ -163,13 +163,13 @@ func InputText(value *string) *InputTextWidget { } } -// Label adds label (alternatively you can use it to set widget's id) +// Label adds label (alternatively you can use it to set widget's id). func (i *InputTextWidget) Label(label string) *InputTextWidget { i.label = tStr(label) return i } -// Labelf adds formatted label +// Labelf adds formatted label. func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -181,31 +181,31 @@ func (i *InputTextWidget) AutoComplete(candidates []string) *InputTextWidget { return i } -// Hint sets hint text +// Hint sets hint text. func (i *InputTextWidget) Hint(hint string) *InputTextWidget { i.hint = tStr(hint) return i } -// Size sets field's width +// Size sets field's width. func (i *InputTextWidget) Size(width float32) *InputTextWidget { i.width = width return i } -// Flags sets flags +// Flags sets flags. func (i *InputTextWidget) Flags(flags InputTextFlags) *InputTextWidget { i.flags = flags return i } -// Callback sets input text callback +// Callback sets input text callback. func (i *InputTextWidget) Callback(cb imgui.InputTextCallback) *InputTextWidget { i.cb = cb return i } -// OnChange sets callback when text was changed +// OnChange sets callback when text was changed. func (i *InputTextWidget) OnChange(onChange func()) *InputTextWidget { i.onChange = onChange return i @@ -270,7 +270,7 @@ func (i *InputTextWidget) Build() { var _ Widget = &InputIntWidget{} -// InputIntWidget is an input text field acceptiong intager values only +// InputIntWidget is an input text field acceptiong intager values only. type InputIntWidget struct { label string value *int32 @@ -293,30 +293,30 @@ func InputInt(value *int32) *InputIntWidget { } } -// Label sets label (id) +// Label sets label (id). func (i *InputIntWidget) Label(label string) *InputIntWidget { i.label = tStr(label) return i } -// Labelf sets formatted label +// Labelf sets formatted label. func (i *InputIntWidget) Labelf(format string, args ...interface{}) *InputIntWidget { return i.Label(fmt.Sprintf(format, args...)) } -// Size sets input's width +// Size sets input's width. func (i *InputIntWidget) Size(width float32) *InputIntWidget { i.width = width return i } -// Flags sets flags +// Flags sets flags. func (i *InputIntWidget) Flags(flags InputTextFlags) *InputIntWidget { i.flags = flags return i } -// OnChange adds on change callback +// OnChange adds on change callback. func (i *InputIntWidget) OnChange(onChange func()) *InputIntWidget { i.onChange = onChange return i @@ -336,7 +336,7 @@ func (i *InputIntWidget) Build() { var _ Widget = &InputFloatWidget{} -// InputFloatWidget does similar to InputIntWIdget, but accepts float numbers +// InputFloatWidget does similar to InputIntWIdget, but accepts float numbers. type InputFloatWidget struct { label string value *float32 @@ -346,7 +346,7 @@ type InputFloatWidget struct { onChange func() } -// InputFloat constructs InputFloatWidget +// InputFloat constructs InputFloatWidget. func InputFloat(value *float32) *InputFloatWidget { return &InputFloatWidget{ label: GenAutoID("##InputFloatWidget"), @@ -358,36 +358,36 @@ func InputFloat(value *float32) *InputFloatWidget { } } -// Label sets label of input field +// Label sets label of input field. func (i *InputFloatWidget) Label(label string) *InputFloatWidget { i.label = tStr(label) return i } -// Labelf sets formatted label +// Labelf sets formatted label. func (i *InputFloatWidget) Labelf(format string, args ...interface{}) *InputFloatWidget { return i.Label(fmt.Sprintf(format, args...)) } -// Size sets input field's width +// Size sets input field's width. func (i *InputFloatWidget) Size(width float32) *InputFloatWidget { i.width = width return i } -// Flags sets flags +// Flags sets flags. func (i *InputFloatWidget) Flags(flags InputTextFlags) *InputFloatWidget { i.flags = flags return i } -// Format sets data format (e.g. %.3f) +// Format sets data format (e.g. %.3f). func (i *InputFloatWidget) Format(format string) *InputFloatWidget { i.format = format return i } -// OnChange sets callback called when text is changed +// OnChange sets callback called when text is changed. func (i *InputFloatWidget) OnChange(onChange func()) *InputFloatWidget { i.onChange = onChange return i @@ -407,14 +407,14 @@ func (i *InputFloatWidget) Build() { var _ Widget = &LabelWidget{} -// LabelWidget is a plain text label +// LabelWidget is a plain text label. type LabelWidget struct { label string fontInfo *FontInfo wrapped bool } -// Label constructs label widget +// Label constructs label widget. func Label(label string) *LabelWidget { return &LabelWidget{ label: tStr(label), @@ -422,18 +422,18 @@ func Label(label string) *LabelWidget { } } -// Labelf allows to add formatted label +// Labelf allows to add formatted label. func Labelf(format string, args ...interface{}) *LabelWidget { return Label(fmt.Sprintf(format, args...)) } -// Wrapped determinates if label is frapped +// Wrapped determinates if label is frapped. func (l *LabelWidget) Wrapped(wrapped bool) *LabelWidget { l.wrapped = wrapped return l } -// Font sets specific font (does like Style().SetFont) +// Font sets specific font (does like Style().SetFont). func (l *LabelWidget) Font(font *FontInfo) *LabelWidget { l.fontInfo = font return l diff --git a/Window.go b/Window.go index 89cc23ac..0dcb66a6 100644 --- a/Window.go +++ b/Window.go @@ -22,7 +22,7 @@ func SingleWindow() *WindowWidget { Size(size[0], size[1]) } -// SingleWindowWithMenuBar creates a SingleWindow and allows to add menubar on its top +// SingleWindowWithMenuBar creates a SingleWindow and allows to add menubar on its top. func SingleWindowWithMenuBar() *WindowWidget { size := Context.platform.DisplaySize() title := fmt.Sprintf("SingleWindow_%d", Context.GetWidgetIndex()) From 3316c6eb9de9397a26d7328b8470b0a749dd71aa Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 15:13:52 +0200 Subject: [PATCH 017/146] SliderWidgets.go: add comments --- SliderWidgets.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/SliderWidgets.go b/SliderWidgets.go index d07f72ff..70465a9a 100644 --- a/SliderWidgets.go +++ b/SliderWidgets.go @@ -8,6 +8,7 @@ import ( var _ Widget = &SliderIntWidget{} +// SliderIntWidget is a slider around int32 values. type SliderIntWidget struct { label string value *int32 @@ -18,6 +19,7 @@ type SliderIntWidget struct { onChange func() } +// SliderInt constructs new SliderIntWidget. func SliderInt(value *int32, min, max int32) *SliderIntWidget { return &SliderIntWidget{ label: GenAutoID("##SliderInt"), @@ -30,27 +32,34 @@ func SliderInt(value *int32, min, max int32) *SliderIntWidget { } } +// Format sets data format displayed on the slider +// NOTE: on C side of imgui, it will be processed like: +// fmt.Sprintf(format, currentValue) so you can do e.g. +// SLiderInt(...).Format("My age is %d") and %d will be replaced with current value. func (s *SliderIntWidget) Format(format string) *SliderIntWidget { s.format = format return s } +// Size sets slider's width. func (s *SliderIntWidget) Size(width float32) *SliderIntWidget { s.width = width return s } +// OnChange sets callback when slider's position gets changed. func (s *SliderIntWidget) OnChange(onChange func()) *SliderIntWidget { s.onChange = onChange - return s } +// Label sets slider label (id). func (s *SliderIntWidget) Label(label string) *SliderIntWidget { s.label = tStr(label) return s } +// Labelf sets formated label. func (s *SliderIntWidget) Labelf(format string, args ...interface{}) *SliderIntWidget { return s.Label(fmt.Sprintf(format, args...)) } @@ -69,6 +78,7 @@ func (s *SliderIntWidget) Build() { var _ Widget = &VSliderIntWidget{} +// VSliderIntWidget stands from Vertical SliderIntWidget. type VSliderIntWidget struct { label string width float32 @@ -81,6 +91,7 @@ type VSliderIntWidget struct { onChange func() } +// VSliderInt creates new vslider int. func VSliderInt(value *int32, min, max int32) *VSliderIntWidget { return &VSliderIntWidget{ label: GenAutoID("##VSliderInt"), @@ -94,31 +105,37 @@ func VSliderInt(value *int32, min, max int32) *VSliderIntWidget { } } +// Size sets slider's size. func (vs *VSliderIntWidget) Size(width, height float32) *VSliderIntWidget { vs.width, vs.height = width, height return vs } +// Flags sets flags. func (vs *VSliderIntWidget) Flags(flags SliderFlags) *VSliderIntWidget { vs.flags = flags return vs } +// Format sets format (see comment on (*SliderIntWidget).Format). func (vs *VSliderIntWidget) Format(format string) *VSliderIntWidget { vs.format = format return vs } +// OnChange sets callback called when slider's position gets changed. func (vs *VSliderIntWidget) OnChange(onChange func()) *VSliderIntWidget { vs.onChange = onChange return vs } +// Label sets slider's label (id). func (vs *VSliderIntWidget) Label(label string) *VSliderIntWidget { vs.label = tStr(label) return vs } +// Labelf sets formated label. func (vs *VSliderIntWidget) Labelf(format string, args ...interface{}) *VSliderIntWidget { return vs.Label(fmt.Sprintf(format, args...)) } @@ -140,6 +157,8 @@ func (vs *VSliderIntWidget) Build() { var _ Widget = &SliderFloatWidget{} +// SliderFloatWidget does similar to SliderIntWidget but slides around +// float32 values. type SliderFloatWidget struct { label string value *float32 @@ -150,6 +169,7 @@ type SliderFloatWidget struct { onChange func() } +// SliderFloat creates new slider float widget. func SliderFloat(value *float32, min, max float32) *SliderFloatWidget { return &SliderFloatWidget{ label: GenAutoID("##SliderFloat"), @@ -162,27 +182,33 @@ func SliderFloat(value *float32, min, max float32) *SliderFloatWidget { } } +// Format sets format of text displayed on the slider. +// default is %.3f. func (sf *SliderFloatWidget) Format(format string) *SliderFloatWidget { sf.format = format return sf } +// OnChange is callback called when slider's position gets changed. func (sf *SliderFloatWidget) OnChange(onChange func()) *SliderFloatWidget { sf.onChange = onChange return sf } +// Size sets slider's width. func (sf *SliderFloatWidget) Size(width float32) *SliderFloatWidget { sf.width = width return sf } +// Label sets slider's label (id). func (sf *SliderFloatWidget) Label(label string) *SliderFloatWidget { sf.label = tStr(label) return sf } +// Labelf sets formated label. func (sf *SliderFloatWidget) Labelf(format string, args ...interface{}) *SliderFloatWidget { return sf.Label(fmt.Sprintf(format, args...)) } From 966d0800d4df0a18e65cd5bc0268af403dafdad3 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 19:11:02 +0200 Subject: [PATCH 018/146] add comments in splitLayout.go --- SplitLayout.go | 105 +++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/SplitLayout.go b/SplitLayout.go index c0c653fc..83ec1bdd 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -2,25 +2,30 @@ package giu import "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{} +var _ Disposable = &splitLayoutState{} -type SplitLayoutState struct { +type splitLayoutState struct { delta float32 sashPos float32 } // Dispose implements disposable interface. -func (s *SplitLayoutState) Dispose() { +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 @@ -34,6 +39,7 @@ type SplitLayoutWidget struct { border bool } +// SplitLayout creates split layout widget func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Widget) *SplitLayoutWidget { return &SplitLayoutWidget{ direction: direction, @@ -45,58 +51,19 @@ func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Wid } } +// 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 } -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) - } - - Child(). - Border(hasBorder). - Size(width, height). - Layout(s.restoreItemSpacing(layout)). - Build() - - if hasFramePadding { - PopStyle() - } - }), - } -} - +// Build implements widget interface func (s *SplitLayoutWidget) Build() { splitLayoutState := s.getState() s.originItemSpacingX, s.originItemSpacingY = GetItemInnerSpacing() @@ -142,13 +109,55 @@ func (s *SplitLayoutWidget) Build() { PopStyle() } -func (s *SplitLayoutWidget) getState() (state *SplitLayoutState) { +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) + } + + Child(). + Border(hasBorder). + Size(width, height). + Layout(s.restoreItemSpacing(layout)). + Build() + + 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} + state = &splitLayoutState{delta: 0.0, sashPos: s.sashPos} Context.SetState(s.id, state) } else { var isOk bool - state, isOk = st.(*SplitLayoutState) + state, isOk = st.(*splitLayoutState) Assert(isOk, "SplitLayoutWidget", "Build", "got unexpected type of widget's state") } From 6ce7503982674662fcbe2803946d760f7890d65a Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 20:09:24 +0200 Subject: [PATCH 019/146] Utils.go: add missing comments --- Utils.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Utils.go b/Utils.go index 95a5a32b..566843e3 100644 --- a/Utils.go +++ b/Utils.go @@ -118,6 +118,8 @@ func GetMousePos() image.Point { return image.Pt(int(pos.X), int(pos.Y)) } +// GetAvailableRegion returns region available for rendering. +// it is always WindowSize-WindowPadding*2 func GetAvailableRegion() (width, height float32) { region := imgui.ContentRegionAvail() return region.X, region.Y @@ -176,18 +178,22 @@ func SetKeyboardFocusHere() { SetKeyboardFocusHereV(0) } +// SetKeyboardFocusHereV gives keyboard focus to next item func SetKeyboardFocusHereV(i int) { imgui.SetKeyboardFocusHereV(i) } +// PushClipRect pushes a clipping rectangle for both ImGui logic (hit-testing etc.) and low-level ImDrawList rendering. func PushClipRect(clipRectMin, clipRectMax image.Point, intersectWithClipRect bool) { imgui.PushClipRect(ToVec2(clipRectMin), ToVec2(clipRectMax), intersectWithClipRect) } +// PopClipRect should be called to end PushClipRect func PopClipRect() { imgui.PopClipRect() } +// Assert checks if cond. If not cond, it alls golang panic func Assert(cond bool, t, method, msg string, args ...interface{}) { if !cond { fatal(t, method, msg, args...) From b5553602bf98f04ea82c2eed9677655f3e30c9ca Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 20:29:09 +0200 Subject: [PATCH 020/146] apply golangci auto-fixes --- Alignment.go | 2 +- SplitLayout.go | 14 +++++++------- Utils.go | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Alignment.go b/Alignment.go index bcae0e78..e23adc3c 100644 --- a/Alignment.go +++ b/Alignment.go @@ -24,7 +24,7 @@ var _ Widget = &AlignmentSetter{} // AlignmentSetter allows to align to right / center a widget or widgets group. // NOTE: Because of AlignSetter uses experimental GetWidgetWidth, -// it is experimantal too. +// it is experimental too. // usage: see examples/align // // list of known bugs: diff --git a/SplitLayout.go b/SplitLayout.go index 83ec1bdd..79180140 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -2,13 +2,13 @@ package giu import "github.com/AllenDang/imgui-go" -// SplitDirection represents a direction (vertical/horizontal) of splitting layout +// SplitDirection represents a direction (vertical/horizontal) of splitting layout. type SplitDirection uint8 const ( - // DirectionHorizontal is a horizontal line + // DirectionHorizontal is a horizontal line. DirectionHorizontal SplitDirection = 1 << iota - // DirectionVertical is a vertical line + // DirectionVertical is a vertical line. DirectionVertical ) @@ -39,7 +39,7 @@ type SplitLayoutWidget struct { border bool } -// SplitLayout creates split layout widget +// SplitLayout creates split layout widget. func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Widget) *SplitLayoutWidget { return &SplitLayoutWidget{ direction: direction, @@ -51,19 +51,19 @@ func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Wid } } -// Border sets if childs should have borders +// 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 +// ID allows to manually set splitter's id. func (s *SplitLayoutWidget) ID(id string) *SplitLayoutWidget { s.id = id return s } -// Build implements widget interface +// Build implements widget interface. func (s *SplitLayoutWidget) Build() { splitLayoutState := s.getState() s.originItemSpacingX, s.originItemSpacingY = GetItemInnerSpacing() diff --git a/Utils.go b/Utils.go index 566843e3..df8eb158 100644 --- a/Utils.go +++ b/Utils.go @@ -119,7 +119,7 @@ func GetMousePos() image.Point { } // GetAvailableRegion returns region available for rendering. -// it is always WindowSize-WindowPadding*2 +// it is always WindowSize-WindowPadding*2. func GetAvailableRegion() (width, height float32) { region := imgui.ContentRegionAvail() return region.X, region.Y @@ -178,7 +178,7 @@ func SetKeyboardFocusHere() { SetKeyboardFocusHereV(0) } -// SetKeyboardFocusHereV gives keyboard focus to next item +// SetKeyboardFocusHereV gives keyboard focus to next item. func SetKeyboardFocusHereV(i int) { imgui.SetKeyboardFocusHereV(i) } @@ -188,12 +188,12 @@ func PushClipRect(clipRectMin, clipRectMax image.Point, intersectWithClipRect bo imgui.PushClipRect(ToVec2(clipRectMin), ToVec2(clipRectMax), intersectWithClipRect) } -// PopClipRect should be called to end PushClipRect +// PopClipRect should be called to end PushClipRect. func PopClipRect() { imgui.PopClipRect() } -// Assert checks if cond. If not cond, it alls golang panic +// Assert checks if cond. If not cond, it alls golang panic. func Assert(cond bool, t, method, msg string, args ...interface{}) { if !cond { fatal(t, method, msg, args...) From 0a10dc616a167644e09486436d959b3dfa50e99d Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 9 Oct 2021 21:16:25 +0200 Subject: [PATCH 021/146] add comments in Popups.go --- .golangci.yml | 2 +- MasterWindow.go | 1 + Popups.go | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index b26b2451..2f0fd0fe 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,7 +73,7 @@ linters: - prealloc - predeclared - promlinter - #- revive + - revive - rowserrcheck - staticcheck - structcheck diff --git a/MasterWindow.go b/MasterWindow.go index ad541b08..45b7c711 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -13,6 +13,7 @@ import ( // MasterWindowFlags wrapps imgui.GLFWWindowFlags. type MasterWindowFlags imgui.GLFWWindowFlags +// master window flags const ( // Specifies the window will be fixed size. MasterWindowFlagsNotResizable MasterWindowFlags = MasterWindowFlags(imgui.GLFWWindowFlagsNotResizable) diff --git a/Popups.go b/Popups.go index fadfd1aa..0f511ed2 100644 --- a/Popups.go +++ b/Popups.go @@ -4,10 +4,14 @@ import ( "github.com/AllenDang/imgui-go" ) +// OpenPopup opens a popup with specified id. +// NOTE: you need to build this popup first (see Pop(Modal)Widget) func OpenPopup(name string) { imgui.OpenPopup(name) } +// CloseCurrentPopup closes currently opened popup. +// If no popups opened, no action will be taken. func CloseCurrentPopup() { imgui.CloseCurrentPopup() } From ce314e40343bf1f0e6559b6d438a0ae7050a3912 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 11:36:17 +0200 Subject: [PATCH 022/146] add comments in Flags.go --- Flags.go | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/Flags.go b/Flags.go index 73fc8252..ce9fc82b 100644 --- a/Flags.go +++ b/Flags.go @@ -2,8 +2,10 @@ package giu import "github.com/AllenDang/imgui-go" +// InputTextFlags represents input text flags type InputTextFlags int +// input text flags const ( // InputTextFlagsNone sets everything default. InputTextFlagsNone InputTextFlags = imgui.InputTextFlagsNone @@ -48,8 +50,10 @@ const ( InputTextFlagsCharsScientific InputTextFlags = imgui.InputTextFlagsCharsScientific ) +// WindowFlags represents a window flags (see (*WindowWidget).Flags type WindowFlags int +// window flags const ( // WindowFlagsNone default = 0. WindowFlagsNone WindowFlags = imgui.WindowFlagsNone @@ -112,8 +116,10 @@ const ( WindowFlagsNoInputs WindowFlags = imgui.WindowFlagsNoInputs ) +// ComboFlags represents imgui.ComboFlags type ComboFlags int +// combo flags list const ( // ComboFlagNone default = 0. ComboFlagNone ComboFlags = imgui.ComboFlagNone @@ -137,6 +143,7 @@ const ( // SelectableFlags represents imgui.SelectableFlags. type SelectableFlags int +// selectable flags list const ( // SelectableFlagsNone default = 0. SelectableFlagsNone SelectableFlags = imgui.SelectableFlagsNone @@ -153,6 +160,7 @@ const ( // TabItemFlags represents tab item flags. type TabItemFlags int +// tab item flags list const ( // TabItemFlagsNone default = 0. TabItemFlagsNone TabItemFlags = imgui.TabItemFlagsNone @@ -170,8 +178,10 @@ const ( TabItemFlagsNoPushID TabItemFlags = imgui.TabItemFlagsNoPushID ) +// TabBarFlags represents imgui.TabBarFlags type TabBarFlags int +// tab bar flags list const ( // TabBarFlagsNone default = 0. TabBarFlagsNone TabBarFlags = imgui.TabBarFlagsNone @@ -204,6 +214,7 @@ const ( // TreeNodeFlags represents tree node widget flags. type TreeNodeFlags int +// tree node flags list const ( // TreeNodeFlagsNone default = 0. TreeNodeFlagsNone TreeNodeFlags = imgui.TreeNodeFlagsNone @@ -250,6 +261,7 @@ const ( // FocusedFlags represents imgui.FocusedFlags. type FocusedFlags int +// focused flags list const ( // FocusedFlagsNone default FocusedFlags = 0. FocusedFlagsNone FocusedFlags = 0 @@ -266,6 +278,7 @@ const ( // HoveredFlags represents a hovered flags. type HoveredFlags int +// hovered flags list const ( // HoveredFlagsNone Return true if directly over the item/window, not obstructed by another window, // not obstructed by an active popup or modal blocking inputs under them. @@ -290,6 +303,7 @@ const ( // ColorEditFlags for ColorEdit3V(), etc. type ColorEditFlags int +// list of color edit flags const ( // ColorEditFlagsNone default = 0. ColorEditFlagsNone ColorEditFlags = imgui.ColorEditFlagsNone @@ -375,9 +389,10 @@ const ( TableFlagsScrollY TableFlags = TableFlags(imgui.TableFlags_ScrollY) TableFlagsSortMulti TableFlags = TableFlags(imgui.TableFlags_SortMulti) TableFlagsSortTristate TableFlags = TableFlags(imgui.TableFlags_SortTristate) - TableFlagsSizingMask_ TableFlags = TableFlags(imgui.TableFlags_SizingMask_) + TableFlagsSizingMask TableFlags = TableFlags(imgui.TableFlags_SizingMask_) ) +// TableRowFlags represents table row flags type TableRowFlags int // table row flags:. @@ -390,6 +405,7 @@ const ( // TableColumnFlags represents a flags for table column (see (*TableColumnWidget).Flags()). type TableColumnFlags int +// table column flags list const ( // Input configuration flags. TableColumnFlagsNone TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_None) @@ -417,14 +433,17 @@ const ( TableColumnFlagsIsHovered TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_IsHovered) // [Internal] Combinations and masks. - TableColumnFlagsWidthMask_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_WidthMask_) - TableColumnFlagsIndentMask_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_IndentMask_) - TableColumnFlagsStatusMask_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_StatusMask_) - TableColumnFlagsNoDirectResize_ TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_NoDirectResize_) + TableColumnFlagsWidthMask TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_WidthMask_) + TableColumnFlagsIndentMask TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_IndentMask_) + TableColumnFlagsStatusMask TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_StatusMask_) + TableColumnFlagsNoDirectResize TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_NoDirectResize_) ) +// SliderFlags represents imgui.SliderFlags +// TODO: Hard-reffer to these constants type SliderFlags int +// slider flags const ( SliderFlagsNone SliderFlags = 0 // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. @@ -441,8 +460,10 @@ const ( SliderFlagsInvalidMask SliderFlags = 0x7000000F ) +// PlotFlags represents imgui.ImPlotFlags type PlotFlags int +// plot flags const ( PlotFlagsNone = PlotFlags(imgui.ImPlotFlags_None) PlotFlagsNoTitle = PlotFlags(imgui.ImPlotFlags_NoTitle) @@ -461,8 +482,10 @@ const ( PlotFlagsCanvasOnly = PlotFlags(imgui.ImPlotFlags_CanvasOnly) ) +// PlotAxisFlags represents imgui.ImPlotAxisFlags type PlotAxisFlags int +// plot axis flags const ( PlotAxisFlagsNone PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_None) PlotAxisFlagsNoLabel PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_NoLabel) From cc481896906ee84e0ebab74c46369a2e2b24259c Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 11:44:25 +0200 Subject: [PATCH 023/146] complete docs for Alignment.go --- Alignment.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Alignment.go b/Alignment.go index 96ee184f..0e290141 100644 --- a/Alignment.go +++ b/Alignment.go @@ -7,14 +7,30 @@ import ( "github.com/AllenDang/imgui-go" ) +// AlignmentType represents a bype of alignment to use with AlignSetter. type AlignmentType byte const ( + // AlignLeft is here just for clearity. + // if set, no action is taken so don't use it. AlignLeft AlignmentType = iota + // AlignCenter centers widget AlignCenter + // AlignRight aligns a widget to right side of window AlignRight ) +var _ Widget = &ALignSetter{} + +// AlignmentSetter allows to align to right / center a widget or widgets group. +// NOTE: Because of AlignSetter uses experimental GetWidgetWidth, +// it is experimantal too. +// usage: see examples/align +// +// list of known bugs: +// - BUG: DatePickerWidget doesn't work properly +// - BUG: there is some bug with SelectableWidget +// - BUG: ComboWidget and ComboCustomWidgets doesn't work properly. type AlignmentSetter struct { alignType AlignmentType layout Layout @@ -22,11 +38,6 @@ type AlignmentSetter struct { } // Align sets widgets alignment. -// usage: see examples/align -// -// - 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, @@ -40,13 +51,16 @@ func (a *AlignmentSetter) To(widgets ...Widget) *AlignmentSetter { return a } -// ID allows to manually set AlignmentSetter ID (it shouldn't be used -// in a normal conditions). +// ID allows to manually set AlignmentSetter ID +// NOTE: there isn't any known reason to use this method, however +// it is here for some random cases. YOU DON'T NEED TO USE IT +// in normal conditions func (a *AlignmentSetter) ID(id string) *AlignmentSetter { a.id = id return a } +// Build implements Widget interface func (a *AlignmentSetter) Build() { if a.layout == nil { return From 600ad21dc968e8ebff13f515317a7fe5767976a9 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 11:48:20 +0200 Subject: [PATCH 024/146] complete comments in CodeEditor.go --- Alignment.go | 2 +- CodeEditor.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Alignment.go b/Alignment.go index 0e290141..6906607b 100644 --- a/Alignment.go +++ b/Alignment.go @@ -20,7 +20,7 @@ const ( AlignRight ) -var _ Widget = &ALignSetter{} +var _ Widget = &AlignmentSetter{} // AlignmentSetter allows to align to right / center a widget or widgets group. // NOTE: Because of AlignSetter uses experimental GetWidgetWidth, diff --git a/CodeEditor.go b/CodeEditor.go index 366be398..30979c4a 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -39,6 +39,7 @@ type CodeEditorWidget struct { border bool } +// CodeEditor creates new code editor widget func CodeEditor() *CodeEditorWidget { return &CodeEditorWidget{ title: GenAutoID("##CodeEditor"), @@ -135,6 +136,7 @@ func (ce *CodeEditorWidget) GetCurrentLineText() string { } // GetCursorPos returns cursor position. +// (in characters) func (ce *CodeEditorWidget) GetCursorPos() (x, y int) { return ce.getState().editor.GetCursorPos() } @@ -159,10 +161,13 @@ func (ce *CodeEditorWidget) SelectWordUnderCursor() { ce.getState().editor.SelectWordUnderCursor() } +// IsTextChanged returns true if the editable text was changed in the frame. func (ce *CodeEditorWidget) IsTextChanged() bool { return ce.getState().editor.IsTextChanged() } +// GetScreenCursorPos returns cursor position on the screen. +// (in pixels) func (ce *CodeEditorWidget) GetScreenCursorPos() (x, y int) { return ce.getState().editor.GetScreenCursorPos() } From 5bef351bc0f5b5b3056f16fb43e7bde27919272d Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:31:55 +0200 Subject: [PATCH 025/146] add comments in ClickableWidgets.go --- ClickableWidgets.go | 199 +++++++++++++++++++++++------------- examples/widgets/widgets.go | 7 +- 2 files changed, 130 insertions(+), 76 deletions(-) diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 8f586578..1f22119a 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -20,16 +20,20 @@ type ButtonWidget struct { onClick func() } -// Build implements Widget interface. -func (b *ButtonWidget) Build() { - if b.disabled { - imgui.BeginDisabled(true) - defer imgui.EndDisabled() +// Button creates a new button widget. +func Button(label string) *ButtonWidget { + return &ButtonWidget{ + id: GenAutoID(label), + width: 0, + height: 0, + onClick: nil, } +} - if imgui.ButtonV(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { - b.onClick() - } +// Buttonf creates button with formated label +// NOTE: works like fmt.Sprintf (see `go doc fmt`). +func Buttonf(format string, args ...interface{}) *ButtonWidget { + return Button(fmt.Sprintf(format, args...)) } // OnClick sets callback called when button is clicked @@ -52,20 +56,16 @@ func (b *ButtonWidget) Size(width, height float32) *ButtonWidget { return b } -// Button creates a new button widget. -func Button(label string) *ButtonWidget { - return &ButtonWidget{ - id: GenAutoID(label), - width: 0, - height: 0, - onClick: nil, +// Build implements Widget interface. +func (b *ButtonWidget) Build() { + if b.disabled { + imgui.BeginDisabled(true) + defer imgui.EndDisabled() } -} -// Buttonf creates button with formated label -// NOTE: works like fmt.Sprintf (see `go doc fmt`). -func Buttonf(format string, args ...interface{}) *ButtonWidget { - return Button(fmt.Sprintf(format, args...)) + if imgui.ButtonV(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { + b.onClick() + } } var _ Widget = &ArrowButtonWidget{} @@ -77,12 +77,6 @@ type ArrowButtonWidget struct { onClick func() } -// OnClick adds callback called when button is clicked. -func (b *ArrowButtonWidget) OnClick(onClick func()) *ArrowButtonWidget { - b.onClick = onClick - return b -} - // ArrowButton creates ArrowButtonWidget. func ArrowButton(dir Direction) *ArrowButtonWidget { return &ArrowButtonWidget{ @@ -92,6 +86,12 @@ func ArrowButton(dir Direction) *ArrowButtonWidget { } } +// OnClick adds callback called when button is clicked. +func (b *ArrowButtonWidget) OnClick(onClick func()) *ArrowButtonWidget { + b.onClick = onClick + return b +} + // ID allows to manually set widget's id. func (b *ArrowButtonWidget) ID(id string) *ArrowButtonWidget { b.id = id @@ -107,16 +107,13 @@ func (b *ArrowButtonWidget) Build() { var _ Widget = &SmallButtonWidget{} +// SmallButtonWidget is like a button but without frame padding. type SmallButtonWidget struct { id string onClick func() } -func (b *SmallButtonWidget) OnClick(onClick func()) *SmallButtonWidget { - b.onClick = onClick - return b -} - +// SmallButton constructs a new small button widget func SmallButton(id string) *SmallButtonWidget { return &SmallButtonWidget{ id: GenAutoID(id), @@ -124,10 +121,18 @@ func SmallButton(id string) *SmallButtonWidget { } } +// SmallButtonf allows to set formated label for small button. +// It calls SmallButton(fmt.Sprintf(label, args...)) func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } +// OnClick adds OnClick event. +func (b *SmallButtonWidget) OnClick(onClick func()) *SmallButtonWidget { + b.onClick = onClick + return b +} + // Build implements Widget interface. func (b *SmallButtonWidget) Build() { if imgui.SmallButton(tStr(b.id)) && b.onClick != nil { @@ -137,6 +142,9 @@ func (b *SmallButtonWidget) Build() { var _ Widget = &InvisibleButtonWidget{} +// InvisibleButtonWidget is a clickable region. +// NOTE: you may want to display other widgets on this button. +// to do so, you may move drawing cursor back by Get/SetCursor(Screen)Pos type InvisibleButtonWidget struct { id string width float32 @@ -144,30 +152,34 @@ type InvisibleButtonWidget struct { onClick func() } +// InvisibleButton constructs a new invisible button widget. +func InvisibleButton() *InvisibleButtonWidget { + return &InvisibleButtonWidget{ + id: GenAutoID("InvisibleButton"), + width: 0, + height: 0, + onClick: nil, + } +} + +// Size sets button's size func (b *InvisibleButtonWidget) Size(width, height float32) *InvisibleButtonWidget { b.width, b.height = width, height return b } +// OnClick sets click event. func (b *InvisibleButtonWidget) OnClick(onClick func()) *InvisibleButtonWidget { b.onClick = onClick return b } +// ID allows to manually set widget's id (no need to use in normal conditions) func (b *InvisibleButtonWidget) ID(id string) *InvisibleButtonWidget { b.id = id return b } -func InvisibleButton() *InvisibleButtonWidget { - return &InvisibleButtonWidget{ - id: GenAutoID("InvisibleButton"), - width: 0, - height: 0, - onClick: nil, - } -} - // Build implements Widget interface. func (b *InvisibleButtonWidget) Build() { if imgui.InvisibleButton(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { @@ -177,6 +189,7 @@ func (b *InvisibleButtonWidget) Build() { var _ Widget = &ImageButtonWidget{} +// ImageButtonWidget is similar to ButtonWidget but with image texture instead of text label. type ImageButtonWidget struct { texture *Texture width float32 @@ -189,6 +202,21 @@ type ImageButtonWidget struct { onClick func() } +// ImageButton constructs image buton widget +func ImageButton(texture *Texture) *ImageButtonWidget { + return &ImageButtonWidget{ + texture: texture, + width: 50, + height: 50, + uv0: image.Point{X: 0, Y: 0}, + uv1: image.Point{X: 1, Y: 1}, + framePadding: -1, + bgColor: colornames.Black, + tintColor: colornames.White, + onClick: nil, + } +} + // Build implements Widget interface. func (b *ImageButtonWidget) Build() { if b.texture == nil && b.texture.id == 0 { @@ -206,58 +234,55 @@ func (b *ImageButtonWidget) Build() { } } +// Size sets BUTTONS size. +// NOTE: image size is button size - 2 * frame padding func (b *ImageButtonWidget) Size(width, height float32) *ImageButtonWidget { b.width, b.height = width, height return b } +// OnClick sets click event. func (b *ImageButtonWidget) OnClick(onClick func()) *ImageButtonWidget { b.onClick = onClick return b } +// UV sets image's uv func (b *ImageButtonWidget) UV(uv0, uv1 image.Point) *ImageButtonWidget { b.uv0, b.uv1 = uv0, uv1 return b } +// BgColor sets button's background color func (b *ImageButtonWidget) BgColor(bgColor color.Color) *ImageButtonWidget { b.bgColor = bgColor return b } +// TintColor sets tit color for image func (b *ImageButtonWidget) TintColor(tintColor color.Color) *ImageButtonWidget { b.tintColor = tintColor return b } +// FramePadding sets button's frame padding (set 0 to fit image to the frame) func (b *ImageButtonWidget) FramePadding(padding int) *ImageButtonWidget { b.framePadding = padding return b } -func ImageButton(texture *Texture) *ImageButtonWidget { - return &ImageButtonWidget{ - texture: texture, - width: 50, - height: 50, - uv0: image.Point{X: 0, Y: 0}, - uv1: image.Point{X: 1, Y: 1}, - framePadding: -1, - bgColor: colornames.Black, - tintColor: colornames.White, - onClick: nil, - } -} - var _ Widget = &ImageButtonWithRgbaWidget{} +// ImageButtonWithRgbaWidget does similar to ImageButtonWIdget, +// but implements image.Image instead of giu.Texture. It is probably +// more useful than the original ImageButtonWIdget. type ImageButtonWithRgbaWidget struct { *ImageButtonWidget rgba image.Image id string } +// ImageButtonWithRgba creates a new widget func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { return &ImageButtonWithRgbaWidget{ id: GenAutoID("ImageButtonWithRgba"), @@ -266,31 +291,37 @@ func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { } } +// Size sets button's size func (b *ImageButtonWithRgbaWidget) Size(width, height float32) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.Size(width, height) return b } +// OnClick sets click events. func (b *ImageButtonWithRgbaWidget) OnClick(onClick func()) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.OnClick(onClick) return b } +// UV sets image's uv color func (b *ImageButtonWithRgbaWidget) UV(uv0, uv1 image.Point) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.UV(uv0, uv1) return b } +// BgColor sets button's background color func (b *ImageButtonWithRgbaWidget) BgColor(bgColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.BgColor(bgColor) return b } +// TintColor sets image's tint color func (b *ImageButtonWithRgbaWidget) TintColor(tintColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.TintColor(tintColor) return b } +// FramePadding sets frame padding (see (*ImageButtonWidget).TintColor) func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.FramePadding(padding) return b @@ -323,10 +354,12 @@ type CheckboxWidget struct { onChange func() } -// Build implements Widget interface. -func (c *CheckboxWidget) Build() { - if imgui.Checkbox(tStr(c.text), c.selected) && c.onChange != nil { - c.onChange() +// Checkbox creates a new CheckboxWidget. +func Checkbox(text string, selected *bool) *CheckboxWidget { + return &CheckboxWidget{ + text: GenAutoID(text), + selected: selected, + onChange: nil, } } @@ -336,45 +369,50 @@ func (c *CheckboxWidget) OnChange(onChange func()) *CheckboxWidget { return c } -// Checkbox creates a new CheckboxWidget. -func Checkbox(text string, selected *bool) *CheckboxWidget { - return &CheckboxWidget{ - text: GenAutoID(text), - selected: selected, - onChange: nil, +// Build implements Widget interface. +func (c *CheckboxWidget) Build() { + if imgui.Checkbox(tStr(c.text), c.selected) && c.onChange != nil { + c.onChange() } } var _ Widget = &RadioButtonWidget{} +// RadioButtonWidget is a small, round button. +// It is common to use it for single-choice questions. +// see examples/widgets type RadioButtonWidget struct { text string active bool onChange func() } -// Build implements Widget interface. -func (r *RadioButtonWidget) Build() { - if imgui.RadioButton(tStr(r.text), r.active) && r.onChange != nil { - r.onChange() +// RadioButton creates a radio buton. +func RadioButton(text string, active bool) *RadioButtonWidget { + return &RadioButtonWidget{ + text: GenAutoID(text), + active: active, + onChange: nil, } } +// OnChange adds callback when button's state gets changed. func (r *RadioButtonWidget) OnChange(onChange func()) *RadioButtonWidget { r.onChange = onChange return r } -func RadioButton(text string, active bool) *RadioButtonWidget { - return &RadioButtonWidget{ - text: GenAutoID(text), - active: active, - onChange: nil, +// Build implements Widget interface. +func (r *RadioButtonWidget) Build() { + if imgui.RadioButton(tStr(r.text), r.active) && r.onChange != nil { + r.onChange() } } var _ Widget = &SelectableWidget{} +// SelectableWidget is a window-width button with a label which can get selected (highlighted). +// useful for certain lists. type SelectableWidget struct { label string selected bool @@ -385,6 +423,7 @@ type SelectableWidget struct { onDClick func() } +// Selectable constructs a selectable widget func Selectable(label string) *SelectableWidget { return &SelectableWidget{ label: GenAutoID(label), @@ -396,25 +435,30 @@ func Selectable(label string) *SelectableWidget { } } +// Selectablef creates a selectable widget with formated label. func Selectablef(format string, args ...interface{}) *SelectableWidget { return Selectable(fmt.Sprintf(format, args...)) } +// Selected sets if selectable widget is selected. func (s *SelectableWidget) Selected(selected bool) *SelectableWidget { s.selected = selected return s } +// Flags add flags func (s *SelectableWidget) Flags(flags SelectableFlags) *SelectableWidget { s.flags = flags return s } +// Size sets selectable's size func (s *SelectableWidget) Size(width, height float32) *SelectableWidget { s.width, s.height = width, height return s } +// OnClick sets on click event func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { s.onClick = onClick return s @@ -422,6 +466,7 @@ func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { // OnDClick handles mouse left button's double click event. // SelectableFlagsAllowDoubleClick will set once tonDClick callback is notnull. +// NOTE: IT IS DEPRECATED and could be removed. Use EventHandler instead. func (s *SelectableWidget) OnDClick(onDClick func()) *SelectableWidget { s.onDClick = onDClick return s @@ -445,6 +490,9 @@ func (s *SelectableWidget) Build() { var _ Widget = &TreeNodeWidget{} +// TreeNodeWidget is a a wide button with open/close state. +// if is opened, the `layout` is displayed below the widget. +// It can be used to create certain lists, advanced settings sections e.t.c. type TreeNodeWidget struct { label string flags TreeNodeFlags @@ -452,6 +500,7 @@ type TreeNodeWidget struct { eventHandler func() } +// TreeNode creates a new tree node widget func TreeNode(label string) *TreeNodeWidget { return &TreeNodeWidget{ label: tStr(label), @@ -461,10 +510,12 @@ func TreeNode(label string) *TreeNodeWidget { } } +// TreeNodef adds TreeNode with formatted label func TreeNodef(format string, args ...interface{}) *TreeNodeWidget { return TreeNode(fmt.Sprintf(format, args...)) } +// Flags sets flags. func (t *TreeNodeWidget) Flags(flags TreeNodeFlags) *TreeNodeWidget { t.flags = flags return t @@ -472,11 +523,13 @@ func (t *TreeNodeWidget) Flags(flags TreeNodeFlags) *TreeNodeWidget { // Event create TreeNode with eventHandler // You could detect events (e.g. IsItemClicked IsMouseDoubleClicked etc...) and handle them for TreeNode inside eventHandler. +// NOTE: DEPRECATED. use EventHandler instead! func (t *TreeNodeWidget) Event(handler func()) *TreeNodeWidget { t.eventHandler = handler return t } +// Layout sets layout to be displayed when tree node is opened. func (t *TreeNodeWidget) Layout(widgets ...Widget) *TreeNodeWidget { t.layout = Layout(widgets) return t diff --git a/examples/widgets/widgets.go b/examples/widgets/widgets.go index 8d192de6..b09cdc75 100644 --- a/examples/widgets/widgets.go +++ b/examples/widgets/widgets.go @@ -90,9 +90,10 @@ func loop() { fmt.Println(checked2) }), g.Dummy(30, 0), - g.RadioButton("Radio 1", radioOp == 0).OnChange(func() { radioOp = 0 }), - g.RadioButton("Radio 2", radioOp == 1).OnChange(func() { radioOp = 1 }), - g.RadioButton("Radio 3", radioOp == 2).OnChange(func() { radioOp = 2 }), + g.Label("Do you like giu?"), + g.RadioButton("Yes, of course", radioOp == 0).OnChange(func() { radioOp = 0 }), + g.RadioButton("I'm going to test it now", radioOp == 1).OnChange(func() { radioOp = 1 }), + g.RadioButton("No", false), ), g.ProgressBar(0.8).Size(g.Auto, 0).Overlay("Progress"), From a22cdb7e3a74807b4b203614cc96c0f27605474c Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:35:58 +0200 Subject: [PATCH 026/146] events.go - add comments --- Events.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Events.go b/Events.go index 502ef3d5..bc20016d 100644 --- a/Events.go +++ b/Events.go @@ -2,14 +2,17 @@ package giu import "github.com/AllenDang/imgui-go" +// MouseButton represents imgui.MoseButton type MouseButton int +// mouse buttons const ( MouseButtonLeft MouseButton = 0 MouseButtonRight MouseButton = 1 MouseButtonMiddle MouseButton = 2 ) +// IsItemHovered returns true if mouse is over the item func IsItemHovered() bool { return imgui.IsItemHovered() } From 44b7ab743c702972deeff9250df7b36f32d8062f Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:39:12 +0200 Subject: [PATCH 027/146] complete comments in inputhandler.go --- InputHandler.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/InputHandler.go b/InputHandler.go index e4090e00..c2321800 100644 --- a/InputHandler.go +++ b/InputHandler.go @@ -2,6 +2,7 @@ package giu // input menager is used to register a keyboard shortcuts in an app. +// Shortcut represents a keyboard shortcut type Shortcut struct { Key Key Modifier Modifier @@ -24,7 +25,7 @@ const ( // GlobalShortcut is registered for all the app. GlobalShortcut ShortcutType = true - // LocLShortcut is registered for current window only. + // LocalShortcut is registered for current window only. LocalShortcut ShortcutType = false ) From c8e1dfff8c54712bc4c5e65842702119eaaeee3c Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:47:54 +0200 Subject: [PATCH 028/146] masterWIndow.go: add missing comments --- MasterWindow.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MasterWindow.go b/MasterWindow.go index 45b7c711..549b435b 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -275,6 +275,7 @@ func (w *MasterWindow) SetCloseCallback(cb func() bool) { w.platform.SetCloseCallback(cb) } +// SetDropCallback sets callback when file was droppend into the window. func (w *MasterWindow) SetDropCallback(cb func([]string)) { w.platform.SetDropCallback(cb) } @@ -359,6 +360,8 @@ func (w *MasterWindow) SetShouldClose(v bool) { w.platform.SetShouldStop(v) } +// SetInputHandler allows to change default input handler. +// see InputHandler.go func (w *MasterWindow) SetInputHandler(handler InputHandler) { Context.InputHandler = handler w.platform.SetInputCallback(func(key glfw.Key, modifier glfw.ModifierKey, action glfw.Action) { From 6bd269680d61097c1ba125c431049e051ec1751e Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:56:18 +0200 Subject: [PATCH 029/146] complete comments in listclipper.go --- ListClipper.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ListClipper.go b/ListClipper.go index d9602c07..358aa4a2 100644 --- a/ListClipper.go +++ b/ListClipper.go @@ -13,15 +13,18 @@ type ListClipperWrapper struct { layout Layout } +// ListClipper creates list clipper func ListClipper() *ListClipperWrapper { return &ListClipperWrapper{} } +// Layout sets layout for list clipper func (l *ListClipperWrapper) Layout(layout ...Widget) *ListClipperWrapper { l.layout = layout return l } +// Build implements widget interface func (l *ListClipperWrapper) Build() { // read all the layout widgets and (eventually) split nested layouts var layout Layout From 7e14204c4ccf32108b843f6f23b03ae1b2c214d7 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 12:58:14 +0200 Subject: [PATCH 030/146] add missing comment on build method in StackWIdget.go --- StackWidget.go | 1 + 1 file changed, 1 insertion(+) diff --git a/StackWidget.go b/StackWidget.go index e2e5e4d5..1031f5f0 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -20,6 +20,7 @@ func Stack(visible int32, layouts ...Widget) *StackWidget { } } +// Build implements widget interface func (s *StackWidget) Build() { // save visible cursor position visiblePos := GetCursorScreenPos() From ed14d6e9b06c191a9cf0e094012a8b6d6c5217c1 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 13:00:15 +0200 Subject: [PATCH 031/146] add missing comment in context.go --- Context.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Context.go b/Context.go index 4ff53811..2c208d26 100644 --- a/Context.go +++ b/Context.go @@ -9,6 +9,8 @@ import ( // Context represents a giu context. var Context context +// Disposable should be implemented by all states stored in context. +// Dispose method is called when state is removed from context. type Disposable interface { Dispose() } From 9fab4b6ea4563058fca9abf4f90c5d54bd9c6b85 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 13:05:46 +0200 Subject: [PATCH 032/146] add comment in Texture.go --- Texture.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Texture.go b/Texture.go index f7ee73ce..be4a3eaa 100644 --- a/Texture.go +++ b/Texture.go @@ -9,6 +9,8 @@ import ( "github.com/faiface/mainthread" ) +// Texture represents imgui.TextureID. +// It is base unit of images in imgui. type Texture struct { id imgui.TextureID } From 634b14c240c0cd3bf0c95218c6815ed9e149305e Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 13:08:07 +0200 Subject: [PATCH 033/146] add comment in window.go --- Window.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Window.go b/Window.go index 5a343c8d..89cc23ac 100644 --- a/Window.go +++ b/Window.go @@ -22,6 +22,7 @@ func SingleWindow() *WindowWidget { Size(size[0], size[1]) } +// SingleWindowWithMenuBar creates a SingleWindow and allows to add menubar on its top func SingleWindowWithMenuBar() *WindowWidget { size := Context.platform.DisplaySize() title := fmt.Sprintf("SingleWindow_%d", Context.GetWidgetIndex()) From 7bd09d0bfd84b45c276a448a7b6cd37813cbe079 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 14:42:03 +0200 Subject: [PATCH 034/146] add comments in TextWidgets.go --- TextWidgets.go | 83 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/TextWidgets.go b/TextWidgets.go index 1db4a483..dd51c6df 100644 --- a/TextWidgets.go +++ b/TextWidgets.go @@ -10,7 +10,7 @@ import ( var _ Widget = &InputTextMultilineWidget{} -// InputTextMultilineWidget represents multiline text input widget +// InputTextMultilineWidget is a large (multiline) text input // see examples/widgets/. type InputTextMultilineWidget struct { label string @@ -45,21 +45,6 @@ func (i *InputTextMultilineWidget) Labelf(format string, args ...interface{}) *I return i.Label(fmt.Sprintf(format, args...)) } -// Build implements Widget interface. -func (i *InputTextMultilineWidget) Build() { - if imgui.InputTextMultilineV( - tStr(i.label), - tStrPtr(i.text), - imgui.Vec2{ - X: i.width, - Y: i.height, - }, - int(i.flags), i.cb, - ) && i.onChange != nil { - i.onChange() - } -} - // Flags sets InputTextFlags (see Flags.go). func (i *InputTextMultilineWidget) Flags(flags InputTextFlags) *InputTextMultilineWidget { i.flags = flags @@ -84,6 +69,21 @@ func (i *InputTextMultilineWidget) Size(width, height float32) *InputTextMultili return i } +// Build implements Widget interface. +func (i *InputTextMultilineWidget) Build() { + if imgui.InputTextMultilineV( + tStr(i.label), + tStrPtr(i.text), + imgui.Vec2{ + X: i.width, + Y: i.height, + }, + int(i.flags), i.cb, + ) && i.onChange != nil { + i.onChange() + } +} + var _ Widget = &BulletWidget{} // BulletWidget adds a small, white dot (bullet). @@ -125,8 +125,20 @@ func (bt *BulletTextWidget) Build() { imgui.BulletText(bt.text) } +var _ Disposable = &inputTextState{} + +type inputTextState struct { + autoCompleteCandidates fuzzy.Matches +} + +// Dispose implements disposable interface +func (s *inputTextState) Dispose() { + s.autoCompleteCandidates = nil +} + var _ Widget = &InputTextWidget{} +// InputTextWidget is a single-line text iinput. type InputTextWidget struct { label string hint string @@ -138,14 +150,7 @@ type InputTextWidget struct { onChange func() } -type inputTextState struct { - autoCompleteCandidates fuzzy.Matches -} - -func (s *inputTextState) Dispose() { - s.autoCompleteCandidates = nil -} - +// InputText creates new input text widget func InputText(value *string) *InputTextWidget { return &InputTextWidget{ label: GenAutoID("##InputText"), @@ -158,11 +163,13 @@ func InputText(value *string) *InputTextWidget { } } +// Label adds label (alternatively you can use it to set widget's id) func (i *InputTextWidget) Label(label string) *InputTextWidget { i.label = tStr(label) return i } +// Labelf adds formatted label func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -174,26 +181,31 @@ func (i *InputTextWidget) AutoComplete(candidates []string) *InputTextWidget { return i } +// Hint sets hint text func (i *InputTextWidget) Hint(hint string) *InputTextWidget { i.hint = tStr(hint) return i } +// Size sets field's width func (i *InputTextWidget) Size(width float32) *InputTextWidget { i.width = width return i } +// Flags sets flags func (i *InputTextWidget) Flags(flags InputTextFlags) *InputTextWidget { i.flags = flags return i } +// Callback sets input text callback func (i *InputTextWidget) Callback(cb imgui.InputTextCallback) *InputTextWidget { i.cb = cb return i } +// OnChange sets callback when text was changed func (i *InputTextWidget) OnChange(onChange func()) *InputTextWidget { i.onChange = onChange return i @@ -258,6 +270,7 @@ func (i *InputTextWidget) Build() { var _ Widget = &InputIntWidget{} +// InputIntWidget is an input text field acceptiong intager values only type InputIntWidget struct { label string value *int32 @@ -266,6 +279,10 @@ type InputIntWidget struct { onChange func() } +// InputInt creates input int widget +// NOTE: value is int32, so its size is up to 10^32-1. +// to process greater values, you need to use InputTextWidget +// with InputTextFlagsCharsDecimal and strconv.ParseInt in OnChange callback. func InputInt(value *int32) *InputIntWidget { return &InputIntWidget{ label: GenAutoID("##InputInt"), @@ -276,25 +293,30 @@ func InputInt(value *int32) *InputIntWidget { } } +// Label sets label (id) func (i *InputIntWidget) Label(label string) *InputIntWidget { i.label = tStr(label) return i } +// Labelf sets formatted label func (i *InputIntWidget) Labelf(format string, args ...interface{}) *InputIntWidget { return i.Label(fmt.Sprintf(format, args...)) } +// Size sets input's width func (i *InputIntWidget) Size(width float32) *InputIntWidget { i.width = width return i } +// Flags sets flags func (i *InputIntWidget) Flags(flags InputTextFlags) *InputIntWidget { i.flags = flags return i } +// OnChange adds on change callback func (i *InputIntWidget) OnChange(onChange func()) *InputIntWidget { i.onChange = onChange return i @@ -314,6 +336,7 @@ func (i *InputIntWidget) Build() { var _ Widget = &InputFloatWidget{} +// InputFloatWidget does similar to InputIntWIdget, but accepts float numbers type InputFloatWidget struct { label string value *float32 @@ -323,6 +346,7 @@ type InputFloatWidget struct { onChange func() } +// InputFloat constructs InputFloatWidget func InputFloat(value *float32) *InputFloatWidget { return &InputFloatWidget{ label: GenAutoID("##InputFloatWidget"), @@ -334,30 +358,36 @@ func InputFloat(value *float32) *InputFloatWidget { } } +// Label sets label of input field func (i *InputFloatWidget) Label(label string) *InputFloatWidget { i.label = tStr(label) return i } +// Labelf sets formatted label func (i *InputFloatWidget) Labelf(format string, args ...interface{}) *InputFloatWidget { return i.Label(fmt.Sprintf(format, args...)) } +// Size sets input field's width func (i *InputFloatWidget) Size(width float32) *InputFloatWidget { i.width = width return i } +// Flags sets flags func (i *InputFloatWidget) Flags(flags InputTextFlags) *InputFloatWidget { i.flags = flags return i } +// Format sets data format (e.g. %.3f) func (i *InputFloatWidget) Format(format string) *InputFloatWidget { i.format = format return i } +// OnChange sets callback called when text is changed func (i *InputFloatWidget) OnChange(onChange func()) *InputFloatWidget { i.onChange = onChange return i @@ -377,12 +407,14 @@ func (i *InputFloatWidget) Build() { var _ Widget = &LabelWidget{} +// LabelWidget is a plain text label type LabelWidget struct { label string fontInfo *FontInfo wrapped bool } +// Label constructs label widget func Label(label string) *LabelWidget { return &LabelWidget{ label: tStr(label), @@ -390,15 +422,18 @@ func Label(label string) *LabelWidget { } } +// Labelf allows to add formatted label func Labelf(format string, args ...interface{}) *LabelWidget { return Label(fmt.Sprintf(format, args...)) } +// Wrapped determinates if label is frapped func (l *LabelWidget) Wrapped(wrapped bool) *LabelWidget { l.wrapped = wrapped return l } +// Font sets specific font (does like Style().SetFont) func (l *LabelWidget) Font(font *FontInfo) *LabelWidget { l.fontInfo = font return l From 095028155b06ac3d26635fe77fb18c5400700fcd Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 14:58:34 +0200 Subject: [PATCH 035/146] style.go: add missing coments --- Style.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Style.go b/Style.go index 381f237c..7e30f0bc 100644 --- a/Style.go +++ b/Style.go @@ -147,10 +147,17 @@ func PopItemWidth() { imgui.PopItemWidth() } +// PushTextWrapPos adds the position, where the text should be frapped. +// use PushTextWrapPos, render text. If text reaches frame end, +// rendering will be continued at the start pos in line below. +// NOTE: Don't forget to call PopWrapTextPos +// NOTE: it is done automatically in LabelWidget (see (*LabelWIdget).Wrapped()) func PushTextWrapPos() { imgui.PushTextWrapPos() } +// PopTextWrapPos should be caled as many times as PushTextWrapPos +// on each frame. func PopTextWrapPos() { imgui.PopTextWrapPos() } @@ -158,6 +165,7 @@ func PopTextWrapPos() { // MouseCursorType represents a type (layout) of mouse cursor. type MouseCursorType int +// cursor types const ( // MouseCursorNone no mouse cursor. MouseCursorNone MouseCursorType = -1 @@ -392,6 +400,9 @@ func (ss *StyleSetter) SetFont(font *FontInfo) *StyleSetter { return ss } +// SetFontSize sets size of the font. +// NOTE: Be aware, that StyleSetter needs to add a new font to font atlas for +// each font's size. func (ss *StyleSetter) SetFontSize(size float32) *StyleSetter { var font FontInfo if ss.font != nil { From f36f90605474b8b6f3b2b573b11d1dc20c7f020d Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 15:05:47 +0200 Subject: [PATCH 036/146] godot: fix lint errors --- Alignment.go | 8 +++---- ClickableWidgets.go | 48 +++++++++++++++++++------------------- CodeEditor.go | 6 ++--- Events.go | 6 ++--- Flags.go | 44 +++++++++++++++++------------------ InputHandler.go | 2 +- ListClipper.go | 6 ++--- MasterWindow.go | 4 ++-- Popups.go | 2 +- StackWidget.go | 2 +- Style.go | 4 ++-- TextWidgets.go | 56 ++++++++++++++++++++++----------------------- Window.go | 2 +- 13 files changed, 95 insertions(+), 95 deletions(-) diff --git a/Alignment.go b/Alignment.go index 6906607b..bcae0e78 100644 --- a/Alignment.go +++ b/Alignment.go @@ -14,9 +14,9 @@ const ( // AlignLeft is here just for clearity. // if set, no action is taken so don't use it. AlignLeft AlignmentType = iota - // AlignCenter centers widget + // AlignCenter centers widget. AlignCenter - // AlignRight aligns a widget to right side of window + // AlignRight aligns a widget to right side of window. AlignRight ) @@ -54,13 +54,13 @@ func (a *AlignmentSetter) To(widgets ...Widget) *AlignmentSetter { // ID allows to manually set AlignmentSetter ID // NOTE: there isn't any known reason to use this method, however // it is here for some random cases. YOU DON'T NEED TO USE IT -// in normal conditions +// in normal conditions. func (a *AlignmentSetter) ID(id string) *AlignmentSetter { a.id = id return a } -// Build implements Widget interface +// Build implements Widget interface. func (a *AlignmentSetter) Build() { if a.layout == nil { return diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 1f22119a..8869a996 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -113,7 +113,7 @@ type SmallButtonWidget struct { onClick func() } -// SmallButton constructs a new small button widget +// SmallButton constructs a new small button widget. func SmallButton(id string) *SmallButtonWidget { return &SmallButtonWidget{ id: GenAutoID(id), @@ -122,7 +122,7 @@ func SmallButton(id string) *SmallButtonWidget { } // SmallButtonf allows to set formated label for small button. -// It calls SmallButton(fmt.Sprintf(label, args...)) +// It calls SmallButton(fmt.Sprintf(label, args...)). func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } @@ -144,7 +144,7 @@ var _ Widget = &InvisibleButtonWidget{} // InvisibleButtonWidget is a clickable region. // NOTE: you may want to display other widgets on this button. -// to do so, you may move drawing cursor back by Get/SetCursor(Screen)Pos +// to do so, you may move drawing cursor back by Get/SetCursor(Screen)Pos. type InvisibleButtonWidget struct { id string width float32 @@ -162,7 +162,7 @@ func InvisibleButton() *InvisibleButtonWidget { } } -// Size sets button's size +// Size sets button's size. func (b *InvisibleButtonWidget) Size(width, height float32) *InvisibleButtonWidget { b.width, b.height = width, height return b @@ -174,7 +174,7 @@ func (b *InvisibleButtonWidget) OnClick(onClick func()) *InvisibleButtonWidget { return b } -// ID allows to manually set widget's id (no need to use in normal conditions) +// ID allows to manually set widget's id (no need to use in normal conditions). func (b *InvisibleButtonWidget) ID(id string) *InvisibleButtonWidget { b.id = id return b @@ -202,7 +202,7 @@ type ImageButtonWidget struct { onClick func() } -// ImageButton constructs image buton widget +// ImageButton constructs image buton widget. func ImageButton(texture *Texture) *ImageButtonWidget { return &ImageButtonWidget{ texture: texture, @@ -235,7 +235,7 @@ func (b *ImageButtonWidget) Build() { } // Size sets BUTTONS size. -// NOTE: image size is button size - 2 * frame padding +// NOTE: image size is button size - 2 * frame padding. func (b *ImageButtonWidget) Size(width, height float32) *ImageButtonWidget { b.width, b.height = width, height return b @@ -247,25 +247,25 @@ func (b *ImageButtonWidget) OnClick(onClick func()) *ImageButtonWidget { return b } -// UV sets image's uv +// UV sets image's uv. func (b *ImageButtonWidget) UV(uv0, uv1 image.Point) *ImageButtonWidget { b.uv0, b.uv1 = uv0, uv1 return b } -// BgColor sets button's background color +// BgColor sets button's background color. func (b *ImageButtonWidget) BgColor(bgColor color.Color) *ImageButtonWidget { b.bgColor = bgColor return b } -// TintColor sets tit color for image +// TintColor sets tit color for image. func (b *ImageButtonWidget) TintColor(tintColor color.Color) *ImageButtonWidget { b.tintColor = tintColor return b } -// FramePadding sets button's frame padding (set 0 to fit image to the frame) +// FramePadding sets button's frame padding (set 0 to fit image to the frame). func (b *ImageButtonWidget) FramePadding(padding int) *ImageButtonWidget { b.framePadding = padding return b @@ -282,7 +282,7 @@ type ImageButtonWithRgbaWidget struct { id string } -// ImageButtonWithRgba creates a new widget +// ImageButtonWithRgba creates a new widget. func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { return &ImageButtonWithRgbaWidget{ id: GenAutoID("ImageButtonWithRgba"), @@ -291,7 +291,7 @@ func ImageButtonWithRgba(rgba image.Image) *ImageButtonWithRgbaWidget { } } -// Size sets button's size +// Size sets button's size. func (b *ImageButtonWithRgbaWidget) Size(width, height float32) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.Size(width, height) return b @@ -303,25 +303,25 @@ func (b *ImageButtonWithRgbaWidget) OnClick(onClick func()) *ImageButtonWithRgba return b } -// UV sets image's uv color +// UV sets image's uv color. func (b *ImageButtonWithRgbaWidget) UV(uv0, uv1 image.Point) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.UV(uv0, uv1) return b } -// BgColor sets button's background color +// BgColor sets button's background color. func (b *ImageButtonWithRgbaWidget) BgColor(bgColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.BgColor(bgColor) return b } -// TintColor sets image's tint color +// TintColor sets image's tint color. func (b *ImageButtonWithRgbaWidget) TintColor(tintColor color.Color) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.TintColor(tintColor) return b } -// FramePadding sets frame padding (see (*ImageButtonWidget).TintColor) +// FramePadding sets frame padding (see (*ImageButtonWidget).TintColor). func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRgbaWidget { b.ImageButtonWidget.FramePadding(padding) return b @@ -380,7 +380,7 @@ var _ Widget = &RadioButtonWidget{} // RadioButtonWidget is a small, round button. // It is common to use it for single-choice questions. -// see examples/widgets +// see examples/widgets. type RadioButtonWidget struct { text string active bool @@ -423,7 +423,7 @@ type SelectableWidget struct { onDClick func() } -// Selectable constructs a selectable widget +// Selectable constructs a selectable widget. func Selectable(label string) *SelectableWidget { return &SelectableWidget{ label: GenAutoID(label), @@ -446,19 +446,19 @@ func (s *SelectableWidget) Selected(selected bool) *SelectableWidget { return s } -// Flags add flags +// Flags add flags. func (s *SelectableWidget) Flags(flags SelectableFlags) *SelectableWidget { s.flags = flags return s } -// Size sets selectable's size +// Size sets selectable's size. func (s *SelectableWidget) Size(width, height float32) *SelectableWidget { s.width, s.height = width, height return s } -// OnClick sets on click event +// OnClick sets on click event. func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { s.onClick = onClick return s @@ -500,7 +500,7 @@ type TreeNodeWidget struct { eventHandler func() } -// TreeNode creates a new tree node widget +// TreeNode creates a new tree node widget. func TreeNode(label string) *TreeNodeWidget { return &TreeNodeWidget{ label: tStr(label), @@ -510,7 +510,7 @@ func TreeNode(label string) *TreeNodeWidget { } } -// TreeNodef adds TreeNode with formatted label +// TreeNodef adds TreeNode with formatted label. func TreeNodef(format string, args ...interface{}) *TreeNodeWidget { return TreeNode(fmt.Sprintf(format, args...)) } diff --git a/CodeEditor.go b/CodeEditor.go index 30979c4a..cf3b3178 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -39,7 +39,7 @@ type CodeEditorWidget struct { border bool } -// CodeEditor creates new code editor widget +// CodeEditor creates new code editor widget. func CodeEditor() *CodeEditorWidget { return &CodeEditorWidget{ title: GenAutoID("##CodeEditor"), @@ -136,7 +136,7 @@ func (ce *CodeEditorWidget) GetCurrentLineText() string { } // GetCursorPos returns cursor position. -// (in characters) +// (in characters). func (ce *CodeEditorWidget) GetCursorPos() (x, y int) { return ce.getState().editor.GetCursorPos() } @@ -167,7 +167,7 @@ func (ce *CodeEditorWidget) IsTextChanged() bool { } // GetScreenCursorPos returns cursor position on the screen. -// (in pixels) +// (in pixels). func (ce *CodeEditorWidget) GetScreenCursorPos() (x, y int) { return ce.getState().editor.GetScreenCursorPos() } diff --git a/Events.go b/Events.go index bc20016d..6d5364a8 100644 --- a/Events.go +++ b/Events.go @@ -2,17 +2,17 @@ package giu import "github.com/AllenDang/imgui-go" -// MouseButton represents imgui.MoseButton +// MouseButton represents imgui.MoseButton. type MouseButton int -// mouse buttons +// mouse buttons. const ( MouseButtonLeft MouseButton = 0 MouseButtonRight MouseButton = 1 MouseButtonMiddle MouseButton = 2 ) -// IsItemHovered returns true if mouse is over the item +// IsItemHovered returns true if mouse is over the item. func IsItemHovered() bool { return imgui.IsItemHovered() } diff --git a/Flags.go b/Flags.go index ce9fc82b..f28f30f0 100644 --- a/Flags.go +++ b/Flags.go @@ -2,10 +2,10 @@ package giu import "github.com/AllenDang/imgui-go" -// InputTextFlags represents input text flags +// InputTextFlags represents input text flags. type InputTextFlags int -// input text flags +// input text flags. const ( // InputTextFlagsNone sets everything default. InputTextFlagsNone InputTextFlags = imgui.InputTextFlagsNone @@ -50,10 +50,10 @@ const ( InputTextFlagsCharsScientific InputTextFlags = imgui.InputTextFlagsCharsScientific ) -// WindowFlags represents a window flags (see (*WindowWidget).Flags +// WindowFlags represents a window flags (see (*WindowWidget).Flags. type WindowFlags int -// window flags +// window flags. const ( // WindowFlagsNone default = 0. WindowFlagsNone WindowFlags = imgui.WindowFlagsNone @@ -116,10 +116,10 @@ const ( WindowFlagsNoInputs WindowFlags = imgui.WindowFlagsNoInputs ) -// ComboFlags represents imgui.ComboFlags +// ComboFlags represents imgui.ComboFlags. type ComboFlags int -// combo flags list +// combo flags list. const ( // ComboFlagNone default = 0. ComboFlagNone ComboFlags = imgui.ComboFlagNone @@ -143,7 +143,7 @@ const ( // SelectableFlags represents imgui.SelectableFlags. type SelectableFlags int -// selectable flags list +// selectable flags list. const ( // SelectableFlagsNone default = 0. SelectableFlagsNone SelectableFlags = imgui.SelectableFlagsNone @@ -160,7 +160,7 @@ const ( // TabItemFlags represents tab item flags. type TabItemFlags int -// tab item flags list +// tab item flags list. const ( // TabItemFlagsNone default = 0. TabItemFlagsNone TabItemFlags = imgui.TabItemFlagsNone @@ -178,10 +178,10 @@ const ( TabItemFlagsNoPushID TabItemFlags = imgui.TabItemFlagsNoPushID ) -// TabBarFlags represents imgui.TabBarFlags +// TabBarFlags represents imgui.TabBarFlags. type TabBarFlags int -// tab bar flags list +// tab bar flags list. const ( // TabBarFlagsNone default = 0. TabBarFlagsNone TabBarFlags = imgui.TabBarFlagsNone @@ -214,7 +214,7 @@ const ( // TreeNodeFlags represents tree node widget flags. type TreeNodeFlags int -// tree node flags list +// tree node flags list. const ( // TreeNodeFlagsNone default = 0. TreeNodeFlagsNone TreeNodeFlags = imgui.TreeNodeFlagsNone @@ -261,7 +261,7 @@ const ( // FocusedFlags represents imgui.FocusedFlags. type FocusedFlags int -// focused flags list +// focused flags list. const ( // FocusedFlagsNone default FocusedFlags = 0. FocusedFlagsNone FocusedFlags = 0 @@ -278,7 +278,7 @@ const ( // HoveredFlags represents a hovered flags. type HoveredFlags int -// hovered flags list +// hovered flags list. const ( // HoveredFlagsNone Return true if directly over the item/window, not obstructed by another window, // not obstructed by an active popup or modal blocking inputs under them. @@ -303,7 +303,7 @@ const ( // ColorEditFlags for ColorEdit3V(), etc. type ColorEditFlags int -// list of color edit flags +// list of color edit flags. const ( // ColorEditFlagsNone default = 0. ColorEditFlagsNone ColorEditFlags = imgui.ColorEditFlagsNone @@ -392,7 +392,7 @@ const ( TableFlagsSizingMask TableFlags = TableFlags(imgui.TableFlags_SizingMask_) ) -// TableRowFlags represents table row flags +// TableRowFlags represents table row flags. type TableRowFlags int // table row flags:. @@ -405,7 +405,7 @@ const ( // TableColumnFlags represents a flags for table column (see (*TableColumnWidget).Flags()). type TableColumnFlags int -// table column flags list +// table column flags list. const ( // Input configuration flags. TableColumnFlagsNone TableColumnFlags = TableColumnFlags(imgui.TableColumnFlags_None) @@ -440,10 +440,10 @@ const ( ) // SliderFlags represents imgui.SliderFlags -// TODO: Hard-reffer to these constants +// TODO: Hard-reffer to these constants. type SliderFlags int -// slider flags +// slider flags. const ( SliderFlagsNone SliderFlags = 0 // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. @@ -460,10 +460,10 @@ const ( SliderFlagsInvalidMask SliderFlags = 0x7000000F ) -// PlotFlags represents imgui.ImPlotFlags +// PlotFlags represents imgui.ImPlotFlags. type PlotFlags int -// plot flags +// plot flags. const ( PlotFlagsNone = PlotFlags(imgui.ImPlotFlags_None) PlotFlagsNoTitle = PlotFlags(imgui.ImPlotFlags_NoTitle) @@ -482,10 +482,10 @@ const ( PlotFlagsCanvasOnly = PlotFlags(imgui.ImPlotFlags_CanvasOnly) ) -// PlotAxisFlags represents imgui.ImPlotAxisFlags +// PlotAxisFlags represents imgui.ImPlotAxisFlags. type PlotAxisFlags int -// plot axis flags +// plot axis flags. const ( PlotAxisFlagsNone PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_None) PlotAxisFlagsNoLabel PlotAxisFlags = PlotAxisFlags(imgui.ImPlotAxisFlags_NoLabel) diff --git a/InputHandler.go b/InputHandler.go index c2321800..f951f773 100644 --- a/InputHandler.go +++ b/InputHandler.go @@ -2,7 +2,7 @@ package giu // input menager is used to register a keyboard shortcuts in an app. -// Shortcut represents a keyboard shortcut +// Shortcut represents a keyboard shortcut. type Shortcut struct { Key Key Modifier Modifier diff --git a/ListClipper.go b/ListClipper.go index 358aa4a2..c4e6e8c5 100644 --- a/ListClipper.go +++ b/ListClipper.go @@ -13,18 +13,18 @@ type ListClipperWrapper struct { layout Layout } -// ListClipper creates list clipper +// ListClipper creates list clipper. func ListClipper() *ListClipperWrapper { return &ListClipperWrapper{} } -// Layout sets layout for list clipper +// Layout sets layout for list clipper. func (l *ListClipperWrapper) Layout(layout ...Widget) *ListClipperWrapper { l.layout = layout return l } -// Build implements widget interface +// Build implements widget interface. func (l *ListClipperWrapper) Build() { // read all the layout widgets and (eventually) split nested layouts var layout Layout diff --git a/MasterWindow.go b/MasterWindow.go index 549b435b..e3977a44 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -13,7 +13,7 @@ import ( // MasterWindowFlags wrapps imgui.GLFWWindowFlags. type MasterWindowFlags imgui.GLFWWindowFlags -// master window flags +// master window flags. const ( // Specifies the window will be fixed size. MasterWindowFlagsNotResizable MasterWindowFlags = MasterWindowFlags(imgui.GLFWWindowFlagsNotResizable) @@ -361,7 +361,7 @@ func (w *MasterWindow) SetShouldClose(v bool) { } // SetInputHandler allows to change default input handler. -// see InputHandler.go +// see InputHandler.go. func (w *MasterWindow) SetInputHandler(handler InputHandler) { Context.InputHandler = handler w.platform.SetInputCallback(func(key glfw.Key, modifier glfw.ModifierKey, action glfw.Action) { diff --git a/Popups.go b/Popups.go index 0f511ed2..f46ca5eb 100644 --- a/Popups.go +++ b/Popups.go @@ -5,7 +5,7 @@ import ( ) // OpenPopup opens a popup with specified id. -// NOTE: you need to build this popup first (see Pop(Modal)Widget) +// NOTE: you need to build this popup first (see Pop(Modal)Widget). func OpenPopup(name string) { imgui.OpenPopup(name) } diff --git a/StackWidget.go b/StackWidget.go index 1031f5f0..b63cf3ea 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -20,7 +20,7 @@ func Stack(visible int32, layouts ...Widget) *StackWidget { } } -// Build implements widget interface +// Build implements widget interface. func (s *StackWidget) Build() { // save visible cursor position visiblePos := GetCursorScreenPos() diff --git a/Style.go b/Style.go index 7e30f0bc..e5788f1d 100644 --- a/Style.go +++ b/Style.go @@ -151,7 +151,7 @@ func PopItemWidth() { // use PushTextWrapPos, render text. If text reaches frame end, // rendering will be continued at the start pos in line below. // NOTE: Don't forget to call PopWrapTextPos -// NOTE: it is done automatically in LabelWidget (see (*LabelWIdget).Wrapped()) +// NOTE: it is done automatically in LabelWidget (see (*LabelWIdget).Wrapped()). func PushTextWrapPos() { imgui.PushTextWrapPos() } @@ -165,7 +165,7 @@ func PopTextWrapPos() { // MouseCursorType represents a type (layout) of mouse cursor. type MouseCursorType int -// cursor types +// cursor types. const ( // MouseCursorNone no mouse cursor. MouseCursorNone MouseCursorType = -1 diff --git a/TextWidgets.go b/TextWidgets.go index dd51c6df..b279f583 100644 --- a/TextWidgets.go +++ b/TextWidgets.go @@ -131,7 +131,7 @@ type inputTextState struct { autoCompleteCandidates fuzzy.Matches } -// Dispose implements disposable interface +// Dispose implements disposable interface. func (s *inputTextState) Dispose() { s.autoCompleteCandidates = nil } @@ -150,7 +150,7 @@ type InputTextWidget struct { onChange func() } -// InputText creates new input text widget +// InputText creates new input text widget. func InputText(value *string) *InputTextWidget { return &InputTextWidget{ label: GenAutoID("##InputText"), @@ -163,13 +163,13 @@ func InputText(value *string) *InputTextWidget { } } -// Label adds label (alternatively you can use it to set widget's id) +// Label adds label (alternatively you can use it to set widget's id). func (i *InputTextWidget) Label(label string) *InputTextWidget { i.label = tStr(label) return i } -// Labelf adds formatted label +// Labelf adds formatted label. func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -181,31 +181,31 @@ func (i *InputTextWidget) AutoComplete(candidates []string) *InputTextWidget { return i } -// Hint sets hint text +// Hint sets hint text. func (i *InputTextWidget) Hint(hint string) *InputTextWidget { i.hint = tStr(hint) return i } -// Size sets field's width +// Size sets field's width. func (i *InputTextWidget) Size(width float32) *InputTextWidget { i.width = width return i } -// Flags sets flags +// Flags sets flags. func (i *InputTextWidget) Flags(flags InputTextFlags) *InputTextWidget { i.flags = flags return i } -// Callback sets input text callback +// Callback sets input text callback. func (i *InputTextWidget) Callback(cb imgui.InputTextCallback) *InputTextWidget { i.cb = cb return i } -// OnChange sets callback when text was changed +// OnChange sets callback when text was changed. func (i *InputTextWidget) OnChange(onChange func()) *InputTextWidget { i.onChange = onChange return i @@ -270,7 +270,7 @@ func (i *InputTextWidget) Build() { var _ Widget = &InputIntWidget{} -// InputIntWidget is an input text field acceptiong intager values only +// InputIntWidget is an input text field acceptiong intager values only. type InputIntWidget struct { label string value *int32 @@ -293,30 +293,30 @@ func InputInt(value *int32) *InputIntWidget { } } -// Label sets label (id) +// Label sets label (id). func (i *InputIntWidget) Label(label string) *InputIntWidget { i.label = tStr(label) return i } -// Labelf sets formatted label +// Labelf sets formatted label. func (i *InputIntWidget) Labelf(format string, args ...interface{}) *InputIntWidget { return i.Label(fmt.Sprintf(format, args...)) } -// Size sets input's width +// Size sets input's width. func (i *InputIntWidget) Size(width float32) *InputIntWidget { i.width = width return i } -// Flags sets flags +// Flags sets flags. func (i *InputIntWidget) Flags(flags InputTextFlags) *InputIntWidget { i.flags = flags return i } -// OnChange adds on change callback +// OnChange adds on change callback. func (i *InputIntWidget) OnChange(onChange func()) *InputIntWidget { i.onChange = onChange return i @@ -336,7 +336,7 @@ func (i *InputIntWidget) Build() { var _ Widget = &InputFloatWidget{} -// InputFloatWidget does similar to InputIntWIdget, but accepts float numbers +// InputFloatWidget does similar to InputIntWIdget, but accepts float numbers. type InputFloatWidget struct { label string value *float32 @@ -346,7 +346,7 @@ type InputFloatWidget struct { onChange func() } -// InputFloat constructs InputFloatWidget +// InputFloat constructs InputFloatWidget. func InputFloat(value *float32) *InputFloatWidget { return &InputFloatWidget{ label: GenAutoID("##InputFloatWidget"), @@ -358,36 +358,36 @@ func InputFloat(value *float32) *InputFloatWidget { } } -// Label sets label of input field +// Label sets label of input field. func (i *InputFloatWidget) Label(label string) *InputFloatWidget { i.label = tStr(label) return i } -// Labelf sets formatted label +// Labelf sets formatted label. func (i *InputFloatWidget) Labelf(format string, args ...interface{}) *InputFloatWidget { return i.Label(fmt.Sprintf(format, args...)) } -// Size sets input field's width +// Size sets input field's width. func (i *InputFloatWidget) Size(width float32) *InputFloatWidget { i.width = width return i } -// Flags sets flags +// Flags sets flags. func (i *InputFloatWidget) Flags(flags InputTextFlags) *InputFloatWidget { i.flags = flags return i } -// Format sets data format (e.g. %.3f) +// Format sets data format (e.g. %.3f). func (i *InputFloatWidget) Format(format string) *InputFloatWidget { i.format = format return i } -// OnChange sets callback called when text is changed +// OnChange sets callback called when text is changed. func (i *InputFloatWidget) OnChange(onChange func()) *InputFloatWidget { i.onChange = onChange return i @@ -407,14 +407,14 @@ func (i *InputFloatWidget) Build() { var _ Widget = &LabelWidget{} -// LabelWidget is a plain text label +// LabelWidget is a plain text label. type LabelWidget struct { label string fontInfo *FontInfo wrapped bool } -// Label constructs label widget +// Label constructs label widget. func Label(label string) *LabelWidget { return &LabelWidget{ label: tStr(label), @@ -422,18 +422,18 @@ func Label(label string) *LabelWidget { } } -// Labelf allows to add formatted label +// Labelf allows to add formatted label. func Labelf(format string, args ...interface{}) *LabelWidget { return Label(fmt.Sprintf(format, args...)) } -// Wrapped determinates if label is frapped +// Wrapped determinates if label is frapped. func (l *LabelWidget) Wrapped(wrapped bool) *LabelWidget { l.wrapped = wrapped return l } -// Font sets specific font (does like Style().SetFont) +// Font sets specific font (does like Style().SetFont). func (l *LabelWidget) Font(font *FontInfo) *LabelWidget { l.fontInfo = font return l diff --git a/Window.go b/Window.go index 89cc23ac..0dcb66a6 100644 --- a/Window.go +++ b/Window.go @@ -22,7 +22,7 @@ func SingleWindow() *WindowWidget { Size(size[0], size[1]) } -// SingleWindowWithMenuBar creates a SingleWindow and allows to add menubar on its top +// SingleWindowWithMenuBar creates a SingleWindow and allows to add menubar on its top. func SingleWindowWithMenuBar() *WindowWidget { size := Context.platform.DisplaySize() title := fmt.Sprintf("SingleWindow_%d", Context.GetWidgetIndex()) From 16eb7538c3bd296affc198a184f18a0892dbd5cf Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 15:13:52 +0200 Subject: [PATCH 037/146] SliderWidgets.go: add comments --- SliderWidgets.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/SliderWidgets.go b/SliderWidgets.go index d07f72ff..70465a9a 100644 --- a/SliderWidgets.go +++ b/SliderWidgets.go @@ -8,6 +8,7 @@ import ( var _ Widget = &SliderIntWidget{} +// SliderIntWidget is a slider around int32 values. type SliderIntWidget struct { label string value *int32 @@ -18,6 +19,7 @@ type SliderIntWidget struct { onChange func() } +// SliderInt constructs new SliderIntWidget. func SliderInt(value *int32, min, max int32) *SliderIntWidget { return &SliderIntWidget{ label: GenAutoID("##SliderInt"), @@ -30,27 +32,34 @@ func SliderInt(value *int32, min, max int32) *SliderIntWidget { } } +// Format sets data format displayed on the slider +// NOTE: on C side of imgui, it will be processed like: +// fmt.Sprintf(format, currentValue) so you can do e.g. +// SLiderInt(...).Format("My age is %d") and %d will be replaced with current value. func (s *SliderIntWidget) Format(format string) *SliderIntWidget { s.format = format return s } +// Size sets slider's width. func (s *SliderIntWidget) Size(width float32) *SliderIntWidget { s.width = width return s } +// OnChange sets callback when slider's position gets changed. func (s *SliderIntWidget) OnChange(onChange func()) *SliderIntWidget { s.onChange = onChange - return s } +// Label sets slider label (id). func (s *SliderIntWidget) Label(label string) *SliderIntWidget { s.label = tStr(label) return s } +// Labelf sets formated label. func (s *SliderIntWidget) Labelf(format string, args ...interface{}) *SliderIntWidget { return s.Label(fmt.Sprintf(format, args...)) } @@ -69,6 +78,7 @@ func (s *SliderIntWidget) Build() { var _ Widget = &VSliderIntWidget{} +// VSliderIntWidget stands from Vertical SliderIntWidget. type VSliderIntWidget struct { label string width float32 @@ -81,6 +91,7 @@ type VSliderIntWidget struct { onChange func() } +// VSliderInt creates new vslider int. func VSliderInt(value *int32, min, max int32) *VSliderIntWidget { return &VSliderIntWidget{ label: GenAutoID("##VSliderInt"), @@ -94,31 +105,37 @@ func VSliderInt(value *int32, min, max int32) *VSliderIntWidget { } } +// Size sets slider's size. func (vs *VSliderIntWidget) Size(width, height float32) *VSliderIntWidget { vs.width, vs.height = width, height return vs } +// Flags sets flags. func (vs *VSliderIntWidget) Flags(flags SliderFlags) *VSliderIntWidget { vs.flags = flags return vs } +// Format sets format (see comment on (*SliderIntWidget).Format). func (vs *VSliderIntWidget) Format(format string) *VSliderIntWidget { vs.format = format return vs } +// OnChange sets callback called when slider's position gets changed. func (vs *VSliderIntWidget) OnChange(onChange func()) *VSliderIntWidget { vs.onChange = onChange return vs } +// Label sets slider's label (id). func (vs *VSliderIntWidget) Label(label string) *VSliderIntWidget { vs.label = tStr(label) return vs } +// Labelf sets formated label. func (vs *VSliderIntWidget) Labelf(format string, args ...interface{}) *VSliderIntWidget { return vs.Label(fmt.Sprintf(format, args...)) } @@ -140,6 +157,8 @@ func (vs *VSliderIntWidget) Build() { var _ Widget = &SliderFloatWidget{} +// SliderFloatWidget does similar to SliderIntWidget but slides around +// float32 values. type SliderFloatWidget struct { label string value *float32 @@ -150,6 +169,7 @@ type SliderFloatWidget struct { onChange func() } +// SliderFloat creates new slider float widget. func SliderFloat(value *float32, min, max float32) *SliderFloatWidget { return &SliderFloatWidget{ label: GenAutoID("##SliderFloat"), @@ -162,27 +182,33 @@ func SliderFloat(value *float32, min, max float32) *SliderFloatWidget { } } +// Format sets format of text displayed on the slider. +// default is %.3f. func (sf *SliderFloatWidget) Format(format string) *SliderFloatWidget { sf.format = format return sf } +// OnChange is callback called when slider's position gets changed. func (sf *SliderFloatWidget) OnChange(onChange func()) *SliderFloatWidget { sf.onChange = onChange return sf } +// Size sets slider's width. func (sf *SliderFloatWidget) Size(width float32) *SliderFloatWidget { sf.width = width return sf } +// Label sets slider's label (id). func (sf *SliderFloatWidget) Label(label string) *SliderFloatWidget { sf.label = tStr(label) return sf } +// Labelf sets formated label. func (sf *SliderFloatWidget) Labelf(format string, args ...interface{}) *SliderFloatWidget { return sf.Label(fmt.Sprintf(format, args...)) } From a02242eafd073b938a2154d16c1ad443ed1e5daa Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 19:11:02 +0200 Subject: [PATCH 038/146] add comments in splitLayout.go --- SplitLayout.go | 105 +++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/SplitLayout.go b/SplitLayout.go index c0c653fc..83ec1bdd 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -2,25 +2,30 @@ package giu import "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{} +var _ Disposable = &splitLayoutState{} -type SplitLayoutState struct { +type splitLayoutState struct { delta float32 sashPos float32 } // Dispose implements disposable interface. -func (s *SplitLayoutState) Dispose() { +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 @@ -34,6 +39,7 @@ type SplitLayoutWidget struct { border bool } +// SplitLayout creates split layout widget func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Widget) *SplitLayoutWidget { return &SplitLayoutWidget{ direction: direction, @@ -45,58 +51,19 @@ func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Wid } } +// 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 } -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) - } - - Child(). - Border(hasBorder). - Size(width, height). - Layout(s.restoreItemSpacing(layout)). - Build() - - if hasFramePadding { - PopStyle() - } - }), - } -} - +// Build implements widget interface func (s *SplitLayoutWidget) Build() { splitLayoutState := s.getState() s.originItemSpacingX, s.originItemSpacingY = GetItemInnerSpacing() @@ -142,13 +109,55 @@ func (s *SplitLayoutWidget) Build() { PopStyle() } -func (s *SplitLayoutWidget) getState() (state *SplitLayoutState) { +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) + } + + Child(). + Border(hasBorder). + Size(width, height). + Layout(s.restoreItemSpacing(layout)). + Build() + + 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} + state = &splitLayoutState{delta: 0.0, sashPos: s.sashPos} Context.SetState(s.id, state) } else { var isOk bool - state, isOk = st.(*SplitLayoutState) + state, isOk = st.(*splitLayoutState) Assert(isOk, "SplitLayoutWidget", "Build", "got unexpected type of widget's state") } From 8dd2571fba5213250547388f767ad3dde75ec405 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 20:09:24 +0200 Subject: [PATCH 039/146] Utils.go: add missing comments --- Utils.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Utils.go b/Utils.go index 95a5a32b..566843e3 100644 --- a/Utils.go +++ b/Utils.go @@ -118,6 +118,8 @@ func GetMousePos() image.Point { return image.Pt(int(pos.X), int(pos.Y)) } +// GetAvailableRegion returns region available for rendering. +// it is always WindowSize-WindowPadding*2 func GetAvailableRegion() (width, height float32) { region := imgui.ContentRegionAvail() return region.X, region.Y @@ -176,18 +178,22 @@ func SetKeyboardFocusHere() { SetKeyboardFocusHereV(0) } +// SetKeyboardFocusHereV gives keyboard focus to next item func SetKeyboardFocusHereV(i int) { imgui.SetKeyboardFocusHereV(i) } +// PushClipRect pushes a clipping rectangle for both ImGui logic (hit-testing etc.) and low-level ImDrawList rendering. func PushClipRect(clipRectMin, clipRectMax image.Point, intersectWithClipRect bool) { imgui.PushClipRect(ToVec2(clipRectMin), ToVec2(clipRectMax), intersectWithClipRect) } +// PopClipRect should be called to end PushClipRect func PopClipRect() { imgui.PopClipRect() } +// Assert checks if cond. If not cond, it alls golang panic func Assert(cond bool, t, method, msg string, args ...interface{}) { if !cond { fatal(t, method, msg, args...) From 92ec72e78343476160baa83fc981db49fbd26a6e Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 10 Oct 2021 20:29:09 +0200 Subject: [PATCH 040/146] apply golangci auto-fixes --- Alignment.go | 2 +- SplitLayout.go | 14 +++++++------- Utils.go | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Alignment.go b/Alignment.go index bcae0e78..e23adc3c 100644 --- a/Alignment.go +++ b/Alignment.go @@ -24,7 +24,7 @@ var _ Widget = &AlignmentSetter{} // AlignmentSetter allows to align to right / center a widget or widgets group. // NOTE: Because of AlignSetter uses experimental GetWidgetWidth, -// it is experimantal too. +// it is experimental too. // usage: see examples/align // // list of known bugs: diff --git a/SplitLayout.go b/SplitLayout.go index 83ec1bdd..79180140 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -2,13 +2,13 @@ package giu import "github.com/AllenDang/imgui-go" -// SplitDirection represents a direction (vertical/horizontal) of splitting layout +// SplitDirection represents a direction (vertical/horizontal) of splitting layout. type SplitDirection uint8 const ( - // DirectionHorizontal is a horizontal line + // DirectionHorizontal is a horizontal line. DirectionHorizontal SplitDirection = 1 << iota - // DirectionVertical is a vertical line + // DirectionVertical is a vertical line. DirectionVertical ) @@ -39,7 +39,7 @@ type SplitLayoutWidget struct { border bool } -// SplitLayout creates split layout widget +// SplitLayout creates split layout widget. func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Widget) *SplitLayoutWidget { return &SplitLayoutWidget{ direction: direction, @@ -51,19 +51,19 @@ func SplitLayout(direction SplitDirection, sashPos float32, layout1, layout2 Wid } } -// Border sets if childs should have borders +// 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 +// ID allows to manually set splitter's id. func (s *SplitLayoutWidget) ID(id string) *SplitLayoutWidget { s.id = id return s } -// Build implements widget interface +// Build implements widget interface. func (s *SplitLayoutWidget) Build() { splitLayoutState := s.getState() s.originItemSpacingX, s.originItemSpacingY = GetItemInnerSpacing() diff --git a/Utils.go b/Utils.go index 566843e3..df8eb158 100644 --- a/Utils.go +++ b/Utils.go @@ -119,7 +119,7 @@ func GetMousePos() image.Point { } // GetAvailableRegion returns region available for rendering. -// it is always WindowSize-WindowPadding*2 +// it is always WindowSize-WindowPadding*2. func GetAvailableRegion() (width, height float32) { region := imgui.ContentRegionAvail() return region.X, region.Y @@ -178,7 +178,7 @@ func SetKeyboardFocusHere() { SetKeyboardFocusHereV(0) } -// SetKeyboardFocusHereV gives keyboard focus to next item +// SetKeyboardFocusHereV gives keyboard focus to next item. func SetKeyboardFocusHereV(i int) { imgui.SetKeyboardFocusHereV(i) } @@ -188,12 +188,12 @@ func PushClipRect(clipRectMin, clipRectMax image.Point, intersectWithClipRect bo imgui.PushClipRect(ToVec2(clipRectMin), ToVec2(clipRectMax), intersectWithClipRect) } -// PopClipRect should be called to end PushClipRect +// PopClipRect should be called to end PushClipRect. func PopClipRect() { imgui.PopClipRect() } -// Assert checks if cond. If not cond, it alls golang panic +// Assert checks if cond. If not cond, it alls golang panic. func Assert(cond bool, t, method, msg string, args ...interface{}) { if !cond { fatal(t, method, msg, args...) From 89cf3ea70467a795aed3f85f134c45572d5e84da Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 14 Oct 2021 21:09:36 +0200 Subject: [PATCH 041/146] make ImageState private --- ClickableWidgets.go | 6 +++--- ImageWidgets.go | 27 ++++++++++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 8869a996..ea4cd19c 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -330,14 +330,14 @@ func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRg // Build implements Widget interface. func (b *ImageButtonWithRgbaWidget) Build() { if state := Context.GetState(b.id); state == nil { - Context.SetState(b.id, &ImageState{}) + Context.SetState(b.id, &imageState{}) NewTextureFromRgba(b.rgba, func(tex *Texture) { - Context.SetState(b.id, &ImageState{texture: tex}) + Context.SetState(b.id, &imageState{texture: tex}) }) } else { var isOk bool - imgState, isOk := state.(*ImageState) + imgState, isOk := state.(*imageState) Assert(isOk, "ImageButtonWithRgbaWidget", "Build", "got unexpected type of widget's state") b.ImageButtonWidget.texture = imgState.texture } diff --git a/ImageWidgets.go b/ImageWidgets.go index a09aeefd..ee64a597 100644 --- a/ImageWidgets.go +++ b/ImageWidgets.go @@ -45,6 +45,7 @@ func (i *ImageWidget) Uv(uv0, uv1 image.Point) *ImageWidget { return i } +// TintColor sets image's tint color func (i *ImageWidget) TintColor(tintColor color.Color) *ImageWidget { i.tintColor = tintColor return i @@ -98,14 +99,14 @@ func (i *ImageWidget) Build() { imgui.ImageV(i.texture.id, size, ToVec2(i.uv0), ToVec2(i.uv1), ToVec4Color(i.tintColor), ToVec4Color(i.borderColor)) } -type ImageState struct { +type imageState struct { loading bool failure bool cancel ctx.CancelFunc texture *Texture } -func (is *ImageState) Dispose() { +func (is *imageState) Dispose() { is.texture = nil // Cancel ongoing image downloaidng if is.loading && is.cancel != nil { @@ -142,9 +143,9 @@ func (i *ImageWithRgbaWidget) OnClick(cb func()) *ImageWithRgbaWidget { // Build implements Widget interface. func (i *ImageWithRgbaWidget) Build() { if i.rgba != nil { - var imgState *ImageState + var imgState *imageState if state := Context.GetState(i.id); state == nil { - imgState = &ImageState{} + imgState = &imageState{} Context.SetState(i.id, imgState) NewTextureFromRgba(i.rgba, func(tex *Texture) { @@ -152,7 +153,7 @@ func (i *ImageWithRgbaWidget) Build() { }) } else { var isOk bool - imgState, isOk = state.(*ImageState) + imgState, isOk = state.(*imageState) Assert(isOk, "ImageWithRgbaWidget", "Build", "unexpected type of widget's state recovered") } @@ -190,7 +191,7 @@ func (i *ImageWithFileWidget) OnClick(cb func()) *ImageWithFileWidget { // Build implements Widget interface. func (i *ImageWithFileWidget) Build() { - imgState := &ImageState{} + imgState := &imageState{} if state := Context.GetState(i.id); state == nil { // Prevent multiple invocation to LoadImage. Context.SetState(i.id, imgState) @@ -203,7 +204,7 @@ func (i *ImageWithFileWidget) Build() { } } else { var isOk bool - imgState, isOk = state.(*ImageState) + imgState, isOk = state.(*imageState) Assert(isOk, "ImageWithFileWidget", "Build", "wrong type of widget's state got") } @@ -273,14 +274,14 @@ func (i *ImageWithURLWidget) LayoutForFailure(widgets ...Widget) *ImageWithURLWi // Build implements Widget interface. func (i *ImageWithURLWidget) Build() { - imgState := &ImageState{} + imgState := &imageState{} if state := Context.GetState(i.id); state == nil { Context.SetState(i.id, imgState) // Prevent multiple invocation to download image. downloadContext, cancalFunc := ctx.WithCancel(ctx.Background()) - Context.SetState(i.id, &ImageState{loading: true, cancel: cancalFunc}) + Context.SetState(i.id, &imageState{loading: true, cancel: cancalFunc}) go func() { // Load image from url @@ -288,7 +289,7 @@ func (i *ImageWithURLWidget) Build() { client.SetTimeout(i.downloadTimeout) resp, err := client.R().SetContext(downloadContext).Get(i.imgURL) if err != nil { - Context.SetState(i.id, &ImageState{failure: true}) + Context.SetState(i.id, &imageState{failure: true}) // Trigger onFailure event if i.onFailure != nil { @@ -300,7 +301,7 @@ func (i *ImageWithURLWidget) Build() { img, _, err := image.Decode(bytes.NewReader(resp.Body())) if err != nil { - Context.SetState(i.id, &ImageState{failure: true}) + Context.SetState(i.id, &imageState{failure: true}) // Trigger onFailure event if i.onFailure != nil { @@ -313,7 +314,7 @@ func (i *ImageWithURLWidget) Build() { rgba := ImageToRgba(img) NewTextureFromRgba(rgba, func(tex *Texture) { - Context.SetState(i.id, &ImageState{ + Context.SetState(i.id, &imageState{ loading: false, failure: false, texture: tex, @@ -327,7 +328,7 @@ func (i *ImageWithURLWidget) Build() { }() } else { var isOk bool - imgState, isOk = state.(*ImageState) + imgState, isOk = state.(*imageState) Assert(isOk, "ImageWithURLWidget", "Build", "wrong type of widget's state recovered.") } From 11c3dd70768e3bfa41618565c894558f7655ac26 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 14 Oct 2021 21:19:34 +0200 Subject: [PATCH 042/146] add comments for ImageWidgets --- ImageWidgets.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ImageWidgets.go b/ImageWidgets.go index ee64a597..cb50b459 100644 --- a/ImageWidgets.go +++ b/ImageWidgets.go @@ -40,12 +40,13 @@ func Image(texture *Texture) *ImageWidget { } } +// Uv allows to specify uv parameters. func (i *ImageWidget) Uv(uv0, uv1 image.Point) *ImageWidget { i.uv0, i.uv1 = uv0, uv1 return i } -// TintColor sets image's tint color +// TintColor sets image's tint color. func (i *ImageWidget) TintColor(tintColor color.Color) *ImageWidget { i.tintColor = tintColor return i @@ -106,6 +107,7 @@ type imageState struct { texture *Texture } +// Dispose cleans imageState (implements Disposable interface). func (is *imageState) Dispose() { is.texture = nil // Cancel ongoing image downloaidng @@ -116,12 +118,17 @@ func (is *imageState) Dispose() { var _ Widget = &ImageWithRgbaWidget{} +// ImageWithRgbaWidget wrapps ImageWidget. +// It is more useful because it doesn't make you to care about +// imgui textures. You can just pass golang-native image.Image and +// display it in giu. type ImageWithRgbaWidget struct { id string rgba image.Image img *ImageWidget } +// ImageWithRgba creates ImageWithRgbaWidget. func ImageWithRgba(rgba image.Image) *ImageWithRgbaWidget { return &ImageWithRgbaWidget{ id: GenAutoID("ImageWithRgba"), @@ -130,11 +137,13 @@ func ImageWithRgba(rgba image.Image) *ImageWithRgbaWidget { } } +// Size sets image's size. func (i *ImageWithRgbaWidget) Size(width, height float32) *ImageWithRgbaWidget { i.img.Size(width, height) return i } +// OnClick sets click callback. func (i *ImageWithRgbaWidget) OnClick(cb func()) *ImageWithRgbaWidget { i.img.OnClick(cb) return i @@ -165,12 +174,18 @@ func (i *ImageWithRgbaWidget) Build() { var _ Widget = &ImageWithFileWidget{} +// ImageWithFileWidget allows to display an image directly +// from .png file. +// NOTE: Be aware that project using this solution may not be portable +// because files are not included in executable binaries! +// You may want to use "embed" package and ImageWithRgba instead. type ImageWithFileWidget struct { id string imgPath string img *ImageWidget } +// ImageWithFile constructs a new ImageWithFileWidget. func ImageWithFile(imgPath string) *ImageWithFileWidget { return &ImageWithFileWidget{ id: fmt.Sprintf("ImageWithFile_%s", imgPath), @@ -179,11 +194,13 @@ func ImageWithFile(imgPath string) *ImageWithFileWidget { } } +// Size sets image's size. func (i *ImageWithFileWidget) Size(width, height float32) *ImageWithFileWidget { i.img.Size(width, height) return i } +// OnClick sets click callback. func (i *ImageWithFileWidget) OnClick(cb func()) *ImageWithFileWidget { i.img.OnClick(cb) return i @@ -214,6 +231,8 @@ func (i *ImageWithFileWidget) Build() { var _ Widget = &ImageWithURLWidget{} +// ImageWithURLWidget allows to display an image using +// an URL as image source. type ImageWithURLWidget struct { id string imgURL string @@ -225,6 +244,7 @@ type ImageWithURLWidget struct { img *ImageWidget } +// ImageWithURL creates ImageWithURLWidget. func ImageWithURL(url string) *ImageWithURLWidget { return &ImageWithURLWidget{ id: fmt.Sprintf("ImageWithURL_%s", url), @@ -242,31 +262,37 @@ func (i *ImageWithURLWidget) OnReady(onReady func()) *ImageWithURLWidget { return i } +// OnFailure sets event trigger when image failed to download/load. func (i *ImageWithURLWidget) OnFailure(onFailure func(error)) *ImageWithURLWidget { i.onFailure = onFailure return i } +// OnClick sets click callback. func (i *ImageWithURLWidget) OnClick(cb func()) *ImageWithURLWidget { i.img.OnClick(cb) return i } +// Timeout sets download timeout. func (i *ImageWithURLWidget) Timeout(downloadTimeout time.Duration) *ImageWithURLWidget { i.downloadTimeout = downloadTimeout return i } +// Size sets image's size. func (i *ImageWithURLWidget) Size(width, height float32) *ImageWithURLWidget { i.img.Size(width, height) return i } +// LayoutForLoading allows to set layout rendered while loading an image. func (i *ImageWithURLWidget) LayoutForLoading(widgets ...Widget) *ImageWithURLWidget { i.whenLoading = Layout(widgets) return i } +// LayoutForFailure allows to specify layout when image failed to download. func (i *ImageWithURLWidget) LayoutForFailure(widgets ...Widget) *ImageWithURLWidget { i.whenFailure = Layout(widgets) return i From b3b6e69a9e88c25d6c022446be1129679529a276 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 17 Oct 2021 13:45:12 +0200 Subject: [PATCH 043/146] popups.go: add comments --- Popups.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Popups.go b/Popups.go index f46ca5eb..99dc509b 100644 --- a/Popups.go +++ b/Popups.go @@ -18,12 +18,15 @@ func CloseCurrentPopup() { var _ Widget = &PopupWidget{} +// PopupWidget is a window wich appears next to the mouse cursor. +// For instance it is used to display color palette in ColorSelectWidget. type PopupWidget struct { name string flags WindowFlags layout Layout } +// Popup creates new popup widget func Popup(name string) *PopupWidget { return &PopupWidget{ name: tStr(name), @@ -32,11 +35,13 @@ func Popup(name string) *PopupWidget { } } +// Flags sets pupup's flags func (p *PopupWidget) Flags(flags WindowFlags) *PopupWidget { p.flags = flags return p } +// Layout sets popup's layout func (p *PopupWidget) Layout(widgets ...Widget) *PopupWidget { p.layout = Layout(widgets) return p @@ -52,6 +57,8 @@ func (p *PopupWidget) Build() { var _ Widget = &PopupModalWidget{} +// PopupModalWidget is a popup window that block every interactions behind it, cannot be closed by +// user, adds a dimming background, has a title bar. type PopupModalWidget struct { name string open *bool @@ -59,6 +66,7 @@ type PopupModalWidget struct { layout Layout } +// PopupModal creates new popup modal widget func PopupModal(name string) *PopupModalWidget { return &PopupModalWidget{ name: tStr(name), @@ -68,16 +76,21 @@ func PopupModal(name string) *PopupModalWidget { } } +// IsOpen allows to control popup's state +// NOTE: changing opens' value will not result in changing popup's state +// if OpenPopup(...) wasn't called! func (p *PopupModalWidget) IsOpen(open *bool) *PopupModalWidget { p.open = open return p } +// Flags allows to specify popup's flags func (p *PopupModalWidget) Flags(flags WindowFlags) *PopupModalWidget { p.flags = flags return p } +// Layout sets layout func (p *PopupModalWidget) Layout(widgets ...Widget) *PopupModalWidget { p.layout = Layout(widgets) return p From 6d54b66ac0536478a2603b975db91d498c2a31d9 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Mon, 25 Oct 2021 17:55:36 +0200 Subject: [PATCH 044/146] add base wrapper for imgui_markdown (use with AllenDang/imgui-go@1320ef8) --- examples/markdown/markdown.go | 27 +++++++++++++++++++++++++++ go.mod | 1 + go.sum | 4 ++++ 3 files changed, 32 insertions(+) create mode 100644 examples/markdown/markdown.go diff --git a/examples/markdown/markdown.go b/examples/markdown/markdown.go new file mode 100644 index 00000000..a73c435d --- /dev/null +++ b/examples/markdown/markdown.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + + "github.com/AllenDang/giu" + "github.com/AllenDang/imgui-go" +) + +var markdown string = fmt.Sprint( + " * list\n", + "[link](https://github.com)\n", +) + +func loop() { + giu.SingleWindow().Layout( + giu.InputTextMultiline(&markdown), + giu.Custom(func() { + imgui.Markdown(&markdown) + }), + ) +} + +func main() { + wnd := giu.NewMasterWindow("ImGui Markdown [Demo]", 640, 480, 0) + wnd.Run(loop) +} diff --git a/go.mod b/go.mod index b77d0b6e..e5237cf4 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be github.com/go-resty/resty/v2 v2.6.0 github.com/kylelemons/godebug v1.1.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d diff --git a/go.sum b/go.sum index ea2af738..029bbcf0 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKY github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= @@ -28,6 +30,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= From 832936b88d54e851df33fbcb8cb070d9a6393c84 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Mon, 25 Oct 2021 18:10:49 +0200 Subject: [PATCH 045/146] imageButtonWidget: fix nil pointer detection (fixes #400) --- ClickableWidgets.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 8f586578..80c44bbf 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -191,7 +191,7 @@ type ImageButtonWidget struct { // Build implements Widget interface. func (b *ImageButtonWidget) Build() { - if b.texture == nil && b.texture.id == 0 { + if b.texture == nil || b.texture.id == 0 { return } From b0e542f809492d75d4c1bb31615b534c1a281950 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Mon, 25 Oct 2021 21:15:58 +0200 Subject: [PATCH 046/146] add support for links (use with gucio321/imgui-go@69dc4f2) --- examples/markdown/markdown.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/markdown/markdown.go b/examples/markdown/markdown.go index a73c435d..63a173d5 100644 --- a/examples/markdown/markdown.go +++ b/examples/markdown/markdown.go @@ -3,20 +3,24 @@ package main import ( "fmt" + "github.com/pkg/browser" + "github.com/AllenDang/giu" "github.com/AllenDang/imgui-go" ) var markdown string = fmt.Sprint( " * list\n", - "[link](https://github.com)\n", + "Here is [a link to some cool website!](https://github.com/AllenDang/giu) you must click it!\n", ) func loop() { giu.SingleWindow().Layout( giu.InputTextMultiline(&markdown), giu.Custom(func() { - imgui.Markdown(&markdown) + imgui.Markdown(&markdown, func(s string) { + browser.OpenURL(s) + }) }), ) } From a6ec95299fad4e46d6d7c51029d2d011eb874520 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 26 Oct 2021 10:28:11 +0200 Subject: [PATCH 047/146] improve markdown example (use with gucio321/imgui-go@b0e542f809492d75d4c1bb31615b534c1a281950) --- examples/markdown/gopher.png | Bin 0 -> 45886 bytes examples/markdown/markdown.go | 70 ++++++++++++++++++++++++++++------ 2 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 examples/markdown/gopher.png diff --git a/examples/markdown/gopher.png b/examples/markdown/gopher.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1e3c42a24bb52380a65f9bdeb2641f99bc53fd GIT binary patch literal 45886 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 literal 0 HcmV?d00001 diff --git a/examples/markdown/markdown.go b/examples/markdown/markdown.go index 63a173d5..796b219b 100644 --- a/examples/markdown/markdown.go +++ b/examples/markdown/markdown.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + "strings" "github.com/pkg/browser" @@ -9,19 +9,67 @@ import ( "github.com/AllenDang/imgui-go" ) -var markdown string = fmt.Sprint( - " * list\n", - "Here is [a link to some cool website!](https://github.com/AllenDang/giu) you must click it!\n", -) +var markdown string = getExampleMarkdownText() + +func getExampleMarkdownText() string { + return strings.Join([]string{ + "Wrapping:", + "Text wraps automatically. To add a new line, use 'Return'.", + "", + "Headers:", + "# H1", + "## H2", + "### H3", + "", + "Emphasis:", + "*emphasis*", + "_emphasis_", + "**strong emphasis**", + "__strong emphasis__", + "", + "Indents:", + "On a new line, at the start of the line, add two spaces per indent.", + " Indent level 1", + " Indent level 2", + "", + "Unordered lists:", + "On a new line, at the start of the line, add two spaces, an asterisks and a space.", + "For nested lists, add two additional spaces in front of the asterisk per list level increment.", + " * Unordered List level 1", + " * Unordered List level 2", + "", + "Link:", + "Here is [a link to some cool website!](https://github.com/AllenDang/giu) you must click it!", + "Image:", + "![gopher image](./gopher.png)", + "", + "Horizontal Rule:", + "***", + "___", + }, "\n") +} func loop() { giu.SingleWindow().Layout( - giu.InputTextMultiline(&markdown), - giu.Custom(func() { - imgui.Markdown(&markdown, func(s string) { - browser.OpenURL(s) - }) - }), + giu.SplitLayout(giu.DirectionHorizontal, 320, + giu.Layout{ + giu.Row( + giu.Label("Markdown Edition:"), + giu.Button("Reset").OnClick(func() { + markdown = getExampleMarkdownText() + }), + ), + giu.Custom(func() { + availableW, availableH := giu.GetAvailableRegion() + giu.InputTextMultiline(&markdown).Size(availableW, availableH).Build() + }), + }, + giu.Custom(func() { + imgui.Markdown(&markdown, func(s string) { + browser.OpenURL(s) + }) + }), + ), ) } From 73285ead94364b6bb94dd7eaac7e2340a9e61bef Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 26 Oct 2021 10:49:37 +0200 Subject: [PATCH 048/146] add giu api for imgui_markdown (use with gucio321/imgui-go@c1d4b06ab6da649c0aa8ac6797d8c0ce30058e4f) --- Utils.go | 8 ++++++++ examples/markdown/markdown.go | 9 +-------- markdown.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 markdown.go diff --git a/Utils.go b/Utils.go index 95a5a32b..ed367190 100644 --- a/Utils.go +++ b/Utils.go @@ -11,6 +11,7 @@ import ( "path/filepath" "github.com/AllenDang/imgui-go" + "github.com/pkg/browser" ) // LoadImage loads image from file and returns *image.RGBA. @@ -201,3 +202,10 @@ func fatal(widgetName, method, message string, args ...interface{}) { log.Panicf("giu: %s.%s: %s", widgetName, method, fmt.Sprintf(message, args...)) } + +// OpenURL opens `url` in default browser. +func OpenURL(url string) { + if err := browser.OpenURL(url); err != nil { + log.Printf("Error opening %s: %v", url, err) + } +} diff --git a/examples/markdown/markdown.go b/examples/markdown/markdown.go index 796b219b..568da4e3 100644 --- a/examples/markdown/markdown.go +++ b/examples/markdown/markdown.go @@ -3,10 +3,7 @@ package main import ( "strings" - "github.com/pkg/browser" - "github.com/AllenDang/giu" - "github.com/AllenDang/imgui-go" ) var markdown string = getExampleMarkdownText() @@ -64,11 +61,7 @@ func loop() { giu.InputTextMultiline(&markdown).Size(availableW, availableH).Build() }), }, - giu.Custom(func() { - imgui.Markdown(&markdown, func(s string) { - browser.OpenURL(s) - }) - }), + giu.Markdown(&markdown), ), ) } diff --git a/markdown.go b/markdown.go new file mode 100644 index 00000000..0c5a7d59 --- /dev/null +++ b/markdown.go @@ -0,0 +1,30 @@ +package giu + +import "github.com/AllenDang/imgui-go" + +// MarkdownWidget implements DearImGui markdown extension +// https://github.com/juliettef/imgui_markdown +// It is like LabelWidget but with md formatting. +type MarkdownWidget struct { + md *string + linkCb func(url string) +} + +// Markdown creates new markdown widget. +func Markdown(md *string) *MarkdownWidget { + return &MarkdownWidget{ + md: md, + linkCb: OpenURL, + } +} + +// OnLink sets another than default link callback. +func (m *MarkdownWidget) OnLink(cb func(url string)) *MarkdownWidget { + m.linkCb = cb + return m +} + +// Build implements Widget interface. +func (m *MarkdownWidget) Build() { + imgui.Markdown(m.md, m.linkCb) +} From 30908ab79d2b5f6e754528ca598c9d14a260ca91 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 26 Oct 2021 19:05:38 +0200 Subject: [PATCH 049/146] markdown: add api for header styles (use with gucio321/imgui-go@1943678) --- FontAtlasProsessor.go | 12 ++++++++++++ examples/markdown/markdown.go | 5 ++++- markdown.go | 30 +++++++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index 85f99982..1782b914 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -36,6 +36,14 @@ func (f *FontInfo) String() string { return fmt.Sprintf("%s:%.2f", f.fontName, f.size) } +func (f *FontInfo) SetSize(size float32) *FontInfo { + result := *f + result.size = size + extraFonts = append(extraFonts, result) + + return &result +} + func init() { extraFontMap = make(map[string]*imgui.Font) @@ -100,6 +108,10 @@ func SetDefaultFontFromBytes(fontBytes []byte, size float32) { }, defaultFonts...) } +func GetDefaultFonts() []FontInfo { + return defaultFonts +} + // AddFont adds font by name, if the font is found, return *FontInfo, otherwise return nil. // To use added font, use giu.Style().SetFont(...). func AddFont(fontName string, size float32) *FontInfo { diff --git a/examples/markdown/markdown.go b/examples/markdown/markdown.go index 568da4e3..789b68e1 100644 --- a/examples/markdown/markdown.go +++ b/examples/markdown/markdown.go @@ -61,7 +61,10 @@ func loop() { giu.InputTextMultiline(&markdown).Size(availableW, availableH).Build() }), }, - giu.Markdown(&markdown), + giu.Markdown(&markdown). + Header(0, (giu.GetDefaultFonts())[0].SetSize(28), true). + Header(1, (giu.GetDefaultFonts())[0].SetSize(26), false). + Header(2, nil, true), ), ) } diff --git a/markdown.go b/markdown.go index 0c5a7d59..0a301925 100644 --- a/markdown.go +++ b/markdown.go @@ -6,8 +6,9 @@ import "github.com/AllenDang/imgui-go" // https://github.com/juliettef/imgui_markdown // It is like LabelWidget but with md formatting. type MarkdownWidget struct { - md *string - linkCb func(url string) + md *string + linkCb func(url string) + headers []imgui.MarkdownHeaderData } // Markdown creates new markdown widget. @@ -24,7 +25,30 @@ func (m *MarkdownWidget) OnLink(cb func(url string)) *MarkdownWidget { return m } +// Header sets header formatting +// NOTE: level (counting from 0!) is header level. (for instance, header `# H1` will have level 0) +func (m *MarkdownWidget) Header(level int, font *FontInfo, separator bool) *MarkdownWidget { + // ensure if header data are at least as long as level + if m.headers == nil { + m.headers = make([]imgui.MarkdownHeaderData, level) + } + + if level <= len(m.headers) { + m.headers = append(m.headers, make([]imgui.MarkdownHeaderData, len(m.headers)-level+1)...) + } + + if font != nil { + if f, ok := extraFontMap[font.String()]; ok { + m.headers[level].Font = *f + } + } + + m.headers[level].HasSeparator = separator + + return m +} + // Build implements Widget interface. func (m *MarkdownWidget) Build() { - imgui.Markdown(m.md, m.linkCb) + imgui.Markdown(m.md, m.linkCb, m.headers) } From 615052e8c4ea5b0be34435cc239b312649322b04 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 26 Oct 2021 19:08:17 +0200 Subject: [PATCH 050/146] go mod: temporarly set replace directive to make PR and workflows runable --- go.mod | 2 ++ go.sum | 2 ++ 2 files changed, 4 insertions(+) diff --git a/go.mod b/go.mod index e5237cf4..5bc726dd 100644 --- a/go.mod +++ b/go.mod @@ -15,3 +15,5 @@ require ( github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) + +replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14 diff --git a/go.sum b/go.sum index 029bbcf0..a7efc6c3 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be h1:vEIVIuBApE github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= +github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14 h1:qb6cwYmsNef/LK5bvmiH3nm8kJV+bBAf7TwB9Z6/MmU= +github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From a6fc4f1f725312bde9ebcc5119c01cb2d2ed05ee Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 26 Oct 2021 19:09:07 +0200 Subject: [PATCH 051/146] raneme markdown.go -> Markdown.go --- markdown.go => Markdown.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename markdown.go => Markdown.go (100%) diff --git a/markdown.go b/Markdown.go similarity index 100% rename from markdown.go rename to Markdown.go From 299b29042c86a362b64774b9e8decb3ff1795fab Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 26 Oct 2021 19:10:20 +0200 Subject: [PATCH 052/146] lintfix --- Markdown.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Markdown.go b/Markdown.go index 0a301925..09288c19 100644 --- a/Markdown.go +++ b/Markdown.go @@ -26,7 +26,7 @@ func (m *MarkdownWidget) OnLink(cb func(url string)) *MarkdownWidget { } // Header sets header formatting -// NOTE: level (counting from 0!) is header level. (for instance, header `# H1` will have level 0) +// NOTE: level (counting from 0!) is header level. (for instance, header `# H1` will have level 0). func (m *MarkdownWidget) Header(level int, font *FontInfo, separator bool) *MarkdownWidget { // ensure if header data are at least as long as level if m.headers == nil { From c1a4b3e4c58f43a2438943f11efc13c9fc7d22f2 Mon Sep 17 00:00:00 2001 From: AllenDang Date: Wed, 27 Oct 2021 16:43:17 +0800 Subject: [PATCH 053/146] Scale image size with DPI scaling factor --- ImageWidgets.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ImageWidgets.go b/ImageWidgets.go index a09aeefd..69f97349 100644 --- a/ImageWidgets.go +++ b/ImageWidgets.go @@ -64,7 +64,9 @@ func (i *ImageWidget) OnClick(cb func()) *ImageWidget { // Size sets image size. func (i *ImageWidget) Size(width, height float32) *ImageWidget { - i.width, i.height = width, height + // Size image with DPI scaling + factor := Context.GetPlatform().GetContentScale() + i.width, i.height = width*factor, height*factor return i } From 7cad3761f75d6f7883ed4b998ca31f285adf27a2 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 27 Oct 2021 18:28:06 +0200 Subject: [PATCH 054/146] markdown: add basic implementation of image callbacks --- Markdown.go | 38 ++++++++++++++++++++++++++++++++++++-- go.mod | 2 +- go.sum | 2 ++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Markdown.go b/Markdown.go index 09288c19..ad150ea6 100644 --- a/Markdown.go +++ b/Markdown.go @@ -1,6 +1,8 @@ package giu -import "github.com/AllenDang/imgui-go" +import ( + "github.com/AllenDang/imgui-go" +) // MarkdownWidget implements DearImGui markdown extension // https://github.com/juliettef/imgui_markdown @@ -50,5 +52,37 @@ func (m *MarkdownWidget) Header(level int, font *FontInfo, separator bool) *Mark // Build implements Widget interface. func (m *MarkdownWidget) Build() { - imgui.Markdown(m.md, m.linkCb, m.headers) + imgui.Markdown(m.md, m.linkCb, loadImage, m.headers) +} + +func loadImage(path string) imgui.MarkdownImageData { + img, err := LoadImage(path) + if err != nil { + return imgui.MarkdownImageData{} + } + + size := img.Bounds() + + // TODO: figure out, why it doesn't work as expected and consider + // if current workaround is save + /* + tex := &Texture{} + NewTextureFromRgba(img, func(t *Texture) { + fmt.Println("creating texture") + tex.id = t.id + }) + */ + + id, err := Context.renderer.LoadImage(img) + if err != nil { + return imgui.MarkdownImageData{} + } + + return imgui.MarkdownImageData{ + TextureID: &id, + Size: imgui.Vec2{ + X: float32(size.Dx()), + Y: float32(size.Dy()), + }, + } } diff --git a/go.mod b/go.mod index 5bc726dd..8cbd81be 100644 --- a/go.mod +++ b/go.mod @@ -16,4 +16,4 @@ require ( golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) -replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14 +replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211027162455-36eca3ee76db diff --git a/go.sum b/go.sum index a7efc6c3..9a2fd132 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKY github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14 h1:qb6cwYmsNef/LK5bvmiH3nm8kJV+bBAf7TwB9Z6/MmU= github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= +github.com/gucio321/imgui-go v1.12.1-0.20211027162455-36eca3ee76db h1:1lTZG3lg8j1x3ULBDzE3oAcmuvmqHmOgI41c8QklVA0= +github.com/gucio321/imgui-go v1.12.1-0.20211027162455-36eca3ee76db/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From 4c19f5ac46387bb6ce5b1463f72cad0dcdf22e67 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 27 Oct 2021 18:59:58 +0200 Subject: [PATCH 055/146] add image scalling logic --- Markdown.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Markdown.go b/Markdown.go index ad150ea6..b64832a5 100644 --- a/Markdown.go +++ b/Markdown.go @@ -1,6 +1,8 @@ package giu import ( + "image" + "github.com/AllenDang/imgui-go" ) @@ -62,6 +64,14 @@ func loadImage(path string) imgui.MarkdownImageData { } size := img.Bounds() + // scale image to not exceed available region + availableW, _ := GetAvailableRegion() + if x := float32(size.Dx()); x > availableW { + size = image.Rect(0, 0, + int(availableW), + int(float32(size.Dy())*availableW/x), + ) + } // TODO: figure out, why it doesn't work as expected and consider // if current workaround is save From 65e115150945f5fa8e9c2c95f0fa728180ae97cd Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 28 Oct 2021 08:24:59 +0200 Subject: [PATCH 056/146] integrate 9c83f95f17c19a4b950e21ce493ac855ae099f20 - call link callback when image clicked --- Markdown.go | 1 + go.mod | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Markdown.go b/Markdown.go index b64832a5..5c0cc108 100644 --- a/Markdown.go +++ b/Markdown.go @@ -94,5 +94,6 @@ func loadImage(path string) imgui.MarkdownImageData { X: float32(size.Dx()), Y: float32(size.Dy()), }, + UseLinkCallback: true, } } diff --git a/go.mod b/go.mod index 8cbd81be..34123e0a 100644 --- a/go.mod +++ b/go.mod @@ -16,4 +16,4 @@ require ( golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) -replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211027162455-36eca3ee76db +replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go 9c83f95f17c19a4b950e21ce493ac855ae099f20 From 645d95b9681c9965b4d395b129800f6b72e16f3e Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 28 Oct 2021 09:22:44 +0200 Subject: [PATCH 057/146] update imgui-go (remove replace directive) --- go.mod | 8 +++----- go.sum | 15 ++++++--------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 34123e0a..cbefdf3b 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,10 @@ go 1.16 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211020111217-535ee3ce6d02 + github.com/AllenDang/imgui-go v1.12.1-0.20211028065201-6f37894affd3 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 - github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 // indirect - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be + github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 // indirect + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be github.com/go-resty/resty/v2 v2.6.0 github.com/kylelemons/godebug v1.1.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 @@ -15,5 +15,3 @@ require ( github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) - -replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go 9c83f95f17c19a4b950e21ce493ac855ae099f20 diff --git a/go.sum b/go.sum index 9a2fd132..673461eb 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,19 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211020111217-535ee3ce6d02 h1:MP/SWCuehFCGBrcVnR6ydkUlD1HQInoZidOCp7fzkTM= -github.com/AllenDang/imgui-go v1.12.1-0.20211020111217-535ee3ce6d02/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= +github.com/AllenDang/imgui-go v1.12.1-0.20211028065201-6f37894affd3 h1:sRTT8DXuVOrSc2MIE8aNREgVzOpETG5FboidUyWcoYw= +github.com/AllenDang/imgui-go v1.12.1-0.20211028065201-6f37894affd3/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= github.com/go-gl/gl v0.0.0-20210315015930-ae072cafe09d/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= -github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 h1:8q7+xl2D2qHPLTII1t4vSMNP2VKwDcn+Avf2WXvdB1A= -github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be h1:vEIVIuBApEBQTEJt19GfhoU+zFSV+sNTa9E9FdnRYfk= +github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 h1:1Zi56D0LNfvkzM+BdoxKryvUEdyWO7LP8oRT+oSYJW0= +github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= -github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14 h1:qb6cwYmsNef/LK5bvmiH3nm8kJV+bBAf7TwB9Z6/MmU= -github.com/gucio321/imgui-go v1.12.1-0.20211026154309-1943678b2f14/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= -github.com/gucio321/imgui-go v1.12.1-0.20211027162455-36eca3ee76db h1:1lTZG3lg8j1x3ULBDzE3oAcmuvmqHmOgI41c8QklVA0= -github.com/gucio321/imgui-go v1.12.1-0.20211027162455-36eca3ee76db/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From abc74db87bd55f9711554a57d505891adbaeb6f0 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 28 Oct 2021 09:26:34 +0200 Subject: [PATCH 058/146] fix small lint error --- Markdown.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Markdown.go b/Markdown.go index 5c0cc108..053d59c3 100644 --- a/Markdown.go +++ b/Markdown.go @@ -73,7 +73,7 @@ func loadImage(path string) imgui.MarkdownImageData { ) } - // TODO: figure out, why it doesn't work as expected and consider + // nolint:gocritic // TODO: figure out, why it doesn't work as expected and consider // if current workaround is save /* tex := &Texture{} From 90d0e507001600fd26c98642e4b555eb1653778f Mon Sep 17 00:00:00 2001 From: AllenDang Date: Fri, 29 Oct 2021 16:59:37 +0800 Subject: [PATCH 059/146] Fix linting issues. --- Canvas.go | 3 +-- Popups.go | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Canvas.go b/Canvas.go index 0870c17e..a7e4d36a 100644 --- a/Canvas.go +++ b/Canvas.go @@ -113,8 +113,7 @@ func (c *Canvas) AddQuadFilled(p1, p2, p3, p4 image.Point, col color.Color) { c.drawlist.AddQuadFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(col)) } -// Stateful path API, add points then finish with PathFillConvex() or PathStroke() - +// Stateful path API, add points then finish with PathFillConvex() or PathStroke(). func (c *Canvas) PathClear() { c.drawlist.PathClear() } diff --git a/Popups.go b/Popups.go index 99dc509b..95d7e84d 100644 --- a/Popups.go +++ b/Popups.go @@ -18,7 +18,7 @@ func CloseCurrentPopup() { var _ Widget = &PopupWidget{} -// PopupWidget is a window wich appears next to the mouse cursor. +// PopupWidget is a window which appears next to the mouse cursor. // For instance it is used to display color palette in ColorSelectWidget. type PopupWidget struct { name string @@ -26,7 +26,7 @@ type PopupWidget struct { layout Layout } -// Popup creates new popup widget +// Popup creates new popup widget. func Popup(name string) *PopupWidget { return &PopupWidget{ name: tStr(name), @@ -35,13 +35,13 @@ func Popup(name string) *PopupWidget { } } -// Flags sets pupup's flags +// Flags sets pupup's flags. func (p *PopupWidget) Flags(flags WindowFlags) *PopupWidget { p.flags = flags return p } -// Layout sets popup's layout +// Layout sets popup's layout. func (p *PopupWidget) Layout(widgets ...Widget) *PopupWidget { p.layout = Layout(widgets) return p @@ -66,7 +66,7 @@ type PopupModalWidget struct { layout Layout } -// PopupModal creates new popup modal widget +// PopupModal creates new popup modal widget. func PopupModal(name string) *PopupModalWidget { return &PopupModalWidget{ name: tStr(name), @@ -84,13 +84,13 @@ func (p *PopupModalWidget) IsOpen(open *bool) *PopupModalWidget { return p } -// Flags allows to specify popup's flags +// Flags allows to specify popup's flags. func (p *PopupModalWidget) Flags(flags WindowFlags) *PopupModalWidget { p.flags = flags return p } -// Layout sets layout +// Layout sets layout. func (p *PopupModalWidget) Layout(widgets ...Widget) *PopupModalWidget { p.layout = Layout(widgets) return p From bfec0fc576187949a7e1ce4606d08498bb2e1c1d Mon Sep 17 00:00:00 2001 From: AllenDang Date: Fri, 29 Oct 2021 17:04:29 +0800 Subject: [PATCH 060/146] Fix linting issue --- ClickableWidgets.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ClickableWidgets.go b/ClickableWidgets.go index 66046fc3..ce7c81ca 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -523,7 +523,7 @@ func (t *TreeNodeWidget) Flags(flags TreeNodeFlags) *TreeNodeWidget { // Event create TreeNode with eventHandler // You could detect events (e.g. IsItemClicked IsMouseDoubleClicked etc...) and handle them for TreeNode inside eventHandler. -// NOTE: DEPRECATED. use EventHandler instead! +// Deprecated: Use EventHandler instead! func (t *TreeNodeWidget) Event(handler func()) *TreeNodeWidget { t.eventHandler = handler return t From 4ce94406d8754a827a893f63863f98186a8807fe Mon Sep 17 00:00:00 2001 From: AllenDang Date: Mon, 1 Nov 2021 19:11:22 +0800 Subject: [PATCH 061/146] Update comment of SetKeyboardFocusHere --- Utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utils.go b/Utils.go index 8e5e4d48..ef73c330 100644 --- a/Utils.go +++ b/Utils.go @@ -174,12 +174,12 @@ func SetItemDefaultFocus() { imgui.SetItemDefaultFocus() } -// SetKeyboardFocusHere sets keyboard focus at the widget. +// SetKeyboardFocusHere sets keyboard focus at *NEXT* widget. func SetKeyboardFocusHere() { SetKeyboardFocusHereV(0) } -// SetKeyboardFocusHereV gives keyboard focus to next item. +// SetKeyboardFocusHereV sets keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. func SetKeyboardFocusHereV(i int) { imgui.SetKeyboardFocusHereV(i) } From aad7c51acb019fedbc9318ae62d2d75dd2b0c329 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 2 Nov 2021 17:29:42 +0100 Subject: [PATCH 062/146] imgui_markdown: bugfix: register markdown text in font atlas to avoid bug when md headers formatting wasn't applied (fix #407) --- Markdown.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Markdown.go b/Markdown.go index 053d59c3..c2b090e2 100644 --- a/Markdown.go +++ b/Markdown.go @@ -54,7 +54,7 @@ func (m *MarkdownWidget) Header(level int, font *FontInfo, separator bool) *Mark // Build implements Widget interface. func (m *MarkdownWidget) Build() { - imgui.Markdown(m.md, m.linkCb, loadImage, m.headers) + imgui.Markdown(tStrPtr(m.md), m.linkCb, loadImage, m.headers) } func loadImage(path string) imgui.MarkdownImageData { From a3b00f417a814b57733f6384fd4aa6bae28b712d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Nov 2021 14:21:24 +0000 Subject: [PATCH 063/146] build(deps): bump github.com/go-resty/resty/v2 from 2.6.0 to 2.7.0 Bumps [github.com/go-resty/resty/v2](https://github.com/go-resty/resty) from 2.6.0 to 2.7.0. - [Release notes](https://github.com/go-resty/resty/releases) - [Commits](https://github.com/go-resty/resty/compare/v2.6.0...v2.7.0) --- updated-dependencies: - dependency-name: github.com/go-resty/resty/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index cbefdf3b..1cf035a0 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be - github.com/go-resty/resty/v2 v2.6.0 + github.com/go-resty/resty/v2 v2.7.0 github.com/kylelemons/godebug v1.1.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 diff --git a/go.sum b/go.sum index 673461eb..3e91b3f3 100644 --- a/go.sum +++ b/go.sum @@ -12,8 +12,8 @@ github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVin github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= -github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= @@ -27,14 +27,13 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= +golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From daa9fbfa433a33d568a1f0c7a584bb1caaab2dc5 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Fri, 5 Nov 2021 13:23:15 +0100 Subject: [PATCH 064/146] markdown impl: add support for images from url --- Markdown.go | 50 +++++++++++++++++++++++++++++------ examples/markdown/markdown.go | 1 + go.mod | 2 ++ go.sum | 6 +++-- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/Markdown.go b/Markdown.go index c2b090e2..cd908c92 100644 --- a/Markdown.go +++ b/Markdown.go @@ -1,9 +1,15 @@ package giu import ( + "bytes" + ctx "context" "image" + "strings" + "time" "github.com/AllenDang/imgui-go" + "github.com/faiface/mainthread" + resty "github.com/go-resty/resty/v2" ) // MarkdownWidget implements DearImGui markdown extension @@ -58,13 +64,37 @@ func (m *MarkdownWidget) Build() { } func loadImage(path string) imgui.MarkdownImageData { - img, err := LoadImage(path) - if err != nil { - return imgui.MarkdownImageData{} + var img *image.RGBA + var err error + + switch { + case strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://"): + downloadContext := ctx.Background() + + // Load image from url + client := resty.New() + client.SetTimeout(5 * time.Second) + resp, err := client.R().SetContext(downloadContext).Get(path) + if err != nil { + return imgui.MarkdownImageData{} + } + + rgba, _, err := image.Decode(bytes.NewReader(resp.Body())) + if err != nil { + return imgui.MarkdownImageData{} + } + + img = ImageToRgba(rgba) + default: + img, err = LoadImage(path) + if err != nil { + return imgui.MarkdownImageData{} + } } size := img.Bounds() // scale image to not exceed available region + // BUG: it causes crash because imgui runs it in goroutine! availableW, _ := GetAvailableRegion() if x := float32(size.Dx()); x > availableW { size = image.Rect(0, 0, @@ -73,7 +103,7 @@ func loadImage(path string) imgui.MarkdownImageData { ) } - // nolint:gocritic // TODO: figure out, why it doesn't work as expected and consider + // nolint:gocritic // TODO/BUG: figure out, why it doesn't work as expected and consider // if current workaround is save /* tex := &Texture{} @@ -83,10 +113,14 @@ func loadImage(path string) imgui.MarkdownImageData { }) */ - id, err := Context.renderer.LoadImage(img) - if err != nil { - return imgui.MarkdownImageData{} - } + var id imgui.TextureID + mainthread.Call(func() { + var err error + id, err = Context.renderer.LoadImage(img) + if err != nil { + return + } + }) return imgui.MarkdownImageData{ TextureID: &id, diff --git a/examples/markdown/markdown.go b/examples/markdown/markdown.go index 789b68e1..07a219d8 100644 --- a/examples/markdown/markdown.go +++ b/examples/markdown/markdown.go @@ -39,6 +39,7 @@ func getExampleMarkdownText() string { "Here is [a link to some cool website!](https://github.com/AllenDang/giu) you must click it!", "Image:", "![gopher image](./gopher.png)", + "![gopher image link](https://raw.githubusercontent.com/AllenDang/giu/master/examples/loadimage/gopher.png)", "", "Horizontal Rule:", "***", diff --git a/go.mod b/go.mod index 1cf035a0..4eea48e9 100644 --- a/go.mod +++ b/go.mod @@ -15,3 +15,5 @@ require ( github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) + +replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8 diff --git a/go.sum b/go.sum index 3e91b3f3..2c167ecc 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211028065201-6f37894affd3 h1:sRTT8DXuVOrSc2MIE8aNREgVzOpETG5FboidUyWcoYw= -github.com/AllenDang/imgui-go v1.12.1-0.20211028065201-6f37894affd3/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= @@ -14,6 +12,10 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKO github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= +github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= +github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= +github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8 h1:N+tZUf/CQAk1fCO5rnABRSyYye8zXKjciX3YZMzRRSs= +github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From 08581a7994011757e70a28b5b15d7791a058886d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Nov 2021 14:31:13 +0000 Subject: [PATCH 065/146] build(deps): bump actions/cache from 2.1.6 to 2.1.7 Bumps [actions/cache](https://github.com/actions/cache) from 2.1.6 to 2.1.7. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2.1.6...v2.1.7) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d0f610d4..8e987f0c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: id: go - name: Cache Go modules - uses: actions/cache@v2.1.6 + uses: actions/cache@v2.1.7 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} From 528cd92a7ee96a474bc4411b49a63c2b5c17ffad Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 24 Nov 2021 08:17:49 +0100 Subject: [PATCH 066/146] move image scalling part into imgui C side --- Markdown.go | 9 --------- go.mod | 2 +- go.sum | 6 ++++-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Markdown.go b/Markdown.go index cd908c92..55d5f63a 100644 --- a/Markdown.go +++ b/Markdown.go @@ -93,15 +93,6 @@ func loadImage(path string) imgui.MarkdownImageData { } size := img.Bounds() - // scale image to not exceed available region - // BUG: it causes crash because imgui runs it in goroutine! - availableW, _ := GetAvailableRegion() - if x := float32(size.Dx()); x > availableW { - size = image.Rect(0, 0, - int(availableW), - int(float32(size.Dy())*availableW/x), - ) - } // nolint:gocritic // TODO/BUG: figure out, why it doesn't work as expected and consider // if current workaround is save diff --git a/go.mod b/go.mod index 4eea48e9..188ee731 100644 --- a/go.mod +++ b/go.mod @@ -16,4 +16,4 @@ require ( golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) -replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8 +replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f diff --git a/go.sum b/go.sum index 2c167ecc..406b74a6 100644 --- a/go.sum +++ b/go.sum @@ -10,12 +10,14 @@ github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVin github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= -github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= +github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8 h1:N+tZUf/CQAk1fCO5rnABRSyYye8zXKjciX3YZMzRRSs= github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= +github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f h1:jB976PjzEyjYxO9RJMwyEMhoVGedRNOqtlClYFddYuE= +github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From 65e916bd2684ae77c8ba88d3b32bf05b14d236eb Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 24 Nov 2021 11:57:09 +0100 Subject: [PATCH 067/146] markdown: add missing image features' impl --- Markdown.go | 6 ++++++ go.mod | 2 +- go.sum | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Markdown.go b/Markdown.go index 55d5f63a..4f9f575e 100644 --- a/Markdown.go +++ b/Markdown.go @@ -4,6 +4,7 @@ import ( "bytes" ctx "context" "image" + "image/color" "strings" "time" @@ -120,5 +121,10 @@ func loadImage(path string) imgui.MarkdownImageData { Y: float32(size.Dy()), }, UseLinkCallback: true, + // default values + Uv0: ToVec2(image.Point{0, 0}), + Uv1: ToVec2(image.Point{1, 1}), + TintColor: ToVec4Color(color.RGBA{255, 255, 255, 255}), + BorderColor: ToVec4Color(color.RGBA{0, 0, 0, 0}), } } diff --git a/go.mod b/go.mod index 188ee731..8bdaa58d 100644 --- a/go.mod +++ b/go.mod @@ -16,4 +16,4 @@ require ( golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) -replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f +replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211124105641-59084587ca5c diff --git a/go.sum b/go.sum index 406b74a6..420ef065 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,8 @@ github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8 h1:N+tZUf/CQA github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f h1:jB976PjzEyjYxO9RJMwyEMhoVGedRNOqtlClYFddYuE= github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= +github.com/gucio321/imgui-go v1.12.1-0.20211124105641-59084587ca5c h1:8pMemr8S3Ya7cQ+XDlM2QfQvIht+2N/nkJEoi00UG9Y= +github.com/gucio321/imgui-go v1.12.1-0.20211124105641-59084587ca5c/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From 669ec1e167009d8b6a7e68797e66aa19cfb815fc Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 24 Nov 2021 13:35:02 +0100 Subject: [PATCH 068/146] update go.mod --- go.mod | 4 +--- go.sum | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8bdaa58d..70add562 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211028065201-6f37894affd3 + github.com/AllenDang/imgui-go v1.12.1-0.20211124112227-66310b6107e8 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be @@ -15,5 +15,3 @@ require ( github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) - -replace github.com/AllenDang/imgui-go => github.com/gucio321/imgui-go v1.12.1-0.20211124105641-59084587ca5c diff --git a/go.sum b/go.sum index 420ef065..0f8fde9c 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= +github.com/AllenDang/imgui-go v1.12.1-0.20211124112227-66310b6107e8 h1:8+CqV/DPX1JnYVWjCxUH/burcMpUCgqChxEZqkB6pp4= +github.com/AllenDang/imgui-go v1.12.1-0.20211124112227-66310b6107e8/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From 5d0cbfb34818e8fdfaef7dbe7478cede4d8a5fd6 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 24 Nov 2021 13:36:25 +0100 Subject: [PATCH 069/146] markdown impl: turn on image scalling by default --- Markdown.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Markdown.go b/Markdown.go index 4f9f575e..96c5b312 100644 --- a/Markdown.go +++ b/Markdown.go @@ -116,6 +116,7 @@ func loadImage(path string) imgui.MarkdownImageData { return imgui.MarkdownImageData{ TextureID: &id, + Scale: true, Size: imgui.Vec2{ X: float32(size.Dx()), Y: float32(size.Dy()), From d070ec29e53d65ab682211e90b7f045a3c48e514 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 24 Nov 2021 13:36:40 +0100 Subject: [PATCH 070/146] run go mod tidy --- go.sum | 8 -------- 1 file changed, 8 deletions(-) diff --git a/go.sum b/go.sum index 0f8fde9c..0fa745f9 100644 --- a/go.sum +++ b/go.sum @@ -12,16 +12,8 @@ github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVin github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-resty/resty/v2 v2.6.0 h1:joIR5PNLM2EFqqESUjCMGXrWmXNHEU9CEiK813oKYS4= -github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w/BIH7cC3Q= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= -github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8 h1:N+tZUf/CQAk1fCO5rnABRSyYye8zXKjciX3YZMzRRSs= -github.com/gucio321/imgui-go v1.12.1-0.20211105072213-652fdf090bb8/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= -github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f h1:jB976PjzEyjYxO9RJMwyEMhoVGedRNOqtlClYFddYuE= -github.com/gucio321/imgui-go v1.12.1-0.20211124071324-882ba5229b7f/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= -github.com/gucio321/imgui-go v1.12.1-0.20211124105641-59084587ca5c h1:8pMemr8S3Ya7cQ+XDlM2QfQvIht+2N/nkJEoi00UG9Y= -github.com/gucio321/imgui-go v1.12.1-0.20211124105641-59084587ca5c/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= From 967f0ee40be81282a892006f3873afc3e6971a33 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 24 Nov 2021 13:45:53 +0100 Subject: [PATCH 071/146] linter: fix minor govet errors --- Markdown.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Markdown.go b/Markdown.go index 96c5b312..48773806 100644 --- a/Markdown.go +++ b/Markdown.go @@ -75,13 +75,13 @@ func loadImage(path string) imgui.MarkdownImageData { // Load image from url client := resty.New() client.SetTimeout(5 * time.Second) - resp, err := client.R().SetContext(downloadContext).Get(path) - if err != nil { + resp, respErr := client.R().SetContext(downloadContext).Get(path) + if respErr != nil { return imgui.MarkdownImageData{} } - rgba, _, err := image.Decode(bytes.NewReader(resp.Body())) - if err != nil { + rgba, _, imgErr := image.Decode(bytes.NewReader(resp.Body())) + if imgErr != nil { return imgui.MarkdownImageData{} } From ec8a7f5418a2962344658689780fbb9c1a4a4716 Mon Sep 17 00:00:00 2001 From: AllenDang Date: Thu, 25 Nov 2021 11:26:18 +0800 Subject: [PATCH 072/146] Update TableColumnFlags --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 70add562..d52a8e3e 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211124112227-66310b6107e8 + github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be diff --git a/go.sum b/go.sum index 0fa745f9..f987bc0c 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211124112227-66310b6107e8 h1:8+CqV/DPX1JnYVWjCxUH/burcMpUCgqChxEZqkB6pp4= -github.com/AllenDang/imgui-go v1.12.1-0.20211124112227-66310b6107e8/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= +github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6 h1:BzLQ4Gh+aIyoT2QULSGe1h3foI+7Ss+gicb6SHN9BtU= +github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From cec845f4b64467251d7d3b2116279a90eb8b17f5 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Fri, 26 Nov 2021 10:26:03 +0100 Subject: [PATCH 073/146] style.go: synchronize styleColorID with imgui --- Style.go | 110 +++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/Style.go b/Style.go index e5788f1d..97fd32f4 100644 --- a/Style.go +++ b/Style.go @@ -218,64 +218,64 @@ func GetFramePadding() (x, y float32) { } // StyleColorID identifies a color in the UI style. -type StyleColorID int +type StyleColorID imgui.StyleColorID // StyleColor identifier. const ( - StyleColorText StyleColorID = 0 - StyleColorTextDisabled StyleColorID = 1 - StyleColorWindowBg StyleColorID = 2 - StyleColorChildBg StyleColorID = 3 - StyleColorPopupBg StyleColorID = 4 - StyleColorBorder StyleColorID = 5 - StyleColorBorderShadow StyleColorID = 6 - StyleColorFrameBg StyleColorID = 7 - StyleColorFrameBgHovered StyleColorID = 8 - StyleColorFrameBgActive StyleColorID = 9 - StyleColorTitleBg StyleColorID = 10 - StyleColorTitleBgActive StyleColorID = 11 - StyleColorTitleBgCollapsed StyleColorID = 12 - StyleColorMenuBarBg StyleColorID = 13 - StyleColorScrollbarBg StyleColorID = 14 - StyleColorScrollbarGrab StyleColorID = 15 - StyleColorScrollbarGrabHovered StyleColorID = 16 - StyleColorScrollbarGrabActive StyleColorID = 17 - StyleColorCheckMark StyleColorID = 18 - StyleColorSliderGrab StyleColorID = 19 - StyleColorSliderGrabActive StyleColorID = 20 - StyleColorButton StyleColorID = 21 - StyleColorButtonHovered StyleColorID = 22 - StyleColorButtonActive StyleColorID = 23 - StyleColorHeader StyleColorID = 24 - StyleColorHeaderHovered StyleColorID = 25 - StyleColorHeaderActive StyleColorID = 26 - StyleColorSeparator StyleColorID = 27 - StyleColorSeparatorHovered StyleColorID = 28 - StyleColorSeparatorActive StyleColorID = 29 - StyleColorResizeGrip StyleColorID = 30 - StyleColorResizeGripHovered StyleColorID = 31 - StyleColorResizeGripActive StyleColorID = 32 - StyleColorTab StyleColorID = 33 - StyleColorTabHovered StyleColorID = 34 - StyleColorTabActive StyleColorID = 35 - StyleColorTabUnfocused StyleColorID = 36 - StyleColorTabUnfocusedActive StyleColorID = 37 - StyleColorPlotLines StyleColorID = 38 - StyleColorPlotLinesHovered StyleColorID = 39 - StyleColorProgressBarActive StyleColorID = 40 - StyleColorPlotHistogram StyleColorID = 40 - StyleColorPlotHistogramHovered StyleColorID = 41 - StyleColorTableHeaderBg StyleColorID = 42 - StyleColorTableBorderStrong StyleColorID = 43 - StyleColorTableBorderLight StyleColorID = 44 - StyleColorTableRowBg StyleColorID = 45 - StyleColorTableRowBgAlt StyleColorID = 46 - StyleColorTextSelectedBg StyleColorID = 47 - StyleColorDragDropTarget StyleColorID = 48 - StyleColorNavHighlight StyleColorID = 49 - StyleColorNavWindowingHighlight StyleColorID = 50 - StyleColorNavWindowingDimBg StyleColorID = 51 - StyleColorModalWindowDimBg StyleColorID = 52 + StyleColorText StyleColorID = StyleColorID(imgui.StyleColorText) + StyleColorTextDisabled StyleColorID = StyleColorID(imgui.StyleColorTextDisabled) + StyleColorWindowBg StyleColorID = StyleColorID(imgui.StyleColorWindowBg) + StyleColorChildBg StyleColorID = StyleColorID(imgui.StyleColorChildBg) + StyleColorPopupBg StyleColorID = StyleColorID(imgui.StyleColorPopupBg) + StyleColorBorder StyleColorID = StyleColorID(imgui.StyleColorBorder) + StyleColorBorderShadow StyleColorID = StyleColorID(imgui.StyleColorBorderShadow) + StyleColorFrameBg StyleColorID = StyleColorID(imgui.StyleColorFrameBg) + StyleColorFrameBgHovered StyleColorID = StyleColorID(imgui.StyleColorFrameBgHovered) + StyleColorFrameBgActive StyleColorID = StyleColorID(imgui.StyleColorFrameBgActive) + StyleColorTitleBg StyleColorID = StyleColorID(imgui.StyleColorTitleBg) + StyleColorTitleBgActive StyleColorID = StyleColorID(imgui.StyleColorTitleBgActive) + StyleColorTitleBgCollapsed StyleColorID = StyleColorID(imgui.StyleColorTitleBgCollapsed) + StyleColorMenuBarBg StyleColorID = StyleColorID(imgui.StyleColorMenuBarBg) + StyleColorScrollbarBg StyleColorID = StyleColorID(imgui.StyleColorScrollbarBg) + StyleColorScrollbarGrab StyleColorID = StyleColorID(imgui.StyleColorScrollbarGrab) + StyleColorScrollbarGrabHovered StyleColorID = StyleColorID(imgui.StyleColorScrollbarGrabHovered) + StyleColorScrollbarGrabActive StyleColorID = StyleColorID(imgui.StyleColorScrollbarGrabActive) + StyleColorCheckMark StyleColorID = StyleColorID(imgui.StyleColorCheckMark) + StyleColorSliderGrab StyleColorID = StyleColorID(imgui.StyleColorSliderGrab) + StyleColorSliderGrabActive StyleColorID = StyleColorID(imgui.StyleColorSliderGrabActive) + StyleColorButton StyleColorID = StyleColorID(imgui.StyleColorButton) + StyleColorButtonHovered StyleColorID = StyleColorID(imgui.StyleColorButtonHovered) + StyleColorButtonActive StyleColorID = StyleColorID(imgui.StyleColorButtonActive) + StyleColorHeader StyleColorID = StyleColorID(imgui.StyleColorHeader) + StyleColorHeaderHovered StyleColorID = StyleColorID(imgui.StyleColorHeaderHovered) + StyleColorHeaderActive StyleColorID = StyleColorID(imgui.StyleColorHeaderActive) + StyleColorSeparator StyleColorID = StyleColorID(imgui.StyleColorSeparator) + StyleColorSeparatorHovered StyleColorID = StyleColorID(imgui.StyleColorSeparatorHovered) + StyleColorSeparatorActive StyleColorID = StyleColorID(imgui.StyleColorSeparatorActive) + StyleColorResizeGrip StyleColorID = StyleColorID(imgui.StyleColorResizeGrip) + StyleColorResizeGripHovered StyleColorID = StyleColorID(imgui.StyleColorResizeGripHovered) + StyleColorResizeGripActive StyleColorID = StyleColorID(imgui.StyleColorResizeGripActive) + StyleColorTab StyleColorID = StyleColorID(imgui.StyleColorTab) + StyleColorTabHovered StyleColorID = StyleColorID(imgui.StyleColorTabHovered) + StyleColorTabActive StyleColorID = StyleColorID(imgui.StyleColorTabActive) + StyleColorTabUnfocused StyleColorID = StyleColorID(imgui.StyleColorTabUnfocused) + StyleColorTabUnfocusedActive StyleColorID = StyleColorID(imgui.StyleColorTabUnfocusedActive) + StyleColorPlotLines StyleColorID = StyleColorID(imgui.StyleColorPlotLines) + StyleColorPlotLinesHovered StyleColorID = StyleColorID(imgui.StyleColorPlotLinesHovered) + StyleColorProgressBarActive StyleColorID = StyleColorPlotLinesHovered + StyleColorPlotHistogram StyleColorID = StyleColorID(imgui.StyleColorPlotHistogram) + StyleColorPlotHistogramHovered StyleColorID = StyleColorID(imgui.StyleColorPlotHistogramHovered) + StyleColorTableHeaderBg StyleColorID = StyleColorID(imgui.StyleColorTableHeaderBg) + StyleColorTableBorderStrong StyleColorID = StyleColorID(imgui.StyleColorTableBorderStrong) + StyleColorTableBorderLight StyleColorID = StyleColorID(imgui.StyleColorTableBorderLight) + StyleColorTableRowBg StyleColorID = StyleColorID(imgui.StyleColorTableRowBg) + StyleColorTableRowBgAlt StyleColorID = StyleColorID(imgui.StyleColorTableRowBgAlt) + StyleColorTextSelectedBg StyleColorID = StyleColorID(imgui.StyleColorTextSelectedBg) + StyleColorDragDropTarget StyleColorID = StyleColorID(imgui.StyleColorDragDropTarget) + StyleColorNavHighlight StyleColorID = StyleColorID(imgui.StyleColorNavHighlight) + StyleColorNavWindowingHighlight StyleColorID = StyleColorID(imgui.StyleColorNavWindowingHighlight) + StyleColorNavWindowingDimBg StyleColorID = StyleColorID(imgui.StyleColorNavWindowingDimBg) + StyleColorModalWindowDimBg StyleColorID = StyleColorID(imgui.StyleColorModalWindowDimBg) ) // StyleVarID identifies a style variable in the UI style. From b3ffea7f7915d842d514560d954c2e4745b3cbf0 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 27 Nov 2021 16:27:56 +0100 Subject: [PATCH 074/146] make TabItem private widget --- examples/bug-409/cache.txt | 57 ++++++++++++++++++++++++++++++++++++++ examples/bug-409/main.go | 27 ++++++++++++++++++ examples/test/test.go | 14 ++++++++++ 3 files changed, 98 insertions(+) create mode 100644 examples/bug-409/cache.txt create mode 100644 examples/bug-409/main.go create mode 100644 examples/test/test.go diff --git a/examples/bug-409/cache.txt b/examples/bug-409/cache.txt new file mode 100644 index 00000000..246100db --- /dev/null +++ b/examples/bug-409/cache.txt @@ -0,0 +1,57 @@ +fatal error: unexpected signal during runtime execution +[signal SIGSEGV: segmentation violation code=0x1 addr=0x178 pc=0x61f1a1] + +runtime stack: +runtime.throw({0x889c5d, 0x7fa5b753ed70}) + /usr/local/go/src/runtime/panic.go:1198 +0x71 +runtime.sigpanic() + /usr/local/go/src/runtime/signal_unix.go:719 +0x396 + +goroutine 3 [syscall]: +runtime.cgocall(0x5e67b0, 0xc000041790) + /usr/local/go/src/runtime/cgocall.go:156 +0x5c fp=0xc000041768 sp=0xc000041730 pc=0x486fbc +github.com/AllenDang/imgui-go._Cfunc_iggContentRegionAvail(0xc000180000) + _cgo_gotypes.go:1303 +0x45 fp=0xc000041790 sp=0xc000041768 pc=0x54fca5 +github.com/AllenDang/imgui-go.ContentRegionAvail() + /home/username/git/d2/me/giu/vendor/github.com/AllenDang/imgui-go/imgui.go:147 +0x7c fp=0xc0000417d0 sp=0xc000041790 pc=0x557adc +github.com/AllenDang/giu.GetAvailableRegion(...) + /home/username/git/d2/me/giu/Utils.go:125 +main.loop.func1() + /home/username/git/d2/me/giu/examples/bug-408/main.go:9 +0x18 fp=0xc0000417e0 sp=0xc0000417d0 pc=0x5e4938 +runtime.goexit() + /usr/local/go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc0000417e8 sp=0xc0000417e0 pc=0x4e49c1 +created by main.loop + /home/username/git/d2/me/giu/examples/bug-408/main.go:8 +0x26 + +goroutine 1 [runnable, locked to thread]: +github.com/go-gl/gl/v3.2-core/gl._Cfunc_glowBindBuffer(0x7fa5dea43660, 0x8893, 0x2) + _cgo_gotypes.go:2983 +0x45 +github.com/go-gl/gl/v3.2-core/gl.BindBuffer(...) + /home/username/git/d2/me/giu/vendor/github.com/go-gl/gl/v3.2-core/gl/package.go:8720 +github.com/AllenDang/imgui-go.(*OpenGL3).Render(0xc000094320, {0x44200000, 0x43f00000}, {0x44200000, 0x43f00000}, 0xc0000d5e08) + /home/username/git/d2/me/giu/vendor/github.com/AllenDang/imgui-go/RendererOpenGL3.go:179 +0xbce +github.com/AllenDang/giu.(*MasterWindow).render(0xc000117490) + /home/username/git/d2/me/giu/MasterWindow.go:205 +0x124 +github.com/AllenDang/giu.(*MasterWindow).run.func1() + /home/username/git/d2/me/giu/MasterWindow.go:220 +0x48 +github.com/faiface/mainthread.Call.func1() + /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:63 +0x26 +github.com/faiface/mainthread.Run(0xc0000af2f0) + /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:44 +0xc9 +github.com/AllenDang/giu.(*MasterWindow).Run(0xc000117490, 0x891b58) + /home/username/git/d2/me/giu/MasterWindow.go:294 +0x72 +main.main() + /home/username/git/d2/me/giu/examples/bug-408/main.go:19 +0x3d + +goroutine 21 [chan receive]: +github.com/faiface/mainthread.Call(0xc000070030) + /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:66 +0xb1 +github.com/AllenDang/giu.(*MasterWindow).run(0xc000117490) + /home/username/git/d2/me/giu/MasterWindow.go:218 +0x87 +github.com/AllenDang/giu.(*MasterWindow).Run.func1() + /home/username/git/d2/me/giu/MasterWindow.go:299 +0x4b +github.com/faiface/mainthread.Run.func1() + /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:37 +0x26 +created by github.com/faiface/mainthread.Run + /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:36 +0xbd +exit status 2 diff --git a/examples/bug-409/main.go b/examples/bug-409/main.go new file mode 100644 index 00000000..aab58cd7 --- /dev/null +++ b/examples/bug-409/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "fmt" + + "github.com/AllenDang/giu" + "github.com/faiface/mainthread" +) + +func loop() { + go func() { + giu.Update() + mainthread.Call(func() { + w, h := giu.GetAvailableRegion() + fmt.Println(w, h) + }) + }() + + giu.SingleWindow().Layout( + giu.Label("Hello World"), + ) +} + +func main() { + wnd := giu.NewMasterWindow("issue 409 [bug]", 640, 480, 0) + wnd.Run(loop) +} diff --git a/examples/test/test.go b/examples/test/test.go new file mode 100644 index 00000000..56366c24 --- /dev/null +++ b/examples/test/test.go @@ -0,0 +1,14 @@ +package main + +import "github.com/AllenDang/giu" + +func main() { + wnd := giu.NewMasterWindow("test", 640, 480, 0) + wnd.Run(loop) +} + +func loop() { + giu.SingleWindow().Layout( + giu.TabItem("tabitem"), + ) +} From c4a17fe31532d9a0b788fe9763aa9b93ecf7a054 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 27 Nov 2021 16:31:24 +0100 Subject: [PATCH 075/146] TabItemWidget: make build method visible only for giu --- Widgets.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Widgets.go b/Widgets.go index 8c8f5600..3694c1fc 100644 --- a/Widgets.go +++ b/Widgets.go @@ -34,7 +34,7 @@ func (l *RowWidget) Build() { switch w.(type) { case *TooltipWidget, *ContextMenuWidget, *PopupModalWidget, - *PopupWidget, *TabItemWidget: + *PopupWidget: // noop default: if _, isLabel := w.(*LabelWidget); isLabel { @@ -538,8 +538,6 @@ func Dummy(width, height float32) *DummyWidget { } } -var _ Widget = &TabItemWidget{} - type TabItemWidget struct { label string open *bool @@ -575,8 +573,7 @@ func (t *TabItemWidget) Layout(widgets ...Widget) *TabItemWidget { return t } -// Build implements Widget interface. -func (t *TabItemWidget) Build() { +func (t *TabItemWidget) buildTabItem() { if imgui.BeginTabItemV(t.label, t.open, int(t.flags)) { t.layout.Build() imgui.EndTabItem() @@ -617,7 +614,7 @@ func (t *TabBarWidget) TabItems(items ...*TabItemWidget) *TabBarWidget { func (t *TabBarWidget) Build() { if imgui.BeginTabBarV(t.id, int(t.flags)) { for _, ti := range t.tabItems { - ti.Build() + ti.buildTabItem() } imgui.EndTabBar() } From 07b1f8c9ab3ee94ec607fc179f80947b98025ace Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 27 Nov 2021 16:40:35 +0100 Subject: [PATCH 076/146] TableWidgets: hide build methods of TableRowWidget, TableColumnWidget and TreeTableRowWidget --- ExtraWidgets.go | 10 ++++------ TableWidgets.go | 16 +++++----------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/ExtraWidgets.go b/ExtraWidgets.go index b97f3dfa..12f2f544 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -161,8 +161,6 @@ func (v *VSplitterWidget) Build() { canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), c, 0, 0) } -var _ Widget = &TreeTableRowWidget{} - type TreeTableRowWidget struct { label string flags TreeNodeFlags @@ -188,7 +186,7 @@ func (ttr *TreeTableRowWidget) Flags(flags TreeNodeFlags) *TreeTableRowWidget { } // Build implements Widget interface. -func (ttr *TreeTableRowWidget) Build() { +func (ttr *TreeTableRowWidget) buildTreeTableRow() { imgui.TableNextRow(0, 0) imgui.TableNextColumn() @@ -214,7 +212,7 @@ func (ttr *TreeTableRowWidget) Build() { if len(ttr.children) > 0 && open { for _, c := range ttr.children { - c.Build() + c.buildTreeTableRow() } imgui.TreePop() @@ -287,13 +285,13 @@ func (tt *TreeTableWidget) Build() { if len(tt.columns) > 0 { for _, col := range tt.columns { - col.Build() + col.buildTableColumn() } imgui.TableHeadersRow() } for _, row := range tt.rows { - row.Build() + row.buildTreeTableRow() } imgui.EndTable() diff --git a/TableWidgets.go b/TableWidgets.go index 338bb56f..01d4c2e2 100644 --- a/TableWidgets.go +++ b/TableWidgets.go @@ -6,8 +6,6 @@ import ( "github.com/AllenDang/imgui-go" ) -var _ Widget = &TableRowWidget{} - type TableRowWidget struct { flags TableRowFlags minRowHeight float64 @@ -39,8 +37,7 @@ func (r *TableRowWidget) MinHeight(height float64) *TableRowWidget { return r } -// Build implements Widget interface. -func (r *TableRowWidget) Build() { +func (r *TableRowWidget) buildTableRow() { imgui.TableNextRow(imgui.TableRowFlags(r.flags), r.minRowHeight) for _, w := range r.layout { @@ -60,8 +57,6 @@ func (r *TableRowWidget) Build() { } } -var _ Widget = &TableColumnWidget{} - type TableColumnWidget struct { label string flags TableColumnFlags @@ -93,8 +88,7 @@ func (c *TableColumnWidget) UserID(id uint32) *TableColumnWidget { return c } -// Build implements Widget interface. -func (c *TableColumnWidget) Build() { +func (c *TableColumnWidget) buildTableColumn() { imgui.TableSetupColumn(c.label, imgui.TableColumnFlags(c.flags), c.innerWidthOrWeight, c.userID) } @@ -180,7 +174,7 @@ func (t *TableWidget) Build() { if len(t.columns) > 0 { for _, col := range t.columns { - col.Build() + col.buildTableColumn() } imgui.TableHeadersRow() } @@ -192,14 +186,14 @@ func (t *TableWidget) Build() { for clipper.Step() { for i := clipper.DisplayStart; i < clipper.DisplayEnd; i++ { row := t.rows[i] - row.Build() + row.buildTableRow() } } clipper.End() } else { for _, row := range t.rows { - row.Build() + row.buildTableRow() } } From 900073204bdbfdd798f6c84e25eda0ce3104839f Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 27 Nov 2021 16:42:49 +0100 Subject: [PATCH 077/146] Revert "make TabItem private widget" This reverts commit b3ffea7f7915d842d514560d954c2e4745b3cbf0. --- examples/bug-409/cache.txt | 57 -------------------------------------- examples/bug-409/main.go | 27 ------------------ examples/test/test.go | 14 ---------- 3 files changed, 98 deletions(-) delete mode 100644 examples/bug-409/cache.txt delete mode 100644 examples/bug-409/main.go delete mode 100644 examples/test/test.go diff --git a/examples/bug-409/cache.txt b/examples/bug-409/cache.txt deleted file mode 100644 index 246100db..00000000 --- a/examples/bug-409/cache.txt +++ /dev/null @@ -1,57 +0,0 @@ -fatal error: unexpected signal during runtime execution -[signal SIGSEGV: segmentation violation code=0x1 addr=0x178 pc=0x61f1a1] - -runtime stack: -runtime.throw({0x889c5d, 0x7fa5b753ed70}) - /usr/local/go/src/runtime/panic.go:1198 +0x71 -runtime.sigpanic() - /usr/local/go/src/runtime/signal_unix.go:719 +0x396 - -goroutine 3 [syscall]: -runtime.cgocall(0x5e67b0, 0xc000041790) - /usr/local/go/src/runtime/cgocall.go:156 +0x5c fp=0xc000041768 sp=0xc000041730 pc=0x486fbc -github.com/AllenDang/imgui-go._Cfunc_iggContentRegionAvail(0xc000180000) - _cgo_gotypes.go:1303 +0x45 fp=0xc000041790 sp=0xc000041768 pc=0x54fca5 -github.com/AllenDang/imgui-go.ContentRegionAvail() - /home/username/git/d2/me/giu/vendor/github.com/AllenDang/imgui-go/imgui.go:147 +0x7c fp=0xc0000417d0 sp=0xc000041790 pc=0x557adc -github.com/AllenDang/giu.GetAvailableRegion(...) - /home/username/git/d2/me/giu/Utils.go:125 -main.loop.func1() - /home/username/git/d2/me/giu/examples/bug-408/main.go:9 +0x18 fp=0xc0000417e0 sp=0xc0000417d0 pc=0x5e4938 -runtime.goexit() - /usr/local/go/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc0000417e8 sp=0xc0000417e0 pc=0x4e49c1 -created by main.loop - /home/username/git/d2/me/giu/examples/bug-408/main.go:8 +0x26 - -goroutine 1 [runnable, locked to thread]: -github.com/go-gl/gl/v3.2-core/gl._Cfunc_glowBindBuffer(0x7fa5dea43660, 0x8893, 0x2) - _cgo_gotypes.go:2983 +0x45 -github.com/go-gl/gl/v3.2-core/gl.BindBuffer(...) - /home/username/git/d2/me/giu/vendor/github.com/go-gl/gl/v3.2-core/gl/package.go:8720 -github.com/AllenDang/imgui-go.(*OpenGL3).Render(0xc000094320, {0x44200000, 0x43f00000}, {0x44200000, 0x43f00000}, 0xc0000d5e08) - /home/username/git/d2/me/giu/vendor/github.com/AllenDang/imgui-go/RendererOpenGL3.go:179 +0xbce -github.com/AllenDang/giu.(*MasterWindow).render(0xc000117490) - /home/username/git/d2/me/giu/MasterWindow.go:205 +0x124 -github.com/AllenDang/giu.(*MasterWindow).run.func1() - /home/username/git/d2/me/giu/MasterWindow.go:220 +0x48 -github.com/faiface/mainthread.Call.func1() - /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:63 +0x26 -github.com/faiface/mainthread.Run(0xc0000af2f0) - /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:44 +0xc9 -github.com/AllenDang/giu.(*MasterWindow).Run(0xc000117490, 0x891b58) - /home/username/git/d2/me/giu/MasterWindow.go:294 +0x72 -main.main() - /home/username/git/d2/me/giu/examples/bug-408/main.go:19 +0x3d - -goroutine 21 [chan receive]: -github.com/faiface/mainthread.Call(0xc000070030) - /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:66 +0xb1 -github.com/AllenDang/giu.(*MasterWindow).run(0xc000117490) - /home/username/git/d2/me/giu/MasterWindow.go:218 +0x87 -github.com/AllenDang/giu.(*MasterWindow).Run.func1() - /home/username/git/d2/me/giu/MasterWindow.go:299 +0x4b -github.com/faiface/mainthread.Run.func1() - /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:37 +0x26 -created by github.com/faiface/mainthread.Run - /home/username/git/d2/me/giu/vendor/github.com/faiface/mainthread/mainthread.go:36 +0xbd -exit status 2 diff --git a/examples/bug-409/main.go b/examples/bug-409/main.go deleted file mode 100644 index aab58cd7..00000000 --- a/examples/bug-409/main.go +++ /dev/null @@ -1,27 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/AllenDang/giu" - "github.com/faiface/mainthread" -) - -func loop() { - go func() { - giu.Update() - mainthread.Call(func() { - w, h := giu.GetAvailableRegion() - fmt.Println(w, h) - }) - }() - - giu.SingleWindow().Layout( - giu.Label("Hello World"), - ) -} - -func main() { - wnd := giu.NewMasterWindow("issue 409 [bug]", 640, 480, 0) - wnd.Run(loop) -} diff --git a/examples/test/test.go b/examples/test/test.go deleted file mode 100644 index 56366c24..00000000 --- a/examples/test/test.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import "github.com/AllenDang/giu" - -func main() { - wnd := giu.NewMasterWindow("test", 640, 480, 0) - wnd.Run(loop) -} - -func loop() { - giu.SingleWindow().Layout( - giu.TabItem("tabitem"), - ) -} From 39461ce637a3cab8f621ec35fb035b67652147ee Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 28 Nov 2021 11:40:20 +0100 Subject: [PATCH 078/146] widgets: expose build methods of TabItem, TableRow, TableColumn and TreeTableRow widgets --- ExtraWidgets.go | 10 +++++----- TableWidgets.go | 12 +++++++----- Widgets.go | 5 +++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ExtraWidgets.go b/ExtraWidgets.go index 12f2f544..32129998 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -185,8 +185,8 @@ func (ttr *TreeTableRowWidget) Flags(flags TreeNodeFlags) *TreeTableRowWidget { return ttr } -// Build implements Widget interface. -func (ttr *TreeTableRowWidget) buildTreeTableRow() { +// BuildTreeTableRow executes table row building steps. +func (ttr *TreeTableRowWidget) BuildTreeTableRow() { imgui.TableNextRow(0, 0) imgui.TableNextColumn() @@ -212,7 +212,7 @@ func (ttr *TreeTableRowWidget) buildTreeTableRow() { if len(ttr.children) > 0 && open { for _, c := range ttr.children { - c.buildTreeTableRow() + c.BuildTreeTableRow() } imgui.TreePop() @@ -285,13 +285,13 @@ func (tt *TreeTableWidget) Build() { if len(tt.columns) > 0 { for _, col := range tt.columns { - col.buildTableColumn() + col.BuildTableColumn() } imgui.TableHeadersRow() } for _, row := range tt.rows { - row.buildTreeTableRow() + row.BuildTreeTableRow() } imgui.EndTable() diff --git a/TableWidgets.go b/TableWidgets.go index 01d4c2e2..f3b50e72 100644 --- a/TableWidgets.go +++ b/TableWidgets.go @@ -37,7 +37,8 @@ func (r *TableRowWidget) MinHeight(height float64) *TableRowWidget { return r } -func (r *TableRowWidget) buildTableRow() { +// BuildTableRow executes table row build steps. +func (r *TableRowWidget) BuildTableRow() { imgui.TableNextRow(imgui.TableRowFlags(r.flags), r.minRowHeight) for _, w := range r.layout { @@ -88,7 +89,8 @@ func (c *TableColumnWidget) UserID(id uint32) *TableColumnWidget { return c } -func (c *TableColumnWidget) buildTableColumn() { +// BuildTableColumn executes table column build steps. +func (c *TableColumnWidget) BuildTableColumn() { imgui.TableSetupColumn(c.label, imgui.TableColumnFlags(c.flags), c.innerWidthOrWeight, c.userID) } @@ -174,7 +176,7 @@ func (t *TableWidget) Build() { if len(t.columns) > 0 { for _, col := range t.columns { - col.buildTableColumn() + col.BuildTableColumn() } imgui.TableHeadersRow() } @@ -186,14 +188,14 @@ func (t *TableWidget) Build() { for clipper.Step() { for i := clipper.DisplayStart; i < clipper.DisplayEnd; i++ { row := t.rows[i] - row.buildTableRow() + row.BuildTableRow() } } clipper.End() } else { for _, row := range t.rows { - row.buildTableRow() + row.BuildTableRow() } } diff --git a/Widgets.go b/Widgets.go index 3694c1fc..b2dc2e98 100644 --- a/Widgets.go +++ b/Widgets.go @@ -573,7 +573,8 @@ func (t *TabItemWidget) Layout(widgets ...Widget) *TabItemWidget { return t } -func (t *TabItemWidget) buildTabItem() { +// BuildTabItem executes tab item build steps. +func (t *TabItemWidget) BuildTabItem() { if imgui.BeginTabItemV(t.label, t.open, int(t.flags)) { t.layout.Build() imgui.EndTabItem() @@ -614,7 +615,7 @@ func (t *TabBarWidget) TabItems(items ...*TabItemWidget) *TabBarWidget { func (t *TabBarWidget) Build() { if imgui.BeginTabBarV(t.id, int(t.flags)) { for _, ti := range t.tabItems { - ti.buildTabItem() + ti.BuildTabItem() } imgui.EndTabBar() } From b3e4ae718b3a78be20ccc69748f7fc96ea7b65f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=9A=E5=AE=87=E8=88=AA?= Date: Wed, 1 Dec 2021 18:32:28 +0800 Subject: [PATCH 079/146] Add giu.SetDefaultFontSize to change overall font size. --- FontAtlasProsessor.go | 28 +++++++++++++++++----------- MasterWindow.go | 2 ++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index 1782b914..734c68ea 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -13,6 +13,7 @@ import ( var ( shouldRebuildFontAtlas bool + defaultFontSize float32 = 14 stringMap sync.Map // key is rune, value indicates whether it's a new rune. defaultFonts []FontInfo extraFonts []FontInfo @@ -44,7 +45,7 @@ func (f *FontInfo) SetSize(size float32) *FontInfo { return &result } -func init() { +func initFontAtlasProcessor() { extraFontMap = make(map[string]*imgui.Font) // Pre register numbers @@ -55,37 +56,42 @@ func init() { switch os { case "darwin": // English font - registerDefaultFont("Menlo", 14) + registerDefaultFont("Menlo", defaultFontSize) // Chinese font - registerDefaultFont("STHeiti", 13) + registerDefaultFont("STHeiti", defaultFontSize-1) // Jananese font - registerDefaultFont("ヒラギノ角ゴシック W0", 17) + registerDefaultFont("ヒラギノ角ゴシック W0", defaultFontSize+3) // Korean font - registerDefaultFont("AppleSDGothicNeo", 16) + registerDefaultFont("AppleSDGothicNeo", defaultFontSize+2) case windows: // English font - registerDefaultFont("Calibri", 16) + registerDefaultFont("Calibri", defaultFontSize+2) // Chinese font - registerDefaultFont("MSYH", 16) + registerDefaultFont("MSYH", defaultFontSize+2) // Japanese font - registerDefaultFont("MSGOTHIC", 16) + registerDefaultFont("MSGOTHIC", defaultFontSize+2) // Korean font - registerDefaultFont("MALGUNSL", 16) + registerDefaultFont("MALGUNSL", defaultFontSize+2) case "linux": // English fonts registerDefaultFonts([]FontInfo{ { fontName: "FreeSans.ttf", - size: 15, + size: defaultFontSize + 1, }, { fontName: "FiraCode-Medium", - size: 15, + size: defaultFontSize + 1, }, }) } } +// Set the default font size. Invoke this before MasterWindow.NewMasterWindow(..). +func SetDefaultFontSize(size float32) { + defaultFontSize = size +} + // SetDefaultFont changes default font. func SetDefaultFont(fontName string, size float32) { fontPath, err := findfont.Find(fontName) diff --git a/MasterWindow.go b/MasterWindow.go index 704caaa9..bea940cf 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -49,6 +49,8 @@ type MasterWindow struct { // it should be called in main function. For more details and use cases, // see examples/helloworld/. func NewMasterWindow(title string, width, height int, flags MasterWindowFlags) *MasterWindow { + initFontAtlasProcessor() + context := imgui.CreateContext(nil) imgui.ImPlotCreateContext() imgui.ImNodesCreateContext() From c9b9d2354e8fc01a338a729efec2b2d9eea51345 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Fri, 17 Dec 2021 10:23:42 +0100 Subject: [PATCH 080/146] deps: brump go-gl/glfw to use glfw v3.3.6 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d52a8e3e..5e5704e8 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 // indirect - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 github.com/kylelemons/godebug v1.1.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 diff --git a/go.sum b/go.sum index f987bc0c..2b631cd5 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,8 @@ github.com/go-gl/gl v0.0.0-20210315015930-ae072cafe09d/go.mod h1:482civXOzJJCPzJ github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 h1:1Zi56D0LNfvkzM+BdoxKryvUEdyWO7LP8oRT+oSYJW0= github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be h1:Z28GdQBfKOL8tNHjvaDn3wHDO7AzTRkmAXvHvnopp98= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211024062804-40e447a793be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= From aaa6da62274f6b8a73722bb9c630aa3b0af8d241 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Mon, 20 Dec 2021 11:57:52 +0100 Subject: [PATCH 081/146] deps: update imgui-go --- go.mod | 4 ++-- go.sum | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 5e5704e8..b17e5922 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,9 @@ go 1.16 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6 + github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 - github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 // indirect + github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 github.com/kylelemons/godebug v1.1.0 // indirect diff --git a/go.sum b/go.sum index 2b631cd5..e7e1937d 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,14 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6 h1:BzLQ4Gh+aIyoT2QULSGe1h3foI+7Ss+gicb6SHN9BtU= -github.com/AllenDang/imgui-go v1.12.1-0.20211125032311-706be5bb9dd6/go.mod h1:2jS7bvvG+PejKdNu4eg2UYqx7Ky8IXGAhxOfjq9qTNk= +github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41 h1:ShBssS1coPMbWwR9t2iOe1fHw6mepKvRR1OuD/EI4PQ= +github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= github.com/go-gl/gl v0.0.0-20210315015930-ae072cafe09d/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= -github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 h1:1Zi56D0LNfvkzM+BdoxKryvUEdyWO7LP8oRT+oSYJW0= -github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk= +github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= From 7588c3d8b1a49fdd4ca1e00ddfe6c45c62de180e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Dec 2021 14:27:13 +0000 Subject: [PATCH 082/146] build(deps): bump actions/setup-go from 2.1.4 to 2.1.5 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2.1.4 to 2.1.5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2.1.4...v2.1.5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/coverage.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8e987f0c..54c8fb9a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ jobs: sudo apt-get --allow-releaseinfo-change update sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - name: Set up Go environment - uses: actions/setup-go@v2.1.4 + uses: actions/setup-go@v2.1.5 with: go-version: 1.16.x id: go diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index b63fe60a..3f724570 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2.3.5 with: fetch-depth: 2 - - uses: actions/setup-go@v2 + - uses: actions/setup-go@v2.1.5 with: go-version: '1.16' - name: Run coverage From 9169d14fd6bfbf917b98a67d7827834e6bed3fda Mon Sep 17 00:00:00 2001 From: Eng Zer Jun Date: Tue, 21 Dec 2021 23:55:52 +0800 Subject: [PATCH 083/146] build: upgrade `go` directive in `go.mod` to 1.17 This commit enables support for module graph pruning and lazy module loading for projects that are at Go 1.17 or higher. Reference: https://go.dev/ref/mod#go-mod-file-go Reference: https://go.dev/ref/mod#graph-pruning Reference: https://go.dev/ref/mod#lazy-loading Signed-off-by: Eng Zer Jun --- go.mod | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b17e5922..ec87bc02 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,25 @@ module github.com/AllenDang/giu -go 1.16 +go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 - github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 - github.com/kylelemons/godebug v1.1.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d ) + +require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect + golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) From a6b4a7e40192e4344663aed5fe495a02dae67a0a Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Wed, 29 Dec 2021 11:18:57 +0800 Subject: [PATCH 084/146] Add ID setter to Child and Table widget. --- TableWidgets.go | 6 ++++++ Widgets.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/TableWidgets.go b/TableWidgets.go index f3b50e72..2dc53cc9 100644 --- a/TableWidgets.go +++ b/TableWidgets.go @@ -120,6 +120,12 @@ func Table() *TableWidget { } } +// ID sets the internal id of table widget. +func (t *TableWidget) ID(id string) *TableWidget { + t.id = id + return t +} + // FastMode Displays visible rows only to boost performance. func (t *TableWidget) FastMode(b bool) *TableWidget { t.fastMode = b diff --git a/Widgets.go b/Widgets.go index b2dc2e98..917eda3d 100644 --- a/Widgets.go +++ b/Widgets.go @@ -98,6 +98,12 @@ func (c *ChildWidget) Layout(widgets ...Widget) *ChildWidget { return c } +// ID sets the interval id of child widgets. +func (c *ChildWidget) ID(id string) *ChildWidget { + c.id = id + return c +} + func Child() *ChildWidget { return &ChildWidget{ id: GenAutoID("Child"), From f158e740fe05f11c258d264382c68299d5e998cd Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 29 Dec 2021 12:32:27 +0100 Subject: [PATCH 085/146] alignsetter: change id of widget inside of GetWidgetWidth method this fixes #425 however it has one weakness: the user can still interract with widget that's width we're measuring. --- Alignment.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Alignment.go b/Alignment.go index e23adc3c..f7039556 100644 --- a/Alignment.go +++ b/Alignment.go @@ -131,6 +131,8 @@ func (a *AlignmentSetter) Build() { // if you find anything else, please report it on // https://github.com/AllenDang/giu Any contribution is appreciated! func GetWidgetWidth(w Widget) (result float32) { + imgui.PushID(GenAutoID("GetWIdgetWidthMeasurement")) + defer imgui.PopID() // save cursor position before rendering currentPos := GetCursorPos() From 355476b1a1091f8db5f3c606a69b78659c71d027 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 29 Dec 2021 12:40:21 +0100 Subject: [PATCH 086/146] GetWidgetWidth: update bugs list --- Alignment.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Alignment.go b/Alignment.go index f7039556..9945df5f 100644 --- a/Alignment.go +++ b/Alignment.go @@ -121,18 +121,16 @@ func (a *AlignmentSetter) Build() { // widget will be processed) // // here is a list of known bugs: -// - BUG: clicking bug - when widget is clickable, it is unable to be -// clicked see: +// - BUG: user can interact with invisible widget (created by GetWidgetWidth) // - https://github.com/AllenDang/giu/issues/341 // - https://github.com/ocornut/imgui/issues/4588 -// - BUG: text pasted into input text is pasted twice -// (see: https://github.com/AllenDang/giu/issues/340) // // if you find anything else, please report it on // https://github.com/AllenDang/giu Any contribution is appreciated! func GetWidgetWidth(w Widget) (result float32) { imgui.PushID(GenAutoID("GetWIdgetWidthMeasurement")) defer imgui.PopID() + // save cursor position before rendering currentPos := GetCursorPos() From f1810697ad396878d696b1980a5535a94c38f518 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Fri, 31 Dec 2021 16:52:30 +0800 Subject: [PATCH 087/146] Update to Dear ImGui v1.86. --- ExtraWidgets.go | 6 ++++-- ListClipper.go | 6 ++++-- TableWidgets.go | 6 ++++-- go.mod | 2 +- go.sum | 4 ++-- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/ExtraWidgets.go b/ExtraWidgets.go index 32129998..64a1fe56 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -446,11 +446,13 @@ func (l *ListBoxWidget) Build() { child := Child().Border(l.border).Size(l.width, l.height).Layout(Layout{ Custom(func() { - var clipper imgui.ListClipper + clipper := imgui.NewListClipper() + defer clipper.Delete() + clipper.Begin(len(l.items)) for clipper.Step() { - for i := clipper.DisplayStart; i < clipper.DisplayEnd; i++ { + for i := clipper.DisplayStart(); i < clipper.DisplayEnd(); i++ { selected := i == state.selectedIndex item := l.items[i] Selectable(item).Selected(selected).Flags(SelectableFlagsAllowDoubleClick).OnClick(func() { diff --git a/ListClipper.go b/ListClipper.go index c4e6e8c5..d945cb33 100644 --- a/ListClipper.go +++ b/ListClipper.go @@ -32,11 +32,13 @@ func (l *ListClipperWrapper) Build() { layout = append(layout, w) }) - var clipper imgui.ListClipper + clipper := imgui.NewListClipper() + defer clipper.Delete() + clipper.Begin(len(layout)) for clipper.Step() { - for i := clipper.DisplayStart; i < clipper.DisplayEnd; i++ { + for i := clipper.DisplayStart(); i < clipper.DisplayEnd(); i++ { layout[i].Build() } } diff --git a/TableWidgets.go b/TableWidgets.go index 2dc53cc9..fae228cd 100644 --- a/TableWidgets.go +++ b/TableWidgets.go @@ -188,11 +188,13 @@ func (t *TableWidget) Build() { } if t.fastMode { - var clipper imgui.ListClipper + clipper := imgui.NewListClipper() + defer clipper.Delete() + clipper.Begin(len(t.rows)) for clipper.Step() { - for i := clipper.DisplayStart; i < clipper.DisplayEnd; i++ { + for i := clipper.DisplayStart(); i < clipper.DisplayEnd(); i++ { row := t.rows[i] row.BuildTableRow() } diff --git a/go.mod b/go.mod index ec87bc02..b6be97a6 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41 + github.com/AllenDang/imgui-go v1.12.1-0.20211231084709-fd27eef3ad1f github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index e7e1937d..bc2bcedc 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41 h1:ShBssS1coPMbWwR9t2iOe1fHw6mepKvRR1OuD/EI4PQ= -github.com/AllenDang/imgui-go v1.12.1-0.20211220065947-c3e78789ac41/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= +github.com/AllenDang/imgui-go v1.12.1-0.20211231084709-fd27eef3ad1f h1:RhjvlMHNHIP0BRFP5MhnthsZ/ySujOBEyha3lQLWXLY= +github.com/AllenDang/imgui-go v1.12.1-0.20211231084709-fd27eef3ad1f/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From 98de1ba85adf0baca59e4e1b8edd4be1135c31be Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Fri, 31 Dec 2021 18:29:51 +0800 Subject: [PATCH 088/146] Fix incorrect background color of popup modal. --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b6be97a6..b44b35c4 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211231084709-fd27eef3ad1f + github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index bc2bcedc..95d4d2b8 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211231084709-fd27eef3ad1f h1:RhjvlMHNHIP0BRFP5MhnthsZ/ySujOBEyha3lQLWXLY= -github.com/AllenDang/imgui-go v1.12.1-0.20211231084709-fd27eef3ad1f/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= +github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00 h1:RHnnawz7Wo2drJdQE0uy2QVga49q9RASxipEa7tUTac= +github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From 8351d07be839b2b6085bafcc94e627d353ae45f5 Mon Sep 17 00:00:00 2001 From: Theo Andresier <49570057+Threpio@users.noreply.github.com> Date: Fri, 31 Dec 2021 15:52:49 +0000 Subject: [PATCH 089/146] Update README.md Fixed example wnd command --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce2d400f..ffef0d46 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ func loop() { } func main() { - wnd := g.NewMasterWindow("Hello world", 400, 200, g.MasterWindowFlagsNotResizable, nil) + wnd := g.NewMasterWindow("Hello world", 400, 200, g.MasterWindowFlagsNotResizable) wnd.Run(loop) } ``` From 26b119e486e6c3084d81e0f4e4fb87526fd22485 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Wed, 12 Jan 2022 16:16:06 +0800 Subject: [PATCH 090/146] Update imgui-go, try to fix the focus lost issue of code editor. --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index b44b35c4..05dcc9c3 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00 + github.com/AllenDang/imgui-go v1.12.1-0.20220112081257-3c75746ab409 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index 95d4d2b8..f0725b6f 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/y github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00 h1:RHnnawz7Wo2drJdQE0uy2QVga49q9RASxipEa7tUTac= github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= +github.com/AllenDang/imgui-go v1.12.1-0.20220112081257-3c75746ab409 h1:IfyLHdkAfYaGkCzScI/ahbqE5FL1kuN/iwLtw7Z+p3s= +github.com/AllenDang/imgui-go v1.12.1-0.20220112081257-3c75746ab409/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From d15a9dc830659dd5634e98db735cf6fb6e4f0596 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Thu, 13 Jan 2022 18:43:59 +0800 Subject: [PATCH 091/146] Fix giu.Update will trigger loop for multiple times. --- Utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utils.go b/Utils.go index ef73c330..0ea6e457 100644 --- a/Utils.go +++ b/Utils.go @@ -81,13 +81,13 @@ func Vec4ToRGBA(vec4 imgui.Vec4) color.RGBA { // Update updates giu app // it is done by default after each frame. -// Hoeever because frames stops rendering, when no user +// However because frames stops rendering, when no user // action is done, it may be necessary to // Update ui manually at some point. func Update() { if Context.isAlive { Context.platform.Update() - Context.IO().SetFrameCountSinceLastInput(0) + // Context.IO().SetFrameCountSinceLastInput(0) } } From 67f04e276bc69a37b144a50f39a520380c1d378b Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Thu, 13 Jan 2022 21:13:07 +0800 Subject: [PATCH 092/146] Set the child bg inside SplitLayout transparent. --- SplitLayout.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/SplitLayout.go b/SplitLayout.go index 79180140..30969260 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -1,6 +1,10 @@ package giu -import "github.com/AllenDang/imgui-go" +import ( + "image/color" + + "github.com/AllenDang/imgui-go" +) // SplitDirection represents a direction (vertical/horizontal) of splitting layout. type SplitDirection uint8 @@ -138,12 +142,16 @@ func (s *SplitLayoutWidget) buildChild(width, height float32, layout Widget) Wid 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() } From 53437c3f2467a18ca925a9ce642924899af0fc41 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Tue, 18 Jan 2022 13:46:55 +0800 Subject: [PATCH 093/146] Remain state when master window is minimized --- MasterWindow.go | 8 ++++++-- go.mod | 2 +- go.sum | 6 ++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index bea940cf..b1bb95c4 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -190,7 +190,9 @@ func (w *MasterWindow) sizeChange(width, height int) { } func (w *MasterWindow) render() { - Context.invalidAllState() + if !w.platform.IsMinimized() { + Context.invalidAllState() + } rebuildFontAtlas() @@ -207,7 +209,9 @@ func (w *MasterWindow) render() { r.Render(p.DisplaySize(), p.FramebufferSize(), imgui.RenderedDrawData()) p.PostRender() - Context.cleanState() + if !w.platform.IsMinimized() { + Context.cleanState() + } } // Run the main loop to create new frame, process events and call update ui func. diff --git a/go.mod b/go.mod index 05dcc9c3..8b462f26 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20220112081257-3c75746ab409 + github.com/AllenDang/imgui-go v1.12.1-0.20220118043609-0be51e9a7c52 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index f0725b6f..b456f69b 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,7 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00 h1:RHnnawz7Wo2drJdQE0uy2QVga49q9RASxipEa7tUTac= -github.com/AllenDang/imgui-go v1.12.1-0.20211231102713-0381b4c77f00/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= -github.com/AllenDang/imgui-go v1.12.1-0.20220112081257-3c75746ab409 h1:IfyLHdkAfYaGkCzScI/ahbqE5FL1kuN/iwLtw7Z+p3s= -github.com/AllenDang/imgui-go v1.12.1-0.20220112081257-3c75746ab409/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= +github.com/AllenDang/imgui-go v1.12.1-0.20220118043609-0be51e9a7c52 h1:4UO2fEJd4KNT/OoZVwlO7CajcWmLlYwg2ko8TjLcpEw= +github.com/AllenDang/imgui-go v1.12.1-0.20220118043609-0be51e9a7c52/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From 54bb7fb7c0f6a12c1e99be5e077b7ab1be210932 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Tue, 18 Jan 2022 13:58:54 +0800 Subject: [PATCH 094/146] Change to use IsVisible to remain Context.state --- MasterWindow.go | 7 ++----- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index b1bb95c4..653e2858 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -190,8 +190,9 @@ func (w *MasterWindow) sizeChange(width, height int) { } func (w *MasterWindow) render() { - if !w.platform.IsMinimized() { + if !w.platform.IsVisible() { Context.invalidAllState() + defer Context.cleanState() } rebuildFontAtlas() @@ -208,10 +209,6 @@ func (w *MasterWindow) render() { r.Render(p.DisplaySize(), p.FramebufferSize(), imgui.RenderedDrawData()) p.PostRender() - - if !w.platform.IsMinimized() { - Context.cleanState() - } } // Run the main loop to create new frame, process events and call update ui func. diff --git a/go.mod b/go.mod index 8b462f26..eedd007f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20220118043609-0be51e9a7c52 + github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/go-resty/resty/v2 v2.7.0 diff --git a/go.sum b/go.sum index b456f69b..e7839500 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20220118043609-0be51e9a7c52 h1:4UO2fEJd4KNT/OoZVwlO7CajcWmLlYwg2ko8TjLcpEw= -github.com/AllenDang/imgui-go v1.12.1-0.20220118043609-0be51e9a7c52/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= +github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2 h1:H9Ohl0tXES9WxO3jq9HdE+4A6eXXybFmRvNdQo2GxLM= +github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= From 83e20c8218bd2403a0a4a611f2ed4c056d2de57d Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Tue, 18 Jan 2022 14:23:25 +0800 Subject: [PATCH 095/146] Revert last commit --- MasterWindow.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MasterWindow.go b/MasterWindow.go index 653e2858..83192279 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -190,7 +190,7 @@ func (w *MasterWindow) sizeChange(width, height int) { } func (w *MasterWindow) render() { - if !w.platform.IsVisible() { + if !w.platform.IsMinimized() { Context.invalidAllState() defer Context.cleanState() } From 94f03dfe32dd68e9f020e8ae6d075e00a9b57378 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Thu, 27 Jan 2022 16:21:48 +0800 Subject: [PATCH 096/146] Skip render loop if master window is invisible --- MasterWindow.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index 83192279..428cf1fc 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -3,6 +3,7 @@ package giu import ( "image" "image/color" + "log" "runtime" "time" @@ -190,11 +191,15 @@ func (w *MasterWindow) sizeChange(width, height int) { } func (w *MasterWindow) render() { - if !w.platform.IsMinimized() { - Context.invalidAllState() - defer Context.cleanState() + if !w.platform.IsVisible() { + return } + Context.invalidAllState() + defer Context.cleanState() + + log.Println("window visibility:", w.platform.IsVisible()) + rebuildFontAtlas() p := w.platform From beab5073e028cd0463fb1d6b0d00c4092a694cc3 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Thu, 27 Jan 2022 16:34:44 +0800 Subject: [PATCH 097/146] Skip rendering loop when master window is minimized --- MasterWindow.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index 428cf1fc..bfd19209 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -3,7 +3,6 @@ package giu import ( "image" "image/color" - "log" "runtime" "time" @@ -191,15 +190,13 @@ func (w *MasterWindow) sizeChange(width, height int) { } func (w *MasterWindow) render() { - if !w.platform.IsVisible() { + if !w.platform.IsVisible() || w.platform.IsMinimized() { return } Context.invalidAllState() defer Context.cleanState() - log.Println("window visibility:", w.platform.IsVisible()) - rebuildFontAtlas() p := w.platform From 4962ff8170380fdb59fbe72fcecab658c01c7979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 28 Jan 2022 21:55:00 +0100 Subject: [PATCH 098/146] Set a sane fallback font on Linux. By default, `sans` is a general alias for some configured sans-serif font. That guarantees, that at least _some_ font is initialized. --- FontAtlasProsessor.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index 734c68ea..c65e59d6 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -83,6 +83,10 @@ func initFontAtlasProcessor() { fontName: "FiraCode-Medium", size: defaultFontSize + 1, }, + { + fontName: "sans", + size: defaultFontSize + 1, + }, }) } } From 68b167059bb77e9a4436e6e75a76343a3a6890a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 28 Jan 2022 22:03:15 +0100 Subject: [PATCH 099/146] Replace resty dependency by standard http library. This reduces the dependency complexity, given that the usage is very simple. --- ImageWidgets.go | 41 ++++++++++++++++++++++------------------- Markdown.go | 15 ++++++--------- go.mod | 2 -- go.sum | 7 ------- 4 files changed, 28 insertions(+), 37 deletions(-) diff --git a/ImageWidgets.go b/ImageWidgets.go index 2e959023..e4367299 100644 --- a/ImageWidgets.go +++ b/ImageWidgets.go @@ -1,15 +1,14 @@ package giu import ( - "bytes" ctx "context" "fmt" "image" "image/color" + "net/http" "time" "github.com/AllenDang/imgui-go" - resty "github.com/go-resty/resty/v2" ) var _ Widget = &ImageWidget{} @@ -311,31 +310,35 @@ func (i *ImageWithURLWidget) Build() { downloadContext, cancalFunc := ctx.WithCancel(ctx.Background()) Context.SetState(i.id, &imageState{loading: true, cancel: cancalFunc}) + errorFn := func(err error) { + Context.SetState(i.id, &imageState{failure: true}) + + // Trigger onFailure event + if i.onFailure != nil { + i.onFailure(err) + } + } + go func() { // Load image from url - client := resty.New() - client.SetTimeout(i.downloadTimeout) - resp, err := client.R().SetContext(downloadContext).Get(i.imgURL) + client := &http.Client{} + client.Timeout = i.downloadTimeout + req, err := http.NewRequestWithContext(downloadContext, "GET", i.imgURL, nil) if err != nil { - Context.SetState(i.id, &imageState{failure: true}) - - // Trigger onFailure event - if i.onFailure != nil { - i.onFailure(err) - } - + errorFn(err) return } - img, _, err := image.Decode(bytes.NewReader(resp.Body())) + resp, err := client.Do(req) if err != nil { - Context.SetState(i.id, &imageState{failure: true}) - - // Trigger onFailure event - if i.onFailure != nil { - i.onFailure(err) - } + errorFn(err) + return + } + defer resp.Body.Close() + img, _, err := image.Decode(resp.Body) + if err != nil { + errorFn(err) return } diff --git a/Markdown.go b/Markdown.go index 48773806..262c3bf6 100644 --- a/Markdown.go +++ b/Markdown.go @@ -1,16 +1,14 @@ package giu import ( - "bytes" - ctx "context" "image" "image/color" + "net/http" "strings" "time" "github.com/AllenDang/imgui-go" "github.com/faiface/mainthread" - resty "github.com/go-resty/resty/v2" ) // MarkdownWidget implements DearImGui markdown extension @@ -70,17 +68,16 @@ func loadImage(path string) imgui.MarkdownImageData { switch { case strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://"): - downloadContext := ctx.Background() - // Load image from url - client := resty.New() - client.SetTimeout(5 * time.Second) - resp, respErr := client.R().SetContext(downloadContext).Get(path) + client := &http.Client{} + client.Timeout = 5 * time.Second + resp, respErr := client.Get(path) if respErr != nil { return imgui.MarkdownImageData{} } + defer resp.Body.Close() - rgba, _, imgErr := image.Decode(bytes.NewReader(resp.Body())) + rgba, _, imgErr := image.Decode(resp.Body) if imgErr != nil { return imgui.MarkdownImageData{} } diff --git a/go.mod b/go.mod index eedd007f..7790e023 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2 github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec - github.com/go-resty/resty/v2 v2.7.0 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 github.com/stretchr/testify v1.7.0 @@ -19,7 +18,6 @@ require ( github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.0.0-20211029224645-99673261e6eb // indirect golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index e7839500..e94fbe18 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,6 @@ github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8I github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= -github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= @@ -26,13 +24,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb h1:pirldcYWx7rx7kE5r+9WsOXPXK0+WH5+uZ7uPmJ44uM= -golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From 3e6631ccdc097e15f7af5cce11108f86a98b1d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Fri, 28 Jan 2022 22:16:44 +0100 Subject: [PATCH 100/146] Set Timeout directly --- ImageWidgets.go | 3 +-- Markdown.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ImageWidgets.go b/ImageWidgets.go index e4367299..89be56c7 100644 --- a/ImageWidgets.go +++ b/ImageWidgets.go @@ -321,8 +321,7 @@ func (i *ImageWithURLWidget) Build() { go func() { // Load image from url - client := &http.Client{} - client.Timeout = i.downloadTimeout + client := &http.Client{Timeout: i.downloadTimeout} req, err := http.NewRequestWithContext(downloadContext, "GET", i.imgURL, nil) if err != nil { errorFn(err) diff --git a/Markdown.go b/Markdown.go index 262c3bf6..366f0511 100644 --- a/Markdown.go +++ b/Markdown.go @@ -69,8 +69,7 @@ func loadImage(path string) imgui.MarkdownImageData { switch { case strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://"): // Load image from url - client := &http.Client{} - client.Timeout = 5 * time.Second + client := &http.Client{Timeout: 5 * time.Second} resp, respErr := client.Get(path) if respErr != nil { return imgui.MarkdownImageData{} From a4dba2357de6403f3f8c1e5e9a83d69b18cf2c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sun, 30 Jan 2022 00:13:49 +0100 Subject: [PATCH 101/146] DatePicker: Allow specifiying a date format --- ExtraWidgets.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ExtraWidgets.go b/ExtraWidgets.go index 64a1fe56..485d20b3 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -500,6 +500,7 @@ type DatePickerWidget struct { date *time.Time width float32 onChange func() + format string } func DatePicker(id string, date *time.Time) *DatePickerWidget { @@ -523,6 +524,18 @@ func (d *DatePickerWidget) OnChange(onChange func()) *DatePickerWidget { return d } +func (d *DatePickerWidget) Format(format string) *DatePickerWidget { + d.format = format + return d +} + +func (d *DatePickerWidget) getFormat() string { + if d.format == "" { + return "2006-01-02" // default + } + return d.format +} + // Build implements Widget interface. func (d *DatePickerWidget) Build() { if d.date == nil { @@ -537,7 +550,7 @@ func (d *DatePickerWidget) Build() { defer PopItemWidth() } - if imgui.BeginComboV(d.id+"##Combo", d.date.Format("2006-01-02"), imgui.ComboFlagsHeightLargest) { + if imgui.BeginComboV(d.id+"##Combo", d.date.Format(d.getFormat()), imgui.ComboFlagsHeightLargest) { // --- [Build year widget] --- imgui.AlignTextToFramePadding() @@ -660,7 +673,7 @@ func (d *DatePickerWidget) calendarField(day int) Widget { Selectable(fmt.Sprintf("%02d", day)).Selected(isToday).OnClick(func() { *d.date, _ = time.ParseInLocation( - "2006-01-02", + d.getFormat(), fmt.Sprintf("%d-%02d-%02d", d.date.Year(), d.date.Month(), From 945cd8b9af95114e3692e459fcbe5e3782a59934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sun, 30 Jan 2022 00:28:26 +0100 Subject: [PATCH 102/146] DatePicker: Allow specifiying the starting day of the week --- ExtraWidgets.go | 58 +++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/ExtraWidgets.go b/ExtraWidgets.go index 485d20b3..2216d736 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -496,19 +496,21 @@ func (l *ListBoxWidget) Build() { var _ Widget = &DatePickerWidget{} type DatePickerWidget struct { - id string - date *time.Time - width float32 - onChange func() - format string + id string + date *time.Time + width float32 + onChange func() + format string + startOfWeek time.Weekday } func DatePicker(id string, date *time.Time) *DatePickerWidget { return &DatePickerWidget{ - id: GenAutoID(id), - date: date, - width: 100, - onChange: func() {}, // small hack - prevent giu from setting nil cb (skip nil check later) + id: GenAutoID(id), + date: date, + width: 100, + startOfWeek: time.Sunday, + onChange: func() {}, // small hack - prevent giu from setting nil cb (skip nil check later) } } @@ -529,6 +531,11 @@ func (d *DatePickerWidget) Format(format string) *DatePickerWidget { return d } +func (d *DatePickerWidget) StartOfWeek(weekday time.Weekday) *DatePickerWidget { + d.startOfWeek = weekday + return d +} + func (d *DatePickerWidget) getFormat() string { if d.format == "" { return "2006-01-02" // default @@ -536,6 +543,13 @@ func (d *DatePickerWidget) getFormat() string { return d.format } +func (d *DatePickerWidget) offsetDay(offset int) time.Weekday { + day := (int(d.startOfWeek) + offset) % 7 + // offset may be negative, thus day can be negative + day = (day + 7) % 7 + return time.Weekday(day) +} + // Build implements Widget interface. func (d *DatePickerWidget) Build() { if d.date == nil { @@ -587,14 +601,11 @@ func (d *DatePickerWidget) Build() { days := d.getDaysGroups() // Create calendar (widget) - columns := []*TableColumnWidget{ - TableColumn("S"), - TableColumn("M"), - TableColumn("T"), - TableColumn("W"), - TableColumn("T"), - TableColumn("F"), - TableColumn("S"), + columns := make([]*TableColumnWidget, 7) + + for i := 0; i < 7; i++ { + firstChar := d.offsetDay(i).String()[0:1] + columns[i] = TableColumn(firstChar) } // Build day widgets @@ -628,17 +639,12 @@ func (d *DatePickerWidget) getDaysGroups() (days [][]int) { lastDay := firstDay.AddDate(0, 1, 0).Add(time.Nanosecond * -1) // calculate first week - days = append(days, []int{}) + days = append(days, make([]int, 7)) monthDay := 1 - for i := 0; i < 7; i++ { - // check for the first month weekday - if i < int(firstDay.Weekday()) { - days[0] = append(days[0], 0) - continue - } - - days[0] = append(days[0], monthDay) + emptyDaysInFirstWeek := (int(firstDay.Weekday()) - int(d.startOfWeek) + 7) % 7 + for i := emptyDaysInFirstWeek; i < 7; i++ { + days[0][i] = monthDay monthDay++ } From 6fa41b35aaa86ebbcbcf25813daf8e3ef7febc02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Tue, 1 Feb 2022 02:28:16 +0100 Subject: [PATCH 103/146] [DatePicker] Fix selecting a date --- ExtraWidgets.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/ExtraWidgets.go b/ExtraWidgets.go index 2216d736..eab9075a 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -678,16 +678,10 @@ func (d *DatePickerWidget) calendarField(day int) Widget { } Selectable(fmt.Sprintf("%02d", day)).Selected(isToday).OnClick(func() { - *d.date, _ = time.ParseInLocation( - d.getFormat(), - fmt.Sprintf("%d-%02d-%02d", - d.date.Year(), - d.date.Month(), - day, - ), - time.Local, - ) - + *d.date = time.Date( + d.date.Year(), d.date.Month(), day, + 0, 0, 0, 0, + d.date.Location()) d.onChange() }).Build() From d3a4406002a602c613188e01cacdb8393b988181 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 1 Feb 2022 08:09:02 +0100 Subject: [PATCH 104/146] workflows: update linter version to v1.44.0 --- .github/workflows/golangci-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 0ebb0bc0..cff6ac64 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -22,7 +22,7 @@ jobs: uses: golangci/golangci-lint-action@v2.5.2 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.42.1 + version: v1.44.0 # Optional: working directory, useful for monorepos # working-directory: somedir From 6243eec977df536536712d9abc19b0679b8201ea Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 1 Feb 2022 08:56:27 +0100 Subject: [PATCH 105/146] all: fix some lint errors --- Canvas.go | 1 + FontAtlasProsessor.go | 2 +- ImageWidgets.go | 9 +++++++-- Markdown.go | 6 +++++- Msgbox.go | 5 ++++- Utils.go | 1 - cmd/gmdeploy/main.go | 2 +- cmd/gmdeploy/utils.go | 3 +-- 8 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Canvas.go b/Canvas.go index a7e4d36a..5963e991 100644 --- a/Canvas.go +++ b/Canvas.go @@ -114,6 +114,7 @@ func (c *Canvas) AddQuadFilled(p1, p2, p3, p4 image.Point, col color.Color) { } // Stateful path API, add points then finish with PathFillConvex() or PathStroke(). + func (c *Canvas) PathClear() { c.drawlist.PathClear() } diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index c65e59d6..86e8adae 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -91,7 +91,7 @@ func initFontAtlasProcessor() { } } -// Set the default font size. Invoke this before MasterWindow.NewMasterWindow(..). +// SetDefaultFontSize sets the default font size. Invoke this before MasterWindow.NewMasterWindow(..). func SetDefaultFontSize(size float32) { defaultFontSize = size } diff --git a/ImageWidgets.go b/ImageWidgets.go index 89be56c7..e411a1d2 100644 --- a/ImageWidgets.go +++ b/ImageWidgets.go @@ -322,7 +322,7 @@ func (i *ImageWithURLWidget) Build() { go func() { // Load image from url client := &http.Client{Timeout: i.downloadTimeout} - req, err := http.NewRequestWithContext(downloadContext, "GET", i.imgURL, nil) + req, err := http.NewRequestWithContext(downloadContext, "GET", i.imgURL, http.NoBody) if err != nil { errorFn(err) return @@ -333,7 +333,12 @@ func (i *ImageWithURLWidget) Build() { errorFn(err) return } - defer resp.Body.Close() + + defer func() { + if closeErr := resp.Body.Close(); closeErr != nil { + errorFn(closeErr) + } + }() img, _, err := image.Decode(resp.Body) if err != nil { diff --git a/Markdown.go b/Markdown.go index 366f0511..018f12c7 100644 --- a/Markdown.go +++ b/Markdown.go @@ -74,7 +74,11 @@ func loadImage(path string) imgui.MarkdownImageData { if respErr != nil { return imgui.MarkdownImageData{} } - defer resp.Body.Close() + + defer func() { + closeErr := resp.Body.Close() + Assert((closeErr == nil), "MarkdownWidget", "loadImage", "Could not close http request!") + }() rgba, _, imgErr := image.Decode(resp.Body) if imgErr != nil { diff --git a/Msgbox.go b/Msgbox.go index fe923441..5e55b149 100644 --- a/Msgbox.go +++ b/Msgbox.go @@ -140,7 +140,10 @@ func (m *MsgboxWidget) getState() *msgboxState { panic("Msgbox is not prepared. Invoke giu.PrepareMsgbox in the end of the layout.") } - return stateRaw.(*msgboxState) + result, isOk := stateRaw.(*msgboxState) + Assert(isOk, "MsgboxWidget", "getState", "unexpected type of widget's state recovered") + + return result } // Msgbox opens message box. diff --git a/Utils.go b/Utils.go index 0ea6e457..787230e8 100644 --- a/Utils.go +++ b/Utils.go @@ -87,7 +87,6 @@ func Vec4ToRGBA(vec4 imgui.Vec4) color.RGBA { func Update() { if Context.isAlive { Context.platform.Update() - // Context.IO().SetFrameCountSinceLastInput(0) } } diff --git a/cmd/gmdeploy/main.go b/cmd/gmdeploy/main.go index 56f3ea82..da0559a6 100644 --- a/cmd/gmdeploy/main.go +++ b/cmd/gmdeploy/main.go @@ -90,7 +90,7 @@ func main() { fmt.Printf("%s.app is generated at %s/build/%s/\n", appName, projectPath, targetOS) case "linux": // nolint:gosec // Compile: cannot fix - cmd := exec.Command("bash", "-c", fmt.Sprintf("go build -ldflags='-s -w' -o %s", filepath.Join(appName))) + cmd := exec.Command("bash", "-c", fmt.Sprintf("go build -ldflags='-s -w' -o %s", appName)) cmd.Dir = projectPath runCmd(cmd) diff --git a/cmd/gmdeploy/utils.go b/cmd/gmdeploy/utils.go index c74ddd05..49f599c2 100644 --- a/cmd/gmdeploy/utils.go +++ b/cmd/gmdeploy/utils.go @@ -1,7 +1,6 @@ package main import ( - "io/ioutil" "log" "os" "os/exec" @@ -9,7 +8,7 @@ import ( func save(name, data string) { const newFileMode = 0o644 - if err := ioutil.WriteFile(name, []byte(data), newFileMode); err != nil { + if err := os.WriteFile(name, []byte(data), newFileMode); err != nil { log.Fatalf("Failed to save %s:%v\n", name, err) } } From ca669bafe0b35fb342b06b992122263d2221b438 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 1 Feb 2022 08:57:11 +0100 Subject: [PATCH 106/146] golangci: comment out revive linter to make linte checks passing --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 0c8ac057..b372da93 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,7 +73,7 @@ linters: - prealloc - predeclared - promlinter - - revive + #- revive - rowserrcheck - staticcheck - structcheck From 5af165bbaea582c8f923176eaba44c7523be29b5 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Fri, 4 Feb 2022 11:25:42 +0800 Subject: [PATCH 107/146] Enable RenderVertexOffset to accept handle large number of draw call --- MasterWindow.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MasterWindow.go b/MasterWindow.go index bfd19209..0cbdf2b1 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -57,7 +57,7 @@ func NewMasterWindow(title string, width, height int, flags MasterWindowFlags) * io := imgui.CurrentIO() - io.SetConfigFlags(imgui.ConfigFlagEnablePowerSavingMode) + io.SetConfigFlags(imgui.ConfigFlagEnablePowerSavingMode | imgui.BackendFlagsRendererHasVtxOffset) // Disable imgui.ini io.SetIniFilename("") From 09022bcb8bde7e7f2b8b745cb61828d75118ce9d Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Fri, 4 Feb 2022 09:19:02 +0100 Subject: [PATCH 108/146] examples: add gifdecode example the example demonstrates how to load a GIF animation decode it, convert to textures and show in a giu app reffers to #447 --- examples/gifdecode/gifdecode.go | 65 ++++++++++++++++++++++++++++++++ examples/gifdecode/golang.gif | Bin 0 -> 62495 bytes 2 files changed, 65 insertions(+) create mode 100644 examples/gifdecode/gifdecode.go create mode 100644 examples/gifdecode/golang.gif diff --git a/examples/gifdecode/gifdecode.go b/examples/gifdecode/gifdecode.go new file mode 100644 index 00000000..63ac2005 --- /dev/null +++ b/examples/gifdecode/gifdecode.go @@ -0,0 +1,65 @@ +package main + +import ( + "bytes" + "image/gif" + "log" + "os" + "time" + + "github.com/AllenDang/giu" +) + +const gifFilepath = "./golang.gif" + +var ( + frames []*giu.Texture + gifImg *gif.GIF + currentFrame int +) + +func loop() { + // load textures + if frames[0] == nil { + for i, frame := range gifImg.Image { + // lol, this is the most magic thing in go i've ever seen :D + i := i + giu.NewTextureFromRgba(giu.ImageToRgba(frame), func(t *giu.Texture) { + frames[i] = t + }) + } + } + + giu.SingleWindow().Layout( + giu.Image(frames[currentFrame]), + ) +} + +func main() { + wnd := giu.NewMasterWindow("GIF renderer [example]", 640, 480, 0) + + gifFileData, err := os.ReadFile(gifFilepath) + if err != nil { + log.Fatal(err) + } + + gifImg, err = gif.DecodeAll(bytes.NewReader(gifFileData)) + if err != nil { + log.Fatal(err) + } + + frames = make([]*giu.Texture, len(gifImg.Image)) + + go func() { + for { + time.Sleep(time.Duration(gifImg.Delay[currentFrame]*10) * time.Millisecond) + giu.Update() + currentFrame++ + if currentFrame == len(frames) { + currentFrame = 0 + } + } + }() + + wnd.Run(loop) +} diff --git a/examples/gifdecode/golang.gif b/examples/gifdecode/golang.gif new file mode 100644 index 0000000000000000000000000000000000000000..23355aa1ab4e4fb556affbf9d6010ccb1ac42a07 GIT binary patch literal 62495 zcmce7Q*>oPyKQXS=}yPC*|BZgHaqFq9a|mSwryj_PIheV+y6P^KHj%;Zau6TqgK`Y zUTUl{*PQc{l$PM;G42EF0}BTG&)|_ziygm7T>;(P+<-tJT?^-m!asW}?c;srJ%gjB z#yX7^$^W(SKacMqLy?;rYq_W##_0tqYV0Ee|5w?A7^oXN#+#8lnQbz4JFJxgrg4Gu6)eAVJ# z1B7$tyt2_e$KqJWLiV!@Pc1sCEYw#^aazD|hfHrEO2mJ)Sw3*_Cz4`HYrBz| zMH0g=4P2&dhHgehe$8$DRuGYeWl2=+L~(VgnKp0Gu-Hw|VyvMMH3$v^9}n$sKP23^ zlHM3vq-bP487-0oXx=2x{*av{a>;%}DitTKIpl0+NZRa;q$URb-h3wY#_CQ=8l7r3 zfiF_$;Z=2sUr{ngFqVh0a6v}yR%AG{IdCaM?Pz_gSp8D9X08jOnZV<6qtJYI8*U>R zxK-9w(qoVQOsn4m2iTv^@-Q+S@Dt92_WN18F%XJMrBJWsU^)>0-S_4t0qtKgrcL;A zZ)(eqTp`0TdLLBlQM}IFu&PlDvGs`HP6g(qDPm0&35% z=A(JD#cy*UzTNH@6frd6(+z7!UJypeAO54$P1w$)CRL`NaGj=qgkbL%nfte?@2U(z*JmgEq4-X&It(BDF+E^9WY;)_=NY0Z zd&pkJCef=G?V>2W<;D%;ARoBd&_1?3N{6(rYNrTC`ZwHfVuKw_Nb~xeUQKoqvkuz zE=>{y@>gHiSA~9@HJy~k2{T82Oj#DwH&AH~e}1vZ@W<3t-*iKxn}+{PIf$fy0A*D>?ZIP_`Rln(_8;hr&A=yiW zj}aq|_hy#sY}an;6zY(9{5KkVy+{|EQypIR+HGwkO?i3QYJ*mR7nuc@a{s~wyasz; zK-G-BFL+TQ?INJtgYP_ilq6lhGhv0m(!KO*(=x5Volq^yoGa7mp?#$cAF78y7&c&Yb5OPBU`H*37( zZ@Y9t0cfeCY4UHKXQCkCK8W`e^xoJFz&dSbA?0^i#4PFYIZZJXm_By*?Rn2i01Ei+ zHZE;H=GJ<8`P*%Jl0M)dFReMg^Q7s0ZR7IxiNyMKB$0qYdlk25Uwc4bYy+Z7`=A|= zeEFSspE`!J*!`Itv72`9_?LM1>?4B7qlm8|q=*ZX&9z|rjXr22N>=3_D=j1=ZBBa3A$h3Ka6{AH;;a?;!dN-NV6-bWXtG!ZauDJvR8f?mD9CgZ zY~OT|tG?;r1l>>@kK18pjJ_zFi9CE&FQK|JWeme26OzX^Nr4_^4D(ARxtX#7_KkWp zuR~L^ckU57j0ABW{KFp|W%y#WDhUC06SuBN$n0z?p{{?GYOqtKsa`^YSjx!%jG+L#W*6pHTpxNzYfLv+ zqJmf(PjByH1G{DK;}0!waUfvLd(V~=+M}7pL4GiSy`d7mZjT8j8_Tc--BOW)>nQl- zszRa1o``uW&qL}jNfD4HMNt&`Zk@7CTMuTPEC2PF+BS+= zTug>p(nYC;S1x~1<$!6Bj>DXfT9;7?u;2Dz^>9z-_!4&(3a-_~u8&1W}FRG?77yPL; zE^|{i-(<&Rh`4E&Xwg!gQ(=itP33Tm)7Xhj??CobckdXn$qfq#B1ziJID)`cuEef% z_LUAin`r4s(#+|kC+Y$&8J8}qZ^>F}caMJfK~HL5EO?f- zbzl1u+Ug_qL(J^T$>{zmi#+PZ^es2 zkP;up{x_xEN(ORnp>K$tGDGB0Ve@8@3x(r{WcPuJrp~OCLUTp1J4Wc1 z4GqUzRl9*BE}YvrDI{UPl1@{pVXUpGZeD>!SF;nCeX%l=AdHEGQmXC1)R=vo zhu|nPhb>JTA2f(vs7ey1UgVv_{~d6msK`8* z^WCjXDCf-4!)Mtr!2O4(?gi$NPi*n6dxNC@c|N}HdM}B`PZfQjkyQiE?9BdL7jcU7 ztYq5>$wSj7;Exw-`1Ugia&001l)MFB)85C^AS~}e@T>^nQz2qxhv)Y2lMV8+-W$V= zanQ@8v;nd6wYCCawxw4}==h zi)denvM>x13oLstR1pV!^6%`dzR^M9`Gdaa_db+t0c1TP2(jOA|HC8{R@9kX_Wr*} z=yRy4_dgOk;_83m3xb6Sg*BO%!lF#6G`+72kr1CLTtdj_4O+i+AFuxE({Xgs+schS zYT}KtWju84=o&w6zi#&e^o|}Z>SD6rz55~-o$-m0CmXwEL#ky*+GWdyv=`A$_*I4Q z54edn64^gAEh70Fs|i36`E86PRu$U0i|Yq6h$p5W)eTd;6)yu09~lC$YKl96X7U#M zpF`QpJq}^h)h(QMGuw<*xYxxnl6z*kjH`mr8irin915|NvCv73FR)%!2GPE-ht8X= zQPDzyASe_hu2~~ND){*3!PfkOL5IF?CA-NWCsXif3YJ*0*Xzwu%!?D&leGRbt> zsZP=eC33m!k{eyts0CxOt{x)~84pS2`Ilim^t2~s<3)mLK6bQN#LHy_oi5c;ceD*v zs=4P#SsL~m;pRez{OuZ7TeS!o9YC;Fbp0OJ&Hd^8RTIMj8JcZqIT7ahf!K>4(QNKD z?YcMyQu3^HyjjsyVk#&fSGJRkT*TlKDjm|Zg_8HbFvAUzU>nW$J2m?29Ku`8l>>2I z4jzvCP43r>N*~WXa~)y0*ZzL3E`vpxbhIk`{T^3n#G5RZ%#lvyR&Oh4V4fw(_}e2HQER zPQ9ck(MTz*QSnNfcYwTh;n00%W?!{SCds{6hNPF-97 zW>swSW*HP6%ol8JJt_g4RpJ{E*0*)3%^~M@=(rS*b=54u0<2Y|0N9jGh2By`rfMsB-9S4okl%Ma)p_?3c0*6U1 zkLlnZxP$#Cr00V4&%^ys@R1uhwyN(yhjfvnP-ZFqk8hS{aP$PnXkMa2hG+t5F~ehK zV46gb;7!!xgi#Klz*Ae}Zxwh+bSU4Vb=}CISYE`bJQU$g*`@JkrN9^w68!DNQV4O= z(N|syVsxO)zCq(l**-e^8BOIt1B}O@Kb-%>laoIoc@NNBInl)=2mkmEKmJo8kzuG3 zhDcUL0w#GOISY#1MFCQVRwazRh~1nL%^g`-qBA4=Ecpi8TiO2HqkTRo7_RV01rqeJy%y<- zAnU+}ct{qUgUqOfNqOg5q}~3ymQi~$+62aIxE4;6TY;%<%=teRG1DRoGl6?64hSz< zGMig-3P|InPpCz+`y)&4NI_*oG!?U2%PIOJs9BufV!RhZJw9_%fm3L)C1(}T)?WQJT(+J#a3dT zWG;6IvQ{eqpbbrVCwn0{e+_q3$RufNDR`)tEvQx*f}gLAemT@x6jyyit?VnE;b@8- zHq((O+?Y6CuH>K|utAL0k*LsU$TzRHVnD>N?GGwzEv7TK?o^eT;A~BB1De~T>F#1Y zwKac|gNOwQ_0%#kN`gW!ZEayxVmy;>^u{+ zw^aGBL~eNj`K^c^uC+!o2hHR_LU>Ea%~Okf;W{TZFK!0dpT!ozL^AJenEYTyBr6rXT- z2YpN{RwdOrbUP!l+F6Oop7c5xSQIY5p7KcQ;71iVDZHnzh-<1Y!t6HXpM5Mb%E9Cc zejPgy8Ounu7A$L_aoC!C9$CzFEVh&kK+)Q8p87FRWs?PQ*q%&wu2d+b#JJ7UHyKx}VBfhw}mUhZWmFo(}rGoBf9xsNK@0 z*S;sKTfi`mUels2t6;)9h+4G%;W9_JA6w2Bj0ydvz?%movo&Nz&tV~#Tc2LtgI5@C z%hylmb>@%mdYGAtbq42A6~3c8oa2Uj`UArremWvgPg6M;}T@u?XC zVT;c*Y`p0W^Mxm`UVTXCv`*>M8PwWM;%jdqF|A;GPo!Fyn{+gOd^jPbK~ljRd*H*G zUh3_G7Nvr$OIkCRnV87tz>Q975Xs4~b?uMv+v2&f0taeE=*EFpSy`csNd-G~!KH{an2Jj~hyy@64MbwDQlAZn3qV=+is_MJQ9}d)U$yHP6Nx($3W~){q6+lVul`h{}EID0Q}I0ka5iyk^izkYLTC3$X7HlZfYUya#PZ_N~Tdo^;TB|5hB+r#|bgc9__&)a+YFgdX zzk5QF(qsk?>7bi$V>li1*X)L6`zuKyV6UjX8 zi9Y2EmJ8l^p(xY!Y?M>Q>eVh}uUNDVVzT81&=<|7($%*S9*?gampUHWlO=65e}G%f zr@woM(Q#??d(?r6!-PMti+e&#QPl9(26z945u1u%ses!*E zEEReQ{z75ckhRPyWhvDl4t1AZ&Hu53El}?^yHRSaxT4?Dda)A~>`M~&#%WX_0>vLr zqR;DA-dt)p%Gi>8m^oAbtM=;c{pDmMi1oTA_~Y@WboCdP5T<|-(FNw#XddY6K_svD z0+w0$BOk4d>1PA z)*r5p4X+z9EK#wtpI16G&iuHLa`ntO0$s{|@TNp8Sp>S5&O$IL`?jMOQA6k>`#A$E$JuB7%?CiB&YApA(WPbZ2bT_~J>>bXIKTuekkIleU5FBl^ZYb-|OK zPfu9+v9COu0^Ny&Zy(-S!v$q6Lil9i?sJgBibogTVFz`IT}((&Xg_3o zz!f@b0Tu<#q*tZtjAIhNav^m4{sgqre403xIWvuS3g-Y#8pT#I-LErQV}zviPL^ZZ z0`@FUM$FXd>_fItHr$_yr!e4PmfVBmlfwU4D%b)#;ea)m$4W`o&$klpVQB@9bWHHm zOIgB|b%lLy)*sw|PWbh;XI#&zauC-_!MDy79Z9}rN1By_M`_RgK89651;v_*3As)k z8!yG9=U9PXMk=zFV`jT7QCo1^@P+3-#D5E=6u-7sa>!%{qdqz@*C6Oh-A+zsE|wQU zKVOKKU@vtyJ`MGumCbK3D-eCOR*of@hT>c*L^G#y@iSGeQfMxbPe@m(&77}lvEY6q zx6xERPb>Oj%T*pO7n|N7Y#MkhmQXKK-_{;$^-!-=B(79jt;osYM9sIRsMHIV(aeJ3 ztO-f6AVIa&%tgQ$?wX=yH~sAIrz&LRTDJ;gV~($fVYZf+X1G}lyLfG8fLcxQRVng{)_ zDEKR;yT4XCrm$;V8!ID#3S1@&cZ`zxw33&CxEQuu)V_xr^Q1;B^=t&J0;cwYG>efP4~GaGfL!==VJ_9MG# zQ-u?P71+e)V%%z5F)E*7%bMmOZQ!vG72is*f?Hz{G?78;+vJdgLbIGK46I-o1)Tp#q85N;ufsWO`CGPi`pSNK?LKC37xU{>&Sm3=_tD3 z+Vvp7<*FWP{kDGIOIrX;QocmN8-VNmZ z)d`;1<(Cf8gxcg9B%ZsKbF3!v9s`(23Uy{!ukJ-6@pqj7KD-BW

-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 Date: Fri, 4 Feb 2022 17:42:16 +0100 Subject: [PATCH 109/146] gifdecode example: use go:embed directive to embed gif image --- examples/gifdecode/gifdecode.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/gifdecode/gifdecode.go b/examples/gifdecode/gifdecode.go index 63ac2005..6b2f1c4d 100644 --- a/examples/gifdecode/gifdecode.go +++ b/examples/gifdecode/gifdecode.go @@ -2,14 +2,17 @@ package main import ( "bytes" + _ "embed" "image/gif" "log" - "os" "time" "github.com/AllenDang/giu" ) +//go:embed golang.gif +var gifFileData []byte + const gifFilepath = "./golang.gif" var ( @@ -36,12 +39,9 @@ func loop() { } func main() { - wnd := giu.NewMasterWindow("GIF renderer [example]", 640, 480, 0) + var err error - gifFileData, err := os.ReadFile(gifFilepath) - if err != nil { - log.Fatal(err) - } + wnd := giu.NewMasterWindow("GIF renderer [example]", 640, 480, 0) gifImg, err = gif.DecodeAll(bytes.NewReader(gifFileData)) if err != nil { From 0e552b202e14b066dfb16944b70a27391ad1c96d Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 17:28:55 +0100 Subject: [PATCH 110/146] textures: check if the main loop is runing before loading texture --- Context.go | 4 ++++ MasterWindow.go | 3 +++ Texture.go | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/Context.go b/Context.go index 2c208d26..acde6898 100644 --- a/Context.go +++ b/Context.go @@ -21,6 +21,10 @@ type state struct { } type context struct { + // TODO: should be handled by mainthread tbh + // see https://github.com/faiface/mainthread/pull/4 + isRunning bool + renderer imgui.Renderer platform imgui.Platform diff --git a/MasterWindow.go b/MasterWindow.go index 0cbdf2b1..fdf302eb 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -215,6 +215,7 @@ func (w *MasterWindow) render() { // Run the main loop to create new frame, process events and call update ui func. func (w *MasterWindow) run() { + Context.isRunning = true p := w.platform ticker := time.NewTicker(time.Second / time.Duration(p.GetTPS())) @@ -229,6 +230,8 @@ func (w *MasterWindow) run() { <-ticker.C } + + Context.isRunning = false } // GetSize return size of master window. diff --git a/Texture.go b/Texture.go index be4a3eaa..1d1acdcb 100644 --- a/Texture.go +++ b/Texture.go @@ -22,6 +22,11 @@ type loadImageResult struct { // NewTextureFromRgba creates a new texture from image.Image and, when it is done, calls loadCallback(loadedTexture). func NewTextureFromRgba(rgba image.Image, loadCallback func(*Texture)) { + Assert(Context.isRunning, "", "NewTextureFromRgba", "cannot load texture befor (*MasterWindow).Run call!") + loadTexture(rgba, loadCallback) +} + +func loadTexture(rgba image.Image, loadCallback func(*Texture)) { go func() { Update() result := mainthread.CallVal(func() interface{} { From 246212c9b16519b95978012a6c9e72f2e3adfc0f Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 18:11:12 +0100 Subject: [PATCH 111/146] texture: add EnqueueNewTextureFromRgba this method adds texture to load queue that is processed while running app it allows user to call texture-loading methods inside of main function so that he shouldn't check if texture isn't currently loaded in app loop --- Context.go | 3 +++ MasterWindow.go | 14 +++++++++++++- Texture.go | 9 +++++++++ examples/loadimage/loadimage.go | 10 +++++++++- go.mod | 1 + go.sum | 2 ++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Context.go b/Context.go index acde6898..0d8a3d6f 100644 --- a/Context.go +++ b/Context.go @@ -4,6 +4,7 @@ import ( "sync" "github.com/AllenDang/imgui-go" + "gopkg.in/eapache/queue.v1" ) // Context represents a giu context. @@ -37,6 +38,8 @@ type context struct { state sync.Map InputHandler InputHandler + + textureLoadingQueue *queue.Queue } func (c *context) GetRenderer() imgui.Renderer { diff --git a/MasterWindow.go b/MasterWindow.go index fdf302eb..85ac4b02 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -9,6 +9,7 @@ import ( "github.com/AllenDang/imgui-go" "github.com/faiface/mainthread" "github.com/go-gl/glfw/v3.3/glfw" + "gopkg.in/eapache/queue.v1" ) // MasterWindowFlags wrapps imgui.GLFWWindowFlags. @@ -88,6 +89,9 @@ func NewMasterWindow(title string, width, height int, flags MasterWindowFlags) * rebuildFontAtlas() } + // init texture loading queue + Context.textureLoadingQueue = queue.New() + mw := &MasterWindow{ clearColor: [4]float32{0, 0, 0, 1}, width: width, @@ -215,7 +219,6 @@ func (w *MasterWindow) render() { // Run the main loop to create new frame, process events and call update ui func. func (w *MasterWindow) run() { - Context.isRunning = true p := w.platform ticker := time.NewTicker(time.Second / time.Duration(p.GetTPS())) @@ -300,10 +303,19 @@ func (w *MasterWindow) SetDropCallback(cb func([]string)) { // up the master window. func (w *MasterWindow) Run(loopFunc func()) { mainthread.Run(func() { + Context.isRunning = true w.updateFunc = loopFunc Context.isAlive = true + // process texture load requests + if Context.textureLoadingQueue != nil && Context.textureLoadingQueue.Length() > 0 { + for Context.textureLoadingQueue.Length() > 0 { + request := Context.textureLoadingQueue.Remove().(textureLoadRequest) + NewTextureFromRgba(request.img, request.cb) + } + } + w.run() Context.isAlive = false diff --git a/Texture.go b/Texture.go index 1d1acdcb..abdc9573 100644 --- a/Texture.go +++ b/Texture.go @@ -15,11 +15,20 @@ type Texture struct { id imgui.TextureID } +type textureLoadRequest struct { + img image.Image + cb func(*Texture) +} + type loadImageResult struct { id imgui.TextureID err error } +func EnqueueNewTextureFromRgba(rgba image.Image, loadCb func(t *Texture)) { + Context.textureLoadingQueue.Add(textureLoadRequest{rgba, loadCb}) +} + // NewTextureFromRgba creates a new texture from image.Image and, when it is done, calls loadCallback(loadedTexture). func NewTextureFromRgba(rgba image.Image, loadCallback func(*Texture)) { Assert(Context.isRunning, "", "NewTextureFromRgba", "cannot load texture befor (*MasterWindow).Run call!") diff --git a/examples/loadimage/loadimage.go b/examples/loadimage/loadimage.go index 0a1ff885..aa5b3c4d 100644 --- a/examples/loadimage/loadimage.go +++ b/examples/loadimage/loadimage.go @@ -10,10 +10,15 @@ import ( g "github.com/AllenDang/giu" ) -var rgba *image.RGBA +var ( + rgba *image.RGBA + tex *g.Texture +) func loop() { g.SingleWindow().Layout( + g.Label("Display image from texture"), + g.Image(tex), g.Label("Display image from rgba"), g.ImageWithRgba(rgba).OnClick(func() { fmt.Println("rgba image was clicked") @@ -63,5 +68,8 @@ func main() { wnd := g.NewMasterWindow("Load Image", 600, 500, g.MasterWindowFlagsNotResizable) wnd.SetIcon([]image.Image{rgba}) + g.EnqueueNewTextureFromRgba(rgba, func(t *g.Texture) { + tex = t + }) wnd.Run(loop) } diff --git a/go.mod b/go.mod index 7790e023..3e660646 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/sahilm/fuzzy v0.1.0 github.com/stretchr/testify v1.7.0 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d + gopkg.in/eapache/queue.v1 v1.1.0 ) require ( diff --git a/go.sum b/go.sum index e94fbe18..0e38e031 100644 --- a/go.sum +++ b/go.sum @@ -30,5 +30,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/eapache/queue.v1 v1.1.0 h1:EldqoJEGtXYiVCMRo2C9mePO2UUGnYn2+qLmlQSqPdc= +gopkg.in/eapache/queue.v1 v1.1.0/go.mod h1:wNtmx1/O7kZSR9zNT1TTOJ7GLpm3Vn7srzlfylFbQwU= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From c1653cf9022cdac98752b0d74a9bf6ceb3983a5d Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 18:15:33 +0100 Subject: [PATCH 112/146] texture: add comments and nil checks --- MasterWindow.go | 4 ++-- Texture.go | 4 ++++ examples/loadimage/loadimage.go | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index 85ac4b02..9ccda58a 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -233,8 +233,6 @@ func (w *MasterWindow) run() { <-ticker.C } - - Context.isRunning = false } // GetSize return size of master window. @@ -328,6 +326,8 @@ func (w *MasterWindow) Run(loopFunc func()) { imgui.ImPlotDestroyContext() w.context.Destroy() }) + + Context.isRunning = false }) } diff --git a/Texture.go b/Texture.go index abdc9573..fbfa665c 100644 --- a/Texture.go +++ b/Texture.go @@ -25,7 +25,11 @@ type loadImageResult struct { err error } +// EnqueueNewTextureFromRgba adds loading texture request to loading queue +// it allows us to run this method in main loop +// NOTE: remember to call it after NewMasterWindow! func EnqueueNewTextureFromRgba(rgba image.Image, loadCb func(t *Texture)) { + Assert((Context.textureLoadingQueue != nil), "", "EnqueueNewTextureFromRgba", "you need to call EnqueueNewTextureFromRgba after giu.NewMasterWindow call!") Context.textureLoadingQueue.Add(textureLoadRequest{rgba, loadCb}) } diff --git a/examples/loadimage/loadimage.go b/examples/loadimage/loadimage.go index aa5b3c4d..ef36a0cb 100644 --- a/examples/loadimage/loadimage.go +++ b/examples/loadimage/loadimage.go @@ -67,9 +67,9 @@ func main() { rgba, _ = g.LoadImage("./fallback.png") wnd := g.NewMasterWindow("Load Image", 600, 500, g.MasterWindowFlagsNotResizable) - wnd.SetIcon([]image.Image{rgba}) g.EnqueueNewTextureFromRgba(rgba, func(t *g.Texture) { tex = t }) + wnd.SetIcon([]image.Image{rgba}) wnd.Run(loop) } From e1ee5f6c540a151a51c35969f5de4a7765835ec4 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 18:20:17 +0100 Subject: [PATCH 113/146] all: fix linter error --- MasterWindow.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MasterWindow.go b/MasterWindow.go index 9ccda58a..2091e856 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -309,7 +309,8 @@ func (w *MasterWindow) Run(loopFunc func()) { // process texture load requests if Context.textureLoadingQueue != nil && Context.textureLoadingQueue.Length() > 0 { for Context.textureLoadingQueue.Length() > 0 { - request := Context.textureLoadingQueue.Remove().(textureLoadRequest) + request, ok := Context.textureLoadingQueue.Remove().(textureLoadRequest) + Assert(ok, "MasterWindow", "Run", "processing texture requests: wrong type of texture request") NewTextureFromRgba(request.img, request.cb) } } From eab3d0019068ed0afd833e27585de36a2566987c Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 18:22:34 +0100 Subject: [PATCH 114/146] masterwindow: put texture load queue process inside of main loop --- MasterWindow.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index 2091e856..5a798b77 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -225,6 +225,15 @@ func (w *MasterWindow) run() { shouldQuit := false for !shouldQuit { mainthread.Call(func() { + // process texture load requests + if Context.textureLoadingQueue != nil && Context.textureLoadingQueue.Length() > 0 { + for Context.textureLoadingQueue.Length() > 0 { + request, ok := Context.textureLoadingQueue.Remove().(textureLoadRequest) + Assert(ok, "MasterWindow", "Run", "processing texture requests: wrong type of texture request") + NewTextureFromRgba(request.img, request.cb) + } + } + p.ProcessEvents() w.render() @@ -306,15 +315,6 @@ func (w *MasterWindow) Run(loopFunc func()) { Context.isAlive = true - // process texture load requests - if Context.textureLoadingQueue != nil && Context.textureLoadingQueue.Length() > 0 { - for Context.textureLoadingQueue.Length() > 0 { - request, ok := Context.textureLoadingQueue.Remove().(textureLoadRequest) - Assert(ok, "MasterWindow", "Run", "processing texture requests: wrong type of texture request") - NewTextureFromRgba(request.img, request.cb) - } - } - w.run() Context.isAlive = false From c71f6eb80213cfda0d2bcc9ccdbcd85327caa1c3 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 20:24:47 +0100 Subject: [PATCH 115/146] package: add appripiate ld flag for static linking on for windows --- build_windows.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 build_windows.go diff --git a/build_windows.go b/build_windows.go new file mode 100644 index 00000000..7a617460 --- /dev/null +++ b/build_windows.go @@ -0,0 +1,5 @@ +//go:build windows +package giu + +// #cgo LDFLAGS: -static +import "C" From 590fb37a843a34ee7afe9fad90f159b73928d3f5 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sun, 6 Feb 2022 20:56:13 +0100 Subject: [PATCH 116/146] attempt to fix workflow; add missing +build comment --- build_windows.go | 1 + 1 file changed, 1 insertion(+) diff --git a/build_windows.go b/build_windows.go index 7a617460..ed230bd2 100644 --- a/build_windows.go +++ b/build_windows.go @@ -1,4 +1,5 @@ //go:build windows +//+build windows package giu // #cgo LDFLAGS: -static From 0a0092147f4e658b1730c3d22a3bf0b6981f814e Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Mon, 7 Feb 2022 09:58:34 +0100 Subject: [PATCH 117/146] workflows: update golang version --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 54c8fb9a..c12119e6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go environment uses: actions/setup-go@v2.1.5 with: - go-version: 1.16.x + go-version: 1.17.x id: go - name: Cache Go modules From fc249d6e38f3fde8ce912c48d8075fb9695c6dcb Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Mon, 7 Feb 2022 10:06:17 +0100 Subject: [PATCH 118/146] build: add missing blank line --- build_windows.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build_windows.go b/build_windows.go index ed230bd2..8d946295 100644 --- a/build_windows.go +++ b/build_windows.go @@ -1,5 +1,6 @@ //go:build windows -//+build windows +// +build windows + package giu // #cgo LDFLAGS: -static From c3062a56b978a457422fd069b16b054cdd2c4985 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 10:16:39 +0100 Subject: [PATCH 119/146] alignment: add manual alignment feature --- Alignment.go | 30 ++++++++++++++++++++++++++++++ examples/align/align.go | 3 +++ 2 files changed, 33 insertions(+) diff --git a/Alignment.go b/Alignment.go index 9945df5f..00cab253 100644 --- a/Alignment.go +++ b/Alignment.go @@ -20,6 +20,36 @@ const ( AlignRight ) +// AlignManually allows to apply alignment manually. +// As long as AlignSetter is really EXPERIMENTAL feature +// and may fail randomly, the following method is supposed to +// always work, as long as you set it up correctly. +// To use it just pass a single widget with its exact width. +// be sure to apply widget's size by using "Size" method! +func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32) Widget { + return Custom(func() { + spacingX, _ := GetItemSpacing() + availableW, _ := GetAvailableRegion() + + var dummyX float32 + + switch alignmentType { + case AlignLeft: + widget.Build() + return + case AlignCenter: + dummyX = (availableW-widgetW)/2 - spacingX + case AlignRight: + dummyX = availableW - widgetW - spacingX + } + + Row( + Dummy(dummyX, 0), + widget, + ).Build() + }) +} + var _ Widget = &AlignmentSetter{} // AlignmentSetter allows to align to right / center a widget or widgets group. diff --git a/examples/align/align.go b/examples/align/align.go index 76b4de32..a0464e93 100644 --- a/examples/align/align.go +++ b/examples/align/align.go @@ -31,6 +31,9 @@ func loop() { giu.Button("button 2"), ), ), + + giu.Label("manual alignment"), + giu.AlignManually(giu.AlignCenter, giu.Button("I'm button with 100 width").Size(100, 30), 100), ) } From 7ede2d30d52bcc0856f2d7254bb7c0ed7cc751fe Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 10:41:45 +0100 Subject: [PATCH 120/146] align setter (manual): add possibility to enforce width setting of item --- Alignment.go | 23 ++++++++++++++++++----- examples/align/align.go | 12 +++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Alignment.go b/Alignment.go index 00cab253..917c869d 100644 --- a/Alignment.go +++ b/Alignment.go @@ -26,7 +26,12 @@ const ( // always work, as long as you set it up correctly. // To use it just pass a single widget with its exact width. // be sure to apply widget's size by using "Size" method! -func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32) Widget { +// forceApplyWidth argument allows you to ask giu to force-set width +// of `widget` +// NOTE that it doesn't work for each widget type! FOr example +// Button won't work because its size is set by argument to imgui call +// not PUshWidth api +func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, forceApplyWidth bool) Widget { return Custom(func() { spacingX, _ := GetItemSpacing() availableW, _ := GetAvailableRegion() @@ -43,10 +48,18 @@ func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32) dummyX = availableW - widgetW - spacingX } - Row( - Dummy(dummyX, 0), - widget, - ).Build() + Dummy(dummyX, 0).Build() + + if forceApplyWidth { + PushItemWidth(widgetW) + } + + imgui.SameLine() + widget.Build() + + if forceApplyWidth { + PopItemWidth() + } }) } diff --git a/examples/align/align.go b/examples/align/align.go index a0464e93..91d92049 100644 --- a/examples/align/align.go +++ b/examples/align/align.go @@ -33,7 +33,17 @@ func loop() { ), giu.Label("manual alignment"), - giu.AlignManually(giu.AlignCenter, giu.Button("I'm button with 100 width").Size(100, 30), 100), + giu.AlignManually( + giu.AlignCenter, + giu.Button("I'm button with 100 width"). + Size(100, 30), + 100, false, + ), + giu.AlignManually( + giu.AlignCenter, + giu.InputText(&text), + 100, true, + ), ) } From 2510057e01123f94b2c068abc5a3b0625e964199 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 10:47:52 +0100 Subject: [PATCH 121/146] minor fix in comment --- Alignment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alignment.go b/Alignment.go index 917c869d..2ff1cd22 100644 --- a/Alignment.go +++ b/Alignment.go @@ -28,7 +28,7 @@ const ( // be sure to apply widget's size by using "Size" method! // forceApplyWidth argument allows you to ask giu to force-set width // of `widget` -// NOTE that it doesn't work for each widget type! FOr example +// NOTE that forcing width doesn't work for each widget type! FOr example // Button won't work because its size is set by argument to imgui call // not PUshWidth api func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, forceApplyWidth bool) Widget { From 397a6a046ef1e1ad766f26f602e3973cb7e5c830 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 10:56:18 +0100 Subject: [PATCH 122/146] fix lint error --- Alignment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alignment.go b/Alignment.go index 2ff1cd22..627455a4 100644 --- a/Alignment.go +++ b/Alignment.go @@ -30,7 +30,7 @@ const ( // of `widget` // NOTE that forcing width doesn't work for each widget type! FOr example // Button won't work because its size is set by argument to imgui call -// not PUshWidth api +// not PUshWidth api. func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, forceApplyWidth bool) Widget { return Custom(func() { spacingX, _ := GetItemSpacing() From e5990bc2bcf344f47169aebc517e298a4398921f Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 10:59:08 +0100 Subject: [PATCH 123/146] AlignManually: minor fix use PopItemWidth() in defer statement to avoid duplication of if statement --- Alignment.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Alignment.go b/Alignment.go index 627455a4..6be70950 100644 --- a/Alignment.go +++ b/Alignment.go @@ -52,14 +52,11 @@ func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, if forceApplyWidth { PushItemWidth(widgetW) + defer PopItemWidth() } imgui.SameLine() widget.Build() - - if forceApplyWidth { - PopItemWidth() - } }) } From 6c9f66fe276c07d163f70f0ad93b419c3585aeb6 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 11:49:03 +0100 Subject: [PATCH 124/146] alignment: fix typo in comment --- Alignment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alignment.go b/Alignment.go index 6be70950..bb9ffb7d 100644 --- a/Alignment.go +++ b/Alignment.go @@ -30,7 +30,7 @@ const ( // of `widget` // NOTE that forcing width doesn't work for each widget type! FOr example // Button won't work because its size is set by argument to imgui call -// not PUshWidth api. +// not PushWidth api. func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, forceApplyWidth bool) Widget { return Custom(func() { spacingX, _ := GetItemSpacing() From ebf9d50945ca3661a82bef679682f6b52fa35699 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 11:57:50 +0100 Subject: [PATCH 125/146] fix another typo --- Alignment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Alignment.go b/Alignment.go index bb9ffb7d..5fe020cf 100644 --- a/Alignment.go +++ b/Alignment.go @@ -28,7 +28,7 @@ const ( // be sure to apply widget's size by using "Size" method! // forceApplyWidth argument allows you to ask giu to force-set width // of `widget` -// NOTE that forcing width doesn't work for each widget type! FOr example +// NOTE that forcing width doesn't work for each widget type! For example // Button won't work because its size is set by argument to imgui call // not PushWidth api. func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, forceApplyWidth bool) Widget { From e617a7be9ddc07b79d2c8dc6f2597fd035e246ca Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 11:58:34 +0100 Subject: [PATCH 126/146] AlignManually: rename argument: widgetW -> widgetWidth --- Alignment.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Alignment.go b/Alignment.go index 5fe020cf..6667710a 100644 --- a/Alignment.go +++ b/Alignment.go @@ -31,7 +31,7 @@ const ( // NOTE that forcing width doesn't work for each widget type! For example // Button won't work because its size is set by argument to imgui call // not PushWidth api. -func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, forceApplyWidth bool) Widget { +func AlignManually(alignmentType AlignmentType, widget Widget, widgetWidth float32, forceApplyWidth bool) Widget { return Custom(func() { spacingX, _ := GetItemSpacing() availableW, _ := GetAvailableRegion() @@ -43,15 +43,15 @@ func AlignManually(alignmentType AlignmentType, widget Widget, widgetW float32, widget.Build() return case AlignCenter: - dummyX = (availableW-widgetW)/2 - spacingX + dummyX = (availableW-widgetWidth)/2 - spacingX case AlignRight: - dummyX = availableW - widgetW - spacingX + dummyX = availableW - widgetWidth - spacingX } Dummy(dummyX, 0).Build() if forceApplyWidth { - PushItemWidth(widgetW) + PushItemWidth(widgetWidth) defer PopItemWidth() } From b02a5f41bd2c9a34e2632ea00935985700771656 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Feb 2022 14:22:03 +0000 Subject: [PATCH 127/146] build(deps): bump actions/setup-go from 2.1.5 to 2.2.0 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2.1.5 to 2.2.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2.1.5...v2.2.0) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/coverage.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c12119e6..716a1d41 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ jobs: sudo apt-get --allow-releaseinfo-change update sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - name: Set up Go environment - uses: actions/setup-go@v2.1.5 + uses: actions/setup-go@v2.2.0 with: go-version: 1.17.x id: go diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 3f724570..cf9b44e0 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2.3.5 with: fetch-depth: 2 - - uses: actions/setup-go@v2.1.5 + - uses: actions/setup-go@v2.2.0 with: go-version: '1.16' - name: Run coverage From d21138fdfb17dc3e7b85bda45b459ecada1a463d Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 9 Feb 2022 16:26:13 +0100 Subject: [PATCH 128/146] update issue template for bug report --- .github/ISSUE_TEMPLATE/bug_report.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5edd255a..033f46fa 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -52,7 +52,10 @@ body: description: What version of giu are you running? options: - master - - v0.5.6 (latest) + - (latest) + - v0.6.1 + - v0.6 + - v0.5.6 validations: required: true - type: input From e8c0164415af3960090f53d287fc739e9e353aec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Feb 2022 14:21:15 +0000 Subject: [PATCH 129/146] build(deps): bump golangci/golangci-lint-action from 2.5.2 to 3 Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 2.5.2 to 3. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/v2.5.2...v3) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/golangci-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index cff6ac64..6b5b367a 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -19,7 +19,7 @@ jobs: sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - uses: actions/checkout@v2.3.5 - name: golangci-lint - uses: golangci/golangci-lint-action@v2.5.2 + uses: golangci/golangci-lint-action@v3 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version version: v1.44.0 From 58ed743c67b7502e53831f48dda0699139ae6ecc Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Fri, 25 Feb 2022 16:16:50 +0100 Subject: [PATCH 130/146] readme: update installation instruction for linux --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index ffef0d46..fefdf689 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,13 @@ First you need to install the required dependencies: # apt install libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libglx-dev libgl1-mesa-dev libxxf86vm-dev ``` +on Red Hat based distributions: +```bash +sudo dnf install libX11-devel libXcursor-devel libXrandr-devel libXinerama-devel libXi-devel libGL-devel libXxf86vm-devel +``` + +you may also need to install C/C++ compiller (like g++) if it isn't already installed. Follow go compilator prompts. + Then, a simple `go build` will work. Cross-compiling is a bit more complicated. Let's say that you want to build for arm64. This is what you would need to do: From 1ae71b9863607b4ed1e65664bc44cd8066fcacc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Feb 2022 14:24:54 +0000 Subject: [PATCH 131/146] build(deps): bump actions/setup-go from 2.2.0 to 3 Bumps [actions/setup-go](https://github.com/actions/setup-go) from 2.2.0 to 3. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v2.2.0...v3) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/coverage.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 716a1d41..93fe30e7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ jobs: sudo apt-get --allow-releaseinfo-change update sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - name: Set up Go environment - uses: actions/setup-go@v2.2.0 + uses: actions/setup-go@v3 with: go-version: 1.17.x id: go diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index cf9b44e0..36b9bf55 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v2.3.5 with: fetch-depth: 2 - - uses: actions/setup-go@v2.2.0 + - uses: actions/setup-go@v3 with: go-version: '1.16' - name: Run coverage From 34bcde3a4556680f2df5f4dc75990689e4c581b5 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Mon, 28 Feb 2022 16:43:40 +0100 Subject: [PATCH 132/146] golangci-lint workflow: brump linter ersion to v1.44.2 --- .github/workflows/golangci-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 6b5b367a..27b112e4 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -22,7 +22,7 @@ jobs: uses: golangci/golangci-lint-action@v3 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.44.0 + version: v1.44.2 # Optional: working directory, useful for monorepos # working-directory: somedir From 2137ee922844bed49f3217ecfeb04b8d04ef3c3d Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Mon, 28 Feb 2022 17:07:58 +0100 Subject: [PATCH 133/146] golangci-lint-action: add setup-go step --- .github/workflows/golangci-lint.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 27b112e4..9866790d 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -13,6 +13,9 @@ jobs: name: lint runs-on: ubuntu-latest steps: + - uses: actions/setup-go@v3 + with: + go-version: '1.17.x' - name: Set up LibGL, Mesa & X11 libraries run: | sudo apt-get --allow-releaseinfo-change update @@ -33,9 +36,6 @@ jobs: # Optional: show only new issues if it's a pull request. The default value is `false`. # only-new-issues: true - # Optional: if set to true then the action will use pre-installed Go. - # skip-go-installation: true - # Optional: if set to true then the action don't cache or restore ~/go/pkg. # skip-pkg-cache: true From 9670e644ee70573000c722eb1aced152be1496c0 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Mon, 28 Feb 2022 17:37:15 +0100 Subject: [PATCH 134/146] attempt to fix golangci-lint workflow --- .github/workflows/golangci-lint.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 9866790d..6b339530 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -14,8 +14,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/setup-go@v3 - with: - go-version: '1.17.x' + with: + go-version: '1.17.x' - name: Set up LibGL, Mesa & X11 libraries run: | sudo apt-get --allow-releaseinfo-change update @@ -40,4 +40,5 @@ jobs: # skip-pkg-cache: true # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true From 654ebe76341ee7f97f7d0b5fb31c1f988a67061a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 14:29:40 +0000 Subject: [PATCH 135/146] build(deps): bump actions/checkout from 2.3.5 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.5 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2.3.5...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- .github/workflows/coverage.yaml | 2 +- .github/workflows/golangci-lint.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 93fe30e7..414ae55d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,7 +19,7 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - name: Checkout out source code - uses: actions/checkout@v2.3.5 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: 'true' diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 36b9bf55..a87d9381 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -10,7 +10,7 @@ jobs: run: | sudo apt-get --allow-releaseinfo-change update sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v3 with: fetch-depth: 2 - uses: actions/setup-go@v3 diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 6b5b367a..7e1978b8 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -17,7 +17,7 @@ jobs: run: | sudo apt-get --allow-releaseinfo-change update sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - - uses: actions/checkout@v2.3.5 + - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: From a6133b487b37459d592ac4c77073d3ff2f63045c Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Fri, 11 Mar 2022 07:48:20 +0100 Subject: [PATCH 136/146] readme: minor fixes and updates --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fefdf689..78c6eddc 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Here is the result: ### What is immediate mode GUI? -Immediate mode GUI system means the UI control doesn't retain its state and value. For example, calling `giu.InputText("ID", &str)` will display a input text box on screen, and the user entered value will be stored in `&str`. Input text box doesn't know anything about it. +Immediate mode GUI system means the UI control doesn't retain its state and value. For example, calling `giu.InputText(&str)` will display a input text box on screen, and the user entered value will be stored in `&str`. Input text box doesn't know anything about it. And the `loop` method in the _Hello world_ example is in charge of **drawing** all widgets based on the parameters passed into them. This method will be invoked 30 times per second to reflect interactive states (like clicked, hovered, value-changed, etc.). It will be the place you define the UI structure. @@ -144,7 +144,7 @@ Or, install [TDM-GCC](https://jmeubank.github.io/tdm-gcc/). First you need to install the required dependencies: ```bash -# apt install libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libglx-dev libgl1-mesa-dev libxxf86vm-dev +sudo apt install libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev libglx-dev libgl1-mesa-dev libxxf86vm-dev ``` on Red Hat based distributions: @@ -159,11 +159,11 @@ Then, a simple `go build` will work. Cross-compiling is a bit more complicated. Let's say that you want to build for arm64. This is what you would need to do: ```bash -# dpkg --add-architecture arm64 -# apt update -# apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ +sudo dpkg --add-architecture arm64 +sudo apt update +sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ libx11-dev:arm64 libxcursor-dev:arm64 libxrandr-dev:arm64 libxinerama-dev:arm64 libxi-dev:arm64 libglx-dev:arm64 libgl1-mesa-dev:arm64 libxxf86vm-dev:arm64 -$ GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ HOST=aarch64-linux-gnu go build -v +GOOS=linux GOARCH=arm64 CGO_ENABLED=1 CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ HOST=aarch64-linux-gnu go build -v ``` ## Deploying From 69afcecb464a3c4a23c950bf058973bf94b88394 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 16 Mar 2022 16:36:28 +0100 Subject: [PATCH 137/146] go mod: update to go 1.18 --- go.mod | 6 +++--- go.sum | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3e660646..c362d0e3 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/AllenDang/giu -go 1.17 +go 1.18 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 @@ -10,7 +10,7 @@ require ( github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 github.com/stretchr/testify v1.7.0 - golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d + golang.org/x/image v0.0.0-20220302094943-723b81ca9867 gopkg.in/eapache/queue.v1 v1.1.0 ) @@ -19,6 +19,6 @@ require ( github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 // indirect + golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index 0e38e031..7adf5bd1 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,12 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4= +golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= From 45c4704584a1d61e4d21942f01d78908c6736bf7 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 16 Mar 2022 16:41:15 +0100 Subject: [PATCH 138/146] all: replace interface{} with new, go 1.18 `any` --- ClickableWidgets.go | 8 ++++---- Context.go | 6 +++--- ExtraWidgets.go | 2 +- FontAtlasProsessor.go | 2 +- SliderWidgets.go | 6 +++--- Style.go | 4 ++-- TextWidgets.go | 12 ++++++------ Texture.go | 2 +- Utils.go | 4 ++-- Widgets.go | 10 +++++----- 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/ClickableWidgets.go b/ClickableWidgets.go index ce7c81ca..9fe611aa 100644 --- a/ClickableWidgets.go +++ b/ClickableWidgets.go @@ -32,7 +32,7 @@ func Button(label string) *ButtonWidget { // Buttonf creates button with formated label // NOTE: works like fmt.Sprintf (see `go doc fmt`). -func Buttonf(format string, args ...interface{}) *ButtonWidget { +func Buttonf(format string, args ...any) *ButtonWidget { return Button(fmt.Sprintf(format, args...)) } @@ -123,7 +123,7 @@ func SmallButton(id string) *SmallButtonWidget { // SmallButtonf allows to set formated label for small button. // It calls SmallButton(fmt.Sprintf(label, args...)). -func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { +func SmallButtonf(format string, args ...any) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } @@ -436,7 +436,7 @@ func Selectable(label string) *SelectableWidget { } // Selectablef creates a selectable widget with formated label. -func Selectablef(format string, args ...interface{}) *SelectableWidget { +func Selectablef(format string, args ...any) *SelectableWidget { return Selectable(fmt.Sprintf(format, args...)) } @@ -511,7 +511,7 @@ func TreeNode(label string) *TreeNodeWidget { } // TreeNodef adds TreeNode with formatted label. -func TreeNodef(format string, args ...interface{}) *TreeNodeWidget { +func TreeNodef(format string, args ...any) *TreeNodeWidget { return TreeNode(fmt.Sprintf(format, args...)) } diff --git a/Context.go b/Context.go index 0d8a3d6f..7880e946 100644 --- a/Context.go +++ b/Context.go @@ -55,7 +55,7 @@ func (c *context) IO() imgui.IO { } func (c *context) invalidAllState() { - c.state.Range(func(k, v interface{}) bool { + c.state.Range(func(k, v any) bool { if s, ok := v.(*state); ok { s.valid = false } @@ -64,7 +64,7 @@ func (c *context) invalidAllState() { } func (c *context) cleanState() { - c.state.Range(func(k, v interface{}) bool { + c.state.Range(func(k, v any) bool { if s, ok := v.(*state); ok { if !s.valid { c.state.Delete(k) @@ -82,7 +82,7 @@ func (c *context) SetState(id string, data Disposable) { c.state.Store(id, &state{valid: true, data: data}) } -func (c *context) GetState(id string) interface{} { +func (c *context) GetState(id string) any { if v, ok := c.state.Load(id); ok { if s, ok := v.(*state); ok { s.valid = true diff --git a/ExtraWidgets.go b/ExtraWidgets.go index eab9075a..03ff248b 100644 --- a/ExtraWidgets.go +++ b/ExtraWidgets.go @@ -347,7 +347,7 @@ func (c *ConditionWidget) Build() { } // RangeBuilder batch create widgets and render only which is visible. -func RangeBuilder(id string, values []interface{}, builder func(int, interface{}) Widget) Layout { +func RangeBuilder(id string, values []any, builder func(int, any) Widget) Layout { var layout Layout layout = append(layout, Custom(func() { imgui.PushID(id) })) diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index 86e8adae..ed216531 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -219,7 +219,7 @@ func rebuildFontAtlas() { var sb strings.Builder - stringMap.Range(func(k, v interface{}) bool { + stringMap.Range(func(k, v any) bool { stringMap.Store(k, true) if ks, ok := k.(rune); ok { sb.WriteRune(ks) diff --git a/SliderWidgets.go b/SliderWidgets.go index 70465a9a..109d5c6a 100644 --- a/SliderWidgets.go +++ b/SliderWidgets.go @@ -60,7 +60,7 @@ func (s *SliderIntWidget) Label(label string) *SliderIntWidget { } // Labelf sets formated label. -func (s *SliderIntWidget) Labelf(format string, args ...interface{}) *SliderIntWidget { +func (s *SliderIntWidget) Labelf(format string, args ...any) *SliderIntWidget { return s.Label(fmt.Sprintf(format, args...)) } @@ -136,7 +136,7 @@ func (vs *VSliderIntWidget) Label(label string) *VSliderIntWidget { } // Labelf sets formated label. -func (vs *VSliderIntWidget) Labelf(format string, args ...interface{}) *VSliderIntWidget { +func (vs *VSliderIntWidget) Labelf(format string, args ...any) *VSliderIntWidget { return vs.Label(fmt.Sprintf(format, args...)) } @@ -209,7 +209,7 @@ func (sf *SliderFloatWidget) Label(label string) *SliderFloatWidget { } // Labelf sets formated label. -func (sf *SliderFloatWidget) Labelf(format string, args ...interface{}) *SliderFloatWidget { +func (sf *SliderFloatWidget) Labelf(format string, args ...any) *SliderFloatWidget { return sf.Label(fmt.Sprintf(format, args...)) } diff --git a/Style.go b/Style.go index 97fd32f4..f6fcb812 100644 --- a/Style.go +++ b/Style.go @@ -359,7 +359,7 @@ var _ Widget = &StyleSetter{} // StyleSetter is a user-friendly way to manage imgui styles. type StyleSetter struct { colors map[StyleColorID]color.Color - styles map[StyleVarID]interface{} + styles map[StyleVarID]any font *FontInfo disabled bool layout Layout @@ -369,7 +369,7 @@ type StyleSetter struct { func Style() *StyleSetter { var ss StyleSetter ss.colors = make(map[StyleColorID]color.Color) - ss.styles = make(map[StyleVarID]interface{}) + ss.styles = make(map[StyleVarID]any) return &ss } diff --git a/TextWidgets.go b/TextWidgets.go index b279f583..7179ca24 100644 --- a/TextWidgets.go +++ b/TextWidgets.go @@ -41,7 +41,7 @@ func (i *InputTextMultilineWidget) Label(label string) *InputTextMultilineWidget } // Labelf is formatting version of Label. -func (i *InputTextMultilineWidget) Labelf(format string, args ...interface{}) *InputTextMultilineWidget { +func (i *InputTextMultilineWidget) Labelf(format string, args ...any) *InputTextMultilineWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -116,7 +116,7 @@ func BulletText(text string) *BulletTextWidget { } // BulletTextf is a formatting version of BulletText. -func BulletTextf(format string, args ...interface{}) *BulletTextWidget { +func BulletTextf(format string, args ...any) *BulletTextWidget { return BulletText(fmt.Sprintf(format, args...)) } @@ -170,7 +170,7 @@ func (i *InputTextWidget) Label(label string) *InputTextWidget { } // Labelf adds formatted label. -func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextWidget { +func (i *InputTextWidget) Labelf(format string, args ...any) *InputTextWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -300,7 +300,7 @@ func (i *InputIntWidget) Label(label string) *InputIntWidget { } // Labelf sets formatted label. -func (i *InputIntWidget) Labelf(format string, args ...interface{}) *InputIntWidget { +func (i *InputIntWidget) Labelf(format string, args ...any) *InputIntWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -365,7 +365,7 @@ func (i *InputFloatWidget) Label(label string) *InputFloatWidget { } // Labelf sets formatted label. -func (i *InputFloatWidget) Labelf(format string, args ...interface{}) *InputFloatWidget { +func (i *InputFloatWidget) Labelf(format string, args ...any) *InputFloatWidget { return i.Label(fmt.Sprintf(format, args...)) } @@ -423,7 +423,7 @@ func Label(label string) *LabelWidget { } // Labelf allows to add formatted label. -func Labelf(format string, args ...interface{}) *LabelWidget { +func Labelf(format string, args ...any) *LabelWidget { return Label(fmt.Sprintf(format, args...)) } diff --git a/Texture.go b/Texture.go index fbfa665c..48dc6b64 100644 --- a/Texture.go +++ b/Texture.go @@ -42,7 +42,7 @@ func NewTextureFromRgba(rgba image.Image, loadCallback func(*Texture)) { func loadTexture(rgba image.Image, loadCallback func(*Texture)) { go func() { Update() - result := mainthread.CallVal(func() interface{} { + result := mainthread.CallVal(func() any { texID, err := Context.renderer.LoadImage(ImageToRgba(rgba)) return &loadImageResult{id: texID, err: err} }) diff --git a/Utils.go b/Utils.go index 787230e8..b5c14b02 100644 --- a/Utils.go +++ b/Utils.go @@ -194,13 +194,13 @@ func PopClipRect() { } // Assert checks if cond. If not cond, it alls golang panic. -func Assert(cond bool, t, method, msg string, args ...interface{}) { +func Assert(cond bool, t, method, msg string, args ...any) { if !cond { fatal(t, method, msg, args...) } } -func fatal(widgetName, method, message string, args ...interface{}) { +func fatal(widgetName, method, message string, args ...any) { if widgetName != "" { widgetName = fmt.Sprintf("(*%s)", widgetName) } diff --git a/Widgets.go b/Widgets.go index 917eda3d..50ef53ae 100644 --- a/Widgets.go +++ b/Widgets.go @@ -401,7 +401,7 @@ func MenuItem(label string) *MenuItemWidget { } } -func MenuItemf(format string, args ...interface{}) *MenuItemWidget { +func MenuItemf(format string, args ...any) *MenuItemWidget { return MenuItem(fmt.Sprintf(format, args...)) } @@ -443,7 +443,7 @@ func Menu(label string) *MenuWidget { } } -func Menuf(format string, args ...interface{}) *MenuWidget { +func Menuf(format string, args ...any) *MenuWidget { return Menu(fmt.Sprintf(format, args...)) } @@ -493,7 +493,7 @@ func (p *ProgressBarWidget) Overlay(overlay string) *ProgressBarWidget { return p } -func (p *ProgressBarWidget) Overlayf(format string, args ...interface{}) *ProgressBarWidget { +func (p *ProgressBarWidget) Overlayf(format string, args ...any) *ProgressBarWidget { return p.Overlay(fmt.Sprintf(format, args...)) } @@ -560,7 +560,7 @@ func TabItem(label string) *TabItemWidget { } } -func TabItemf(format string, args ...interface{}) *TabItemWidget { +func TabItemf(format string, args ...any) *TabItemWidget { return TabItem(fmt.Sprintf(format, args...)) } @@ -654,7 +654,7 @@ func Tooltip(tip string) *TooltipWidget { } } -func Tooltipf(format string, args ...interface{}) *TooltipWidget { +func Tooltipf(format string, args ...any) *TooltipWidget { return Tooltip(fmt.Sprintf(format, args...)) } From cbc525400ee95fa246269be88438087c0eaa9ed9 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 16 Mar 2022 16:43:13 +0100 Subject: [PATCH 139/146] gitignore: add idea config directory --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 2c148ca8..16914be1 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ # vim cache files *.swp +# JetBrains idea configuration +.idea + # Test binary, built with `go test -c` *.test From af9673df20b51312bdae661a9d4cd46ced15bf7f Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Wed, 16 Mar 2022 16:47:01 +0100 Subject: [PATCH 140/146] workflows: update to use go 18 --- .github/workflows/build.yml | 2 +- .github/workflows/coverage.yaml | 2 +- .github/workflows/golangci-lint.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 414ae55d..1314b8f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: - name: Set up Go environment uses: actions/setup-go@v3 with: - go-version: 1.17.x + go-version: 1.18.x id: go - name: Cache Go modules diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index a87d9381..2844aeb7 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -15,7 +15,7 @@ jobs: fetch-depth: 2 - uses: actions/setup-go@v3 with: - go-version: '1.16' + go-version: '1.18.x' - name: Run coverage run: go test -race -coverprofile=coverage.txt -covermode=atomic - name: Upload coverage to Codecov diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 1386a863..2f99b16f 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -15,7 +15,7 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.17.x' + go-version: '1.18.x' - name: Set up LibGL, Mesa & X11 libraries run: | sudo apt-get --allow-releaseinfo-change update From 1b7dc95d50078a30aff858c686c8167aea01c5d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Mar 2022 15:33:10 +0100 Subject: [PATCH 141/146] build(deps): bump github.com/stretchr/testify from 1.7.0 to 1.7.1 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.0 to 1.7.1. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.7.0...v1.7.1) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 3e660646..1dddd6dc 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d gopkg.in/eapache/queue.v1 v1.1.0 ) diff --git a/go.sum b/go.sum index 0e38e031..723fbb70 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI= github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= From ac2ffda6549fe63008f60969cea2ae6d1344016e Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sat, 19 Mar 2022 11:45:29 +0100 Subject: [PATCH 142/146] readme: add cross-building instruction for linux --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 78c6eddc..5e0eadcf 100644 --- a/README.md +++ b/README.md @@ -180,14 +180,21 @@ go build -ldflags "-s -w" . go build -ldflags "-s -w -H=windowsgui -extldflags=-static" . ``` -### Build Windows version on MacOS. +### Build Windows version on MacOS/Linux. 1. Install mingw-64. +on Mac: ```sh brew install mingw-w64 ``` +on Linux: + +```sh +sudo dnf install mingw64-gcc mingw64-gcc-c++ mingw-winpthreads-static +``` + 2. Prepare and embed the application icon into the executable and build. ```sh From 02e72d9237d62767afa1637e6189aeffd2e50b47 Mon Sep 17 00:00:00 2001 From: gucio321 <73652197+gucio321@users.noreply.github.com> Date: Sat, 19 Mar 2022 14:18:11 +0100 Subject: [PATCH 143/146] fonts: fix SetSize method didn't worked --- FontAtlasProsessor.go | 9 +++++++++ Style.go | 15 ++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index 86e8adae..be5e5e78 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -40,7 +40,15 @@ func (f *FontInfo) String() string { func (f *FontInfo) SetSize(size float32) *FontInfo { result := *f result.size = size + + for _, i := range extraFonts { + if i.String() == result.String() { + return &result + } + } + extraFonts = append(extraFonts, result) + shouldRebuildFontAtlas = true return &result } @@ -285,6 +293,7 @@ func rebuildFontAtlas() { } else { f = fonts.AddFontFromMemoryTTFV(fontInfo.fontByte, fontInfo.size, imgui.DefaultFontConfig, ranges.Data()) } + extraFontMap[fontInfo.String()] = &f } diff --git a/Style.go b/Style.go index 97fd32f4..0971c1cb 100644 --- a/Style.go +++ b/Style.go @@ -411,11 +411,7 @@ func (ss *StyleSetter) SetFontSize(size float32) *StyleSetter { font = defaultFonts[0] } - font.size = size - - extraFonts = append(extraFonts, font) - - ss.font = &font + ss.font = font.SetSize(size) return ss } @@ -466,9 +462,10 @@ func (ss *StyleSetter) Build() { } } - isFontPushed := false if ss.font != nil { - isFontPushed = PushFont(ss.font) + if PushFont(ss.font) { + defer PopFont() + } } imgui.BeginDisabled(ss.disabled) @@ -477,10 +474,6 @@ func (ss *StyleSetter) Build() { imgui.EndDisabled() - if isFontPushed { - PopFont() - } - imgui.PopStyleColorV(len(ss.colors)) imgui.PopStyleVarV(len(ss.styles)) } From 2c70cfcf45e8f29a9fd3431abba724a0bfbe110c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 14:27:22 +0000 Subject: [PATCH 144/146] build(deps): bump actions/cache from 2.1.7 to 3 Bumps [actions/cache](https://github.com/actions/cache) from 2.1.7 to 3. - [Release notes](https://github.com/actions/cache/releases) - [Commits](https://github.com/actions/cache/compare/v2.1.7...v3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 414ae55d..8fdab0ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -36,7 +36,7 @@ jobs: id: go - name: Cache Go modules - uses: actions/cache@v2.1.7 + uses: actions/cache@v3 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} From b46ea41be0f64854eefcc75cda8bc694c470dbe9 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 22 Mar 2022 09:04:00 +0100 Subject: [PATCH 145/146] workflows: update golangci lint version --- .github/workflows/golangci-lint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index 2f99b16f..19d41cfb 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -25,7 +25,7 @@ jobs: uses: golangci/golangci-lint-action@v3 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version - version: v1.44.2 + version: v1.45 # Optional: working directory, useful for monorepos # working-directory: somedir From 106202cd7fa8e8e005342f87dfb5a1501c0667a8 Mon Sep 17 00:00:00 2001 From: Allen Dang Date: Tue, 22 Mar 2022 19:45:26 +0800 Subject: [PATCH 146/146] Solve #30 --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3e660646..a549c81b 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,9 @@ go 1.17 require ( github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 - github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2 + github.com/AllenDang/imgui-go v1.12.1-0.20220322114136-499bbf6a42ad github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 - github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec + github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220320163800-277f93cfa958 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/sahilm/fuzzy v0.1.0 github.com/stretchr/testify v1.7.0 diff --git a/go.sum b/go.sum index 0e38e031..5ab3b02b 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,16 @@ github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8 h1:dKZMqib/yUDoCFigmz2agG8geZ/e3iRq304/KJXqKyw= github.com/AllenDang/go-findfont v0.0.0-20200702051237-9f180485aeb8/go.mod h1:b4uuDd0s6KRIPa84cEEchdQ9ICh7K0OryZHbSzMca9k= -github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2 h1:H9Ohl0tXES9WxO3jq9HdE+4A6eXXybFmRvNdQo2GxLM= -github.com/AllenDang/imgui-go v1.12.1-0.20220118055608-8cbd98e97ca2/go.mod h1:lSWsbR1qGBZz405YzfHXcwEyWQq206QC7cYMHoLvmI4= +github.com/AllenDang/imgui-go v1.12.1-0.20220322114136-499bbf6a42ad h1:Kr961C2uEEAklK+jBRiZVnQH0AgS7o6pXrIgUTUUGiM= +github.com/AllenDang/imgui-go v1.12.1-0.20220322114136-499bbf6a42ad/go.mod h1:kuPs9RWleaUuK7D49bE6HPxyRA36Lp4ICKGp+5OnnbY= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3 h1:baVdMKlASEHrj19iqjARrPbaRisD7EuZEVJj6ZMLl1Q= github.com/faiface/mainthread v0.0.0-20171120011319-8b78f0a41ae3/go.mod h1:VEPNJUlxl5KdWjDvz6Q1l+rJlxF2i6xqDeGuGAxa87M= -github.com/go-gl/gl v0.0.0-20210315015930-ae072cafe09d/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk= github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec h1:3FLiRYO6PlQFDpUU7OEFlWgjGD1jnBIVSJ5SYRWk+9c= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220320163800-277f93cfa958 h1:TL70PMkdPCt9cRhKTqsm+giRpgrd0IGEj763nNr2VFY= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20220320163800-277f93cfa958/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=