From 34eeed6befc8d19a8c325bd7228567e20001216d Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 14 Sep 2021 20:33:18 +0200 Subject: [PATCH 01/27] eventHandler: fix golints --- EventHandler.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/EventHandler.go b/EventHandler.go index 50821c1c..e531f6d0 100644 --- a/EventHandler.go +++ b/EventHandler.go @@ -1,9 +1,12 @@ package giu +var _ Disposable = &eventHandlerState{} + type eventHandlerState struct { isActive bool } +// Dispose implements Disposable interface func (s *eventHandlerState) Dispose() { // noop } @@ -20,6 +23,8 @@ type keyEvent struct { cond func(Key) bool } +var _ Widget = &EventHandler{} + // EventHandler is a universal event handler for giu widgets. // put giu.Event()... after any widget to handle any event type EventHandler struct { @@ -30,6 +35,7 @@ type EventHandler struct { onDeactivate func() } +// Event adds a new event to widget above func Event() *EventHandler { return &EventHandler{ mouseEvents: make([]mouseEvent, 0), @@ -37,16 +43,19 @@ func Event() *EventHandler { } } +// OnHover sets callback when item gets hovered func (eh *EventHandler) OnHover(onHover func()) *EventHandler { eh.hover = onHover return eh } +// OnActivate sets callback when item gets activated func (eh *EventHandler) OnActivate(cb func()) *EventHandler { eh.onActivate = cb return eh } +// OnActivate sets callback when item gets deactivated func (eh *EventHandler) OnDeactivate(cb func()) *EventHandler { eh.onDeactivate = cb return eh @@ -54,16 +63,19 @@ func (eh *EventHandler) OnDeactivate(cb func()) *EventHandler { // Key events +// OnKeyDown sets callback when key `key` is down func (eh *EventHandler) OnKeyDown(key Key, cb func()) *EventHandler { eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyDown}) return eh } +// OnKeyDown sets callback when key `key` is pressed func (eh *EventHandler) OnKeyPressed(key Key, cb func()) *EventHandler { eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyPressed}) return eh } +// OnKeyDown sets callback when key `key` is released func (eh *EventHandler) OnKeyReleased(key Key, cb func()) *EventHandler { eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyReleased}) return eh @@ -71,26 +83,31 @@ func (eh *EventHandler) OnKeyReleased(key Key, cb func()) *EventHandler { // Mouse events +// OnKeyDown sets callback when mouse button `mouseButton` is clicked func (eh *EventHandler) OnClick(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseClicked}) return eh } +// OnKeyDown sets callback when mouse button `mouseButton` is double-clicked func (eh *EventHandler) OnDClick(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseDoubleClicked}) return eh } +// OnKeyDown sets callback when mouse button `mouseButton` is down func (eh *EventHandler) OnMouseDown(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseDown}) return eh } +// OnKeyDown sets callback when mouse button `mouseButton` is released func (eh *EventHandler) OnMouseReleased(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseReleased}) return eh } +// Build implements Widget interface func (eh *EventHandler) Build() { if eh.onActivate != nil || eh.onDeactivate != nil { isActive := IsItemActive() From cdbf8805fbe94d4229a7a9abe4096b1c83749d97 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 14 Sep 2021 20:37:22 +0200 Subject: [PATCH 02/27] layout.g,direction.go: add comments --- Direction.go | 2 ++ Layout.go | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/Direction.go b/Direction.go index 41bdc859..60ecd0de 100644 --- a/Direction.go +++ b/Direction.go @@ -1,7 +1,9 @@ package giu +// Direction represents a ArrowButton direction type Direction uint8 +// directions const ( DirectionLeft Direction = iota DirectionRight diff --git a/Layout.go b/Layout.go index dd41406c..c4a60648 100644 --- a/Layout.go +++ b/Layout.go @@ -5,12 +5,20 @@ const ( Auto float32 = -1 ) +// Widget is a base unit of giu rendering system. +// each widget just needs to implement Build method which is called, +// when widget needs to be rendered. type Widget interface { Build() } +var _ Widget = Layout{} + +// Layout is a set of widgets. It implements Widget interface so +// Layout can be used as a widget. type Layout []Widget +// Build implements Widget interface func (l Layout) Build() { for _, w := range l { if w != nil { From 9a59f791a07fea13018328e6653e5a095f465900 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 14 Sep 2021 21:10:42 +0200 Subject: [PATCH 03/27] masterWindow.go: add comments --- MasterWindow.go | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/MasterWindow.go b/MasterWindow.go index 98fd68e0..fe827692 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -10,6 +10,7 @@ import ( "github.com/AllenDang/imgui-go" ) +// MasterWindowFlags wrapps imgui.GLFWWindowFlags type MasterWindowFlags imgui.GLFWWindowFlags const ( @@ -25,10 +26,11 @@ const ( MasterWindowFlagsTransparent MasterWindowFlags = MasterWindowFlags(imgui.GLFWWindowFlagsTransparent) ) -var ( - DontCare int = imgui.GlfwDontCare -) +// DontCare could be used as an argument to (*MasterWindow).SetSizeLimits +var DontCare int = imgui.GlfwDontCare +// MasterWindow represents a glfw master window +// It is a base for a windows (see Window.go) type MasterWindow struct { width int height int @@ -41,6 +43,9 @@ type MasterWindow struct { updateFunc func() } +// MasterWindow creates a new master window and initializes GLFW. +// 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 { context := imgui.CreateContext(nil) imgui.ImPlotCreateContext() @@ -166,7 +171,7 @@ func (w *MasterWindow) setTheme() { style.ScaleAllSizes(scale) } -// Set background color of master window. +// SetBgColor sets background color of master window. func (w *MasterWindow) SetBgColor(color color.RGBA) { w.clearColor = [4]float32{float32(color.R) / 255.0, float32(color.G) / 255.0, float32(color.B) / 255.0, float32(color.A) / 255.0} } @@ -214,7 +219,7 @@ func (w *MasterWindow) run() { } } -// Return size of master window. +// GetSize return size of master window. func (w *MasterWindow) GetSize() (width, height int) { if w.platform != nil { if glfwPlatform, ok := w.platform.(*imgui.GLFW); ok { @@ -225,7 +230,7 @@ func (w *MasterWindow) GetSize() (width, height int) { return w.width, w.height } -// Return position of master window. +// GetPos return position of master window. func (w *MasterWindow) GetPos() (x, y int) { if w.platform != nil { if glfwPlatform, ok := w.platform.(*imgui.GLFW); ok { @@ -236,7 +241,7 @@ func (w *MasterWindow) GetPos() (x, y int) { return } -// Set position of master window. +// SetPos sets position of master window. func (w *MasterWindow) SetPos(x, y int) { if w.platform != nil { if glfwPlatform, ok := w.platform.(*imgui.GLFW); ok { @@ -245,6 +250,7 @@ func (w *MasterWindow) SetPos(x, y int) { } } +// SetSize sets size of master window func (w *MasterWindow) SetSize(x, y int) { if w.platform != nil { if glfwPlatform, ok := w.platform.(*imgui.GLFW); ok { @@ -272,8 +278,10 @@ func (w *MasterWindow) SetDropCallback(cb func([]string)) { w.platform.SetDropCallback(cb) } -// Call the main loop. +// Run runs the main loop. // loopFunc will be used to construct the ui. +// Run should be called at the end of main function, after setting +// up the master window. func (w *MasterWindow) Run(loopFunc func()) { mainthread.Run(func() { w.updateFunc = loopFunc @@ -295,6 +303,7 @@ func (w *MasterWindow) Run(loopFunc func()) { }) } +// RegisterKeyboardShortcuts registers a global - master window - keyboard shortcuts func (w *MasterWindow) RegisterKeyboardShortcuts(s ...WindowShortcut) *MasterWindow { for _, shortcut := range s { RegisterKeyboardShortcuts(Shortcut{ @@ -334,6 +343,7 @@ func (w *MasterWindow) SetSizeLimits(minw, minh, maxw, maxh int) { w.platform.SetSizeLimits(minw, minh, maxw, maxh) } +// SetTitle updates master window's title func (w *MasterWindow) SetTitle(title string) { w.platform.SetTitle(title) } From b40c1de1478544942bc4dfd0db6c06f0b6d3358a Mon Sep 17 00:00:00 2001 From: gucio321 Date: Tue, 14 Sep 2021 21:26:22 +0200 Subject: [PATCH 04/27] fix golints --- Canvas.go | 24 +++++------ Context.go | 2 +- Msgbox.go | 14 +++--- ProgressIndicator.go | 8 ++-- SplitLayout.go | 6 +-- Style.go | 8 ++-- Texture.go | 4 +- Widgets.go | 100 +++++++++++++++++++++---------------------- 8 files changed, 81 insertions(+), 85 deletions(-) diff --git a/Canvas.go b/Canvas.go index 5de1526e..24d8ca76 100644 --- a/Canvas.go +++ b/Canvas.go @@ -40,20 +40,20 @@ const ( DrawFlagsRoundCornersMask DrawFlags = DrawFlagsRoundCornersAll | DrawFlagsRoundCornersNone ) -func (c *Canvas) AddRect(pMin, pMax image.Point, color color.RGBA, rounding float32, rounding_corners DrawFlags, thickness float32) { - c.drawlist.AddRect(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(rounding_corners), thickness) +func (c *Canvas) AddRect(pMin, pMax image.Point, color color.RGBA, rounding float32, roundingCorners DrawFlags, thickness float32) { + c.drawlist.AddRect(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(roundingCorners), thickness) } -func (c *Canvas) AddRectFilled(pMin, pMax image.Point, color color.RGBA, rounding float32, rounding_corners DrawFlags) { - c.drawlist.AddRectFilled(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(rounding_corners)) +func (c *Canvas) AddRectFilled(pMin, pMax image.Point, color color.RGBA, rounding float32, roundingCorners DrawFlags) { + c.drawlist.AddRectFilled(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(roundingCorners)) } func (c *Canvas) AddText(pos image.Point, color color.RGBA, text string) { c.drawlist.AddText(ToVec2(pos), ToVec4Color(color), tStr(text)) } -func (c *Canvas) AddBezierCubic(pos0, cp0, cp1, pos1 image.Point, color color.RGBA, thickness float32, num_segments int) { - c.drawlist.AddBezierCubic(ToVec2(pos0), ToVec2(cp0), ToVec2(cp1), ToVec2(pos1), ToVec4Color(color), thickness, num_segments) +func (c *Canvas) AddBezierCubic(pos0, cp0, cp1, pos1 image.Point, color color.RGBA, thickness float32, numSegments int) { + c.drawlist.AddBezierCubic(ToVec2(pos0), ToVec2(cp0), ToVec2(cp1), ToVec2(pos1), ToVec4Color(color), thickness, numSegments) } func (c *Canvas) AddTriangle(p1, p2, p3 image.Point, color color.RGBA, thickness float32) { @@ -102,16 +102,16 @@ func (c *Canvas) PathStroke(color color.RGBA, closed bool, thickness float32) { c.drawlist.PathStroke(ToVec4Color(color), closed, thickness) } -func (c *Canvas) PathArcTo(center image.Point, radius, a_min, a_max float32, num_segments int) { - c.drawlist.PathArcTo(ToVec2(center), radius, a_min, a_max, num_segments) +func (c *Canvas) PathArcTo(center image.Point, radius, min, max float32, numSegments int) { + c.drawlist.PathArcTo(ToVec2(center), radius, min, max, numSegments) } -func (c *Canvas) PathArcToFast(center image.Point, radius float32, a_min_of_12, a_max_of_12 int) { - c.drawlist.PathArcToFast(ToVec2(center), radius, a_min_of_12, a_max_of_12) +func (c *Canvas) PathArcToFast(center image.Point, radius float32, min12, max12 int) { + c.drawlist.PathArcToFast(ToVec2(center), radius, min12, max12) } -func (c *Canvas) PathBezierCubicCurveTo(p1, p2, p3 image.Point, num_segments int) { - c.drawlist.PathBezierCubicCurveTo(ToVec2(p1), ToVec2(p2), ToVec2(p3), num_segments) +func (c *Canvas) PathBezierCubicCurveTo(p1, p2, p3 image.Point, numSegments int) { + c.drawlist.PathBezierCubicCurveTo(ToVec2(p1), ToVec2(p2), ToVec2(p3), numSegments) } func (c *Canvas) AddImage(texture *Texture, pMin, pMax image.Point) { diff --git a/Context.go b/Context.go index ab106fca..ad19d6ec 100644 --- a/Context.go +++ b/Context.go @@ -84,6 +84,6 @@ func (c *context) GetState(id string) interface{} { // Get widget index for current layout func (c *context) GetWidgetIndex() int { i := c.widgetIndexCounter - c.widgetIndexCounter += 1 + c.widgetIndexCounter++ return i } diff --git a/Msgbox.go b/Msgbox.go index 769da792..7952061e 100644 --- a/Msgbox.go +++ b/Msgbox.go @@ -80,7 +80,7 @@ func buildMsgboxButtons(buttons MsgboxButtons, callback DialogResultCallback) La } } -const msgboxId string = "###Msgbox" +const msgboxID string = "###Msgbox" // Embed various Msgboxs to layout. Invoke this function in the same layout level where you call g.Msgbox. func PrepareMsgbox() Layout { @@ -89,24 +89,24 @@ func PrepareMsgbox() Layout { var state *MsgboxState // Register state. - stateRaw := Context.GetState(msgboxId) + stateRaw := Context.GetState(msgboxID) if stateRaw == nil { state = &MsgboxState{title: "Info", content: "Content", buttons: MsgboxButtonsOk, resultCallback: nil, open: false} - Context.SetState(msgboxId, state) + Context.SetState(msgboxID, state) } else { state = stateRaw.(*MsgboxState) } if state.open { - OpenPopup(msgboxId) + OpenPopup(msgboxID) state.open = false } SetNextWindowSize(300, 0) - PopupModal(fmt.Sprintf("%s%s", state.title, msgboxId)).Layout( + PopupModal(fmt.Sprintf("%s%s", state.title, msgboxID)).Layout( Custom(func() { // Ensure the state is valid. - Context.GetState(msgboxId) + Context.GetState(msgboxID) }), Label(state.content).Wrapped(true), buildMsgboxButtons(state.buttons, state.resultCallback), @@ -118,7 +118,7 @@ func PrepareMsgbox() Layout { type MsgboxWidget struct{} func (m *MsgboxWidget) getState() *MsgboxState { - stateRaw := Context.GetState(msgboxId) + stateRaw := Context.GetState(msgboxID) if stateRaw == nil { panic("Msgbox is not prepared. Invoke giu.PrepareMsgbox in the end of the layout.") } diff --git a/ProgressIndicator.go b/ProgressIndicator.go index bdd77bd8..5fe7e189 100644 --- a/ProgressIndicator.go +++ b/ProgressIndicator.go @@ -33,7 +33,7 @@ func (ps *ProgressIndicatorState) Dispose() { } type ProgressIndicatorWidget struct { - internalId string + internalID string width float32 height float32 radius float32 @@ -42,7 +42,7 @@ type ProgressIndicatorWidget struct { func ProgressIndicator(label string, width, height, radius float32) *ProgressIndicatorWidget { return &ProgressIndicatorWidget{ - internalId: "###giu-progress-indicator", + internalID: "###giu-progress-indicator", width: width * Context.GetPlatform().GetContentScale(), height: height * Context.GetPlatform().GetContentScale(), radius: radius * Context.GetPlatform().GetContentScale(), @@ -52,10 +52,10 @@ func ProgressIndicator(label string, width, height, radius float32) *ProgressInd func (p *ProgressIndicatorWidget) Build() { // State exists - if s := Context.GetState(p.internalId); s == nil { + if s := Context.GetState(p.internalID); s == nil { // Register state and start go routine ps := ProgressIndicatorState{angle: 0.0, stop: false} - Context.SetState(p.internalId, &ps) + Context.SetState(p.internalID, &ps) go ps.Update() } else { state := s.(*ProgressIndicatorState) diff --git a/SplitLayout.go b/SplitLayout.go index 5f312edf..3669cebb 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -88,10 +88,10 @@ func (s *SplitLayoutWidget) Build() { var splitLayoutState *SplitLayoutState // Register state - stateId := fmt.Sprintf("SplitLayout_%s", s.id) - if state := Context.GetState(stateId); state == nil { + stateID := fmt.Sprintf("SplitLayout_%s", s.id) + if state := Context.GetState(stateID); state == nil { splitLayoutState = &SplitLayoutState{delta: 0.0, sashPos: s.sashPos} - Context.SetState(stateId, splitLayoutState) + Context.SetState(stateID, splitLayoutState) } else { splitLayoutState = state.(*SplitLayoutState) } diff --git a/Style.go b/Style.go index 75b79bc0..5948595f 100644 --- a/Style.go +++ b/Style.go @@ -301,13 +301,13 @@ func Style() *StyleSetter { return &ss } -func (ss *StyleSetter) SetColor(colorId StyleColorID, col color.RGBA) *StyleSetter { - ss.colors[colorId] = col +func (ss *StyleSetter) SetColor(colorID StyleColorID, col color.RGBA) *StyleSetter { + ss.colors[colorID] = col return ss } -func (ss *StyleSetter) SetStyle(varId StyleVarID, width, height float32) *StyleSetter { - ss.styles[varId] = imgui.Vec2{X: width, Y: height} +func (ss *StyleSetter) SetStyle(varID StyleVarID, width, height float32) *StyleSetter { + ss.styles[varID] = imgui.Vec2{X: width, Y: height} return ss } diff --git a/Texture.go b/Texture.go index a9b2594f..b8c6daa8 100644 --- a/Texture.go +++ b/Texture.go @@ -24,8 +24,8 @@ func NewTextureFromRgba(rgba image.Image, loadCallback func(*Texture)) { go func() { Update() result := mainthread.CallVal(func() interface{} { - texId, err := Context.renderer.LoadImage(ImageToRgba(rgba)) - return &loadImageResult{id: texId, err: err} + texID, err := Context.renderer.LoadImage(ImageToRgba(rgba)) + return &loadImageResult{id: texID, err: err} }) tid, ok := result.(*loadImageResult) diff --git a/Widgets.go b/Widgets.go index 9e1f5960..fefec948 100644 --- a/Widgets.go +++ b/Widgets.go @@ -29,9 +29,7 @@ func Row(widgets ...Widget) *RowWidget { } func (l *RowWidget) Build() { - index := 0 - - for _, w := range l.widgets { + for index, w := range l.widgets { _, isTooltip := w.(*TooltipWidget) _, isContextMenu := w.(*ContextMenuWidget) _, isPopupModal := w.(*PopupModalWidget) @@ -47,8 +45,6 @@ func (l *RowWidget) Build() { imgui.SameLine() } - index += 1 - w.Build() } } @@ -211,9 +207,9 @@ func ArrowButton(id string, dir Direction) *ArrowButtonWidget { } } -func (ab *ArrowButtonWidget) Build() { - if imgui.ArrowButton(GenAutoID(ab.id), uint8(ab.dir)) && ab.onClick != nil { - ab.onClick() +func (b *ArrowButtonWidget) Build() { + if imgui.ArrowButton(GenAutoID(b.id), uint8(b.dir)) && b.onClick != nil { + b.onClick() } } @@ -238,9 +234,9 @@ func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } -func (sb *SmallButtonWidget) Build() { - if imgui.SmallButton(GenAutoID(sb.id)) && sb.onClick != nil { - sb.onClick() +func (b *SmallButtonWidget) Build() { + if imgui.SmallButton(GenAutoID(b.id)) && b.onClick != nil { + b.onClick() } } @@ -276,9 +272,9 @@ func InvisibleButton() *InvisibleButtonWidget { } } -func (ib *InvisibleButtonWidget) Build() { - if imgui.InvisibleButton(tStr(ib.id), imgui.Vec2{X: ib.width, Y: ib.height}) && ib.onClick != nil { - ib.onClick() +func (b *InvisibleButtonWidget) Build() { + if imgui.InvisibleButton(tStr(b.id), imgui.Vec2{X: b.width, Y: b.height}) && b.onClick != nil { + b.onClick() } } @@ -294,10 +290,10 @@ type ImageButtonWidget struct { onClick func() } -func (i *ImageButtonWidget) Build() { - if i.texture != nil && i.texture.id != 0 { - if imgui.ImageButtonV(i.texture.id, imgui.Vec2{X: i.width, Y: i.height}, ToVec2(i.uv0), ToVec2(i.uv1), i.framePadding, ToVec4Color(i.bgColor), ToVec4Color(i.tintColor)) && i.onClick != nil { - i.onClick() +func (b *ImageButtonWidget) Build() { + if b.texture != nil && b.texture.id != 0 { + if imgui.ImageButtonV(b.texture.id, imgui.Vec2{X: b.width, Y: b.height}, ToVec2(b.uv0), ToVec2(b.uv1), b.framePadding, ToVec4Color(b.bgColor), ToVec4Color(b.tintColor)) && b.onClick != nil { + b.onClick() } } } @@ -391,21 +387,21 @@ func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRg return b } -func (i *ImageButtonWithRgbaWidget) Build() { - state := Context.GetState(i.id) +func (b *ImageButtonWithRgbaWidget) Build() { + state := Context.GetState(b.id) if state == nil { - Context.SetState(i.id, &ImageState{}) + Context.SetState(b.id, &ImageState{}) - NewTextureFromRgba(i.rgba, func(tex *Texture) { - Context.SetState(i.id, &ImageState{texture: tex}) + NewTextureFromRgba(b.rgba, func(tex *Texture) { + Context.SetState(b.id, &ImageState{texture: tex}) }) } else { imgState := state.(*ImageState) - i.ImageButtonWidget.texture = imgState.texture + b.ImageButtonWidget.texture = imgState.texture } - i.ImageButtonWidget.Build() + b.ImageButtonWidget.Build() } type CheckboxWidget struct { @@ -900,9 +896,9 @@ func (i *ImageWithFileWidget) Build() { widget.Build() } -type ImageWithUrlWidget struct { +type ImageWithURLWidget struct { id string - imgUrl string + imgURL string downloadTimeout time.Duration width float32 height float32 @@ -913,10 +909,10 @@ type ImageWithUrlWidget struct { onClick func() } -func ImageWithUrl(url string) *ImageWithUrlWidget { - return &ImageWithUrlWidget{ - id: fmt.Sprintf("ImageWithUrl_%s", url), - imgUrl: url, +func ImageWithURL(url string) *ImageWithURLWidget { + return &ImageWithURLWidget{ + id: fmt.Sprintf("ImageWithURL_%s", url), + imgURL: url, downloadTimeout: 10 * time.Second, width: 100, height: 100, @@ -926,42 +922,42 @@ func ImageWithUrl(url string) *ImageWithUrlWidget { } // Event trigger when image is downloaded and ready to display. -func (i *ImageWithUrlWidget) OnReady(onReady func()) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) OnReady(onReady func()) *ImageWithURLWidget { i.onReady = onReady return i } -func (i *ImageWithUrlWidget) OnFailure(onFailure func(error)) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) OnFailure(onFailure func(error)) *ImageWithURLWidget { i.onFailure = onFailure return i } -func (i *ImageWithUrlWidget) OnClick(cb func()) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) OnClick(cb func()) *ImageWithURLWidget { i.onClick = cb return i } -func (i *ImageWithUrlWidget) Timeout(downloadTimeout time.Duration) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) Timeout(downloadTimeout time.Duration) *ImageWithURLWidget { i.downloadTimeout = downloadTimeout return i } -func (i *ImageWithUrlWidget) Size(width, height float32) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) Size(width, height float32) *ImageWithURLWidget { i.width, i.height = width, height return i } -func (i *ImageWithUrlWidget) LayoutForLoading(widgets ...Widget) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) LayoutForLoading(widgets ...Widget) *ImageWithURLWidget { i.whenLoading = Layout(widgets) return i } -func (i *ImageWithUrlWidget) LayoutForFailure(widgets ...Widget) *ImageWithUrlWidget { +func (i *ImageWithURLWidget) LayoutForFailure(widgets ...Widget) *ImageWithURLWidget { i.whenFailure = Layout(widgets) return i } -func (i *ImageWithUrlWidget) Build() { +func (i *ImageWithURLWidget) Build() { state := Context.GetState(i.id) widget := Image(nil).OnClick(i.onClick).Size(i.width, i.height) @@ -975,7 +971,7 @@ func (i *ImageWithUrlWidget) Build() { // Load image from url client := resty.New() client.SetTimeout(i.downloadTimeout) - resp, err := client.R().SetContext(downloadContext).Get(i.imgUrl) + resp, err := client.R().SetContext(downloadContext).Get(i.imgURL) if err != nil { Context.SetState(i.id, &ImageState{failure: true}) @@ -1768,9 +1764,9 @@ func SliderFloat(label string, value *float32, min, max float32) *SliderFloatWid } } -func (s *SliderFloatWidget) Format(format string) *SliderFloatWidget { - s.format = format - return s +func (sf *SliderFloatWidget) Format(format string) *SliderFloatWidget { + sf.format = format + return sf } func (sf *SliderFloatWidget) OnChange(onChange func()) *SliderFloatWidget { @@ -2034,11 +2030,11 @@ func (t *TabBarWidget) TabItems(items ...*TabItemWidget) *TabBarWidget { } func (t *TabBarWidget) Build() { - buildingId := t.id - if len(buildingId) == 0 { - buildingId = GenAutoID("TabBar") + buildingID := t.id + if len(buildingID) == 0 { + buildingID = GenAutoID("TabBar") } - if imgui.BeginTabBarV(buildingId, int(t.flags)) { + if imgui.BeginTabBarV(buildingID, int(t.flags)) { for _, ti := range t.tabItems { ti.Build() } @@ -2101,7 +2097,7 @@ type TableColumnWidget struct { label string flags TableColumnFlags innerWidthOrWeight float32 - userId uint32 + userID uint32 } func TableColumn(label string) *TableColumnWidget { @@ -2109,7 +2105,7 @@ func TableColumn(label string) *TableColumnWidget { label: tStr(label), flags: 0, innerWidthOrWeight: 0, - userId: 0, + userID: 0, } } @@ -2123,13 +2119,13 @@ func (c *TableColumnWidget) InnerWidthOrWeight(w float32) *TableColumnWidget { return c } -func (c *TableColumnWidget) UserId(id uint32) *TableColumnWidget { - c.userId = id +func (c *TableColumnWidget) UserID(id uint32) *TableColumnWidget { + c.userID = id return c } func (c *TableColumnWidget) Build() { - imgui.TableSetupColumn(c.label, imgui.TableColumnFlags(c.flags), c.innerWidthOrWeight, c.userId) + imgui.TableSetupColumn(c.label, imgui.TableColumnFlags(c.flags), c.innerWidthOrWeight, c.userID) } type TableWidget struct { From 28f21ca9fd84969decda39554fa33378e35d95d2 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 15 Sep 2021 10:52:53 +0200 Subject: [PATCH 05/27] style.go: add comments --- Style.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/Style.go b/Style.go index 5948595f..d462b0eb 100644 --- a/Style.go +++ b/Style.go @@ -6,6 +6,9 @@ import ( "github.com/AllenDang/imgui-go" ) +// PushFont sets font to "font" +// NOTE: PopFont has to be called +// NOTE: Don't use PushFont. use StyleSetter instead func PushFont(font *FontInfo) bool { if f, ok := extraFontMap[font.String()]; ok { imgui.PushFont(*f) @@ -14,86 +17,117 @@ func PushFont(font *FontInfo) bool { return false } +// PopFont pops the font (should be called after PushFont) func PopFont() { imgui.PopFont() } +// PushStyleColor wrapps imgui.PushStyleColor +// NOTE: don't forget to call PopStyleColor()! func PushStyleColor(id StyleColorID, col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorID(id), ToVec4Color(col)) } +// PushColorText calls PushStyleColor(StyleColorText,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorText(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorText, ToVec4Color(col)) } +// PushColorTextDisabled calls PushStyleColor(StyleColorTextDisabled,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorTextDisabled(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorTextDisabled, ToVec4Color(col)) } +// PushColorWindowBg calls PushStyleColor(StyleColorWindowBg,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorWindowBg(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorWindowBg, ToVec4Color(col)) } +// PushColorFrameBg calls PushStyleColor(StyleColorFrameBg,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorFrameBg(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorFrameBg, ToVec4Color(col)) } +// PushColorButton calls PushStyleColor(StyleColorButton,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorButton(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorButton, ToVec4Color(col)) } +// PushColorButtonHovered calls PushStyleColor(StyleColorButtonHovered,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorButtonHovered(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorButtonHovered, ToVec4Color(col)) } +// PushColorButtonActive calls PushStyleColor(StyleColorButtonActive,...) +// NOTE: don't forget to call PopStyleColor()! func PushColorButtonActive(col color.RGBA) { imgui.PushStyleColor(imgui.StyleColorButtonActive, ToVec4Color(col)) } +// PushWindowPadding calls PushStyleVar(StyleWindowPadding,...) func PushWindowPadding(width, height float32) { width *= Context.GetPlatform().GetContentScale() height *= Context.GetPlatform().GetContentScale() imgui.PushStyleVarVec2(imgui.StyleVarWindowPadding, imgui.Vec2{X: width, Y: height}) } +// PushFramePadding calls PushStyleVar(StyleFramePadding,...) func PushFramePadding(width, height float32) { width *= Context.GetPlatform().GetContentScale() height *= Context.GetPlatform().GetContentScale() imgui.PushStyleVarVec2(imgui.StyleVarFramePadding, imgui.Vec2{X: width, Y: height}) } +// PushItemSpacing calls PushStyleVar(StyleVarItemSpacing,...) func PushItemSpacing(width, height float32) { width *= Context.GetPlatform().GetContentScale() height *= Context.GetPlatform().GetContentScale() imgui.PushStyleVarVec2(imgui.StyleVarItemSpacing, imgui.Vec2{X: width, Y: height}) } -// Alignment for button text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. +// PushButtonTextAlign sets alignment for button text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. func PushButtonTextAlign(width, height float32) { width *= Context.GetPlatform().GetContentScale() height *= Context.GetPlatform().GetContentScale() imgui.PushStyleVarVec2(imgui.StyleVarButtonTextAlign, imgui.Vec2{X: width, Y: height}) } -// Alignment for selectable text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. +// PushSelectableTextAlign sets alignment for selectable text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. func PushSelectableTextAlign(width, height float32) { width *= Context.GetPlatform().GetContentScale() height *= Context.GetPlatform().GetContentScale() imgui.PushStyleVarVec2(imgui.StyleVarSelectableTextAlign, imgui.Vec2{X: width, Y: height}) } +// PopStyle should be called to stop applying style. +// It should be called as much times, as you Called PushStyle... +// NOTE: If you don't call PopStyle imgui will panic func PopStyle() { imgui.PopStyleVar() } +// PopStyleV does similary to PopStyle, but allows to specify number +// of styles you're going to pop func PopStyleV(count int) { imgui.PopStyleVarV(count) } +// PopStyleColor is used to stop applying colors styles. +// It should be called after each PushStyleColor... (for each push) +// If PopStyleColor wasn't called after PushColor... or was called +// inproperly, imgui will panic func PopStyleColor() { imgui.PopStyleColor() } +// PopStyleColorV does similar to PopStyleColor, but allows to specify +// how much style colors would you like to pop func PopStyleColorV(count int) { imgui.PopStyleColorV(count) } @@ -105,11 +139,16 @@ func AlignTextToFramePadding() { imgui.AlignTextToFramePadding() } +// PushItemWidth sets following item's widths +// NOTE: don't forget to call PopItemWidth! If you don't do so, imgui +// will panic func PushItemWidth(width float32) { width *= Context.GetPlatform().GetContentScale() imgui.PushItemWidth(width) } +// PopItemWidth should be called to stop applying PushItemWidth effect +// If it isn't called imgui will panic func PopItemWidth() { imgui.PopItemWidth() } @@ -122,6 +161,7 @@ func PopTextWrapPos() { imgui.PopTextWrapPos() } +// MouseCursorType represents a type (layout) of mouse cursor type MouseCursorType int const ( @@ -146,25 +186,30 @@ const ( MouseCursorCount MouseCursorType = 8 ) +// SetMouseCursor sets mouse cursor layout func SetMouseCursor(cursor MouseCursorType) { imgui.SetMouseCursor(int(cursor)) } +// GetWindowPadding returns window padding func GetWindowPadding() (float32, float32) { vec2 := imgui.CurrentStyle().WindowPadding() return vec2.X, vec2.Y } +// GetItemSpacing returns current item spacing func GetItemSpacing() (float32, float32) { vec2 := imgui.CurrentStyle().ItemSpacing() return vec2.X, vec2.Y } +// GetItemInnerSpacing returns current item inner spacing func GetItemInnerSpacing() (float32, float32) { vec2 := imgui.CurrentStyle().ItemInnerSpacing() return vec2.X, vec2.Y } +// GetFramePadding returns current frame padding func GetFramePadding() (float32, float32) { vec2 := imgui.CurrentStyle().FramePadding() return vec2.X, vec2.Y @@ -285,6 +330,9 @@ const ( StyleVarSelectableTextAlign ) +var _ Widget = &StyleSetter{} + +// StyleSetter is a user-friendly way to manage imgui styles type StyleSetter struct { colors map[StyleColorID]color.RGBA styles map[StyleVarID]imgui.Vec2 @@ -293,6 +341,7 @@ type StyleSetter struct { layout Layout } +// Style initializes a style setter (see examples/setstyle) func Style() *StyleSetter { var ss StyleSetter ss.colors = make(map[StyleColorID]color.RGBA) @@ -301,31 +350,37 @@ func Style() *StyleSetter { return &ss } +// SetColor sets colorID's color func (ss *StyleSetter) SetColor(colorID StyleColorID, col color.RGBA) *StyleSetter { ss.colors[colorID] = col return ss } +/// SetStyle sets styleVarID to width and height func (ss *StyleSetter) SetStyle(varID StyleVarID, width, height float32) *StyleSetter { ss.styles[varID] = imgui.Vec2{X: width, Y: height} return ss } +// SetFont sets font func (ss *StyleSetter) SetFont(font *FontInfo) *StyleSetter { ss.font = font return ss } +// SetDisabled sets if items are disabled func (ss *StyleSetter) SetDisabled(d bool) *StyleSetter { ss.disabled = d return ss } +// To allows to specify a layout, StyleSetter should apply style for func (ss *StyleSetter) To(widgets ...Widget) *StyleSetter { ss.layout = widgets return ss } +// Build implements Widget func (ss *StyleSetter) Build() { if ss.layout == nil || len(ss.layout) == 0 { return From 19cbf31d998451d2f3605ae3808946bee2f0844b Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 15 Sep 2021 10:59:35 +0200 Subject: [PATCH 06/27] keycode.go: add comments --- Keycode.go | 8 ++++++-- examples/loadimage/loadimage.go | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Keycode.go b/Keycode.go index 9f55d881..b898a0b4 100644 --- a/Keycode.go +++ b/Keycode.go @@ -2,8 +2,8 @@ package giu import "github.com/go-gl/glfw/v3.3/glfw" -type Key int -type Modifier int +// Key represents a glfw key +type Key glfw.Key // These key codes are inspired by the USB HID Usage Tables v1.12 (p. 53-60), // but re-arranged to map to 7-bit ASCII for printable keys (function keys are @@ -133,6 +133,10 @@ const ( KeyLast Key = Key(glfw.KeyLast) ) +// Modifier represents glfw.Modifier +type Modifier glfw.ModifierKey + +// modifier keys const ( ModNone Modifier = iota ModControl Modifier = Modifier(glfw.ModControl) diff --git a/examples/loadimage/loadimage.go b/examples/loadimage/loadimage.go index 0843e879..0a1ff885 100644 --- a/examples/loadimage/loadimage.go +++ b/examples/loadimage/loadimage.go @@ -25,12 +25,12 @@ func loop() { }).Size(300, 200), g.Label("Display image from url (wait few seconds to download)"), - g.ImageWithUrl("https://png.pngitem.com/pimgs/s/3-36108_gopher-golang-hd-png-download.png").OnClick(func() { + g.ImageWithURL("https://png.pngitem.com/pimgs/s/3-36108_gopher-golang-hd-png-download.png").OnClick(func() { fmt.Println("image from url clicked") }).Size(300, 200), g.Label("Display images from url with loading and fallback"), - g.ImageWithUrl( + g.ImageWithURL( "https://png.pngitem.com/pimgs/s/424-4241958_transparent-gopher-png-golang-gopher-png-png-download.png"). Timeout(5*time.Second). Size(300, 200). @@ -47,12 +47,12 @@ func loop() { }), g.Label("Handle failure event"), - g.ImageWithUrl("http://x.y/z.jpg").Timeout(2*time.Second).OnFailure(func(err error) { + g.ImageWithURL("http://x.y/z.jpg").Timeout(2*time.Second).OnFailure(func(err error) { fmt.Printf("Failed to download image, Error msg is %s\n", err.Error()) }), g.Label("Display image from url without placeholder (no size when loading)"), - g.ImageWithUrl("https://www.pngitem.com/pimgs/m/424-4242405_go-lang-gopher-clipart-png-download-golang-gopher.png").Size(300, 200), + g.ImageWithURL("https://www.pngitem.com/pimgs/m/424-4242405_go-lang-gopher-clipart-png-download-golang-gopher.png").Size(300, 200), g.Label("Footer"), ) From f2beaba27d74684cb4d6873d4c08c5719e494e8e Mon Sep 17 00:00:00 2001 From: gucio321 Date: Wed, 15 Sep 2021 11:15:32 +0200 Subject: [PATCH 07/27] utils: add comments --- Utils.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Utils.go b/Utils.go index 40a8cbb5..8c26cea9 100644 --- a/Utils.go +++ b/Utils.go @@ -10,6 +10,7 @@ import ( "github.com/AllenDang/imgui-go" ) +// LoadImage loads image from file and returns *image.RGBA func LoadImage(imgPath string) (*image.RGBA, error) { imgFile, err := os.Open(imgPath) if err != nil { @@ -25,6 +26,7 @@ func LoadImage(imgPath string) (*image.RGBA, error) { return ImageToRgba(img), nil } +// ImageToRgba converts image.Image to *image.RGBA func ImageToRgba(img image.Image) *image.RGBA { switch trueImg := img.(type) { case *image.RGBA: @@ -36,6 +38,7 @@ func ImageToRgba(img image.Image) *image.RGBA { } } +// ToVec4Color converts rgba color to imgui.Vec4 func ToVec4Color(col color.RGBA) imgui.Vec4 { return imgui.Vec4{ X: float32(col.R) / 255, @@ -45,6 +48,7 @@ func ToVec4Color(col color.RGBA) imgui.Vec4 { } } +// ToVec2 converts image.Point to imgui.Vec2 func ToVec2(pt image.Point) imgui.Vec2 { return imgui.Vec2{ X: float32(pt.X), @@ -52,6 +56,7 @@ func ToVec2(pt image.Point) imgui.Vec2 { } } +// Vec4ToRgba converts imgui's Vec4 to golang rgba color func Vec4ToRGBA(vec4 imgui.Vec4) color.RGBA { return color.RGBA{ R: uint8(vec4.X * 255), @@ -61,6 +66,11 @@ 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 +// action is done, it may be necessary to +// Update ui manually at some point. func Update() { if Context.isAlive { Context.platform.Update() @@ -68,24 +78,29 @@ func Update() { } } +// GetCursorScreenPos returns imgui drawing cursor on the screen func GetCursorScreenPos() image.Point { pos := imgui.CursorScreenPos() return image.Pt(int(pos.X), int(pos.Y)) } +// SetCursorScreenPos sets imgui drawing cursor on the screen func SetCursorScreenPos(pos image.Point) { imgui.SetCursorScreenPos(imgui.Vec2{X: float32(pos.X), Y: float32(pos.Y)}) } +// GetCursorPos gets imgui drawing cursor inside of current window func GetCursorPos() image.Point { pos := imgui.CursorPos() return image.Pt(int(pos.X), int(pos.Y)) } +// SetCursorPos sets imgui drawing cursor inside of current window func SetCursorPos(pos image.Point) { imgui.SetCursorPos(imgui.Vec2{X: float32(pos.X), Y: float32(pos.Y)}) } +// GetMousePos returns mouse position func GetMousePos() image.Point { pos := imgui.MousePos() return image.Pt(int(pos.X), int(pos.Y)) @@ -96,21 +111,26 @@ func GetAvailableRegion() (width, height float32) { return region.X, region.Y } +// CalcTextSize calls CalcTextSizeV(text, false, -1) func CalcTextSize(text string) (width, height float32) { return CalcTextSizeV(text, false, -1) } +// CalcTextSizeV calculates text dimensions func CalcTextSizeV(text string, hideAfterDoubleHash bool, wrapWidth float32) (w, h float32) { size := imgui.CalcTextSize(text, hideAfterDoubleHash, wrapWidth) return size.X, size.Y } +// SetNextWindowSize sets size of the next window func SetNextWindowSize(width, height float32) { imgui.SetNextWindowSize(imgui.Vec2{X: width * Context.platform.GetContentScale(), Y: height * Context.platform.GetContentScale()}) } +// ExecCondition represents imgui.Condition type ExecCondition imgui.Condition +// imgui conditions const ( ConditionAlways ExecCondition = ExecCondition(imgui.ConditionAlways) ConditionOnce ExecCondition = ExecCondition(imgui.ConditionOnce) @@ -118,18 +138,22 @@ const ( ConditionAppearing ExecCondition = ExecCondition(imgui.ConditionAppearing) ) +// SetNextWindowPos sets position of next window func SetNextWindowPos(x, y float32) { imgui.SetNextWindowPos(imgui.Vec2{X: x, Y: y}) } +// SetNextWindowSizeV does similar to SetNextWIndowSize but allows to specify imgui.Condition func SetNextWindowSizeV(width, height float32, condition ExecCondition) { imgui.SetNextWindowSizeV(imgui.Vec2{X: width * Context.platform.GetContentScale(), Y: height * Context.platform.GetContentScale()}, imgui.Condition(condition)) } +// SetItemDefaultFocus set the item focused by default func SetItemDefaultFocus() { imgui.SetItemDefaultFocus() } +// SetKeyboardFocusHere sets keyboard focus at the widget func SetKeyboardFocusHere() { SetKeyboardFocusHereV(0) } From 7ec45082d2d3f4553d92984cc38586ce4679bb1a Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 12 Sep 2021 12:29:31 +0200 Subject: [PATCH 08/27] github/workflows: add golangci-lint workflow --- .github/workflows/golangci-lint.yaml | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 .github/workflows/golangci-lint.yaml diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml new file mode 100644 index 00000000..b98af243 --- /dev/null +++ b/.github/workflows/golangci-lint.yaml @@ -0,0 +1,43 @@ +name: golangci-lint +on: + push: + tags: + - v* + branches: + - master + - main + pull_request: + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - name: Set up LibGL, Mesa & X11 libraries + run: | + sudo apt-get --allow-releaseinfo-change update + sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev + - uses: actions/checkout@v2 + - name: golangci-lint + 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 + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # 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 + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true From fa6a374bbca7ad20ee998fad7a91d70e2fe67f44 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 11:42:46 +0200 Subject: [PATCH 09/27] fix .golangci.yml config --- .golangci-lint.yaml | 42 ------------------ .golangci.yml | 103 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 42 deletions(-) delete mode 100644 .golangci-lint.yaml create mode 100644 .golangci.yml diff --git a/.golangci-lint.yaml b/.golangci-lint.yaml deleted file mode 100644 index b130b67e..00000000 --- a/.golangci-lint.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: golangci-lint -on: - push: - tags: - - v* - branches: - - master - pull_request: - -jobs: - golangci: - name: lint - runs-on: ubuntu-latest - steps: - - name: Set up LibGL, Mesa & X11 libraries - run: | - sudo apt-get --allow-releaseinfo-change update - sudo apt-get install -y libgtk-3-dev libasound2-dev libxxf86vm-dev - - uses: actions/checkout@v2 - - name: golangci-lint - 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 - - # Optional: working directory, useful for monorepos - # working-directory: somedir - - # Optional: golangci-lint command line arguments. - # args: --issues-exit-code=0 - - # 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 - - # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. - # skip-build-cache: true diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..9444f801 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,103 @@ +--- +linters-settings: + dupl: + threshold: 100 + funlen: + lines: 100 + statements: 50 + goconst: + min-len: 2 + min-occurrences: 2 + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + gocyclo: + min-complexity: 15 + goimports: + local-prefixes: github.com/AllenDang/giu + govet: + check-shadowing: true + lll: + line-length: 140 + maligned: + suggest-new: true + misspell: + locale: US + +linters: + disable-all: true + enable: + - asciicheck + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + - errcheck + - errorlint + - exportloopref + #- forcetypeassert + #- funlen + - gci + #- godot + #- gochecknoglobals + #- gochecknoinits + - gocognit + - goconst + - gocritic + - gocyclo + - godox + - goerr113 + - gofmt + - gofumpt + - goheader + - goimports + #- gomnd + - goprintffuncname + - gosec + - gosimple + - govet + - ifshort + - importas + - ineffassign + - lll + - makezero + - misspell + - nakedret + - nestif + - nilerr + #- nlreturn + - nolintlint + - prealloc + - predeclared + - promlinter + - revive + - rowserrcheck + - staticcheck + - structcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - varcheck + - wastedassign + - whitespace + - wrapcheck + #- wsl + +run: + timeout: 5m + skip-dirs: + - .github + - build + - web + +issues: + max-same-issues: 0 + exclude-use-default: false From f75dabd7752a677e10874fec28b7a83f0ee48e1c Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 12:18:00 +0200 Subject: [PATCH 10/27] apply auto-fixes run golangci-lint run --fix ./... --- .golangci.yml | 2 +- Flags.go | 4 ++-- MasterWindow.go | 3 +-- StackWidget.go | 4 ++-- Style.go | 2 +- Texture.go | 5 ++--- Widgets.go | 2 +- cmd/gmdeploy/utils.go | 4 ++-- 8 files changed, 12 insertions(+), 14 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 9444f801..656ad88f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -88,7 +88,7 @@ linters: - varcheck - wastedassign - whitespace - - wrapcheck + #- wrapcheck #- wsl run: diff --git a/Flags.go b/Flags.go index 931a39c2..5d55e946 100644 --- a/Flags.go +++ b/Flags.go @@ -353,7 +353,7 @@ const ( TableFlagsSizingFixedFit TableFlags = 1 << 13 // Columns default to WidthFixed or WidthAuto (if resizable or not resizable), matching contents width. TableFlagsSizingFixedSame TableFlags = 2 << 13 // Columns default to WidthFixed or WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable TableFlagsNoKeepColumnsVisible. TableFlagsSizingStretchProp TableFlags = 3 << 13 // Columns default to WidthStretch with default weights proportional to each columns contents widths. - TableFlagsSizingStretchSame TableFlags = 4 << 13 // Columns default to WidthStretch with default weights all equal, unless overriden by TableSetupColumn(). + TableFlagsSizingStretchSame TableFlags = 4 << 13 // Columns default to WidthStretch with default weights all equal, unless overridden by TableSetupColumn(). // Sizing Extra Options TableFlagsNoHostExtendX TableFlags = 1 << 16 // Make outer width auto-fit to columns, overriding outersize.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. TableFlagsNoHostExtendY TableFlags = 1 << 17 // Make outer height stop exactly at outersize.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible. @@ -433,7 +433,7 @@ type PlotFlags int const ( PlotFlagsNone PlotFlags = 0 // default - PlotFlagsNoTitle PlotFlags = 1 << 0 // the plot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MyPlot") + PlotFlagsNoTitle PlotFlags = 1 << 0 // the plot title will not be displayed (titles are also hidden if preceded by double hashes, e.g. "##MyPlot") PlotFlagsNoLegend PlotFlags = 1 << 1 // the legend will not be displayed PlotFlagsNoMenus PlotFlags = 1 << 2 // the user will not be able to open context menus with right-click PlotFlagsNoBoxSelect PlotFlags = 1 << 3 // the user will not be able to box-select with right-click drag diff --git a/MasterWindow.go b/MasterWindow.go index fe827692..b06fa01b 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -5,9 +5,8 @@ import ( "image/color" "time" - "github.com/faiface/mainthread" - "github.com/AllenDang/imgui-go" + "github.com/faiface/mainthread" ) // MasterWindowFlags wrapps imgui.GLFWWindowFlags diff --git a/StackWidget.go b/StackWidget.go index 496fdfd4..5cd82301 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -26,9 +26,9 @@ func (s *StackWidget) Build() { // build visible layout // NOTE: it is important to build the visiblely showed layout before - // building another ones, becouse the interactive layout widgets + // building another ones, because the interactive layout widgets // (e.g. buttons) should be rendered on top of `stack` - var layouts []Widget = s.layouts + layouts := s.layouts if s.visible >= 0 && s.visible < int32(len(s.layouts)) { s.layouts[s.visible].Build() diff --git a/Style.go b/Style.go index d462b0eb..af7a927a 100644 --- a/Style.go +++ b/Style.go @@ -112,7 +112,7 @@ func PopStyle() { imgui.PopStyleVar() } -// PopStyleV does similary to PopStyle, but allows to specify number +// PopStyleV does similarly to PopStyle, but allows to specify number // of styles you're going to pop func PopStyleV(count int) { imgui.PopStyleVarV(count) diff --git a/Texture.go b/Texture.go index b8c6daa8..f7ee73ce 100644 --- a/Texture.go +++ b/Texture.go @@ -5,9 +5,8 @@ import ( "image" "runtime" - "github.com/faiface/mainthread" - "github.com/AllenDang/imgui-go" + "github.com/faiface/mainthread" ) type Texture struct { @@ -31,7 +30,7 @@ func NewTextureFromRgba(rgba image.Image, loadCallback func(*Texture)) { tid, ok := result.(*loadImageResult) switch { case !ok: - panic("giu: NewTextureFromRgba: unexpected error occured") + panic("giu: NewTextureFromRgba: unexpected error occurred") case tid.err != nil: panic(fmt.Sprintf("giu: NewTextureFromRgba: error loading texture: %v", tid.err)) } diff --git a/Widgets.go b/Widgets.go index 007e7cb2..4b0f28e2 100644 --- a/Widgets.go +++ b/Widgets.go @@ -1052,7 +1052,7 @@ func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextW return i.Label(fmt.Sprintf(format, args...)) } -// Enable auto complete popup by using fuzzy search of current value agains candidates +// Enable auto complete popup by using fuzzy search of current value against candidates // Press enter to confirm the first candidate func (i *InputTextWidget) AutoComplete(candidates []string) *InputTextWidget { i.candidates = candidates diff --git a/cmd/gmdeploy/utils.go b/cmd/gmdeploy/utils.go index ca264df3..609e6e26 100644 --- a/cmd/gmdeploy/utils.go +++ b/cmd/gmdeploy/utils.go @@ -8,14 +8,14 @@ import ( ) func Save(name, data string) { - err := ioutil.WriteFile(name, []byte(data), 0644) + err := ioutil.WriteFile(name, []byte(data), 0o644) if err != nil { log.Fatalf("Failed to save %s:%v\n", name, err) } } func MkdirAll(name string) { - err := os.MkdirAll(name, 0755) + err := os.MkdirAll(name, 0o755) if err != nil { log.Fatalf("Failed to make all dir, %s:%v\n", name, err) } From cd7cd6b7847155f52361e521cb1f945eaa0a107b Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 19:11:46 +0200 Subject: [PATCH 11/27] gmdeploy: lintfix --- cmd/gmdeploy/main.go | 57 ++++++++++++++++++++++++++----------------- cmd/gmdeploy/utils.go | 17 ++++++------- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/cmd/gmdeploy/main.go b/cmd/gmdeploy/main.go index e43b1a73..56f3ea82 100644 --- a/cmd/gmdeploy/main.go +++ b/cmd/gmdeploy/main.go @@ -3,6 +3,7 @@ package main import ( "flag" "fmt" + "log" "os" "os/exec" "path/filepath" @@ -29,7 +30,7 @@ func main() { flag.Parse() - if len(targetOS) == 0 { + if targetOS == "" { targetOS = runtime.GOOS } @@ -38,79 +39,89 @@ func main() { // Prepare build dir outputDir := filepath.Join(projectPath, "build", targetOS) - os.RemoveAll(outputDir) - MkdirAll(outputDir) + if err := os.RemoveAll(outputDir); err != nil { + log.Fatalf("error removing content of %s", outputDir) + } + + mkdirAll(outputDir) switch targetOS { case "darwin": - // Compile + const iconExtension = ".icns" + // nolint:gosec // Compile: cannot fix cmd := exec.Command("bash", "-c", fmt.Sprintf("go build -ldflags='-s -w' -o %s", appName)) cmd.Dir = projectPath - RunCmd(cmd) + runCmd(cmd) // Upx if upx { + // nolint:gosec // cannot fix cmd = exec.Command("upx", appName) - RunCmd(cmd) + runCmd(cmd) } // Bundle macOSPath := filepath.Join(outputDir, fmt.Sprintf("%s.app", appName), "Contents", "MacOS") - MkdirAll(macOSPath) + mkdirAll(macOSPath) // Copy compiled executable to build folder + // nolint:gosec // cannot fix cmd = exec.Command("mv", appName, macOSPath) - RunCmd(cmd) + runCmd(cmd) // Prepare Info.plist contentsPath := filepath.Join(outputDir, fmt.Sprintf("%s.app", appName), "Contents") - Save(filepath.Join(contentsPath, "Info.plist"), darwinPlist(appName)) + save(filepath.Join(contentsPath, "Info.plist"), darwinPlist(appName)) // Prepare PkgInfo - Save(filepath.Join(contentsPath, "PkgInfo"), darwinPkginfo()) + save(filepath.Join(contentsPath, "PkgInfo"), darwinPkginfo()) - if len(iconPath) > 0 && filepath.Ext(iconPath) == ".icns" { + if len(iconPath) > 0 && filepath.Ext(iconPath) == iconExtension { // Prepare icon resourcesPath := filepath.Join(contentsPath, "Resources") - MkdirAll(resourcesPath) + mkdirAll(resourcesPath) // Rename icon file name to [appName].icns - cmd = exec.Command("cp", iconPath, filepath.Join(resourcesPath, fmt.Sprintf("%s.icns", appName))) - RunCmd(cmd) + // nolint:gosec // cannot fix + cmd = exec.Command("cp", iconPath, filepath.Join(resourcesPath, fmt.Sprintf("%s%s", appName, iconExtension))) + runCmd(cmd) } fmt.Printf("%s.app is generated at %s/build/%s/\n", appName, projectPath, targetOS) case "linux": - // Compile + // nolint:gosec // Compile: cannot fix cmd := exec.Command("bash", "-c", fmt.Sprintf("go build -ldflags='-s -w' -o %s", filepath.Join(appName))) cmd.Dir = projectPath - RunCmd(cmd) + runCmd(cmd) // Bundle contentsPath := filepath.Join(outputDir, fmt.Sprintf("%s.app", appName)) binPath := filepath.Join(contentsPath, "bin") - MkdirAll(binPath) + mkdirAll(binPath) // Copy compiled executable to build folder + // nolint:gosec // rename command - cannot be fixed cmd = exec.Command("mv", appName, binPath) - RunCmd(cmd) + runCmd(cmd) // create desktop entry hasIcon := iconPath != "" && filepath.Ext(iconPath) == ".icns" desktopPath := filepath.Join(contentsPath, "share", "applications") - MkdirAll(desktopPath) + mkdirAll(desktopPath) - Save(filepath.Join(desktopPath, fmt.Sprintf("%s.desktop", appName)), linuxDesktop(appName, hasIcon)) + save(filepath.Join(desktopPath, fmt.Sprintf("%s.desktop", appName)), linuxDesktop(appName, hasIcon)) if hasIcon { // Prepare icon iconsPath := filepath.Join(contentsPath, "share", "icons") - MkdirAll(iconsPath) + mkdirAll(iconsPath) // Rename icon file name to [appName].icns - cmd = exec.Command("cp", iconPath, filepath.Join(iconsPath, fmt.Sprintf("%s.icns", appName))) - RunCmd(cmd) + newIconName := filepath.Join(iconsPath, fmt.Sprintf("%s.icns", appName)) + // nolint:gosec // cp comman - cannot fix + cmd = exec.Command("cp", iconPath, newIconName) + runCmd(cmd) } default: fmt.Printf("Sorry, %s is not supported yet.\n", targetOS) diff --git a/cmd/gmdeploy/utils.go b/cmd/gmdeploy/utils.go index 609e6e26..c74ddd05 100644 --- a/cmd/gmdeploy/utils.go +++ b/cmd/gmdeploy/utils.go @@ -7,23 +7,22 @@ import ( "os/exec" ) -func Save(name, data string) { - err := ioutil.WriteFile(name, []byte(data), 0o644) - if err != nil { +func save(name, data string) { + const newFileMode = 0o644 + if err := ioutil.WriteFile(name, []byte(data), newFileMode); err != nil { log.Fatalf("Failed to save %s:%v\n", name, err) } } -func MkdirAll(name string) { - err := os.MkdirAll(name, 0o755) - if err != nil { +func mkdirAll(name string) { + const newDirMode = 0o755 + if err := os.MkdirAll(name, newDirMode); err != nil { log.Fatalf("Failed to make all dir, %s:%v\n", name, err) } } -func RunCmd(cmd *exec.Cmd) { - err := cmd.Run() - if err != nil { +func runCmd(cmd *exec.Cmd) { + if err := cmd.Run(); err != nil { log.Fatalf("Failed to execute command:%s with error %v\n", cmd.String(), err) } } From 486553714fdd2a834b5a2814fe1848beb826be44 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 19:33:46 +0200 Subject: [PATCH 12/27] all: fix unconvert --- Alignment.go | 4 ++-- ProgressIndicator.go | 4 ++-- StackWidget.go | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Alignment.go b/Alignment.go index 51fae50e..e58c23ff 100644 --- a/Alignment.go +++ b/Alignment.go @@ -92,9 +92,9 @@ func (a *AlignmentSetter) Build() { case AlignLeft: // noop case AlignCenter: - SetCursorPos(image.Pt(int(availableW/2-w/2), int(currentPos.Y))) + SetCursorPos(image.Pt(int(availableW/2-w/2), currentPos.Y)) case AlignRight: - SetCursorPos(image.Pt(int(availableW-w), int(currentPos.Y))) + SetCursorPos(image.Pt(int(availableW-w), currentPos.Y)) default: panic(fmt.Sprintf("giu: (*AlignSetter).Build: unknown align type %d", a.alignType)) } diff --git a/ProgressIndicator.go b/ProgressIndicator.go index 5fe7e189..f2198163 100644 --- a/ProgressIndicator.go +++ b/ProgressIndicator.go @@ -78,8 +78,8 @@ func (p *ProgressIndicatorWidget) Build() { color := imgui.CurrentStyle().GetColor(imgui.StyleColorText) rgba := Vec4ToRGBA(color) - canvas.AddCircle(centerPt, float32(p.radius), rgba, int(p.radius), float32(p.radius/20.0)) - canvas.AddCircleFilled(centerPt2, float32(p.radius/5), rgba) + canvas.AddCircle(centerPt, p.radius, rgba, int(p.radius), p.radius/20.0) + canvas.AddCircleFilled(centerPt2, p.radius/5, rgba) // Draw text if len(p.label) > 0 { diff --git a/StackWidget.go b/StackWidget.go index 5cd82301..145420f3 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -16,7 +16,7 @@ type StackWidget struct { func Stack(visible int32, layouts ...Widget) *StackWidget { return &StackWidget{ visible: visible, - layouts: []Widget(layouts), + layouts: layouts, } } From 323f8cb1eff0d5fa6f4e0c8b41ea2a4d9643f6e4 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 20:33:04 +0200 Subject: [PATCH 13/27] all: fix various revive lint errors --- Canvas.go | 2 ++ CodeEditor.go | 36 ++++++++++++++++++++++++++++++++++-- EventHandler.go | 2 +- Events.go | 16 ++++++++++++++++ Flags.go | 3 +++ InputHandler.go | 2 ++ Msgbox.go | 36 ++++++++++++++++++++++++++++-------- Plot.go | 9 +++++++++ ProgressIndicator.go | 22 ++++++++++++++++------ SplitLayout.go | 3 +++ Window.go | 28 ++++++++++++++++++++++++++++ 11 files changed, 142 insertions(+), 17 deletions(-) diff --git a/Canvas.go b/Canvas.go index 24d8ca76..d8aceedb 100644 --- a/Canvas.go +++ b/Canvas.go @@ -21,8 +21,10 @@ func (c *Canvas) AddLine(p1, p2 image.Point, color color.RGBA, thickness float32 c.drawlist.AddLine(ToVec2(p1), ToVec2(p2), ToVec4Color(color), thickness) } +// DrawFlags represents imgui.DrawFlags type DrawFlags int +// draw flags enum: const ( DrawFlagsNone DrawFlags = 0 DrawFlagsClosed DrawFlags = 1 << 0 // PathStroke(), AddPolyline(): specify that shape should be closed (portant: this is always == 1 for legacy reason) diff --git a/CodeEditor.go b/CodeEditor.go index e58a93cc..725234f0 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -6,8 +6,10 @@ import ( "github.com/AllenDang/imgui-go" ) +// LanguageDefinition represents code editor's language definition type LanguageDefinition byte +// language definitions: const ( LanguageDefinitionSQL LanguageDefinition = iota LanguageDefinitionCPP @@ -15,14 +17,21 @@ const ( LanguageDefinitionC ) +var _ Disposable = &codeEditorState{} + type codeEditorState struct { editor imgui.TextEditor } +// Dispose implements Disposable interface func (s *codeEditorState) Dispose() { // noop } +// static check if code editor implements Widget interface +var _ Widget = &CodeEditorWidget{} + +// CodeEditorWidget represents imgui.TextEditor type CodeEditorWidget struct { title string width, @@ -30,22 +39,26 @@ type CodeEditorWidget struct { border bool } +// CodeEditor creates a new code editor widget func CodeEditor(title string) *CodeEditorWidget { return &CodeEditorWidget{ title: title, } } +// ShowWhitespace sets if whitespaces are shown in code editor func (ce *CodeEditorWidget) ShowWhitespaces(s bool) *CodeEditorWidget { ce.getState().editor.SetShowWhitespaces(s) return ce } +// TabSize sets editor's tab size func (ce *CodeEditorWidget) TabSize(size int) *CodeEditorWidget { ce.getState().editor.SetTabSize(size) return ce } +// LanguageDefinition sets code editor language definition func (ce *CodeEditorWidget) LanguageDefinition(definition LanguageDefinition) *CodeEditorWidget { s := ce.getState() lookup := map[LanguageDefinition]func(){ @@ -65,63 +78,77 @@ func (ce *CodeEditorWidget) LanguageDefinition(definition LanguageDefinition) *C return ce } +// Text sets editor's text func (ce *CodeEditorWidget) Text(str string) *CodeEditorWidget { ce.getState().editor.SetText(str) return ce } +// ErrorMarkers sets error markers func (ce *CodeEditorWidget) ErrorMarkers(markers imgui.ErrorMarkers) *CodeEditorWidget { ce.getState().editor.SetErrorMarkers(markers) return ce } +// HandleKeyboardInputs sets if editor should handle keyboard input func (ce *CodeEditorWidget) HandleKeyboardInputs(b bool) *CodeEditorWidget { ce.getState().editor.SetHandleKeyboardInputs(b) return ce } +// Size sets editor's size func (ce *CodeEditorWidget) Size(w, h float32) *CodeEditorWidget { ce.width, ce.height = w, h return ce } +// Border sets editors borders func (ce *CodeEditorWidget) Border(border bool) *CodeEditorWidget { ce.border = border return ce } +// HasSelection returns true if some text is selected func (ce *CodeEditorWidget) HasSelection() bool { return ce.getState().editor.HasSelection() } +// GetSelectedText returns selected text func (ce *CodeEditorWidget) GetSelectedText() string { return ce.getState().editor.GetSelectedText() } +// GetText returns whole text from editor func (ce *CodeEditorWidget) GetText() string { return ce.getState().editor.GetText() } +// GetCurrentLineText returns current line func (ce *CodeEditorWidget) GetCurrentLineText() string { return ce.getState().editor.GetCurrentLineText() } -func (ce *CodeEditorWidget) GetCursorPos() (int, int) { +// GetCursorPos returns cursor position +func (ce *CodeEditorWidget) GetCursorPos() (x, y int) { return ce.getState().editor.GetCursorPos() } -func (ce *CodeEditorWidget) GetSelectionStart() (int, int) { +// GetSelectionStart returns star pos of selection +func (ce *CodeEditorWidget) GetSelectionStart() (x, y int) { return ce.getState().editor.GetSelectionStart() } +// InsertText inserts the `text` func (ce *CodeEditorWidget) InsertText(text string) { ce.getState().editor.InsertText(text) } +// GetWordUnderCursor returns the word under the cursor func (ce *CodeEditorWidget) GetWordUnderCursor() string { return ce.getState().editor.GetWordUnderCursor() } +// SelectWordUnderCursor selects the word under cursor func (ce *CodeEditorWidget) SelectWordUnderCursor() { ce.getState().editor.SelectWordUnderCursor() } @@ -134,22 +161,27 @@ func (ce *CodeEditorWidget) GetScreenCursorPos() (int, int) { return ce.getState().editor.GetScreenCursorPos() } +// Copy copies selection func (ce *CodeEditorWidget) Copy() { ce.getState().editor.Copy() } +// Cut cuts selection func (ce *CodeEditorWidget) Cut() { ce.getState().editor.Cut() } +// Paste does the same as Ctrl+V func (ce *CodeEditorWidget) Paste() { ce.getState().editor.Paste() } +// Delete deletes the selection func (ce *CodeEditorWidget) Delete() { ce.getState().editor.Delete() } +// Build implements Widget interface func (ce *CodeEditorWidget) Build() { s := ce.getState() diff --git a/EventHandler.go b/EventHandler.go index e531f6d0..3c14c235 100644 --- a/EventHandler.go +++ b/EventHandler.go @@ -83,7 +83,7 @@ func (eh *EventHandler) OnKeyReleased(key Key, cb func()) *EventHandler { // Mouse events -// OnKeyDown sets callback when mouse button `mouseButton` is clicked +// OnClick sets callback when mouse button `mouseButton` is clicked func (eh *EventHandler) OnClick(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseClicked}) return eh diff --git a/Events.go b/Events.go index 98c6e274..509c3aed 100644 --- a/Events.go +++ b/Events.go @@ -14,54 +14,70 @@ func IsItemHovered() bool { return imgui.IsItemHovered() } +// IsItemClicked returns true if mouse is clicked +// NOTE: if you're looking for clicking detection, see EventHandler.go func IsItemClicked(mouseButton MouseButton) bool { return imgui.IsItemClicked(int(mouseButton)) } +// IsItemActive returns true if item is active func IsItemActive() bool { return imgui.IsItemActive() } +// IsKeyDown returns true if key `key` is down func IsKeyDown(key Key) bool { return imgui.IsKeyDown(int(key)) } +// IsKeyPressed returns true if key `key` is pressed func IsKeyPressed(key Key) bool { return imgui.IsKeyPressed(int(key)) } +// IsKeyReleased returns true if key `key` is released func IsKeyReleased(key Key) bool { return imgui.IsKeyReleased(int(key)) } +// IsMouseDown returns true if mouse button `button` is down func IsMouseDown(button MouseButton) bool { return imgui.IsMouseDown(int(button)) } +// IsMouseClicked returns true if mouse button `button` is clicked +// NOTE: if you're looking for clicking detection, see EventHandler.go func IsMouseClicked(button MouseButton) bool { return imgui.IsMouseClicked(int(button)) } +// IsMouseReleased returns true if mouse button `button` is released func IsMouseReleased(button MouseButton) bool { return imgui.IsMouseReleased(int(button)) } +// IsMouseDoubleClicked returns true if mouse button `button` is double clicked func IsMouseDoubleClicked(button MouseButton) bool { return imgui.IsMouseDoubleClicked(int(button)) } +// IsWindowAppearing returns true if window is appearing func IsWindowAppearing() bool { return imgui.IsWindowAppearing() } +// IsWindowCollapsed returns true if window is disappearing func IsWindowCollapsed() bool { return imgui.IsWindowCollapsed() } +// IsWindowFocused returns true if window is focused +// NOTE: see also (*Window).HasFocus and (*Window).BringToFront func IsWindowFocused(flags FocusedFlags) bool { return imgui.IsWindowFocused(int(flags)) } +// IsWindowHovered returns true if the window is hovered func IsWindowHovered(flags HoveredFlags) bool { return imgui.IsWindowHovered(int(flags)) } diff --git a/Flags.go b/Flags.go index 5d55e946..b420c2be 100644 --- a/Flags.go +++ b/Flags.go @@ -177,6 +177,7 @@ const ( TabBarFlagsFittingPolicyDefault TabBarFlags = TabBarFlagsFittingPolicyResizeDown ) +// TreeNodeFlags represents tree node widget flags type TreeNodeFlags int const ( @@ -237,6 +238,7 @@ const ( FocusedFlagsRootAndChildWindows = FocusedFlagsRootWindow | FocusedFlagsChildWindows ) +// HoveredFlags represents a hovered flags type HoveredFlags int const ( @@ -327,6 +329,7 @@ const ( type TableFlags int +// Table flags enum: const ( // Features TableFlagsNone TableFlags = 0 diff --git a/InputHandler.go b/InputHandler.go index cb458321..33a51636 100644 --- a/InputHandler.go +++ b/InputHandler.go @@ -83,6 +83,8 @@ func handler(key glfw.Key, mod glfw.ModifierKey, action glfw.Action) { } } +// WindowShortcut represents a window-level shortcut +// could be used as an argument to (*Window).RegisterKeyboardShortcuts type WindowShortcut struct { Key Key Modifier Modifier diff --git a/Msgbox.go b/Msgbox.go index 7952061e..aee36675 100644 --- a/Msgbox.go +++ b/Msgbox.go @@ -2,8 +2,11 @@ package giu import "fmt" +// DialogResult represents dialog result +// dialog resullt is bool. if OK/Yes it is true, else (Cancel/No) - false type DialogResult bool +// dialog results const ( DialogResultOK DialogResult = true DialogResultCancel DialogResult = false @@ -12,17 +15,25 @@ const ( DialogResultNo = DialogResultCancel ) +// MsgboxButtons determines which buttons are in the dialog. type MsgboxButtons uint8 +// button sets const ( + // Yes-No question MsgboxButtonsYesNo MsgboxButtons = 1 << iota + // Ok / Cancel dialog MsgboxButtonsOkCancel + // info MsgboxButtonsOk ) +// DialogResultCallback is a callback for dialogs type DialogResultCallback func(DialogResult) -type MsgboxState struct { +var _ Disposable = &msgboxState{} + +type msgboxState struct { title string content string resultCallback DialogResultCallback @@ -30,7 +41,8 @@ type MsgboxState struct { open bool } -func (ms *MsgboxState) Dispose() { +// Dispose implements disposable interface +func (ms *msgboxState) Dispose() { // Nothing to do here. } @@ -82,20 +94,22 @@ func buildMsgboxButtons(buttons MsgboxButtons, callback DialogResultCallback) La const msgboxID string = "###Msgbox" -// Embed various Msgboxs to layout. Invoke this function in the same layout level where you call g.Msgbox. +// PrepareMsgbox should be invoked in function in the same layout level where you call g.Msgbox. +// BUG: calling this more than 1 time per frame causes unexpected +// merging msgboxes layouts (see https://github.com/AllenDang/giu/issues/290) func PrepareMsgbox() Layout { return Layout{ Custom(func() { - var state *MsgboxState + var state *msgboxState // Register state. stateRaw := Context.GetState(msgboxID) if stateRaw == nil { - state = &MsgboxState{title: "Info", content: "Content", buttons: MsgboxButtonsOk, resultCallback: nil, open: false} + state = &msgboxState{title: "Info", content: "Content", buttons: MsgboxButtonsOk, resultCallback: nil, open: false} Context.SetState(msgboxID, state) } else { - state = stateRaw.(*MsgboxState) + state = stateRaw.(*msgboxState) } if state.open { @@ -115,17 +129,21 @@ func PrepareMsgbox() Layout { } } +// MsgboxWidget represents message dialog type MsgboxWidget struct{} -func (m *MsgboxWidget) getState() *MsgboxState { +func (m *MsgboxWidget) getState() *msgboxState { stateRaw := Context.GetState(msgboxID) if stateRaw == nil { panic("Msgbox is not prepared. Invoke giu.PrepareMsgbox in the end of the layout.") } - return stateRaw.(*MsgboxState) + return stateRaw.(*msgboxState) } +// Msgbox opens message box. +// call it whenever you want to open popup with +// question / info func Msgbox(title, content string) *MsgboxWidget { result := &MsgboxWidget{} @@ -141,12 +159,14 @@ func Msgbox(title, content string) *MsgboxWidget { return result } +// Buttons sets which buttons should be possible func (m *MsgboxWidget) Buttons(buttons MsgboxButtons) *MsgboxWidget { s := m.getState() s.buttons = buttons return m } +// ResultCallback sets result callback func (m *MsgboxWidget) ResultCallback(cb DialogResultCallback) *MsgboxWidget { s := m.getState() s.resultCallback = cb diff --git a/Plot.go b/Plot.go index d992e382..1bd12275 100644 --- a/Plot.go +++ b/Plot.go @@ -6,23 +6,29 @@ import ( "github.com/AllenDang/imgui-go" ) +// PlotWidget is implemented by all the particular plots, which can be used +// in (*PlotCanvasWidget).Plots type PlotWidget interface { Plot() } +// ImPlotYAxis represents y axis settings type ImPlotYAxis int +// ImPlotYAxis enum: const ( ImPlotYAxisLeft ImPlotYAxis = 0 // left (default) ImPlotYAxisFirstOnRight ImPlotYAxis = 1 // first on right side ImPlotYAxisSecondOnRight ImPlotYAxis = 2 // second on right side ) +// PlotTicker represents axis ticks type PlotTicker struct { Position float64 Label string } +// PlotCanvasWidget represents a giu plot widget. type PlotCanvasWidget struct { title string xLabel string @@ -43,6 +49,7 @@ type PlotCanvasWidget struct { plots []PlotWidget } +// Plot adds creates a new plot widget. func Plot(title string) *PlotCanvasWidget { return &PlotCanvasWidget{ title: title, @@ -98,6 +105,7 @@ func (p *PlotCanvasWidget) XTicks(ticks []PlotTicker, showDefault bool) *PlotCan return p } +// YTicks sets y axis ticks func (p *PlotCanvasWidget) YTicks(ticks []PlotTicker, showDefault bool, yAxis ImPlotYAxis) *PlotCanvasWidget { length := len(ticks) if length == 0 { @@ -119,6 +127,7 @@ func (p *PlotCanvasWidget) YTicks(ticks []PlotTicker, showDefault bool, yAxis Im return p } +// Flags sets plot canvas flags func (p *PlotCanvasWidget) Flags(flags PlotFlags) *PlotCanvasWidget { p.flags = flags return p diff --git a/ProgressIndicator.go b/ProgressIndicator.go index f2198163..e5fe2c1c 100644 --- a/ProgressIndicator.go +++ b/ProgressIndicator.go @@ -8,12 +8,14 @@ import ( "github.com/AllenDang/imgui-go" ) -type ProgressIndicatorState struct { +var _ Disposable = &progressIndicatorState{} + +type progressIndicatorState struct { angle float64 stop bool } -func (ps *ProgressIndicatorState) Update() { +func (ps *progressIndicatorState) update() { ticker := time.NewTicker(time.Second / 60) for !ps.stop { if ps.angle > 6.2 { @@ -28,10 +30,16 @@ func (ps *ProgressIndicatorState) Update() { ticker.Stop() } -func (ps *ProgressIndicatorState) Dispose() { +// Dispose implements Disposable interface +func (ps *progressIndicatorState) Dispose() { ps.stop = true } +// static check to ensure if ProgressIndicatorWidget implements Widget interface +var _ Widget = &ProgressIndicatorWidget{} + +// ProgressIndicatorWidget represents progress indicator widget +// see examples/extrawidgets/ type ProgressIndicatorWidget struct { internalID string width float32 @@ -40,6 +48,7 @@ type ProgressIndicatorWidget struct { label string } +// ProgressIndicator creates a new ProgressIndicatorWidget func ProgressIndicator(label string, width, height, radius float32) *ProgressIndicatorWidget { return &ProgressIndicatorWidget{ internalID: "###giu-progress-indicator", @@ -50,15 +59,16 @@ func ProgressIndicator(label string, width, height, radius float32) *ProgressInd } } +// Build implements Widget interface func (p *ProgressIndicatorWidget) Build() { // State exists if s := Context.GetState(p.internalID); s == nil { // Register state and start go routine - ps := ProgressIndicatorState{angle: 0.0, stop: false} + ps := progressIndicatorState{angle: 0.0, stop: false} Context.SetState(p.internalID, &ps) - go ps.Update() + go ps.update() } else { - state := s.(*ProgressIndicatorState) + state := s.(*progressIndicatorState) child := Child().Border(false).Size(p.width, p.height).Layout(Layout{ Custom(func() { diff --git a/SplitLayout.go b/SplitLayout.go index 3669cebb..853e1103 100644 --- a/SplitLayout.go +++ b/SplitLayout.go @@ -13,11 +13,14 @@ const ( DirectionVertical ) +var _ Disposable = &SplitLayoutState{} + type SplitLayoutState struct { delta float32 sashPos float32 } +// Dispose implements Disposable interface func (s *SplitLayoutState) Dispose() { // Nothing to do here. } diff --git a/Window.go b/Window.go index aa8c99b3..9787bb9f 100644 --- a/Window.go +++ b/Window.go @@ -6,6 +6,9 @@ import ( "github.com/AllenDang/imgui-go" ) +// SingleWindow creates one window filling all available space +// in MasterWindow. If SingleWindow is set up, no other windows can't be +// definied. func SingleWindow() *WindowWidget { size := Context.platform.DisplaySize() title := fmt.Sprintf("SingleWindow_%d", Context.GetWidgetIndex()) @@ -32,16 +35,23 @@ func SingleWindowWithMenuBar() *WindowWidget { imgui.WindowFlagsNoResize).Size(size[0], size[1]) } +var _ Disposable = &windowState{} + type windowState struct { hasFocus bool currentPosition, currentSize imgui.Vec2 } +// Dispose implements Disposable interface func (s *windowState) Dispose() { // noop } +// WindowWidget represents imgui.Window +// Windows are used to display ui widgets. +// They are in second place in the giu hierarchy (after the MasterWindow) +// NOTE: to disable multiple window, use SingleWindow type WindowWidget struct { title string open *bool @@ -51,32 +61,44 @@ type WindowWidget struct { bringToFront bool } +// Window creates a WindowWidget func Window(title string) *WindowWidget { return &WindowWidget{ title: title, } } +// IsOpen sets if window widget is `opened` (minimalized) func (w *WindowWidget) IsOpen(open *bool) *WindowWidget { w.open = open return w } +// Flags sets window flags func (w *WindowWidget) Flags(flags WindowFlags) *WindowWidget { w.flags = flags return w } +// Size sets window size +// NOTE: size can be changed by user, if you want to prevent +// user from changing window size, use NoResize flag func (w *WindowWidget) Size(width, height float32) *WindowWidget { w.width, w.height = width, height return w } +// Pos sets the window start position +// NOTE: The position could be changed by user later. +// To prevent user from changin window position use +// WIndowFlagsNoMove func (w *WindowWidget) Pos(x, y float32) *WindowWidget { w.x, w.y = x, y return w } +// Layout is a final step of the window setup. +// it should be called to add a layout to the window and build it. func (w *WindowWidget) Layout(widgets ...Widget) { if widgets == nil { return @@ -120,24 +142,30 @@ func (w *WindowWidget) Layout(widgets ...Widget) { imgui.End() } +// CurrentPosition returns a current position of the window func (w *WindowWidget) CurrentPosition() (x, y float32) { pos := w.getState().currentPosition return pos.X, pos.Y } +// CurrentSize returns current size of the window func (w *WindowWidget) CurrentSize() (width, height float32) { size := w.getState().currentSize return size.X, size.Y } +// BringToFront sets window focused func (w *WindowWidget) BringToFront() { w.bringToFront = true } +// HasFocus returns true if window is focused func (w *WindowWidget) HasFocus() bool { return w.getState().hasFocus } +// Registerkeyboardshortcuts adds local (window-level) keyboard shortcuts +// see InputHandler.go func (w *WindowWidget) RegisterKeyboardShortcuts(s ...WindowShortcut) *WindowWidget { if w.HasFocus() { for _, shortcut := range s { From fb8c8ceebb41fb1b39455962e818c9c4a0d935c0 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 21:00:04 +0200 Subject: [PATCH 14/27] widgets: add build methods comments --- Flags.go | 1 + Widgets.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/Flags.go b/Flags.go index b420c2be..66ab2c25 100644 --- a/Flags.go +++ b/Flags.go @@ -127,6 +127,7 @@ const ( SelectableFlagsDisabled SelectableFlags = 1 << 3 ) +// TabItemFlags represents tab item flags type TabItemFlags int const ( diff --git a/Widgets.go b/Widgets.go index 4b0f28e2..25d4edbc 100644 --- a/Widgets.go +++ b/Widgets.go @@ -14,20 +14,27 @@ import ( "github.com/sahilm/fuzzy" ) +// GenAutoID automatically generates fidget's id func GenAutoID(id string) string { return fmt.Sprintf("%s##%d", id, Context.GetWidgetIndex()) } +var _ Widget = &RowWidget{} + +// RowWidget joins a layout into one line +// calls imgui.SameLine() type RowWidget struct { widgets Layout } +// Row creates RowWidget func Row(widgets ...Widget) *RowWidget { return &RowWidget{ widgets: widgets, } } +// Build implements Widget interface func (l *RowWidget) Build() { for index, w := range l.widgets { _, isTooltip := w.(*TooltipWidget) @@ -49,10 +56,16 @@ func (l *RowWidget) Build() { } } +// SameLine wrapps imgui.SomeLine +// Don't use if you don't have to (use RowWidget instead) func SameLine() { imgui.SameLine() } +var _ Widget = &InputTextMultilineWidget{} + +// InputTextMultilineWidget represents multiline text input widget +// see examples/widgets/ type InputTextMultilineWidget struct { label string text *string @@ -62,6 +75,7 @@ type InputTextMultilineWidget struct { onChange func() } +// InputTextMultiline creates InputTextMultilineWidget func InputTextMultiline(text *string) *InputTextMultilineWidget { return &InputTextMultilineWidget{ text: text, @@ -73,15 +87,18 @@ func InputTextMultiline(text *string) *InputTextMultilineWidget { } } +// Label sets input field label func (i *InputTextMultilineWidget) Label(label string) *InputTextMultilineWidget { i.label = tStr(label) return i } +// Labelf is formatting version of Label func (i *InputTextMultilineWidget) Labelf(format string, args ...interface{}) *InputTextMultilineWidget { return i.Label(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (i *InputTextMultilineWidget) Build() { if len(i.label) == 0 { i.label = GenAutoID(i.label) @@ -121,6 +138,7 @@ type ButtonWidget struct { onClick func() } +// Build implements Widget interface func (b *ButtonWidget) Build() { if b.disabled { imgui.BeginDisabled(true) @@ -167,6 +185,7 @@ func Bullet() *BulletWidget { return &BulletWidget{} } +// Build implements Widget interface func (b *BulletWidget) Build() { imgui.Bullet() } @@ -185,6 +204,7 @@ func BulletTextf(format string, args ...interface{}) *BulletTextWidget { return BulletText(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (bt *BulletTextWidget) Build() { imgui.BulletText(bt.text) } @@ -213,6 +233,7 @@ func (b *ArrowButtonWidget) ID(id string) *ArrowButtonWidget { return b } +// Build implements Widget interface func (b *ArrowButtonWidget) Build() { if imgui.ArrowButton(b.id, uint8(b.dir)) && b.onClick != nil { b.onClick() @@ -240,6 +261,7 @@ func SmallButtonf(format string, args ...interface{}) *SmallButtonWidget { return SmallButton(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (b *SmallButtonWidget) Build() { if imgui.SmallButton(GenAutoID(b.id)) && b.onClick != nil { b.onClick() @@ -278,6 +300,7 @@ func InvisibleButton() *InvisibleButtonWidget { } } +// 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 { b.onClick() @@ -296,6 +319,7 @@ type ImageButtonWidget struct { onClick func() } +// Build implements Widget interface func (b *ImageButtonWidget) Build() { if b.texture == nil && b.texture.id == 0 { return @@ -401,6 +425,7 @@ func (b *ImageButtonWithRgbaWidget) FramePadding(padding int) *ImageButtonWithRg return b } +// Build implements Widget interface func (b *ImageButtonWithRgbaWidget) Build() { if state := Context.GetState(b.id); state == nil { Context.SetState(b.id, &ImageState{}) @@ -422,6 +447,7 @@ type CheckboxWidget struct { onChange func() } +// Build implements Widget interface func (c *CheckboxWidget) Build() { if imgui.Checkbox(GenAutoID(c.text), c.selected) && c.onChange != nil { c.onChange() @@ -447,6 +473,7 @@ type RadioButtonWidget struct { onChange func() } +// Build implements Widget interface func (r *RadioButtonWidget) Build() { if imgui.RadioButton(GenAutoID(r.text), r.active) && r.onChange != nil { r.onChange() @@ -474,6 +501,7 @@ type ChildWidget struct { layout Layout } +// Build implements Widget interface func (c *ChildWidget) Build() { if imgui.BeginChildV(GenAutoID("Child"), imgui.Vec2{X: c.width, Y: c.height}, c.border, int(c.flags)) { c.layout.Build() @@ -546,6 +574,7 @@ func (cc *ComboCustomWidget) Size(width float32) *ComboCustomWidget { return cc } +// Build implements Widget interface func (cc *ComboCustomWidget) Build() { if cc.width > 0 { imgui.PushItemWidth(cc.width) @@ -589,6 +618,7 @@ func (c *ComboWidget) Flags(flags ComboFlags) *ComboWidget { return c } +// Build implements Widget interface func (c *ComboWidget) Build() { if c.width > 0 { imgui.PushItemWidth(c.width) @@ -648,6 +678,7 @@ func (c *ContextMenuWidget) ID(id string) *ContextMenuWidget { return c } +// Build implements Widget interface func (c *ContextMenuWidget) Build() { if imgui.BeginPopupContextItemV(c.id, int(c.mouseButton)) { c.layout.Build() @@ -685,6 +716,7 @@ func (d *DragIntWidget) Format(format string) *DragIntWidget { return d } +// Build implements Widget interface func (d *DragIntWidget) Build() { imgui.DragIntV(GenAutoID(d.label), d.value, d.speed, d.min, d.max, d.format) } @@ -700,6 +732,7 @@ func Column(widgets ...Widget) *ColumnWidget { } } +// Build implements Widget interface func (g *ColumnWidget) Build() { imgui.BeginGroup() @@ -755,6 +788,7 @@ func (i *ImageWidget) Size(width, height float32) *ImageWidget { return i } +// Build implements Widget interface func (i *ImageWidget) Build() { size := imgui.Vec2{X: i.width, Y: i.height} rect := imgui.ContentRegionAvail() @@ -823,6 +857,7 @@ func (i *ImageWithRgbaWidget) OnClick(cb func()) *ImageWithRgbaWidget { return i } +// Build implements Widget interface func (i *ImageWithRgbaWidget) Build() { if i.rgba != nil { var imgState *ImageState @@ -867,6 +902,7 @@ func (i *ImageWithFileWidget) OnClick(cb func()) *ImageWithFileWidget { return i } +// Build implements Widget interface func (i *ImageWithFileWidget) Build() { imgState := &ImageState{} if state := Context.GetState(i.id); state == nil { @@ -945,6 +981,7 @@ func (i *ImageWithURLWidget) LayoutForFailure(widgets ...Widget) *ImageWithURLWi return i } +// Build implements Widget interface func (i *ImageWithURLWidget) Build() { var imgState *ImageState = &ImageState{} if state := Context.GetState(i.id); state == nil { @@ -1084,6 +1121,7 @@ func (i *InputTextWidget) OnChange(onChange func()) *InputTextWidget { return i } +// Build implements Widget interface func (i *InputTextWidget) Build() { // Get state var state *inputTextState @@ -1180,6 +1218,7 @@ func (i *InputIntWidget) OnChange(onChange func()) *InputIntWidget { return i } +// Build implements Widget interface func (i *InputIntWidget) Build() { if i.width != 0 { PushItemWidth(i.width) @@ -1240,6 +1279,7 @@ func (i *InputFloatWidget) OnChange(onChange func()) *InputFloatWidget { return i } +// Build implements Widget interface func (i *InputFloatWidget) Build() { if i.width != 0 { PushItemWidth(i.width) @@ -1278,6 +1318,7 @@ func (l *LabelWidget) Font(font *FontInfo) *LabelWidget { return l } +// Build implements Widget interface func (l *LabelWidget) Build() { if l.wrapped { PushTextWrapPos() @@ -1308,6 +1349,7 @@ func (m *MainMenuBarWidget) Layout(widgets ...Widget) *MainMenuBarWidget { return m } +// Build implements Widget interface func (m *MainMenuBarWidget) Build() { if imgui.BeginMainMenuBar() { m.layout.Build() @@ -1330,6 +1372,7 @@ func (m *MenuBarWidget) Layout(widgets ...Widget) *MenuBarWidget { return m } +// Build implements Widget interface func (m *MenuBarWidget) Build() { if imgui.BeginMenuBar() { m.layout.Build() @@ -1372,6 +1415,7 @@ func (m *MenuItemWidget) OnClick(onClick func()) *MenuItemWidget { return m } +// Build implements Widget interface func (m *MenuItemWidget) Build() { if imgui.MenuItemV(GenAutoID(m.label), "", m.selected, m.enabled) && m.onClick != nil { m.onClick() @@ -1406,6 +1450,7 @@ func (m *MenuWidget) Layout(widgets ...Widget) *MenuWidget { return m } +// Build implements Widget interface func (m *MenuWidget) Build() { if imgui.BeginMenuV(GenAutoID(m.label), m.enabled) { m.layout.Build() @@ -1437,6 +1482,7 @@ func (p *PopupWidget) Layout(widgets ...Widget) *PopupWidget { return p } +// Build implements Widget interface func (p *PopupWidget) Build() { if imgui.BeginPopup(p.name, int(p.flags)) { p.layout.Build() @@ -1475,6 +1521,7 @@ func (p *PopupModalWidget) Layout(widgets ...Widget) *PopupModalWidget { return p } +// Build implements Widget interface func (p *PopupModalWidget) Build() { if imgui.BeginPopupModalV(p.name, p.open, int(p.flags)) { p.layout.Build() @@ -1521,6 +1568,7 @@ func (p *ProgressBarWidget) Overlayf(format string, args ...interface{}) *Progre return p.Overlay(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (p *ProgressBarWidget) Build() { imgui.ProgressBarV(p.fraction, imgui.Vec2{X: p.width, Y: p.height}, p.overlay) } @@ -1578,6 +1626,7 @@ func (s *SelectableWidget) OnDClick(onDClick func()) *SelectableWidget { return s } +// Build implements Widget interface func (s *SelectableWidget) Build() { // If onDClick is set, check flags and set related flag when necessary if s.onDClick != nil && s.flags&SelectableFlagsAllowDoubleClick != 0 { @@ -1595,6 +1644,7 @@ func (s *SelectableWidget) Build() { type SeparatorWidget struct{} +// Build implements Widget interface func (s *SeparatorWidget) Build() { imgui.Separator() } @@ -1650,6 +1700,7 @@ func (s *SliderIntWidget) Labelf(format string, args ...interface{}) *SliderIntW return s.Label(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (s *SliderIntWidget) Build() { if s.width != 0 { PushItemWidth(s.width) @@ -1715,6 +1766,7 @@ func (vs *VSliderIntWidget) Labelf(format string, args ...interface{}) *VSliderI return vs.Label(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (vs *VSliderIntWidget) Build() { if imgui.VSliderIntV( GenAutoID(vs.label), @@ -1776,6 +1828,7 @@ func (sf *SliderFloatWidget) Labelf(format string, args ...interface{}) *SliderF return sf.Label(fmt.Sprintf(format, args...)) } +// Build implements Widget interface func (sf *SliderFloatWidget) Build() { if sf.width != 0 { PushItemWidth(sf.width) @@ -1792,6 +1845,7 @@ type DummyWidget struct { height float32 } +// Build implements Widget interface func (d *DummyWidget) Build() { w, h := GetAvailableRegion() @@ -1853,6 +1907,7 @@ func (h *HSplitterWidget) ID(id string) *HSplitterWidget { return h } +// Build implements Widget interface func (h *HSplitterWidget) Build() { // Calc line position. width := int(40 * Context.GetPlatform().GetContentScale()) @@ -1926,6 +1981,7 @@ func (v *VSplitterWidget) ID(id string) *VSplitterWidget { return v } +// Build implements Widget interface func (v *VSplitterWidget) Build() { // Calc line position. width := int(2 * Context.GetPlatform().GetContentScale()) @@ -1994,6 +2050,7 @@ func (t *TabItemWidget) Layout(widgets ...Widget) *TabItemWidget { return t } +// Build implements Widget interface func (t *TabItemWidget) Build() { if imgui.BeginTabItemV(t.label, t.open, int(t.flags)) { t.layout.Build() @@ -2028,6 +2085,7 @@ func (t *TabBarWidget) TabItems(items ...*TabItemWidget) *TabBarWidget { return t } +// Build implements Widget interface func (t *TabBarWidget) Build() { buildingID := t.id if len(buildingID) == 0 { @@ -2072,6 +2130,7 @@ func (r *TableRowWidget) MinHeight(height float64) *TableRowWidget { return r } +// Build implements Widget interface func (r *TableRowWidget) Build() { imgui.TableNextRow(imgui.TableRowFlags(r.flags), r.minRowHeight) @@ -2123,6 +2182,7 @@ func (c *TableColumnWidget) UserID(id uint32) *TableColumnWidget { return c } +// Build implements Widget interface func (c *TableColumnWidget) Build() { imgui.TableSetupColumn(c.label, imgui.TableColumnFlags(c.flags), c.innerWidthOrWeight, c.userID) } @@ -2187,6 +2247,7 @@ func (t *TableWidget) Flags(flags TableFlags) *TableWidget { return t } +// Build implements Widget interface func (t *TableWidget) Build() { if len(t.rows) == 0 { return @@ -2255,6 +2316,7 @@ func (ttr *TreeTableRowWidget) Flags(flags TreeNodeFlags) *TreeTableRowWidget { return ttr } +// Build implements Widget interface func (ttr *TreeTableRowWidget) Build() { imgui.TableNextRow(0, 0) imgui.TableNextColumn() @@ -2332,6 +2394,7 @@ func (tt *TreeTableWidget) Rows(rows ...*TreeTableRowWidget) *TreeTableWidget { return tt } +// Build implements Widget interface func (tt *TreeTableWidget) Build() { if len(tt.rows) == 0 { return @@ -2367,6 +2430,7 @@ type TooltipWidget struct { layout Layout } +// Build implements Widget interface func (t *TooltipWidget) Build() { if imgui.IsItemHovered() { if t.layout != nil { @@ -2432,6 +2496,7 @@ func (t *TreeNodeWidget) Layout(widgets ...Widget) *TreeNodeWidget { return t } +// Build implements Widget interface func (t *TreeNodeWidget) Build() { open := imgui.TreeNodeV(t.label, int(t.flags)) @@ -2449,6 +2514,7 @@ func (t *TreeNodeWidget) Build() { type SpacingWidget struct{} +// Build implements Widget interface func (s *SpacingWidget) Build() { imgui.Spacing() } @@ -2461,6 +2527,7 @@ type CustomWidget struct { builder func() } +// Build implements Widget interface func (c *CustomWidget) Build() { if c.builder != nil { c.builder() @@ -2487,6 +2554,7 @@ func Condition(cond bool, layoutIf Layout, layoutElse Layout) *ConditionWidget { } } +// Build implements Widget interface func (c *ConditionWidget) Build() { if c.cond { if c.layoutIf != nil { @@ -2583,6 +2651,7 @@ func (l *ListBoxWidget) OnMenu(onMenu func(selectedIndex int, menu string)) *Lis return l } +// Build implements Widget interface func (l *ListBoxWidget) Build() { var state *ListBoxState if s := Context.GetState(l.id); s == nil { @@ -2667,6 +2736,7 @@ func (d *DatePickerWidget) OnChange(onChange func()) *DatePickerWidget { return d } +// Build implements Widget interface func (d *DatePickerWidget) Build() { if d.date == nil { return @@ -2852,6 +2922,7 @@ func (ce *ColorEditWidget) Size(width float32) *ColorEditWidget { return ce } +// Build implements Widget interface func (ce *ColorEditWidget) Build() { c := ToVec4Color(*ce.color) col := [4]float32{ From 7b32c8c17e7e3ca8640d3bacc2090f7f1c2843e1 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 21:09:59 +0200 Subject: [PATCH 15/27] widgets: add static checks --- Widgets.go | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/Widgets.go b/Widgets.go index 25d4edbc..05a65cd8 100644 --- a/Widgets.go +++ b/Widgets.go @@ -130,6 +130,8 @@ func (i *InputTextMultilineWidget) Size(width, height float32) *InputTextMultili return i } +var _ Widget = &ButtonWidget{} + type ButtonWidget struct { id string width float32 @@ -179,6 +181,8 @@ func Buttonf(format string, args ...interface{}) *ButtonWidget { return Button(fmt.Sprintf(format, args...)) } +var _ Widget = &BulletWidget{} + type BulletWidget struct{} func Bullet() *BulletWidget { @@ -190,6 +194,8 @@ func (b *BulletWidget) Build() { imgui.Bullet() } +var _ Widget = &BulletTextWidget{} + type BulletTextWidget struct { text string } @@ -209,6 +215,8 @@ func (bt *BulletTextWidget) Build() { imgui.BulletText(bt.text) } +var _ Widget = &ArrowButtonWidget{} + type ArrowButtonWidget struct { id string dir Direction @@ -240,6 +248,8 @@ func (b *ArrowButtonWidget) Build() { } } +var _ Widget = &SmallButtonWidget{} + type SmallButtonWidget struct { id string onClick func() @@ -268,6 +278,8 @@ func (b *SmallButtonWidget) Build() { } } +var _ Widget = &InvisibleButtonWidget{} + type InvisibleButtonWidget struct { id string width float32 @@ -307,6 +319,8 @@ func (b *InvisibleButtonWidget) Build() { } } +var _ Widget = &ImageButtonWidget{} + type ImageButtonWidget struct { texture *Texture width float32 @@ -381,6 +395,8 @@ func ImageButton(texture *Texture) *ImageButtonWidget { } } +var _ Widget = &ImageButtonWithRgbaWidget{} + type ImageButtonWithRgbaWidget struct { *ImageButtonWidget rgba image.Image @@ -441,6 +457,8 @@ func (b *ImageButtonWithRgbaWidget) Build() { b.ImageButtonWidget.Build() } +var _ Widget = &CheckboxWidget{} + type CheckboxWidget struct { text string selected *bool @@ -467,6 +485,8 @@ func Checkbox(text string, selected *bool) *CheckboxWidget { } } +var _ Widget = &RadioButtonWidget{} + type RadioButtonWidget struct { text string active bool @@ -493,6 +513,8 @@ func RadioButton(text string, active bool) *RadioButtonWidget { } } +var _ Widget = &ChildWidget{} + type ChildWidget struct { width float32 height float32 @@ -541,6 +563,8 @@ func Child() *ChildWidget { } } +var _ Widget = &ComboCustomWidget{} + type ComboCustomWidget struct { label string previewValue string @@ -587,6 +611,8 @@ func (cc *ComboCustomWidget) Build() { } } +var _ Widget = &ComboWidget{} + type ComboWidget struct { label string previewValue string @@ -649,6 +675,8 @@ func (c *ComboWidget) OnChange(onChange func()) *ComboWidget { return c } +var _ Widget = &ContextMenuWidget{} + type ContextMenuWidget struct { id string mouseButton MouseButton @@ -686,6 +714,8 @@ func (c *ContextMenuWidget) Build() { } } +var _ Widget = &DragIntWidget{} + type DragIntWidget struct { label string value *int32 @@ -721,6 +751,8 @@ func (d *DragIntWidget) Build() { imgui.DragIntV(GenAutoID(d.label), d.value, d.speed, d.min, d.max, d.format) } +var _ Widget = &ColumnWidget{} + type ColumnWidget struct { widgets Layout } @@ -741,6 +773,8 @@ func (g *ColumnWidget) Build() { imgui.EndGroup() } +var _ Widget = &ImageWidget{} + type ImageWidget struct { texture *Texture width float32 @@ -833,6 +867,8 @@ func (is *ImageState) Dispose() { } } +var _ Widget = &ImageWithRgbaWidget{} + type ImageWithRgbaWidget struct { id string rgba image.Image @@ -878,6 +914,8 @@ func (i *ImageWithRgbaWidget) Build() { i.img.Build() } +var _ Widget = &ImageWithFileWidget{} + type ImageWithFileWidget struct { id string imgPath string @@ -923,6 +961,8 @@ func (i *ImageWithFileWidget) Build() { i.img.Build() } +var _ Widget = &ImageWithURLWidget{} + type ImageWithURLWidget struct { id string imgURL string @@ -1049,6 +1089,8 @@ func (i *ImageWithURLWidget) Build() { } } +var _ Widget = &InputTextWidget{} + type InputTextWidget struct { label string hint string @@ -1176,6 +1218,8 @@ func (i *InputTextWidget) Build() { } } +var _ Widget = &InputIntWidget{} + type InputIntWidget struct { label string value *int32 @@ -1230,6 +1274,8 @@ func (i *InputIntWidget) Build() { } } +var _ Widget = &InputFloatWidget{} + type InputFloatWidget struct { label string value *float32 @@ -1291,6 +1337,8 @@ func (i *InputFloatWidget) Build() { } } +var _ Widget = &LabelWidget{} + type LabelWidget struct { label string fontInfo *FontInfo @@ -1334,6 +1382,8 @@ func (l *LabelWidget) Build() { imgui.Text(l.label) } +var _ Widget = &MainMenuBarWidget{} + type MainMenuBarWidget struct { layout Layout } @@ -1357,6 +1407,8 @@ func (m *MainMenuBarWidget) Build() { } } +var _ Widget = &MenuBarWidget{} + type MenuBarWidget struct { layout Layout } @@ -1380,6 +1432,8 @@ func (m *MenuBarWidget) Build() { } } +var _ Widget = &MenuItemWidget{} + type MenuItemWidget struct { label string selected bool @@ -1422,6 +1476,8 @@ func (m *MenuItemWidget) Build() { } } +var _ Widget = &MenuWidget{} + type MenuWidget struct { label string enabled bool @@ -1458,6 +1514,8 @@ func (m *MenuWidget) Build() { } } +var _ Widget = &PopupWidget{} + type PopupWidget struct { name string flags WindowFlags @@ -1490,6 +1548,8 @@ func (p *PopupWidget) Build() { } } +var _ Widget = &PopupModalWidget{} + type PopupModalWidget struct { name string open *bool @@ -1537,6 +1597,8 @@ func CloseCurrentPopup() { imgui.CloseCurrentPopup() } +var _ Widget = &ProgressBarWidget{} + type ProgressBarWidget struct { fraction float32 width float32 @@ -1573,6 +1635,8 @@ func (p *ProgressBarWidget) Build() { imgui.ProgressBarV(p.fraction, imgui.Vec2{X: p.width, Y: p.height}, p.overlay) } +var _ Widget = &SelectableWidget{} + type SelectableWidget struct { label string selected bool @@ -1642,6 +1706,8 @@ func (s *SelectableWidget) Build() { } } +var _ Widget = &SeparatorWidget{} + type SeparatorWidget struct{} // Build implements Widget interface @@ -1653,6 +1719,8 @@ func Separator() *SeparatorWidget { return &SeparatorWidget{} } +var _ Widget = &SliderIntWidget{} + type SliderIntWidget struct { label string value *int32 @@ -1712,6 +1780,8 @@ func (s *SliderIntWidget) Build() { } } +var _ Widget = &VSliderIntWidget{} + type VSliderIntWidget struct { label string width float32 @@ -1781,6 +1851,8 @@ func (vs *VSliderIntWidget) Build() { } } +var _ Widget = &SliderFloatWidget{} + type SliderFloatWidget struct { label string value *float32 @@ -1840,6 +1912,8 @@ func (sf *SliderFloatWidget) Build() { } } +var _ Widget = &DummyWidget{} + type DummyWidget struct { width float32 height float32 @@ -1867,6 +1941,8 @@ func Dummy(width, height float32) *DummyWidget { } } +var _ Widget = &HSplitterWidget{} + type HSplitterWidget struct { id string width float32 @@ -1941,6 +2017,8 @@ func (h *HSplitterWidget) Build() { canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), color, 0, 0) } +var _ Widget = &VSplitterWidget{} + type VSplitterWidget struct { id string width float32 @@ -2015,6 +2093,8 @@ func (v *VSplitterWidget) Build() { canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), color, 0, 0) } +var _ Widget = &TabItemWidget{} + type TabItemWidget struct { label string open *bool @@ -2058,6 +2138,8 @@ func (t *TabItemWidget) Build() { } } +var _ Widget = &TabBarWidget{} + type TabBarWidget struct { id string flags TabBarFlags @@ -2099,6 +2181,8 @@ func (t *TabBarWidget) Build() { } } +var _ Widget = &TableRowWidget{} + type TableRowWidget struct { flags TableRowFlags minRowHeight float64 @@ -2151,6 +2235,8 @@ func (r *TableRowWidget) Build() { } } +var _ Widget = &TableColumnWidget{} + type TableColumnWidget struct { label string flags TableColumnFlags @@ -2187,6 +2273,8 @@ func (c *TableColumnWidget) Build() { imgui.TableSetupColumn(c.label, imgui.TableColumnFlags(c.flags), c.innerWidthOrWeight, c.userID) } +var _ Widget = &TableWidget{} + type TableWidget struct { flags TableFlags size imgui.Vec2 @@ -2292,6 +2380,8 @@ func (t *TableWidget) Build() { } } +var _ Widget = &TreeTableRowWidget{} + type TreeTableRowWidget struct { label string flags TreeNodeFlags @@ -2350,6 +2440,8 @@ func (ttr *TreeTableRowWidget) Build() { } } +var _ Widget = &TreeTableWidget{} + type TreeTableWidget struct { flags TableFlags size imgui.Vec2 @@ -2425,6 +2517,8 @@ func (tt *TreeTableWidget) Build() { } } +var _ Widget = &TooltipWidget{} + type TooltipWidget struct { tip string layout Layout @@ -2459,6 +2553,8 @@ func (t *TooltipWidget) Layout(widgets ...Widget) *TooltipWidget { return t } +var _ Widget = &TreeNodeWidget{} + type TreeNodeWidget struct { label string flags TreeNodeFlags @@ -2512,6 +2608,8 @@ func (t *TreeNodeWidget) Build() { } } +var _ Widget = &SpacingWidget{} + type SpacingWidget struct{} // Build implements Widget interface @@ -2523,6 +2621,8 @@ func Spacing() *SpacingWidget { return &SpacingWidget{} } +var _ Widget = &CustomWidget{} + type CustomWidget struct { builder func() } @@ -2540,6 +2640,8 @@ func Custom(builder func()) *CustomWidget { } } +var _ Widget = &ConditionWidget{} + type ConditionWidget struct { cond bool layoutIf Layout @@ -2594,6 +2696,8 @@ func (s *ListBoxState) Dispose() { // Nothing to do here. } +var _ Widget = &ListBoxWidget{} + type ListBoxWidget struct { id string width float32 @@ -2708,6 +2812,8 @@ func (l *ListBoxWidget) Build() { child.Build() } +var _ Widget = &DatePickerWidget{} + type DatePickerWidget struct { id string date *time.Time @@ -2891,6 +2997,8 @@ func (d *DatePickerWidget) calendarField(day int) Widget { }) } +var _ Widget = &ColorEditWidget{} + type ColorEditWidget struct { label string color *color.RGBA From 1e959cf418d0981bd59533cac62374a56d1c5475 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 21:14:10 +0200 Subject: [PATCH 16/27] fix stylecheck and gocritics --- StackWidget.go | 1 + Style.go | 2 +- Widgets.go | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/StackWidget.go b/StackWidget.go index 145420f3..e2e5e4d5 100644 --- a/StackWidget.go +++ b/StackWidget.go @@ -33,6 +33,7 @@ func (s *StackWidget) Build() { if s.visible >= 0 && s.visible < int32(len(s.layouts)) { s.layouts[s.visible].Build() // remove visible layout from layouts list + // nolint:gocritic // remove visible widget layouts = append(s.layouts[:s.visible], s.layouts[:s.visible+1]...) } diff --git a/Style.go b/Style.go index af7a927a..016acbd1 100644 --- a/Style.go +++ b/Style.go @@ -356,7 +356,7 @@ func (ss *StyleSetter) SetColor(colorID StyleColorID, col color.RGBA) *StyleSett return ss } -/// SetStyle sets styleVarID to width and height +// SetStyle sets styleVarID to width and height func (ss *StyleSetter) SetStyle(varID StyleVarID, width, height float32) *StyleSetter { ss.styles[varID] = imgui.Vec2{X: width, Y: height} return ss diff --git a/Widgets.go b/Widgets.go index 05a65cd8..e595c017 100644 --- a/Widgets.go +++ b/Widgets.go @@ -1023,7 +1023,8 @@ func (i *ImageWithURLWidget) LayoutForFailure(widgets ...Widget) *ImageWithURLWi // Build implements Widget interface func (i *ImageWithURLWidget) Build() { - var imgState *ImageState = &ImageState{} + imgState := &ImageState{} + if state := Context.GetState(i.id); state == nil { Context.SetState(i.id, imgState) From 5eb29c8562e4dfb91673edbcb845bad4a0363c5f Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 21:20:25 +0200 Subject: [PATCH 17/27] event handler: fix comments --- .golangci.yml | 2 +- EventHandler.go | 12 ++++++------ MasterWindow.go | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 656ad88f..a397f12c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -51,7 +51,7 @@ linters: - goconst - gocritic - gocyclo - - godox + #- godox - goerr113 - gofmt - gofumpt diff --git a/EventHandler.go b/EventHandler.go index 3c14c235..4acb9021 100644 --- a/EventHandler.go +++ b/EventHandler.go @@ -55,7 +55,7 @@ func (eh *EventHandler) OnActivate(cb func()) *EventHandler { return eh } -// OnActivate sets callback when item gets deactivated +// OnDeactivate sets callback when item gets deactivated func (eh *EventHandler) OnDeactivate(cb func()) *EventHandler { eh.onDeactivate = cb return eh @@ -69,13 +69,13 @@ func (eh *EventHandler) OnKeyDown(key Key, cb func()) *EventHandler { return eh } -// OnKeyDown sets callback when key `key` is pressed +// OnKeyPressed sets callback when key `key` is pressed func (eh *EventHandler) OnKeyPressed(key Key, cb func()) *EventHandler { eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyPressed}) return eh } -// OnKeyDown sets callback when key `key` is released +// OnKeyReleaed sets callback when key `key` is released func (eh *EventHandler) OnKeyReleased(key Key, cb func()) *EventHandler { eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyReleased}) return eh @@ -89,19 +89,19 @@ func (eh *EventHandler) OnClick(mouseButton MouseButton, callback func()) *Event return eh } -// OnKeyDown sets callback when mouse button `mouseButton` is double-clicked +// OnDClick sets callback when mouse button `mouseButton` is double-clicked func (eh *EventHandler) OnDClick(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseDoubleClicked}) return eh } -// OnKeyDown sets callback when mouse button `mouseButton` is down +// OnMouseDown sets callback when mouse button `mouseButton` is down func (eh *EventHandler) OnMouseDown(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseDown}) return eh } -// OnKeyDown sets callback when mouse button `mouseButton` is released +// OnMouseReleased sets callback when mouse button `mouseButton` is released func (eh *EventHandler) OnMouseReleased(mouseButton MouseButton, callback func()) *EventHandler { eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseReleased}) return eh diff --git a/MasterWindow.go b/MasterWindow.go index b06fa01b..75239f93 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -42,7 +42,7 @@ type MasterWindow struct { updateFunc func() } -// MasterWindow creates a new master window and initializes GLFW. +// NewMasterWindow creates a new master window and initializes GLFW. // 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 { From 16e485e9274e94b2178d9165d5f5970238c8a3ab Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sat, 18 Sep 2021 21:32:15 +0200 Subject: [PATCH 18/27] add comment in canvas --- Canvas.go | 14 ++++++++++++++ Flags.go | 1 + Plot.go | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/Canvas.go b/Canvas.go index d8aceedb..82d8507e 100644 --- a/Canvas.go +++ b/Canvas.go @@ -7,16 +7,20 @@ import ( "github.com/AllenDang/imgui-go" ) +// Canvas represents imgui.DrawList +// for more details see examples/canvas type Canvas struct { drawlist imgui.DrawList } +// GetCanvas creates new Canvas func GetCanvas() *Canvas { return &Canvas{ drawlist: imgui.GetWindowDrawList(), } } +// AddLine draws a line (from p1 to p2) func (c *Canvas) AddLine(p1, p2 image.Point, color color.RGBA, thickness float32) { c.drawlist.AddLine(ToVec2(p1), ToVec2(p2), ToVec4Color(color), thickness) } @@ -42,42 +46,52 @@ const ( DrawFlagsRoundCornersMask DrawFlags = DrawFlagsRoundCornersAll | DrawFlagsRoundCornersNone ) +// AddRect draws a rectangle func (c *Canvas) AddRect(pMin, pMax image.Point, color color.RGBA, rounding float32, roundingCorners DrawFlags, thickness float32) { c.drawlist.AddRect(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(roundingCorners), thickness) } +// AddRectFilled draws a rectangle filled with `color` func (c *Canvas) AddRectFilled(pMin, pMax image.Point, color color.RGBA, rounding float32, roundingCorners DrawFlags) { c.drawlist.AddRectFilled(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(roundingCorners)) } +// AddText draws text func (c *Canvas) AddText(pos image.Point, color color.RGBA, text string) { c.drawlist.AddText(ToVec2(pos), ToVec4Color(color), tStr(text)) } +// AddBezierCubic draws bezier cubic func (c *Canvas) AddBezierCubic(pos0, cp0, cp1, pos1 image.Point, color color.RGBA, thickness float32, numSegments int) { c.drawlist.AddBezierCubic(ToVec2(pos0), ToVec2(cp0), ToVec2(cp1), ToVec2(pos1), ToVec4Color(color), thickness, numSegments) } +// AddTriangle draws a triangle func (c *Canvas) AddTriangle(p1, p2, p3 image.Point, color color.RGBA, thickness float32) { c.drawlist.AddTriangle(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec4Color(color), thickness) } +// AddTriangleFilled draws a filled triangle func (c *Canvas) AddTriangleFilled(p1, p2, p3 image.Point, color color.RGBA) { c.drawlist.AddTriangleFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec4Color(color)) } +// AddCircle draws a circle func (c *Canvas) AddCircle(center image.Point, radius float32, color color.RGBA, segments int, thickness float32) { c.drawlist.AddCircle(ToVec2(center), radius, ToVec4Color(color), segments, thickness) } +// AddCircleFilled draws a filled circle func (c *Canvas) AddCircleFilled(center image.Point, radius float32, color color.RGBA) { c.drawlist.AddCircleFilled(ToVec2(center), radius, ToVec4Color(color)) } +// AddQuad draws a quad func (c *Canvas) AddQuad(p1, p2, p3, p4 image.Point, color color.RGBA, thickness float32) { c.drawlist.AddQuad(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(color), thickness) } +// AddQuadFilled draws a filled quad func (c *Canvas) AddQuadFilled(p1, p2, p3, p4 image.Point, color color.RGBA) { c.drawlist.AddQuadFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(color)) } diff --git a/Flags.go b/Flags.go index 66ab2c25..dec943a2 100644 --- a/Flags.go +++ b/Flags.go @@ -328,6 +328,7 @@ const ( ColorEditFlagsInputHSV ColorEditFlags = 1 << 28 ) +// TableFlags represents table flags type TableFlags int // Table flags enum: diff --git a/Plot.go b/Plot.go index 1bd12275..5b78a3ae 100644 --- a/Plot.go +++ b/Plot.go @@ -75,6 +75,7 @@ func Plot(title string) *PlotCanvasWidget { } } +// AxisLimits sets X and Y axis limits func (p *PlotCanvasWidget) AxisLimits(xmin, xmax, ymin, ymax float64, cond ExecCondition) *PlotCanvasWidget { p.xMin = xmin p.xMax = xmax @@ -85,6 +86,7 @@ func (p *PlotCanvasWidget) AxisLimits(xmin, xmax, ymin, ymax float64, cond ExecC return p } +// XTicks sets x axis ticks func (p *PlotCanvasWidget) XTicks(ticks []PlotTicker, showDefault bool) *PlotCanvasWidget { length := len(ticks) if length == 0 { @@ -133,11 +135,13 @@ func (p *PlotCanvasWidget) Flags(flags PlotFlags) *PlotCanvasWidget { return p } +// XAxeFlags sets x axis fags func (p *PlotCanvasWidget) XAxeFlags(flags PlotAxisFlags) *PlotCanvasWidget { p.xFlags = flags return p } +// YAxeFlags sets y axis flags func (p *PlotCanvasWidget) YAxeFlags(yFlags, y2Flags, y3Flags PlotAxisFlags) *PlotCanvasWidget { p.yFlags = yFlags p.y2Flags = y2Flags @@ -145,17 +149,20 @@ func (p *PlotCanvasWidget) YAxeFlags(yFlags, y2Flags, y3Flags PlotAxisFlags) *Pl return p } +// Plots adds plots to plot canvas func (p *PlotCanvasWidget) Plots(plots ...PlotWidget) *PlotCanvasWidget { p.plots = plots return p } +// Size set canvas size func (p *PlotCanvasWidget) Size(width, height int) *PlotCanvasWidget { p.width = width p.height = height return p } +// Build implements Widget interface func (p *PlotCanvasWidget) Build() { if len(p.plots) > 0 { imgui.ImPlotSetNextPlotLimits(p.xMin, p.xMax, p.yMin, p.yMax, imgui.Condition(p.axisLimitCondition)) From 0058b8cb7a05749f1ba2a1ffae38893cd1bcf318 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 11:47:51 +0200 Subject: [PATCH 19/27] plot: add some comments --- Plot.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Plot.go b/Plot.go index 5b78a3ae..ea492759 100644 --- a/Plot.go +++ b/Plot.go @@ -184,6 +184,7 @@ func (p *PlotCanvasWidget) Build() { } } +// PlotBarWidget adds bar plot (column chart) to the canvas type PlotBarWidget struct { title string data []float64 @@ -192,6 +193,7 @@ type PlotBarWidget struct { offset int } +// PlotBar adds a plot bar (column chart) func PlotBar(title string, data []float64) *PlotBarWidget { return &PlotBarWidget{ title: title, @@ -202,25 +204,30 @@ func PlotBar(title string, data []float64) *PlotBarWidget { } } +// Width sets bar width func (p *PlotBarWidget) Width(width float64) *PlotBarWidget { p.width = width return p } +// Shift sets shift of the bar func (p *PlotBarWidget) Shift(shift float64) *PlotBarWidget { p.shift = shift return p } +// Offset sets bar's offset func (p *PlotBarWidget) Offset(offset int) *PlotBarWidget { p.offset = offset return p } +// Plot implements Plot interface func (p *PlotBarWidget) Plot() { imgui.ImPlotBars(p.title, p.data, p.width, p.shift, p.offset) } +// PlotBarHWidget represents a column chart on Y axis type PlotBarHWidget struct { title string data []float64 @@ -229,6 +236,7 @@ type PlotBarHWidget struct { offset int } +// PlotBarH adds plot bars on y axis func PlotBarH(title string, data []float64) *PlotBarHWidget { return &PlotBarHWidget{ title: title, @@ -239,25 +247,30 @@ func PlotBarH(title string, data []float64) *PlotBarHWidget { } } +// Height sets bar height (in fact bars' width) func (p *PlotBarHWidget) Height(height float64) *PlotBarHWidget { p.height = height return p } +// Shift sets shift func (p *PlotBarHWidget) Shift(shift float64) *PlotBarHWidget { p.shift = shift return p } +// Offset sets offset func (p *PlotBarHWidget) Offset(offset int) *PlotBarHWidget { p.offset = offset return p } +// Plot implements plot interface func (p *PlotBarHWidget) Plot() { imgui.ImPlotBarsH(tStr(p.title), p.data, p.height, p.shift, p.offset) } +// PlotLineWidget represents a plot line (linear chart) type PlotLineWidget struct { title string values []float64 @@ -266,6 +279,7 @@ type PlotLineWidget struct { yAxis ImPlotYAxis } +// PlotLine adds a new plot line to the canvas func PlotLine(title string, values []float64) *PlotLineWidget { return &PlotLineWidget{ title: title, @@ -276,37 +290,44 @@ func PlotLine(title string, values []float64) *PlotLineWidget { } } +// SetPlotYAxis sets yAxis parameters func (p *PlotLineWidget) SetPlotYAxis(yAxis ImPlotYAxis) *PlotLineWidget { p.yAxis = yAxis return p } +// XScale sets x-axis-scale func (p *PlotLineWidget) XScale(scale float64) *PlotLineWidget { p.xScale = scale return p } +// X0 sets a start position on x axis func (p *PlotLineWidget) X0(x0 float64) *PlotLineWidget { p.x0 = x0 return p } +// Offset sets chart offset func (p *PlotLineWidget) Offset(offset int) *PlotLineWidget { p.offset = offset return p } +// Plot implements Plot interface func (p *PlotLineWidget) Plot() { imgui.ImPlotSetPlotYAxis(imgui.ImPlotYAxis(p.yAxis)) imgui.ImPlotLine(tStr(p.title), p.values, p.xScale, p.x0, p.offset) } +// PlotLineXYWidget adds XY plot line type PlotLineXYWidget struct { title string xs, ys []float64 offset int } +// PlotLineXY adds XY plot line to canvas func PlotLineXY(title string, xvalues, yvalues []float64) *PlotLineXYWidget { return &PlotLineXYWidget{ title: title, @@ -316,15 +337,18 @@ func PlotLineXY(title string, xvalues, yvalues []float64) *PlotLineXYWidget { } } +// Offset sets chart's offset func (p *PlotLineXYWidget) Offset(offset int) *PlotLineXYWidget { p.offset = offset return p } +// Plot implements Plot interface func (p *PlotLineXYWidget) Plot() { imgui.ImPlotLineXY(tStr(p.title), p.xs, p.ys, p.offset) } +// PlotPieChartWidget represents a pie chart type PlotPieChartWidget struct { labels []string values []float64 @@ -334,6 +358,7 @@ type PlotPieChartWidget struct { angle0 float64 } +// PlotPieChart adds pie chart to the canvas func PlotPieChart(labels []string, values []float64, x, y, radius float64) *PlotPieChartWidget { return &PlotPieChartWidget{ labels: labels, @@ -352,6 +377,7 @@ func (p *PlotPieChartWidget) Normalize(n bool) *PlotPieChartWidget { return p } +// LabelFormat sets format of labels func (p *PlotPieChartWidget) LabelFormat(fmtStr string) *PlotPieChartWidget { p.labelFormat = fmtStr return p From a7ce405979ee301784dd4e56030dfcfed039c9a1 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 12:07:53 +0200 Subject: [PATCH 20/27] all: add some comments --- Alignment.go | 3 +++ Flags.go | 2 ++ FontAtlasProsessor.go | 9 ++++++--- Style.go | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Alignment.go b/Alignment.go index e58c23ff..0ab7c942 100644 --- a/Alignment.go +++ b/Alignment.go @@ -40,11 +40,14 @@ func Align(at AlignmentType) *AlignmentSetter { } } +// To sets a layout, alignment should be applied to func (a *AlignmentSetter) To(widgets ...Widget) *AlignmentSetter { a.layout = Layout(widgets) return a } +// ID allows to manually set AlignmentSetter ID (it shouldn't be used +// in a normal conditions) func (a *AlignmentSetter) ID(id string) *AlignmentSetter { a.id = id return a diff --git a/Flags.go b/Flags.go index dec943a2..74bd5eb7 100644 --- a/Flags.go +++ b/Flags.go @@ -112,6 +112,7 @@ const ( ComboFlagNoPreview ComboFlags = 1 << 6 ) +// SelectableFlags represents imgui.SelectableFlags type SelectableFlags int const ( @@ -224,6 +225,7 @@ const ( TreeNodeFlagsCollapsingHeader TreeNodeFlags = TreeNodeFlagsFramed | TreeNodeFlagsNoTreePushOnOpen | TreeNodeFlagsNoAutoOpenOnLog ) +// FocusedFlags represents imgui.FocusedFlags type FocusedFlags int const ( diff --git a/FontAtlasProsessor.go b/FontAtlasProsessor.go index eaff5470..962f1b74 100644 --- a/FontAtlasProsessor.go +++ b/FontAtlasProsessor.go @@ -23,6 +23,8 @@ const ( preRegisterString = "\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" ) +// FontInfo represents a the font. +// type FontInfo struct { fontName string fontPath string @@ -76,7 +78,7 @@ func init() { } } -// Change default font +// SetDefaultFont changes default font func SetDefaultFont(fontName string, size float32) { fontPath, err := findfont.Find(fontName) if err != nil { @@ -88,7 +90,7 @@ func SetDefaultFont(fontName string, size float32) { defaultFonts = append([]FontInfo{fontInfo}, defaultFonts...) } -// Change default font by bytes of the font file +// SetDefaultFontFromBytes changes default font by bytes of the font file. func SetDefaultFontFromBytes(fontBytes []byte, size float32) { defaultFonts = append([]FontInfo{ { @@ -98,7 +100,7 @@ func SetDefaultFontFromBytes(fontBytes []byte, size float32) { }, defaultFonts...) } -// Add font by name, if the font is found, return *FontInfo, otherwise return nil. +// 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 { fontPath, err := findfont.Find(fontName) @@ -118,6 +120,7 @@ func AddFont(fontName string, size float32) *FontInfo { return &fi } +// AddFontFromBytes does similar to AddFont, but using data from memory func AddFontFromBytes(fontName string, fontBytes []byte, size float32) *FontInfo { fi := FontInfo{ fontName: fontName, diff --git a/Style.go b/Style.go index 016acbd1..49875b29 100644 --- a/Style.go +++ b/Style.go @@ -279,6 +279,7 @@ const ( // StyleVarID identifies a style variable in the UI style. type StyleVarID int +// Style IDs const ( // StyleVarAlpha is a float StyleVarAlpha StyleVarID = iota From abc97126df5fb5a455bf62812c0fd0f4ca4ca3e5 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 15:56:41 +0200 Subject: [PATCH 21/27] disable revive: fix part of lll's and stylechecks --- .golangci.yml | 4 +- CodeEditor.go | 2 +- EventHandler.go | 2 +- Flags.go | 298 +++++++++++++++++++++++++++++++++--------------- Plot.go | 8 +- Utils.go | 10 +- Widgets.go | 12 +- Window.go | 2 +- 8 files changed, 229 insertions(+), 109 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a397f12c..53f878ee 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -69,14 +69,12 @@ linters: - makezero - misspell - nakedret - - nestif - nilerr - #- nlreturn - nolintlint - prealloc - predeclared - promlinter - - revive + #- revive - rowserrcheck - staticcheck - structcheck diff --git a/CodeEditor.go b/CodeEditor.go index 725234f0..02971b7a 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -46,7 +46,7 @@ func CodeEditor(title string) *CodeEditorWidget { } } -// ShowWhitespace sets if whitespaces are shown in code editor +// ShowWhitespaces sets if whitespaces are shown in code editor func (ce *CodeEditorWidget) ShowWhitespaces(s bool) *CodeEditorWidget { ce.getState().editor.SetShowWhitespaces(s) return ce diff --git a/EventHandler.go b/EventHandler.go index 4acb9021..6ed73433 100644 --- a/EventHandler.go +++ b/EventHandler.go @@ -75,7 +75,7 @@ func (eh *EventHandler) OnKeyPressed(key Key, cb func()) *EventHandler { return eh } -// OnKeyReleaed sets callback when key `key` is released +// OnKeyReleased sets callback when key `key` is released func (eh *EventHandler) OnKeyReleased(key Key, cb func()) *EventHandler { eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyReleased}) return eh diff --git a/Flags.go b/Flags.go index 74bd5eb7..b6f6206f 100644 --- a/Flags.go +++ b/Flags.go @@ -336,139 +336,249 @@ type TableFlags int // Table flags enum: const ( // Features - TableFlagsNone TableFlags = 0 - TableFlagsResizable TableFlags = 1 << 0 // Enable resizing columns. - TableFlagsReorderable TableFlags = 1 << 1 // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers) - TableFlagsHideable TableFlags = 1 << 2 // Enable hiding/disabling columns in context menu. - TableFlagsSortable TableFlags = 1 << 3 // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see TableFlagsSortMulti and TableFlagsSortTristate. - TableFlagsNoSavedSettings TableFlags = 1 << 4 // Disable persisting columns order, width and sort settings in the .ini file. - TableFlagsContextMenuInBody TableFlags = 1 << 5 // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow(). + + TableFlagsNone TableFlags = 0 + // Enable resizing columns. + TableFlagsResizable TableFlags = 1 << 0 + // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers) + TableFlagsReorderable TableFlags = 1 << 1 + // Enable hiding/disabling columns in context menu. + TableFlagsHideable TableFlags = 1 << 2 + // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see TableFlagsSortMulti and TableFlagsSortTristate. + TableFlagsSortable TableFlags = 1 << 3 + // Disable persisting columns order, width and sort settings in the .ini file. + TableFlagsNoSavedSettings TableFlags = 1 << 4 + // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow(). + TableFlagsContextMenuInBody TableFlags = 1 << 5 // Decorations - TableFlagsRowBg TableFlags = 1 << 6 // Set each RowBg color with ColTableRowBg or ColTableRowBgAlt (equivalent of calling TableSetBgColor with TableBgFlagsRowBg0 on each row manually) - TableFlagsBordersInnerH TableFlags = 1 << 7 // Draw horizontal borders between rows. - TableFlagsBordersOuterH TableFlags = 1 << 8 // Draw horizontal borders at the top and bottom. - TableFlagsBordersInnerV TableFlags = 1 << 9 // Draw vertical borders between columns. - TableFlagsBordersOuterV TableFlags = 1 << 10 // Draw vertical borders on the left and right sides. - TableFlagsBordersH TableFlags = TableFlagsBordersInnerH | TableFlagsBordersOuterH // Draw horizontal borders. - TableFlagsBordersV TableFlags = TableFlagsBordersInnerV | TableFlagsBordersOuterV // Draw vertical borders. - TableFlagsBordersInner TableFlags = TableFlagsBordersInnerV | TableFlagsBordersInnerH // Draw inner borders. - TableFlagsBordersOuter TableFlags = TableFlagsBordersOuterV | TableFlagsBordersOuterH // Draw outer borders. - TableFlagsBorders TableFlags = TableFlagsBordersInner | TableFlagsBordersOuter // Draw all borders. - TableFlagsNoBordersInBody TableFlags = 1 << 11 // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style - TableFlagsNoBordersInBodyUntilResizeTableFlags TableFlags = 1 << 12 // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style + + // Set each RowBg color with ColTableRowBg or ColTableRowBgAlt (equivalent of calling TableSetBgColor with TableBgFlagsRowBg0 on each row manually) + TableFlagsRowBg TableFlags = 1 << 6 + // Draw horizontal borders between rows. + TableFlagsBordersInnerH TableFlags = 1 << 7 + // Draw horizontal borders at the top and bottom. + TableFlagsBordersOuterH TableFlags = 1 << 8 + // Draw vertical borders between columns. + TableFlagsBordersInnerV TableFlags = 1 << 9 + // Draw vertical borders on the left and right sides. + TableFlagsBordersOuterV TableFlags = 1 << 10 + // Draw horizontal borders. + TableFlagsBordersH TableFlags = TableFlagsBordersInnerH | TableFlagsBordersOuterH + // Draw vertical borders. + TableFlagsBordersV TableFlags = TableFlagsBordersInnerV | TableFlagsBordersOuterV + // Draw inner borders. + TableFlagsBordersInner TableFlags = TableFlagsBordersInnerV | TableFlagsBordersInnerH + // Draw outer borders. + TableFlagsBordersOuter TableFlags = TableFlagsBordersOuterV | TableFlagsBordersOuterH + // Draw all borders. + TableFlagsBorders TableFlags = TableFlagsBordersInner | TableFlagsBordersOuter + // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style + TableFlagsNoBordersInBody TableFlags = 1 << 11 + // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style + TableFlagsNoBordersInBodyUntilResizeTableFlags TableFlags = 1 << 12 // Sizing Policy (read above for defaults)TableFlags - TableFlagsSizingFixedFit TableFlags = 1 << 13 // Columns default to WidthFixed or WidthAuto (if resizable or not resizable), matching contents width. - TableFlagsSizingFixedSame TableFlags = 2 << 13 // Columns default to WidthFixed or WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable TableFlagsNoKeepColumnsVisible. - TableFlagsSizingStretchProp TableFlags = 3 << 13 // Columns default to WidthStretch with default weights proportional to each columns contents widths. - TableFlagsSizingStretchSame TableFlags = 4 << 13 // Columns default to WidthStretch with default weights all equal, unless overridden by TableSetupColumn(). + + // Columns default to WidthFixed or WidthAuto (if resizable or not resizable), matching contents width. + TableFlagsSizingFixedFit TableFlags = 1 << 13 + // Columns default to WidthFixed or WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. + // Implicitly enable TableFlagsNoKeepColumnsVisible. + TableFlagsSizingFixedSame TableFlags = 2 << 13 + // Columns default to WidthStretch with default weights proportional to each columns contents widths. + TableFlagsSizingStretchProp TableFlags = 3 << 13 + // Columns default to WidthStretch with default weights all equal, unless overridden by TableSetupColumn(). + TableFlagsSizingStretchSame TableFlags = 4 << 13 // Sizing Extra Options - TableFlagsNoHostExtendX TableFlags = 1 << 16 // Make outer width auto-fit to columns, overriding outersize.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. - TableFlagsNoHostExtendY TableFlags = 1 << 17 // Make outer height stop exactly at outersize.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible. - TableFlagsNoKeepColumnsVisible TableFlags = 1 << 18 // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable. - TableFlagsPreciseWidths TableFlags = 1 << 19 // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth. + + // Make outer width auto-fit to columns, overriding outersize.x value. + // Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. + TableFlagsNoHostExtendX TableFlags = 1 << 16 + // Make outer height stop exactly at outersize.y (prevent auto-extending table past the limit). + // Only available when ScrollX/ScrollY are disabled. + // Data below the limit will be clipped and not visible. + TableFlagsNoHostExtendY TableFlags = 1 << 17 + // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable. + TableFlagsNoKeepColumnsVisible TableFlags = 1 << 18 + // Disable distributing remainder width to stretched columns + // (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). + // With larger number of columns, resizing will appear to be less smooth. + TableFlagsPreciseWidths TableFlags = 1 << 19 + // Clipping - TableFlagsNoClip TableFlags = 1 << 20 // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). + + // Disable clipping rectangle for every individual columns (reduce draw command count, + // items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). + TableFlagsNoClip TableFlags = 1 << 20 // Padding - TableFlagsPadOuterX TableFlags = 1 << 21 // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers. - TableFlagsNoPadOuterX TableFlags = 1 << 22 // Default if BordersOuterV is off. Disable outer-most padding. - TableFlagsNoPadInnerX TableFlags = 1 << 23 // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off). + + // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers. + TableFlagsPadOuterX TableFlags = 1 << 21 + // Default if BordersOuterV is off. Disable outer-most padding. + TableFlagsNoPadOuterX TableFlags = 1 << 22 + // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off). + TableFlagsNoPadInnerX TableFlags = 1 << 23 + // Scrolling - TableFlagsScrollX TableFlags = 1 << 24 // Enable horizontal scrolling. Require 'outersize' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. - TableFlagsScrollY TableFlags = 1 << 25 // Enable vertical scrolling. Require 'outersize' parameter of BeginTable() to specify the container size. + + // Enable horizontal scrolling. Require 'outersize' parameter of BeginTable() to specify the container size. + // Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. + TableFlagsScrollX TableFlags = 1 << 24 + // Enable vertical scrolling. Require 'outersize' parameter of BeginTable() to specify the container size. + TableFlagsScrollY TableFlags = 1 << 25 // Sorting - TableFlagsSortMulti TableFlags = 1 << 26 // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1). - TableFlagsSortTristate TableFlags = 1 << 27 // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0). + + // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1). + TableFlagsSortMulti TableFlags = 1 << 26 + // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0). + TableFlagsSortTristate TableFlags = 1 << 27 // [Internal] Combinations and masks - TableFlagsSizingMask TableFlags = TableFlagsSizingFixedFit | TableFlagsSizingFixedSame | TableFlagsSizingStretchProp | TableFlagsSizingStretchSame + TableFlagsSizingMask TableFlags = TableFlagsSizingFixedFit | TableFlagsSizingFixedSame | + TableFlagsSizingStretchProp | TableFlagsSizingStretchSame ) type TableRowFlags int const ( - TableRowFlagsNone TableRowFlags = 0 - TableRowFlagsHeaders TableRowFlags = 1 << 0 // Identify header row (set default background color + width of its contents accounted different for auto column width) + TableRowFlagsNone TableRowFlags = 0 + // Identify header row (set default background color + width of its contents accounted different for auto column width) + TableRowFlagsHeaders TableRowFlags = 1 << 0 ) type TableColumnFlags int const ( // Input configuration flags - TableColumnFlagsNone TableColumnFlags = 0 - TableColumnFlagsDefaultHide TableColumnFlags = 1 << 0 // Default as a hidden/disabled column. - TableColumnFlagsDefaultSort TableColumnFlags = 1 << 1 // Default as a sorting column. - TableColumnFlagsWidthStretch TableColumnFlags = 1 << 2 // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is SizingStretchSame or SizingStretchProp). - TableColumnFlagsWidthFixed TableColumnFlags = 1 << 3 // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is SizingFixedFit and table is resizable). - TableColumnFlagsNoResize TableColumnFlags = 1 << 4 // Disable manual resizing. - TableColumnFlagsNoReorder TableColumnFlags = 1 << 5 // Disable manual reordering this column, this will also prevent other columns from crossing over this column. - TableColumnFlagsNoHide TableColumnFlags = 1 << 6 // Disable ability to hide/disable this column. - TableColumnFlagsNoClip TableColumnFlags = 1 << 7 // Disable clipping for this column (all NoClip columns will render in a same draw command). - TableColumnFlagsNoSort TableColumnFlags = 1 << 8 // Disable ability to sort on this field (even if TableFlagsSortable is set on the table). - TableColumnFlagsNoSortAscending TableColumnFlags = 1 << 9 // Disable ability to sort in the ascending direction. - TableColumnFlagsNoSortDescending TableColumnFlags = 1 << 10 // Disable ability to sort in the descending direction. - TableColumnFlagsNoHeaderWidth TableColumnFlags = 1 << 11 // Disable header text width contribution to automatic column width. - TableColumnFlagsPreferSortAscending TableColumnFlags = 1 << 12 // Make the initial sort direction Ascending when first sorting on this column (default). - TableColumnFlagsPreferSortDescending TableColumnFlags = 1 << 13 // Make the initial sort direction Descending when first sorting on this column. - TableColumnFlagsIndentEnable TableColumnFlags = 1 << 14 // Use current Indent value when entering cell (default for column 0). - TableColumnFlagsIndentDisable TableColumnFlags = 1 << 15 // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes within the cell will still be honored. + TableColumnFlagsNone TableColumnFlags = 0 + // Default as a hidden/disabled column. + TableColumnFlagsDefaultHide TableColumnFlags = 1 << 0 + // Default as a sorting column. + TableColumnFlagsDefaultSort TableColumnFlags = 1 << 1 + // Column will stretch. Preferable with horizontal scrolling disabled + // (default if table sizing policy is SizingStretchSame or SizingStretchProp). + TableColumnFlagsWidthStretch TableColumnFlags = 1 << 2 + // Column will not stretch. Preferable with horizontal scrolling enabled + // (default if table sizing policy is SizingFixedFit and table is resizable). + TableColumnFlagsWidthFixed TableColumnFlags = 1 << 3 + // Disable manual resizing. + TableColumnFlagsNoResize TableColumnFlags = 1 << 4 + // Disable manual reordering this column, this will also prevent other columns from crossing over this column. + TableColumnFlagsNoReorder TableColumnFlags = 1 << 5 + // Disable ability to hide/disable this column. + TableColumnFlagsNoHide TableColumnFlags = 1 << 6 + // Disable clipping for this column (all NoClip columns will render in a same draw command). + TableColumnFlagsNoClip TableColumnFlags = 1 << 7 + // Disable ability to sort on this field (even if TableFlagsSortable is set on the table). + TableColumnFlagsNoSort TableColumnFlags = 1 << 8 + // Disable ability to sort in the ascending direction. + TableColumnFlagsNoSortAscending TableColumnFlags = 1 << 9 + // Disable ability to sort in the descending direction. + TableColumnFlagsNoSortDescending TableColumnFlags = 1 << 10 + // Disable header text width contribution to automatic column width. + TableColumnFlagsNoHeaderWidth TableColumnFlags = 1 << 11 + // Make the initial sort direction Ascending when first sorting on this column (default). + TableColumnFlagsPreferSortAscending TableColumnFlags = 1 << 12 + // Make the initial sort direction Descending when first sorting on this column. + TableColumnFlagsPreferSortDescending TableColumnFlags = 1 << 13 + // Use current Indent value when entering cell (default for column 0). + TableColumnFlagsIndentEnable TableColumnFlags = 1 << 14 + // Ignore current Indent value when entering cell (default for columns > 0). Indentation changes within the cell will still be honored. + TableColumnFlagsIndentDisable TableColumnFlags = 1 << 15 // Output status flags read-only via TableGetColumnFlags() - TableColumnFlagsIsEnabled TableColumnFlags = 1 << 20 // Status: is enabled == not hidden by user/api (referred to as "Hide" in DefaultHide and NoHide) flags. - TableColumnFlagsIsVisible TableColumnFlags = 1 << 21 // Status: is visible == is enabled AND not clipped by scrolling. - TableColumnFlagsIsSorted TableColumnFlags = 1 << 22 // Status: is currently part of the sort specs - TableColumnFlagsIsHovered TableColumnFlags = 1 << 23 // Status: is hovered by mouse + // Status: is enabled == not hidden by user/api (referred to as "Hide" in DefaultHide and NoHide) flags. + TableColumnFlagsIsEnabled TableColumnFlags = 1 << 20 + // Status: is visible == is enabled AND not clipped by scrolling. + TableColumnFlagsIsVisible TableColumnFlags = 1 << 21 + // Status: is currently part of the sort specs + TableColumnFlagsIsSorted TableColumnFlags = 1 << 22 + // Status: is hovered by mouse + TableColumnFlagsIsHovered TableColumnFlags = 1 << 23 // [Internal] Combinations and masks - TableColumnFlagsWidthMask TableColumnFlags = TableColumnFlagsWidthStretch | TableColumnFlagsWidthFixed - TableColumnFlagsIndentMask TableColumnFlags = TableColumnFlagsIndentEnable | TableColumnFlagsIndentDisable - TableColumnFlagsStatusMask TableColumnFlags = TableColumnFlagsIsEnabled | TableColumnFlagsIsVisible | TableColumnFlagsIsSorted | TableColumnFlagsIsHovered - TableColumnFlagsNoDirectResize TableColumnFlags = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge) + TableColumnFlagsWidthMask TableColumnFlags = TableColumnFlagsWidthStretch | TableColumnFlagsWidthFixed + TableColumnFlagsIndentMask TableColumnFlags = TableColumnFlagsIndentEnable | TableColumnFlagsIndentDisable + TableColumnFlagsStatusMask TableColumnFlags = TableColumnFlagsIsEnabled | + TableColumnFlagsIsVisible | TableColumnFlagsIsSorted | TableColumnFlagsIsHovered + // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge) + TableColumnFlagsNoDirectResize TableColumnFlags = 1 << 30 ) type SliderFlags int const ( - SliderFlagsNone SliderFlags = 0 - SliderFlagsAlwaysClamp SliderFlags = 1 << 4 // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. - SliderFlagsLogarithmic SliderFlags = 1 << 5 // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlagsNoRoundToFormat with this if using a format-string with small amount of digits. - SliderFlagsNoRoundToFormat SliderFlags = 1 << 6 // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits) - SliderFlagsNoInput SliderFlags = 1 << 7 // Disable CTRL+Click or Enter key allowing to input text directly into the widget - SliderFlagsInvalidMask SliderFlags = 0x7000000F // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. + SliderFlagsNone SliderFlags = 0 + // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds. + SliderFlagsAlwaysClamp SliderFlags = 1 << 4 + // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlagsNoRoundToFormat with this if using + // a format-string with small amount of digits. + SliderFlagsLogarithmic SliderFlags = 1 << 5 + // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits) + SliderFlagsNoRoundToFormat SliderFlags = 1 << 6 + // Disable CTRL+Click or Enter key allowing to input text directly into the widget + SliderFlagsNoInput SliderFlags = 1 << 7 + // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast + // to this enum, and will trigger an assert if needed. + SliderFlagsInvalidMask SliderFlags = 0x7000000F ) type PlotFlags int const ( - PlotFlagsNone PlotFlags = 0 // default - PlotFlagsNoTitle PlotFlags = 1 << 0 // the plot title will not be displayed (titles are also hidden if preceded by double hashes, e.g. "##MyPlot") - PlotFlagsNoLegend PlotFlags = 1 << 1 // the legend will not be displayed - PlotFlagsNoMenus PlotFlags = 1 << 2 // the user will not be able to open context menus with right-click - PlotFlagsNoBoxSelect PlotFlags = 1 << 3 // the user will not be able to box-select with right-click drag - PlotFlagsNoMousePos PlotFlags = 1 << 4 // the mouse position, in plot coordinates, will not be displayed inside of the plot - PlotFlagsNoHighlight PlotFlags = 1 << 5 // plot items will not be highlighted when their legend entry is hovered - PlotFlagsNoChild PlotFlags = 1 << 6 // a child window region will not be used to capture mouse scroll (can boost performance for single Gui window applications) - PlotFlagsEqual PlotFlags = 1 << 7 // primary x and y axes will be constrained to have the same units/pixel (does not apply to auxiliary y-axes) - PlotFlagsYAxis2 PlotFlags = 1 << 8 // enable a 2nd y-axis on the right side - PlotFlagsYAxis3 PlotFlags = 1 << 9 // enable a 3rd y-axis on the right side - PlotFlagsQuery PlotFlags = 1 << 10 // the user will be able to draw query rects with middle-mouse or CTRL + right-click drag - PlotFlagsCrosshairs PlotFlags = 1 << 11 // the default mouse cursor will be replaced with a crosshair when hovered - PlotFlagsAntiAliased PlotFlags = 1 << 12 // plot lines will be software anti-aliased (not recommended for high density plots, prefer MSAA) + // default + PlotFlagsNone PlotFlags = 0 + // the plot title will not be displayed (titles are also hidden if preceded by double hashes, e.g. "##MyPlot") + PlotFlagsNoTitle PlotFlags = 1 << 0 + // the legend will not be displayed + PlotFlagsNoLegend PlotFlags = 1 << 1 + // the user will not be able to open context menus with right-click + PlotFlagsNoMenus PlotFlags = 1 << 2 + // the user will not be able to box-select with right-click drag + PlotFlagsNoBoxSelect PlotFlags = 1 << 3 + // the mouse position, in plot coordinates, will not be displayed inside of the plot + PlotFlagsNoMousePos PlotFlags = 1 << 4 + // plot items will not be highlighted when their legend entry is hovered + PlotFlagsNoHighlight PlotFlags = 1 << 5 + // a child window region will not be used to capture mouse scroll (can boost performance for single Gui window applications) + PlotFlagsNoChild PlotFlags = 1 << 6 + // primary x and y axes will be constrained to have the same units/pixel (does not apply to auxiliary y-axes) + PlotFlagsEqual PlotFlags = 1 << 7 + // enable a 2nd y-axis on the right side + PlotFlagsYAxis2 PlotFlags = 1 << 8 + // enable a 3rd y-axis on the right side + PlotFlagsYAxis3 PlotFlags = 1 << 9 + // the user will be able to draw query rects with middle-mouse or CTRL + right-click drag + PlotFlagsQuery PlotFlags = 1 << 10 + // the default mouse cursor will be replaced with a crosshair when hovered + PlotFlagsCrosshairs PlotFlags = 1 << 11 + // plot lines will be software anti-aliased (not recommended for high density plots, prefer MSAA) + PlotFlagsAntiAliased PlotFlags = 1 << 12 PlotFlagsCanvasOnly PlotFlags = PlotFlagsNoTitle | PlotFlagsNoLegend | PlotFlagsNoMenus | PlotFlagsNoBoxSelect | PlotFlagsNoMousePos ) type PlotAxisFlags int const ( - PlotAxisFlagsNone PlotAxisFlags = 0 // default - PlotAxisFlagsNoLabel PlotAxisFlags = 1 << 0 // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL) - PlotAxisFlagsNoGridLines PlotAxisFlags = 1 << 1 // the axis grid lines will not be displayed - PlotAxisFlagsNoTickMarks PlotAxisFlags = 1 << 2 // the axis tick marks will not be displayed - PlotAxisFlagsNoTickLabels PlotAxisFlags = 1 << 3 // the axis tick labels will not be displayed - PlotAxisFlagsLogScale PlotAxisFlags = 1 << 4 // a logartithmic (base 10) axis scale will be used (mutually exclusive with PlotAxisFlagsTime) - PlotAxisFlagsTime PlotAxisFlags = 1 << 5 // axis will display date/time formatted labels (mutually exclusive with PlotAxisFlagsLogScale) - PlotAxisFlagsInvert PlotAxisFlags = 1 << 6 // the axis will be inverted - PlotAxisFlagsLockMin PlotAxisFlags = 1 << 7 // the axis minimum value will be locked when panning/zooming - PlotAxisFlagsLockMax PlotAxisFlags = 1 << 8 // the axis maximum value will be locked when panning/zooming + // default + PlotAxisFlagsNone PlotAxisFlags = 0 + // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL) + PlotAxisFlagsNoLabel PlotAxisFlags = 1 << 0 + // the axis grid lines will not be displayed + PlotAxisFlagsNoGridLines PlotAxisFlags = 1 << 1 + // the axis tick marks will not be displayed + PlotAxisFlagsNoTickMarks PlotAxisFlags = 1 << 2 + // the axis tick labels will not be displayed + PlotAxisFlagsNoTickLabels PlotAxisFlags = 1 << 3 + // a logartithmic (base 10) axis scale will be used (mutually exclusive with PlotAxisFlagsTime) + PlotAxisFlagsLogScale PlotAxisFlags = 1 << 4 + // axis will display date/time formatted labels (mutually exclusive with PlotAxisFlagsLogScale) + PlotAxisFlagsTime PlotAxisFlags = 1 << 5 + // the axis will be inverted + PlotAxisFlagsInvert PlotAxisFlags = 1 << 6 + // the axis minimum value will be locked when panning/zooming + PlotAxisFlagsLockMin PlotAxisFlags = 1 << 7 + // the axis maximum value will be locked when panning/zooming + PlotAxisFlagsLockMax PlotAxisFlags = 1 << 8 PlotAxisFlagsLock PlotAxisFlags = PlotAxisFlagsLockMin | PlotAxisFlagsLockMax - PlotAxisFlagsNoDecorations PlotAxisFlags = PlotAxisFlagsNoLabel | PlotAxisFlagsNoGridLines | PlotAxisFlagsNoTickMarks | PlotAxisFlagsNoTickLabels + PlotAxisFlagsNoDecorations PlotAxisFlags = PlotAxisFlagsNoLabel | PlotAxisFlagsNoGridLines | + PlotAxisFlagsNoTickMarks | PlotAxisFlagsNoTickLabels ) diff --git a/Plot.go b/Plot.go index ea492759..286f7b91 100644 --- a/Plot.go +++ b/Plot.go @@ -175,7 +175,13 @@ func (p *PlotCanvasWidget) Build() { imgui.ImPlotSetNextPlotTicksY(p.yTicksValue, p.yTicksLabel, p.yTicksShowDefault, int(p.yTicksYAxis)) } - if imgui.ImPlotBegin(tStr(p.title), tStr(p.xLabel), tStr(p.yLabel), ToVec2(image.Pt(p.width, p.height)), imgui.ImPlotFlags(p.flags), imgui.ImPlotAxisFlags(p.xFlags), imgui.ImPlotAxisFlags(p.yFlags), imgui.ImPlotAxisFlags(p.y2Flags), imgui.ImPlotAxisFlags(p.y3Flags), tStr(p.y2Label), tStr(p.y3Label)) { + if imgui.ImPlotBegin( + tStr(p.title), tStr(p.xLabel), + tStr(p.yLabel), ToVec2(image.Pt(p.width, p.height)), + imgui.ImPlotFlags(p.flags), imgui.ImPlotAxisFlags(p.xFlags), + imgui.ImPlotAxisFlags(p.yFlags), imgui.ImPlotAxisFlags(p.y2Flags), + imgui.ImPlotAxisFlags(p.y3Flags), tStr(p.y2Label), tStr(p.y3Label), + ) { for _, plot := range p.plots { plot.Plot() } diff --git a/Utils.go b/Utils.go index 8c26cea9..4d8317a8 100644 --- a/Utils.go +++ b/Utils.go @@ -56,7 +56,7 @@ func ToVec2(pt image.Point) imgui.Vec2 { } } -// Vec4ToRgba converts imgui's Vec4 to golang rgba color +// Vec4ToRGBA converts imgui's Vec4 to golang rgba color func Vec4ToRGBA(vec4 imgui.Vec4) color.RGBA { return color.RGBA{ R: uint8(vec4.X * 255), @@ -145,7 +145,13 @@ func SetNextWindowPos(x, y float32) { // SetNextWindowSizeV does similar to SetNextWIndowSize but allows to specify imgui.Condition func SetNextWindowSizeV(width, height float32, condition ExecCondition) { - imgui.SetNextWindowSizeV(imgui.Vec2{X: width * Context.platform.GetContentScale(), Y: height * Context.platform.GetContentScale()}, imgui.Condition(condition)) + imgui.SetNextWindowSizeV( + imgui.Vec2{ + X: width * Context.platform.GetContentScale(), + Y: height * Context.platform.GetContentScale(), + }, + imgui.Condition(condition), + ) } // SetItemDefaultFocus set the item focused by default diff --git a/Widgets.go b/Widgets.go index e595c017..9893c9e8 100644 --- a/Widgets.go +++ b/Widgets.go @@ -985,7 +985,7 @@ func ImageWithURL(url string) *ImageWithURLWidget { } } -// Event trigger when image is downloaded and ready to display. +// OnReady sets event trigger when image is downloaded and ready to display. func (i *ImageWithURLWidget) OnReady(onReady func()) *ImageWithURLWidget { i.onReady = onReady return i @@ -1132,7 +1132,7 @@ func (i *InputTextWidget) Labelf(format string, args ...interface{}) *InputTextW return i.Label(fmt.Sprintf(format, args...)) } -// Enable auto complete popup by using fuzzy search of current value against candidates +// AutoComplete enables auto complete popup by using fuzzy search of current value against candidates // Press enter to confirm the first candidate func (i *InputTextWidget) AutoComplete(candidates []string) *InputTextWidget { i.candidates = candidates @@ -1684,7 +1684,7 @@ func (s *SelectableWidget) OnClick(onClick func()) *SelectableWidget { return s } -// Handle mouse left button's double click event. +// OnDClick handles mouse left button's double click event. // SelectableFlagsAllowDoubleClick will set once tonDClick callback is notnull func (s *SelectableWidget) OnDClick(onDClick func()) *SelectableWidget { s.onDClick = onDClick @@ -2298,7 +2298,7 @@ func Table() *TableWidget { } } -// Display visible rows only to boost performance. +// FastMode Displays visible rows only to boost performance. func (t *TableWidget) FastMode(b bool) *TableWidget { t.fastMode = b return t @@ -2581,7 +2581,7 @@ func (t *TreeNodeWidget) Flags(flags TreeNodeFlags) *TreeNodeWidget { return t } -// Create TreeNode with eventHandler +// Event create TreeNode with eventHandler // You could detect events (e.g. IsItemClicked IsMouseDoubleClicked etc...) and handle them for TreeNode inside eventHandler func (t *TreeNodeWidget) Event(handler func()) *TreeNodeWidget { t.eventHandler = handler @@ -2670,7 +2670,7 @@ func (c *ConditionWidget) Build() { } } -// Batch create widgets and render only which is visible. +// RangeBuilder batch create widgets and render only which is visible. func RangeBuilder(id string, values []interface{}, builder func(int, interface{}) Widget) Layout { var layout Layout diff --git a/Window.go b/Window.go index 9787bb9f..e54ac2c4 100644 --- a/Window.go +++ b/Window.go @@ -164,7 +164,7 @@ func (w *WindowWidget) HasFocus() bool { return w.getState().hasFocus } -// Registerkeyboardshortcuts adds local (window-level) keyboard shortcuts +// RegisterKeyboardShortcuts adds local (window-level) keyboard shortcuts // see InputHandler.go func (w *WindowWidget) RegisterKeyboardShortcuts(s ...WindowShortcut) *WindowWidget { if w.HasFocus() { From c733b581870eb5a60e9db7e4100896b7ba5959e1 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 16:10:37 +0200 Subject: [PATCH 22/27] fix all lll lint errors --- Canvas.go | 40 +++++++++++++++++--------- Flags.go | 86 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 85 insertions(+), 41 deletions(-) diff --git a/Canvas.go b/Canvas.go index 82d8507e..0322145f 100644 --- a/Canvas.go +++ b/Canvas.go @@ -30,20 +30,32 @@ type DrawFlags int // draw flags enum: const ( - DrawFlagsNone DrawFlags = 0 - DrawFlagsClosed DrawFlags = 1 << 0 // PathStroke(), AddPolyline(): specify that shape should be closed (portant: this is always == 1 for legacy reason) - DrawFlagsRoundCornersTopLeft DrawFlags = 1 << 4 // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). Was 0x01. - DrawFlagsRoundCornersTopRight DrawFlags = 1 << 5 // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). Was 0x02. - DrawFlagsRoundCornersBottomLeft DrawFlags = 1 << 6 // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). Was 0x04. - DrawFlagsRoundCornersBottomRight DrawFlags = 1 << 7 // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, we default to all corners). Wax 0x08. - DrawFlagsRoundCornersNone DrawFlags = 1 << 8 // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag! - DrawFlagsRoundCornersTop DrawFlags = DrawFlagsRoundCornersTopLeft | DrawFlagsRoundCornersTopRight - DrawFlagsRoundCornersBottom DrawFlags = DrawFlagsRoundCornersBottomLeft | DrawFlagsRoundCornersBottomRight - DrawFlagsRoundCornersLeft DrawFlags = DrawFlagsRoundCornersBottomLeft | DrawFlagsRoundCornersTopLeft - DrawFlagsRoundCornersRight DrawFlags = DrawFlagsRoundCornersBottomRight | DrawFlagsRoundCornersTopRight - DrawFlagsRoundCornersAll DrawFlags = DrawFlagsRoundCornersTopLeft | DrawFlagsRoundCornersTopRight | DrawFlagsRoundCornersBottomLeft | DrawFlagsRoundCornersBottomRight - DrawFlagsRoundCornersDefault DrawFlags = DrawFlagsRoundCornersAll // Default to ALL corners if none of the RoundCornersXX flags are specified. - DrawFlagsRoundCornersMask DrawFlags = DrawFlagsRoundCornersAll | DrawFlagsRoundCornersNone + DrawFlagsNone DrawFlags = 0 + // PathStroke(), AddPolyline(): specify that shape should be closed (portant: this is always == 1 for legacy reason) + DrawFlagsClosed DrawFlags = 1 << 0 + // AddRect(), AddRectFilled(), PathRect(): enable rounding top-left corner only (when rounding > 0.0f, we default to all corners). + // Was 0x01. + DrawFlagsRoundCornersTopLeft DrawFlags = 1 << 4 + // AddRect(), AddRectFilled(), PathRect(): enable rounding top-right corner only (when rounding > 0.0f, we default to all corners). + // Was 0x02. + DrawFlagsRoundCornersTopRight DrawFlags = 1 << 5 + // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-left corner only (when rounding > 0.0f, we default to all corners). + // Was 0x04. + DrawFlagsRoundCornersBottomLeft DrawFlags = 1 << 6 + // AddRect(), AddRectFilled(), PathRect(): enable rounding bottom-right corner only (when rounding > 0.0f, + // we default to all corners). Wax 0x08. + DrawFlagsRoundCornersBottomRight DrawFlags = 1 << 7 + // AddRect(), AddRectFilled(), PathRect(): disable rounding on all corners (when rounding > 0.0f). This is NOT zero, NOT an implicit flag! + DrawFlagsRoundCornersNone DrawFlags = 1 << 8 + DrawFlagsRoundCornersTop DrawFlags = DrawFlagsRoundCornersTopLeft | DrawFlagsRoundCornersTopRight + DrawFlagsRoundCornersBottom DrawFlags = DrawFlagsRoundCornersBottomLeft | DrawFlagsRoundCornersBottomRight + DrawFlagsRoundCornersLeft DrawFlags = DrawFlagsRoundCornersBottomLeft | DrawFlagsRoundCornersTopLeft + DrawFlagsRoundCornersRight DrawFlags = DrawFlagsRoundCornersBottomRight | DrawFlagsRoundCornersTopRight + DrawFlagsRoundCornersAll DrawFlags = DrawFlagsRoundCornersTopLeft | DrawFlagsRoundCornersTopRight | + DrawFlagsRoundCornersBottomLeft | DrawFlagsRoundCornersBottomRight + // Default to ALL corners if none of the RoundCornersXX flags are specified. + DrawFlagsRoundCornersDefault DrawFlags = DrawFlagsRoundCornersAll + DrawFlagsRoundCornersMask DrawFlags = DrawFlagsRoundCornersAll | DrawFlagsRoundCornersNone ) // AddRect draws a rectangle diff --git a/Flags.go b/Flags.go index b6f6206f..b51b7bd1 100644 --- a/Flags.go +++ b/Flags.go @@ -3,27 +3,53 @@ package giu type InputTextFlags int const ( - InputTextFlagsNone InputTextFlags = 0 - InputTextFlagsCharsDecimal InputTextFlags = 1 << 0 // Allow 0123456789.+-*/ - InputTextFlagsCharsHexadecimal InputTextFlags = 1 << 1 // Allow 0123456789ABCDEFabcdef - InputTextFlagsCharsUppercase InputTextFlags = 1 << 2 // Turn a..z into A..Z - InputTextFlagsCharsNoBlank InputTextFlags = 1 << 3 // Filter out spaces, tabs - InputTextFlagsAutoSelectAll InputTextFlags = 1 << 4 // Select entire text when first taking mouse focus - InputTextFlagsEnterReturnsTrue InputTextFlags = 1 << 5 // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. - InputTextFlagsCallbackCompletion InputTextFlags = 1 << 6 // Callback on pressing TAB (for completion handling) - InputTextFlagsCallbackHistory InputTextFlags = 1 << 7 // Callback on pressing Up/Down arrows (for history handling) - InputTextFlagsCallbackAlways InputTextFlags = 1 << 8 // Callback on each iteration. User code may query cursor position, modify text buffer. - InputTextFlagsCallbackCharFilter InputTextFlags = 1 << 9 // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. - InputTextFlagsAllowTabInput InputTextFlags = 1 << 10 // Pressing TAB input a '\t' character into the text field - InputTextFlagsCtrlEnterForNewLine InputTextFlags = 1 << 11 // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). - InputTextFlagsNoHorizontalScroll InputTextFlags = 1 << 12 // Disable following the cursor horizontally - InputTextFlagsAlwaysOverwrite InputTextFlags = 1 << 13 // Overwrite mode - InputTextFlagsReadOnly InputTextFlags = 1 << 14 // Read-only mode - InputTextFlagsPassword InputTextFlags = 1 << 15 // Password mode, display all characters as '*' - InputTextFlagsNoUndoRedo InputTextFlags = 1 << 16 // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). - InputTextFlagsCharsScientific InputTextFlags = 1 << 17 // Allow 0123456789.+-*/eE (Scientific notation input) - InputTextFlagsCallbackResize InputTextFlags = 1 << 18 // Callback on buffer capacity changes request (beyond 'bufsize' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imguistdlib.h for an example of using this) - InputTextFlagsCallbackEdit InputTextFlags = 1 << 19 // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) + InputTextFlagsNone InputTextFlags = 0 + // Allow 0123456789.+-*/ + InputTextFlagsCharsDecimal InputTextFlags = 1 << 0 + // Allow 0123456789ABCDEFabcdef + InputTextFlagsCharsHexadecimal InputTextFlags = 1 << 1 + // Turn a..z into A..Z + InputTextFlagsCharsUppercase InputTextFlags = 1 << 2 + // Filter out spaces, tabs + InputTextFlagsCharsNoBlank InputTextFlags = 1 << 3 + // Select entire text when first taking mouse focus + InputTextFlagsAutoSelectAll InputTextFlags = 1 << 4 + // Return 'true' when Enter is pressed (as opposed to every time the value was modified). + // Consider looking at the IsItemDeactivatedAfterEdit() function. + InputTextFlagsEnterReturnsTrue InputTextFlags = 1 << 5 + // Callback on pressing TAB (for completion handling) + InputTextFlagsCallbackCompletion InputTextFlags = 1 << 6 + // Callback on pressing Up/Down arrows (for history handling) + InputTextFlagsCallbackHistory InputTextFlags = 1 << 7 + // Callback on each iteration. User code may query cursor position, modify text buffer. + InputTextFlagsCallbackAlways InputTextFlags = 1 << 8 + // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. + InputTextFlagsCallbackCharFilter InputTextFlags = 1 << 9 + // Pressing TAB input a '\t' character into the text field + InputTextFlagsAllowTabInput InputTextFlags = 1 << 10 + // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter + // (default is opposite: unfocus with Ctrl+Enter, add line with Enter). + InputTextFlagsCtrlEnterForNewLine InputTextFlags = 1 << 11 + // Disable following the cursor horizontally + InputTextFlagsNoHorizontalScroll InputTextFlags = 1 << 12 + // Overwrite mode + InputTextFlagsAlwaysOverwrite InputTextFlags = 1 << 13 + // Read-only mode + InputTextFlagsReadOnly InputTextFlags = 1 << 14 + // Password mode, display all characters as '*' + InputTextFlagsPassword InputTextFlags = 1 << 15 + // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo + // stack you need e.g. to call ClearActiveID(). + InputTextFlagsNoUndoRedo InputTextFlags = 1 << 16 + // Allow 0123456789.+-*/eE (Scientific notation input) + InputTextFlagsCharsScientific InputTextFlags = 1 << 17 + // Callback on buffer capacity changes request (beyond 'bufsize' parameter value), allowing the string to grow. + // Notify when the string wants to be resized (for string types which hold a cache of their Size). + // You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imguistdlib.h for an example of using this) + InputTextFlagsCallbackResize InputTextFlags = 1 << 18 + // Callback on any edit (note that InputText() already returns true on edit, + // the callback is useful mainly to manipulate the underlying buffer while focus is active) + InputTextFlagsCallbackEdit InputTextFlags = 1 << 19 ) type WindowFlags int @@ -245,7 +271,8 @@ const ( type HoveredFlags int const ( - // HoveredFlagsNone is the default and matches if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. + // HoveredFlagsNone is the default and matches if directly over the item/window, + // not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. HoveredFlagsNone HoveredFlags = 0 // HoveredFlagsChildWindows is for IsWindowHovered() and matches if any children of the window is hovered HoveredFlagsChildWindows HoveredFlags = 1 << 0 @@ -255,16 +282,20 @@ const ( HoveredFlagsAnyWindow HoveredFlags = 1 << 2 // HoveredFlagsAllowWhenBlockedByPopup matches even if a popup window is normally blocking access to this item/window HoveredFlagsAllowWhenBlockedByPopup HoveredFlags = 1 << 3 - // HoveredFlagsAllowWhenBlockedByModal matches even if a modal popup window is normally blocking access to this item/window. UNIMPLEMENTED in imgui. + // HoveredFlagsAllowWhenBlockedByModal matches even if a modal popup window is normally blocking access to this item/window. + // UNIMPLEMENTED in imgui. // HoveredFlagsAllowWhenBlockedByModal HoveredFlags = 1 << 4 - // HoveredFlagsAllowWhenBlockedByActiveItem matches true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. + // HoveredFlagsAllowWhenBlockedByActiveItem matches true even if an active item is blocking access to this item/window. + // Useful for Drag and Drop patterns. HoveredFlagsAllowWhenBlockedByActiveItem HoveredFlags = 1 << 5 // HoveredFlagsAllowWhenOverlapped matches even if the position is obstructed or overlapped by another window HoveredFlagsAllowWhenOverlapped HoveredFlags = 1 << 6 // HoveredFlagsAllowWhenDisabled matches even if the item is disabled HoveredFlagsAllowWhenDisabled HoveredFlags = 1 << 7 - // HoveredFlagsRectOnly combines HoveredFlagsAllowWhenBlockedByPopup, HoveredFlagsAllowWhenBlockedByActiveItem, and HoveredFlagsAllowWhenOverlapped. - HoveredFlagsRectOnly HoveredFlags = HoveredFlagsAllowWhenBlockedByPopup | HoveredFlagsAllowWhenBlockedByActiveItem | HoveredFlagsAllowWhenOverlapped + // HoveredFlagsRectOnly combines HoveredFlagsAllowWhenBlockedByPopup, + // HoveredFlagsAllowWhenBlockedByActiveItem, and HoveredFlagsAllowWhenOverlapped. + HoveredFlagsRectOnly HoveredFlags = HoveredFlagsAllowWhenBlockedByPopup | + HoveredFlagsAllowWhenBlockedByActiveItem | HoveredFlagsAllowWhenOverlapped // HoveredFlagsRootAndChildWindows combines HoveredFlagsRootWindow and HoveredFlagsChildWindows. HoveredFlagsRootAndChildWindows HoveredFlags = HoveredFlagsRootWindow | HoveredFlagsChildWindows ) @@ -352,7 +383,8 @@ const ( TableFlagsContextMenuInBody TableFlags = 1 << 5 // Decorations - // Set each RowBg color with ColTableRowBg or ColTableRowBgAlt (equivalent of calling TableSetBgColor with TableBgFlagsRowBg0 on each row manually) + // Set each RowBg color with ColTableRowBg or ColTableRowBgAlt + // (equivalent of calling TableSetBgColor with TableBgFlagsRowBg0 on each row manually) TableFlagsRowBg TableFlags = 1 << 6 // Draw horizontal borders between rows. TableFlagsBordersInnerH TableFlags = 1 << 7 From 48ec89c200898b816b78b4421eb69866f09ae64a Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 16:12:10 +0200 Subject: [PATCH 23/27] add doc.go --- doc.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 doc.go diff --git a/doc.go b/doc.go new file mode 100644 index 00000000..e81dda83 --- /dev/null +++ b/doc.go @@ -0,0 +1,5 @@ +// Package giu - A rapid cross-platform GUI framework for Go based on Dear ImGui +// and the great Go binding imgui-go. +// +// for details and usage see README of the project. +package giu From a6574cdf15031408ade8de706e975e90fbe6c998 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 16:23:23 +0200 Subject: [PATCH 24/27] fix some gocritic lints --- Canvas.go | 58 ++++++++++++++++++++++++------------------------- CodeEditor.go | 2 +- InputHandler.go | 2 +- MasterWindow.go | 9 ++++++-- Style.go | 8 +++---- Utils.go | 12 ++++++++-- Widgets.go | 22 +++++++++---------- 7 files changed, 63 insertions(+), 50 deletions(-) diff --git a/Canvas.go b/Canvas.go index 0322145f..1403c745 100644 --- a/Canvas.go +++ b/Canvas.go @@ -21,8 +21,8 @@ func GetCanvas() *Canvas { } // AddLine draws a line (from p1 to p2) -func (c *Canvas) AddLine(p1, p2 image.Point, color color.RGBA, thickness float32) { - c.drawlist.AddLine(ToVec2(p1), ToVec2(p2), ToVec4Color(color), thickness) +func (c *Canvas) AddLine(p1, p2 image.Point, col color.RGBA, thickness float32) { + c.drawlist.AddLine(ToVec2(p1), ToVec2(p2), ToVec4Color(col), thickness) } // DrawFlags represents imgui.DrawFlags @@ -59,53 +59,53 @@ const ( ) // AddRect draws a rectangle -func (c *Canvas) AddRect(pMin, pMax image.Point, color color.RGBA, rounding float32, roundingCorners DrawFlags, thickness float32) { - c.drawlist.AddRect(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(roundingCorners), thickness) +func (c *Canvas) AddRect(pMin, pMax image.Point, col color.RGBA, rounding float32, roundingCorners DrawFlags, thickness float32) { + c.drawlist.AddRect(ToVec2(pMin), ToVec2(pMax), ToVec4Color(col), rounding, int(roundingCorners), thickness) } -// AddRectFilled draws a rectangle filled with `color` -func (c *Canvas) AddRectFilled(pMin, pMax image.Point, color color.RGBA, rounding float32, roundingCorners DrawFlags) { - c.drawlist.AddRectFilled(ToVec2(pMin), ToVec2(pMax), ToVec4Color(color), rounding, int(roundingCorners)) +// AddRectFilled draws a rectangle filled with `col` +func (c *Canvas) AddRectFilled(pMin, pMax image.Point, col color.RGBA, rounding float32, roundingCorners DrawFlags) { + c.drawlist.AddRectFilled(ToVec2(pMin), ToVec2(pMax), ToVec4Color(col), rounding, int(roundingCorners)) } // AddText draws text -func (c *Canvas) AddText(pos image.Point, color color.RGBA, text string) { - c.drawlist.AddText(ToVec2(pos), ToVec4Color(color), tStr(text)) +func (c *Canvas) AddText(pos image.Point, col color.RGBA, text string) { + c.drawlist.AddText(ToVec2(pos), ToVec4Color(col), tStr(text)) } // AddBezierCubic draws bezier cubic -func (c *Canvas) AddBezierCubic(pos0, cp0, cp1, pos1 image.Point, color color.RGBA, thickness float32, numSegments int) { - c.drawlist.AddBezierCubic(ToVec2(pos0), ToVec2(cp0), ToVec2(cp1), ToVec2(pos1), ToVec4Color(color), thickness, numSegments) +func (c *Canvas) AddBezierCubic(pos0, cp0, cp1, pos1 image.Point, col color.RGBA, thickness float32, numSegments int) { + c.drawlist.AddBezierCubic(ToVec2(pos0), ToVec2(cp0), ToVec2(cp1), ToVec2(pos1), ToVec4Color(col), thickness, numSegments) } // AddTriangle draws a triangle -func (c *Canvas) AddTriangle(p1, p2, p3 image.Point, color color.RGBA, thickness float32) { - c.drawlist.AddTriangle(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec4Color(color), thickness) +func (c *Canvas) AddTriangle(p1, p2, p3 image.Point, col color.RGBA, thickness float32) { + c.drawlist.AddTriangle(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec4Color(col), thickness) } // AddTriangleFilled draws a filled triangle -func (c *Canvas) AddTriangleFilled(p1, p2, p3 image.Point, color color.RGBA) { - c.drawlist.AddTriangleFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec4Color(color)) +func (c *Canvas) AddTriangleFilled(p1, p2, p3 image.Point, col color.RGBA) { + c.drawlist.AddTriangleFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec4Color(col)) } // AddCircle draws a circle -func (c *Canvas) AddCircle(center image.Point, radius float32, color color.RGBA, segments int, thickness float32) { - c.drawlist.AddCircle(ToVec2(center), radius, ToVec4Color(color), segments, thickness) +func (c *Canvas) AddCircle(center image.Point, radius float32, col color.RGBA, segments int, thickness float32) { + c.drawlist.AddCircle(ToVec2(center), radius, ToVec4Color(col), segments, thickness) } // AddCircleFilled draws a filled circle -func (c *Canvas) AddCircleFilled(center image.Point, radius float32, color color.RGBA) { - c.drawlist.AddCircleFilled(ToVec2(center), radius, ToVec4Color(color)) +func (c *Canvas) AddCircleFilled(center image.Point, radius float32, col color.RGBA) { + c.drawlist.AddCircleFilled(ToVec2(center), radius, ToVec4Color(col)) } // AddQuad draws a quad -func (c *Canvas) AddQuad(p1, p2, p3, p4 image.Point, color color.RGBA, thickness float32) { - c.drawlist.AddQuad(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(color), thickness) +func (c *Canvas) AddQuad(p1, p2, p3, p4 image.Point, col color.RGBA, thickness float32) { + c.drawlist.AddQuad(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(col), thickness) } // AddQuadFilled draws a filled quad -func (c *Canvas) AddQuadFilled(p1, p2, p3, p4 image.Point, color color.RGBA) { - c.drawlist.AddQuadFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(color)) +func (c *Canvas) AddQuadFilled(p1, p2, p3, p4 image.Point, col color.RGBA) { + c.drawlist.AddQuadFilled(ToVec2(p1), ToVec2(p2), ToVec2(p3), ToVec2(p4), ToVec4Color(col)) } // Stateful path API, add points then finish with PathFillConvex() or PathStroke() @@ -122,12 +122,12 @@ func (c *Canvas) PathLineToMergeDuplicate(pos image.Point) { c.drawlist.PathLineToMergeDuplicate(ToVec2(pos)) } -func (c *Canvas) PathFillConvex(color color.RGBA) { - c.drawlist.PathFillConvex(ToVec4Color(color)) +func (c *Canvas) PathFillConvex(col color.RGBA) { + c.drawlist.PathFillConvex(ToVec4Color(col)) } -func (c *Canvas) PathStroke(color color.RGBA, closed bool, thickness float32) { - c.drawlist.PathStroke(ToVec4Color(color), closed, thickness) +func (c *Canvas) PathStroke(col color.RGBA, closed bool, thickness float32) { + c.drawlist.PathStroke(ToVec4Color(col), closed, thickness) } func (c *Canvas) PathArcTo(center image.Point, radius, min, max float32, numSegments int) { @@ -146,6 +146,6 @@ func (c *Canvas) AddImage(texture *Texture, pMin, pMax image.Point) { c.drawlist.AddImage(texture.id, ToVec2(pMin), ToVec2(pMax)) } -func (c *Canvas) AddImageV(texture *Texture, pMin, pMax image.Point, uvMin, uvMax image.Point, color color.RGBA) { - c.drawlist.AddImageV(texture.id, ToVec2(pMin), ToVec2(pMax), ToVec2(uvMin), ToVec2(uvMax), ToVec4Color(color)) +func (c *Canvas) AddImageV(texture *Texture, pMin, pMax, uvMin, uvMax image.Point, col color.RGBA) { + c.drawlist.AddImageV(texture.id, ToVec2(pMin), ToVec2(pMax), ToVec2(uvMin), ToVec2(uvMax), ToVec4Color(col)) } diff --git a/CodeEditor.go b/CodeEditor.go index 02971b7a..1a6375e1 100644 --- a/CodeEditor.go +++ b/CodeEditor.go @@ -157,7 +157,7 @@ func (ce *CodeEditorWidget) IsTextChanged() bool { return ce.getState().editor.IsTextChanged() } -func (ce *CodeEditorWidget) GetScreenCursorPos() (int, int) { +func (ce *CodeEditorWidget) GetScreenCursorPos() (x, y int) { return ce.getState().editor.GetScreenCursorPos() } diff --git a/InputHandler.go b/InputHandler.go index 33a51636..303b5586 100644 --- a/InputHandler.go +++ b/InputHandler.go @@ -1,6 +1,6 @@ -// input menager is used to register a keyboard shortcuts in an app package giu +// input menager is used to register a keyboard shortcuts in an app import ( "github.com/go-gl/glfw/v3.3/glfw" ) diff --git a/MasterWindow.go b/MasterWindow.go index 75239f93..f8214465 100644 --- a/MasterWindow.go +++ b/MasterWindow.go @@ -171,8 +171,13 @@ func (w *MasterWindow) setTheme() { } // SetBgColor sets background color of master window. -func (w *MasterWindow) SetBgColor(color color.RGBA) { - w.clearColor = [4]float32{float32(color.R) / 255.0, float32(color.G) / 255.0, float32(color.B) / 255.0, float32(color.A) / 255.0} +func (w *MasterWindow) SetBgColor(bgColor color.RGBA) { + w.clearColor = [4]float32{ + float32(bgColor.R) / 255.0, + float32(bgColor.G) / 255.0, + float32(bgColor.B) / 255.0, + float32(bgColor.A) / 255.0, + } } func (w *MasterWindow) sizeChange(width, height int) { diff --git a/Style.go b/Style.go index 49875b29..db98ba18 100644 --- a/Style.go +++ b/Style.go @@ -192,25 +192,25 @@ func SetMouseCursor(cursor MouseCursorType) { } // GetWindowPadding returns window padding -func GetWindowPadding() (float32, float32) { +func GetWindowPadding() (x, y float32) { vec2 := imgui.CurrentStyle().WindowPadding() return vec2.X, vec2.Y } // GetItemSpacing returns current item spacing -func GetItemSpacing() (float32, float32) { +func GetItemSpacing() (w, h float32) { vec2 := imgui.CurrentStyle().ItemSpacing() return vec2.X, vec2.Y } // GetItemInnerSpacing returns current item inner spacing -func GetItemInnerSpacing() (float32, float32) { +func GetItemInnerSpacing() (w, h float32) { vec2 := imgui.CurrentStyle().ItemInnerSpacing() return vec2.X, vec2.Y } // GetFramePadding returns current frame padding -func GetFramePadding() (float32, float32) { +func GetFramePadding() (x, y float32) { vec2 := imgui.CurrentStyle().FramePadding() return vec2.X, vec2.Y } diff --git a/Utils.go b/Utils.go index 4d8317a8..7d48ef52 100644 --- a/Utils.go +++ b/Utils.go @@ -1,22 +1,30 @@ package giu import ( + "fmt" "image" "image/color" "image/draw" "image/png" "os" + "path/filepath" "github.com/AllenDang/imgui-go" ) // LoadImage loads image from file and returns *image.RGBA func LoadImage(imgPath string) (*image.RGBA, error) { - imgFile, err := os.Open(imgPath) + imgFile, err := os.Open(filepath.Clean(imgPath)) if err != nil { return nil, err } - defer imgFile.Close() + + defer func() { + // nolint:govet // we want to reuse this err variable here + if err := imgFile.Close(); err != nil { + panic(fmt.Sprintf("error closing image file: %s", imgPath)) + } + }() img, err := png.Decode(imgFile) if err != nil { diff --git a/Widgets.go b/Widgets.go index 9893c9e8..2d8dcbcd 100644 --- a/Widgets.go +++ b/Widgets.go @@ -100,7 +100,7 @@ func (i *InputTextMultilineWidget) Labelf(format string, args ...interface{}) *I // Build implements Widget interface func (i *InputTextMultilineWidget) Build() { - if len(i.label) == 0 { + if i.label == "" { i.label = GenAutoID(i.label) } @@ -1999,7 +1999,7 @@ func (h *HSplitterWidget) Build() { ptMax := image.Pt(centerX+width/2, centerY+height/2) style := imgui.CurrentStyle() - color := Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrab)) + c := Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrab)) // Place a invisible button to capture event. imgui.InvisibleButton(h.id, imgui.Vec2{X: h.width, Y: h.height}) @@ -2010,12 +2010,12 @@ func (h *HSplitterWidget) Build() { } if imgui.IsItemHovered() { imgui.SetMouseCursor(imgui.MouseCursorResizeNS) - color = Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrabActive)) + c = Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrabActive)) } // Draw a line in the very center canvas := GetCanvas() - canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), color, 0, 0) + canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), c, 0, 0) } var _ Widget = &VSplitterWidget{} @@ -2075,7 +2075,7 @@ func (v *VSplitterWidget) Build() { ptMax := image.Pt(centerX+width/2, centerY+height/2) style := imgui.CurrentStyle() - color := Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrab)) + c := Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrab)) // Place a invisible button to capture event. imgui.InvisibleButton(v.id, imgui.Vec2{X: v.width, Y: v.height}) @@ -2086,12 +2086,12 @@ func (v *VSplitterWidget) Build() { } if imgui.IsItemHovered() { imgui.SetMouseCursor(imgui.MouseCursorResizeEW) - color = Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrabActive)) + c = Vec4ToRGBA(style.GetColor(imgui.StyleColorScrollbarGrabActive)) } // Draw a line in the very center canvas := GetCanvas() - canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), color, 0, 0) + canvas.AddRectFilled(pt.Add(ptMin), pt.Add(ptMax), c, 0, 0) } var _ Widget = &TabItemWidget{} @@ -2171,7 +2171,7 @@ func (t *TabBarWidget) TabItems(items ...*TabItemWidget) *TabBarWidget { // Build implements Widget interface func (t *TabBarWidget) Build() { buildingID := t.id - if len(buildingID) == 0 { + if buildingID == "" { buildingID = GenAutoID("TabBar") } if imgui.BeginTabBarV(buildingID, int(t.flags)) { @@ -2649,7 +2649,7 @@ type ConditionWidget struct { layoutElse Layout } -func Condition(cond bool, layoutIf Layout, layoutElse Layout) *ConditionWidget { +func Condition(cond bool, layoutIf, layoutElse Layout) *ConditionWidget { return &ConditionWidget{ cond: cond, layoutIf: layoutIf, @@ -3008,10 +3008,10 @@ type ColorEditWidget struct { onChange func() } -func ColorEdit(label string, color *color.RGBA) *ColorEditWidget { +func ColorEdit(label string, c *color.RGBA) *ColorEditWidget { return &ColorEditWidget{ label: tStr(label), - color: color, + color: c, flags: ColorEditFlagsNone, } } From 29076822accf13e490ec6e5aadc08d5ba25e55ec Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 16:31:23 +0200 Subject: [PATCH 25/27] fix all lint errors --- EventHandler.go | 1 + Widgets.go | 3 +++ 2 files changed, 4 insertions(+) diff --git a/EventHandler.go b/EventHandler.go index 6ed73433..74f6b482 100644 --- a/EventHandler.go +++ b/EventHandler.go @@ -108,6 +108,7 @@ func (eh *EventHandler) OnMouseReleased(mouseButton MouseButton, callback func() } // Build implements Widget interface +// nolint:gocognit,gocyclo // will fix later func (eh *EventHandler) Build() { if eh.onActivate != nil || eh.onDeactivate != nil { isActive := IsItemActive() diff --git a/Widgets.go b/Widgets.go index 2d8dcbcd..62273c5c 100644 --- a/Widgets.go +++ b/Widgets.go @@ -1985,6 +1985,7 @@ func (h *HSplitterWidget) ID(id string) *HSplitterWidget { } // Build implements Widget interface +// nolint:dupl // will fix later func (h *HSplitterWidget) Build() { // Calc line position. width := int(40 * Context.GetPlatform().GetContentScale()) @@ -2061,6 +2062,7 @@ func (v *VSplitterWidget) ID(id string) *VSplitterWidget { } // Build implements Widget interface +// nolint:dupl // will fix later func (v *VSplitterWidget) Build() { // Calc line position. width := int(2 * Context.GetPlatform().GetContentScale()) @@ -2757,6 +2759,7 @@ func (l *ListBoxWidget) OnMenu(onMenu func(selectedIndex int, menu string)) *Lis } // Build implements Widget interface +// nolint:gocognit // will fix later func (l *ListBoxWidget) Build() { var state *ListBoxState if s := Context.GetState(l.id); s == nil { From 4fb1dbd27d8f8a75f1b1638704c8992232ec92fc Mon Sep 17 00:00:00 2001 From: gucio321 Date: Sun, 19 Sep 2021 16:44:46 +0200 Subject: [PATCH 26/27] fix remaining gocritic --- Alignment.go | 1 + 1 file changed, 1 insertion(+) diff --git a/Alignment.go b/Alignment.go index 3cd02c19..f961f224 100644 --- a/Alignment.go +++ b/Alignment.go @@ -62,6 +62,7 @@ func (a *AlignmentSetter) Build() { } // exclude some widgets from alignment process + // nolint:gocritic // could have more cases later switch item.(type) { case *CustomWidget: item.Build() From 4f5a1a8bc0879aa988ebb27e80b82bc3279d3899 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Mon, 20 Sep 2021 18:41:56 +0200 Subject: [PATCH 27/27] Widgets.go: fix gocritic lint error --- Widgets.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Widgets.go b/Widgets.go index 568689ad..61683d34 100644 --- a/Widgets.go +++ b/Widgets.go @@ -44,8 +44,7 @@ func (l *RowWidget) Build() { *PopupWidget, *TabItemWidget: // noop default: - switch w.(type) { - case *LabelWidget: + if _, isLabel := w.(*LabelWidget); isLabel { AlignTextToFramePadding() }