| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745 |
- package giu
- import (
- "fmt"
- "image/color"
- "github.com/AllenDang/imgui-go"
- )
- // 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() {
- isFirst := true
- l.widgets.Range(func(w Widget) {
- switch w.(type) {
- case *TooltipWidget,
- *ContextMenuWidget, *PopupModalWidget,
- *PopupWidget:
- // noop
- default:
- if _, isLabel := w.(*LabelWidget); isLabel {
- AlignTextToFramePadding()
- }
- if !isFirst {
- imgui.SameLine()
- } else {
- isFirst = false
- }
- }
- w.Build()
- })
- }
- // SameLine wrapps imgui.SomeLine
- // Don't use if you don't have to (use RowWidget instead).
- func SameLine() {
- imgui.SameLine()
- }
- var _ Widget = &ChildWidget{}
- type ChildWidget struct {
- id string
- width float32
- height float32
- border bool
- flags WindowFlags
- layout Layout
- }
- // Build implements Widget interface.
- func (c *ChildWidget) Build() {
- if imgui.BeginChildV(c.id, imgui.Vec2{X: c.width, Y: c.height}, c.border, int(c.flags)) {
- c.layout.Build()
- }
- imgui.EndChild()
- }
- func (c *ChildWidget) Border(border bool) *ChildWidget {
- c.border = border
- return c
- }
- func (c *ChildWidget) Size(width, height float32) *ChildWidget {
- c.width, c.height = width, height
- return c
- }
- func (c *ChildWidget) Flags(flags WindowFlags) *ChildWidget {
- c.flags = flags
- return c
- }
- func (c *ChildWidget) Layout(widgets ...Widget) *ChildWidget {
- c.layout = Layout(widgets)
- return c
- }
- // ID sets the interval id of child widgets.
- func (c *ChildWidget) ID(id string) *ChildWidget {
- c.id = id
- return c
- }
- func Child() *ChildWidget {
- return &ChildWidget{
- id: GenAutoID("Child"),
- width: 0,
- height: 0,
- border: true,
- flags: 0,
- layout: nil,
- }
- }
- var _ Widget = &ComboCustomWidget{}
- // ComboCustomWidget represents a combo with custom layout when opened.
- type ComboCustomWidget struct {
- label string
- previewValue string
- width float32
- flags ComboFlags
- layout Layout
- }
- // ComboCustom creates a new combo custom widget.
- func ComboCustom(label, previewValue string) *ComboCustomWidget {
- return &ComboCustomWidget{
- label: GenAutoID(label),
- previewValue: tStr(previewValue),
- width: 0,
- flags: 0,
- layout: nil,
- }
- }
- // Layout add combo's layout.
- func (cc *ComboCustomWidget) Layout(widgets ...Widget) *ComboCustomWidget {
- cc.layout = Layout(widgets)
- return cc
- }
- // Flags allows to set combo flags (see Flags.go).
- func (cc *ComboCustomWidget) Flags(flags ComboFlags) *ComboCustomWidget {
- cc.flags = flags
- return cc
- }
- // Size sets combo preiview width.
- func (cc *ComboCustomWidget) Size(width float32) *ComboCustomWidget {
- cc.width = width
- return cc
- }
- // Build implements Widget interface.
- func (cc *ComboCustomWidget) Build() {
- if cc.width > 0 {
- imgui.PushItemWidth(cc.width)
- defer imgui.PopItemWidth()
- }
- if imgui.BeginComboV(tStr(cc.label), cc.previewValue, int(cc.flags)) {
- cc.layout.Build()
- imgui.EndCombo()
- }
- }
- var _ Widget = &ComboWidget{}
- // ComboWidget is a wrapper of ComboCustomWidget.
- // It creates a combo of selectables. (it is the most frequently used).
- type ComboWidget struct {
- label string
- previewValue string
- items []string
- selected *int32
- width float32
- flags ComboFlags
- onChange func()
- }
- // Combo creates a new ComboWidget.
- func Combo(label, previewValue string, items []string, selected *int32) *ComboWidget {
- return &ComboWidget{
- label: GenAutoID(label),
- previewValue: tStr(previewValue),
- items: tStrSlice(items),
- selected: selected,
- flags: 0,
- width: 0,
- onChange: nil,
- }
- }
- // Build implements Widget interface.
- func (c *ComboWidget) Build() {
- if c.width > 0 {
- imgui.PushItemWidth(c.width)
- defer imgui.PopItemWidth()
- }
- if imgui.BeginComboV(tStr(c.label), c.previewValue, int(c.flags)) {
- for i, item := range c.items {
- if imgui.Selectable(item) {
- *c.selected = int32(i)
- if c.onChange != nil {
- c.onChange()
- }
- }
- }
- imgui.EndCombo()
- }
- }
- // Flags allows to set combo flags (see Flags.go).
- func (c *ComboWidget) Flags(flags ComboFlags) *ComboWidget {
- c.flags = flags
- return c
- }
- // Size sets combo's width.
- func (c *ComboWidget) Size(width float32) *ComboWidget {
- c.width = width
- return c
- }
- // OnChange sets callback when combo value gets changed.
- func (c *ComboWidget) OnChange(onChange func()) *ComboWidget {
- c.onChange = onChange
- return c
- }
- var _ Widget = &ContextMenuWidget{}
- type ContextMenuWidget struct {
- id string
- mouseButton MouseButton
- layout Layout
- }
- func ContextMenu() *ContextMenuWidget {
- return &ContextMenuWidget{
- mouseButton: MouseButtonRight,
- layout: nil,
- id: GenAutoID("ContextMenu"),
- }
- }
- func (c *ContextMenuWidget) Layout(widgets ...Widget) *ContextMenuWidget {
- c.layout = Layout(widgets)
- return c
- }
- func (c *ContextMenuWidget) MouseButton(mouseButton MouseButton) *ContextMenuWidget {
- c.mouseButton = mouseButton
- return c
- }
- func (c *ContextMenuWidget) ID(id string) *ContextMenuWidget {
- c.id = id
- return c
- }
- // Build implements Widget interface.
- func (c *ContextMenuWidget) Build() {
- if imgui.BeginPopupContextItemV(c.id, int(c.mouseButton)) {
- c.layout.Build()
- imgui.EndPopup()
- }
- }
- var _ Widget = &DragIntWidget{}
- type DragIntWidget struct {
- label string
- value *int32
- speed float32
- min int32
- max int32
- format string
- }
- func DragInt(label string, value *int32, min, max int32) *DragIntWidget {
- return &DragIntWidget{
- label: GenAutoID(label),
- value: value,
- speed: 1.0,
- min: min,
- max: max,
- format: "%d",
- }
- }
- func (d *DragIntWidget) Speed(speed float32) *DragIntWidget {
- d.speed = speed
- return d
- }
- func (d *DragIntWidget) Format(format string) *DragIntWidget {
- d.format = format
- return d
- }
- // Build implements Widget interface.
- func (d *DragIntWidget) Build() {
- imgui.DragIntV(tStr(d.label), d.value, d.speed, d.min, d.max, d.format)
- }
- var _ Widget = &ColumnWidget{}
- // ColumnWidget will place all widgets one by one vertically.
- type ColumnWidget struct {
- widgets Layout
- }
- // Column creates a new ColumnWidget.
- func Column(widgets ...Widget) *ColumnWidget {
- return &ColumnWidget{
- widgets: widgets,
- }
- }
- // Build implements Widget interface.
- func (g *ColumnWidget) Build() {
- imgui.BeginGroup()
- g.widgets.Build()
- imgui.EndGroup()
- }
- var _ Widget = &MainMenuBarWidget{}
- type MainMenuBarWidget struct {
- layout Layout
- }
- func MainMenuBar() *MainMenuBarWidget {
- return &MainMenuBarWidget{
- layout: nil,
- }
- }
- func (m *MainMenuBarWidget) Layout(widgets ...Widget) *MainMenuBarWidget {
- m.layout = Layout(widgets)
- return m
- }
- // Build implements Widget interface.
- func (m *MainMenuBarWidget) Build() {
- if imgui.BeginMainMenuBar() {
- m.layout.Build()
- imgui.EndMainMenuBar()
- }
- }
- var _ Widget = &MenuBarWidget{}
- type MenuBarWidget struct {
- layout Layout
- }
- func MenuBar() *MenuBarWidget {
- return &MenuBarWidget{
- layout: nil,
- }
- }
- func (m *MenuBarWidget) Layout(widgets ...Widget) *MenuBarWidget {
- m.layout = Layout(widgets)
- return m
- }
- // Build implements Widget interface.
- func (m *MenuBarWidget) Build() {
- if imgui.BeginMenuBar() {
- m.layout.Build()
- imgui.EndMenuBar()
- }
- }
- var _ Widget = &MenuItemWidget{}
- type MenuItemWidget struct {
- label string
- selected bool
- enabled bool
- onClick func()
- }
- func MenuItem(label string) *MenuItemWidget {
- return &MenuItemWidget{
- label: GenAutoID(label),
- selected: false,
- enabled: true,
- onClick: nil,
- }
- }
- func MenuItemf(format string, args ...any) *MenuItemWidget {
- return MenuItem(fmt.Sprintf(format, args...))
- }
- func (m *MenuItemWidget) Selected(s bool) *MenuItemWidget {
- m.selected = s
- return m
- }
- func (m *MenuItemWidget) Enabled(e bool) *MenuItemWidget {
- m.enabled = e
- return m
- }
- func (m *MenuItemWidget) OnClick(onClick func()) *MenuItemWidget {
- m.onClick = onClick
- return m
- }
- // Build implements Widget interface.
- func (m *MenuItemWidget) Build() {
- if imgui.MenuItemV(tStr(m.label), "", m.selected, m.enabled) && m.onClick != nil {
- m.onClick()
- }
- }
- var _ Widget = &MenuWidget{}
- type MenuWidget struct {
- label string
- enabled bool
- layout Layout
- }
- func Menu(label string) *MenuWidget {
- return &MenuWidget{
- label: GenAutoID(label),
- enabled: true,
- layout: nil,
- }
- }
- func Menuf(format string, args ...any) *MenuWidget {
- return Menu(fmt.Sprintf(format, args...))
- }
- func (m *MenuWidget) Enabled(e bool) *MenuWidget {
- m.enabled = e
- return m
- }
- func (m *MenuWidget) Layout(widgets ...Widget) *MenuWidget {
- m.layout = Layout(widgets)
- return m
- }
- // Build implements Widget interface.
- func (m *MenuWidget) Build() {
- if imgui.BeginMenuV(tStr(m.label), m.enabled) {
- m.layout.Build()
- imgui.EndMenu()
- }
- }
- var _ Widget = &ProgressBarWidget{}
- type ProgressBarWidget struct {
- fraction float32
- width float32
- height float32
- overlay string
- }
- func ProgressBar(fraction float32) *ProgressBarWidget {
- return &ProgressBarWidget{
- fraction: fraction,
- width: 0,
- height: 0,
- overlay: "",
- }
- }
- func (p *ProgressBarWidget) Size(width, height float32) *ProgressBarWidget {
- p.width, p.height = width, height
- return p
- }
- func (p *ProgressBarWidget) Overlay(overlay string) *ProgressBarWidget {
- p.overlay = tStr(overlay)
- return p
- }
- func (p *ProgressBarWidget) Overlayf(format string, args ...any) *ProgressBarWidget {
- 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)
- }
- var _ Widget = &SeparatorWidget{}
- type SeparatorWidget struct{}
- // Build implements Widget interface.
- func (s *SeparatorWidget) Build() {
- imgui.Separator()
- }
- func Separator() *SeparatorWidget {
- return &SeparatorWidget{}
- }
- var _ Widget = &DummyWidget{}
- type DummyWidget struct {
- width float32
- height float32
- }
- // Build implements Widget interface.
- func (d *DummyWidget) Build() {
- w, h := GetAvailableRegion()
- if d.width < 0 {
- d.width = w + d.width
- }
- if d.height < 0 {
- d.height = h + d.height
- }
- imgui.Dummy(imgui.Vec2{X: d.width, Y: d.height})
- }
- func Dummy(width, height float32) *DummyWidget {
- return &DummyWidget{
- width: width,
- height: height,
- }
- }
- type TabItemWidget struct {
- label string
- open *bool
- flags TabItemFlags
- layout Layout
- }
- func TabItem(label string) *TabItemWidget {
- return &TabItemWidget{
- label: tStr(label),
- open: nil,
- flags: 0,
- layout: nil,
- }
- }
- func TabItemf(format string, args ...any) *TabItemWidget {
- return TabItem(fmt.Sprintf(format, args...))
- }
- func (t *TabItemWidget) IsOpen(open *bool) *TabItemWidget {
- t.open = open
- return t
- }
- func (t *TabItemWidget) Flags(flags TabItemFlags) *TabItemWidget {
- t.flags = flags
- return t
- }
- func (t *TabItemWidget) Layout(widgets ...Widget) *TabItemWidget {
- t.layout = Layout(widgets)
- return t
- }
- // BuildTabItem executes tab item build steps.
- func (t *TabItemWidget) BuildTabItem() {
- if imgui.BeginTabItemV(t.label, t.open, int(t.flags)) {
- t.layout.Build()
- imgui.EndTabItem()
- }
- }
- var _ Widget = &TabBarWidget{}
- type TabBarWidget struct {
- id string
- flags TabBarFlags
- tabItems []*TabItemWidget
- }
- func TabBar() *TabBarWidget {
- return &TabBarWidget{
- id: GenAutoID("TabBar"),
- flags: 0,
- }
- }
- func (t *TabBarWidget) Flags(flags TabBarFlags) *TabBarWidget {
- t.flags = flags
- return t
- }
- func (t *TabBarWidget) ID(id string) *TabBarWidget {
- t.id = id
- return t
- }
- func (t *TabBarWidget) TabItems(items ...*TabItemWidget) *TabBarWidget {
- t.tabItems = items
- return t
- }
- // Build implements Widget interface.
- func (t *TabBarWidget) Build() {
- if imgui.BeginTabBarV(t.id, int(t.flags)) {
- for _, ti := range t.tabItems {
- ti.BuildTabItem()
- }
- imgui.EndTabBar()
- }
- }
- var _ Widget = &TooltipWidget{}
- type TooltipWidget struct {
- tip string
- layout Layout
- }
- // Build implements Widget interface.
- func (t *TooltipWidget) Build() {
- if imgui.IsItemHovered() {
- if t.layout != nil {
- imgui.BeginTooltip()
- t.layout.Build()
- imgui.EndTooltip()
- } else {
- imgui.SetTooltip(t.tip)
- }
- }
- }
- func Tooltip(tip string) *TooltipWidget {
- return &TooltipWidget{
- tip: tStr(tip),
- layout: nil,
- }
- }
- func Tooltipf(format string, args ...any) *TooltipWidget {
- return Tooltip(fmt.Sprintf(format, args...))
- }
- func (t *TooltipWidget) Layout(widgets ...Widget) *TooltipWidget {
- t.layout = Layout(widgets)
- return t
- }
- var _ Widget = &SpacingWidget{}
- type SpacingWidget struct{}
- // Build implements Widget interface.
- func (s *SpacingWidget) Build() {
- imgui.Spacing()
- }
- func Spacing() *SpacingWidget {
- return &SpacingWidget{}
- }
- var _ Widget = &ColorEditWidget{}
- type ColorEditWidget struct {
- label string
- color *color.RGBA
- flags ColorEditFlags
- width float32
- onChange func()
- }
- func ColorEdit(label string, c *color.RGBA) *ColorEditWidget {
- return &ColorEditWidget{
- label: GenAutoID(label),
- color: c,
- flags: ColorEditFlagsNone,
- }
- }
- func (ce *ColorEditWidget) OnChange(cb func()) *ColorEditWidget {
- ce.onChange = cb
- return ce
- }
- func (ce *ColorEditWidget) Flags(f ColorEditFlags) *ColorEditWidget {
- ce.flags = f
- return ce
- }
- func (ce *ColorEditWidget) Size(width float32) *ColorEditWidget {
- ce.width = width
- return ce
- }
- // Build implements Widget interface.
- func (ce *ColorEditWidget) Build() {
- c := ToVec4Color(*ce.color)
- col := [4]float32{
- c.X,
- c.Y,
- c.Z,
- c.W,
- }
- if ce.width > 0 {
- imgui.PushItemWidth(ce.width)
- }
- if imgui.ColorEdit4V(
- tStr(ce.label),
- &col,
- int(ce.flags),
- ) {
- *ce.color = Vec4ToRGBA(imgui.Vec4{
- X: col[0],
- Y: col[1],
- Z: col[2],
- W: col[3],
- })
- if ce.onChange != nil {
- ce.onChange()
- }
- }
- if ce.width > 0 {
- imgui.PopItemWidth()
- }
- }
|