| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- package giu
- import (
- "fmt"
- "math"
- "github.com/AllenDang/imgui-go"
- "github.com/sahilm/fuzzy"
- )
- var _ Widget = &InputTextMultilineWidget{}
- // InputTextMultilineWidget is a large (multiline) text input
- // see examples/widgets/.
- type InputTextMultilineWidget struct {
- label string
- text *string
- width, height float32
- flags InputTextFlags
- cb imgui.InputTextCallback
- onChange func()
- }
- // InputTextMultiline creates InputTextMultilineWidget.
- func InputTextMultiline(text *string) *InputTextMultilineWidget {
- return &InputTextMultilineWidget{
- text: text,
- width: 0,
- height: 0,
- flags: 0,
- cb: nil,
- onChange: nil,
- label: GenAutoID("##InputTextMultiline"),
- }
- }
- // Label sets input field label.
- func (i *InputTextMultilineWidget) Label(label string) *InputTextMultilineWidget {
- i.label = label
- return i
- }
- // Labelf is formatting version of Label.
- func (i *InputTextMultilineWidget) Labelf(format string, args ...any) *InputTextMultilineWidget {
- return i.Label(fmt.Sprintf(format, args...))
- }
- // Flags sets InputTextFlags (see Flags.go).
- func (i *InputTextMultilineWidget) Flags(flags InputTextFlags) *InputTextMultilineWidget {
- i.flags = flags
- return i
- }
- // Callback sets imgui.InputTextCallback.
- func (i *InputTextMultilineWidget) Callback(cb imgui.InputTextCallback) *InputTextMultilineWidget {
- i.cb = cb
- return i
- }
- // OnChange set callback called when user action taken on input text field (when text was changed).
- func (i *InputTextMultilineWidget) OnChange(onChange func()) *InputTextMultilineWidget {
- i.onChange = onChange
- return i
- }
- // Size sets input field size.
- func (i *InputTextMultilineWidget) Size(width, height float32) *InputTextMultilineWidget {
- i.width, i.height = width, height
- return i
- }
- // Build implements Widget interface.
- func (i *InputTextMultilineWidget) Build() {
- if imgui.InputTextMultilineV(
- tStr(i.label),
- tStrPtr(i.text),
- imgui.Vec2{
- X: i.width,
- Y: i.height,
- },
- int(i.flags), i.cb,
- ) && i.onChange != nil {
- i.onChange()
- }
- }
- var _ Widget = &BulletWidget{}
- // BulletWidget adds a small, white dot (bullet).
- // useful in enumerations.
- type BulletWidget struct{}
- // Bullet creates a bullet widget.
- func Bullet() *BulletWidget {
- return &BulletWidget{}
- }
- // Build implements Widget interface.
- func (b *BulletWidget) Build() {
- imgui.Bullet()
- }
- var _ Widget = &BulletTextWidget{}
- // BulletTextWidget does similar to BulletWidget, but allows
- // to add a text after a bullet. Very useful to create lists.
- type BulletTextWidget struct {
- text string
- }
- // BulletText creates bulletTextWidget.
- func BulletText(text string) *BulletTextWidget {
- return &BulletTextWidget{
- text: tStr(text),
- }
- }
- // BulletTextf is a formatting version of BulletText.
- func BulletTextf(format string, args ...any) *BulletTextWidget {
- return BulletText(fmt.Sprintf(format, args...))
- }
- // Build implements Widget interface.
- func (bt *BulletTextWidget) Build() {
- imgui.BulletText(bt.text)
- }
- var _ Disposable = &inputTextState{}
- type inputTextState struct {
- autoCompleteCandidates fuzzy.Matches
- }
- // Dispose implements disposable interface.
- func (s *inputTextState) Dispose() {
- s.autoCompleteCandidates = nil
- }
- var _ Widget = &InputTextWidget{}
- // InputTextWidget is a single-line text iinput.
- type InputTextWidget struct {
- label string
- hint string
- value *string
- width float32
- candidates []string
- flags InputTextFlags
- cb imgui.InputTextCallback
- onChange func()
- }
- // InputText creates new input text widget.
- func InputText(value *string) *InputTextWidget {
- return &InputTextWidget{
- label: GenAutoID("##InputText"),
- hint: "",
- value: value,
- width: 0,
- flags: 0,
- cb: nil,
- onChange: nil,
- }
- }
- // Label adds label (alternatively you can use it to set widget's id).
- func (i *InputTextWidget) Label(label string) *InputTextWidget {
- i.label = tStr(label)
- return i
- }
- // Labelf adds formatted label.
- func (i *InputTextWidget) Labelf(format string, args ...any) *InputTextWidget {
- return i.Label(fmt.Sprintf(format, args...))
- }
- // 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
- return i
- }
- // Hint sets hint text.
- func (i *InputTextWidget) Hint(hint string) *InputTextWidget {
- i.hint = tStr(hint)
- return i
- }
- // Size sets field's width.
- func (i *InputTextWidget) Size(width float32) *InputTextWidget {
- i.width = width
- return i
- }
- // Flags sets flags.
- func (i *InputTextWidget) Flags(flags InputTextFlags) *InputTextWidget {
- i.flags = flags
- return i
- }
- // Callback sets input text callback.
- func (i *InputTextWidget) Callback(cb imgui.InputTextCallback) *InputTextWidget {
- i.cb = cb
- return i
- }
- // OnChange sets callback when text was changed.
- func (i *InputTextWidget) OnChange(onChange func()) *InputTextWidget {
- i.onChange = onChange
- return i
- }
- // Build implements Widget interface.
- func (i *InputTextWidget) Build() {
- // Get state
- var state *inputTextState
- if s := Context.GetState(i.label); s == nil {
- state = &inputTextState{}
- Context.SetState(i.label, state)
- } else {
- var isOk bool
- state, isOk = s.(*inputTextState)
- Assert(isOk, "InputTextWidget", "Build", "wrong state type recovered.")
- }
- if i.width != 0 {
- PushItemWidth(i.width)
- defer PopItemWidth()
- }
- isChanged := imgui.InputTextWithHint(i.label, i.hint, tStrPtr(i.value), int(i.flags), i.cb)
- if isChanged && i.onChange != nil {
- i.onChange()
- }
- if isChanged {
- // Enable auto complete
- if len(i.candidates) > 0 {
- matches := fuzzy.Find(*i.value, i.candidates)
- if matches.Len() > 0 {
- size := int(math.Min(5, float64(matches.Len())))
- matches = matches[:size]
- state.autoCompleteCandidates = matches
- }
- }
- }
- // Draw autocomplete list
- if len(state.autoCompleteCandidates) > 0 {
- labels := make(Layout, len(state.autoCompleteCandidates))
- for i, m := range state.autoCompleteCandidates {
- labels[i] = Label(m.Str)
- }
- SetNextWindowPos(imgui.GetItemRectMin().X, imgui.GetItemRectMax().Y)
- imgui.BeginTooltip()
- labels.Build()
- imgui.EndTooltip()
- // Press enter will replace value string with first match candidate
- if IsKeyPressed(KeyEnter) {
- *i.value = state.autoCompleteCandidates[0].Str
- state.autoCompleteCandidates = nil
- }
- }
- }
- var _ Widget = &InputIntWidget{}
- // InputIntWidget is an input text field acceptiong intager values only.
- type InputIntWidget struct {
- label string
- value *int32
- width float32
- flags InputTextFlags
- onChange func()
- }
- // InputInt creates input int widget
- // NOTE: value is int32, so its size is up to 10^32-1.
- // to process greater values, you need to use InputTextWidget
- // with InputTextFlagsCharsDecimal and strconv.ParseInt in OnChange callback.
- func InputInt(value *int32) *InputIntWidget {
- return &InputIntWidget{
- label: GenAutoID("##InputInt"),
- value: value,
- width: 0,
- flags: 0,
- onChange: nil,
- }
- }
- // Label sets label (id).
- func (i *InputIntWidget) Label(label string) *InputIntWidget {
- i.label = tStr(label)
- return i
- }
- // Labelf sets formatted label.
- func (i *InputIntWidget) Labelf(format string, args ...any) *InputIntWidget {
- return i.Label(fmt.Sprintf(format, args...))
- }
- // Size sets input's width.
- func (i *InputIntWidget) Size(width float32) *InputIntWidget {
- i.width = width
- return i
- }
- // Flags sets flags.
- func (i *InputIntWidget) Flags(flags InputTextFlags) *InputIntWidget {
- i.flags = flags
- return i
- }
- // OnChange adds on change callback.
- func (i *InputIntWidget) OnChange(onChange func()) *InputIntWidget {
- i.onChange = onChange
- return i
- }
- // Build implements Widget interface.
- func (i *InputIntWidget) Build() {
- if i.width != 0 {
- PushItemWidth(i.width)
- defer PopItemWidth()
- }
- if imgui.InputIntV(i.label, i.value, 0, 100, int(i.flags)) && i.onChange != nil {
- i.onChange()
- }
- }
- var _ Widget = &InputFloatWidget{}
- // InputFloatWidget does similar to InputIntWIdget, but accepts float numbers.
- type InputFloatWidget struct {
- label string
- value *float32
- width float32
- flags InputTextFlags
- format string
- onChange func()
- }
- // InputFloat constructs InputFloatWidget.
- func InputFloat(value *float32) *InputFloatWidget {
- return &InputFloatWidget{
- label: GenAutoID("##InputFloatWidget"),
- width: 0,
- value: value,
- format: "%.3f",
- flags: 0,
- onChange: nil,
- }
- }
- // Label sets label of input field.
- func (i *InputFloatWidget) Label(label string) *InputFloatWidget {
- i.label = tStr(label)
- return i
- }
- // Labelf sets formatted label.
- func (i *InputFloatWidget) Labelf(format string, args ...any) *InputFloatWidget {
- return i.Label(fmt.Sprintf(format, args...))
- }
- // Size sets input field's width.
- func (i *InputFloatWidget) Size(width float32) *InputFloatWidget {
- i.width = width
- return i
- }
- // Flags sets flags.
- func (i *InputFloatWidget) Flags(flags InputTextFlags) *InputFloatWidget {
- i.flags = flags
- return i
- }
- // Format sets data format (e.g. %.3f).
- func (i *InputFloatWidget) Format(format string) *InputFloatWidget {
- i.format = format
- return i
- }
- // OnChange sets callback called when text is changed.
- func (i *InputFloatWidget) OnChange(onChange func()) *InputFloatWidget {
- i.onChange = onChange
- return i
- }
- // Build implements Widget interface.
- func (i *InputFloatWidget) Build() {
- if i.width != 0 {
- PushItemWidth(i.width)
- defer PopItemWidth()
- }
- if imgui.InputFloatV(i.label, i.value, 0, 0, i.format, int(i.flags)) && i.onChange != nil {
- i.onChange()
- }
- }
- var _ Widget = &LabelWidget{}
- // LabelWidget is a plain text label.
- type LabelWidget struct {
- label string
- fontInfo *FontInfo
- wrapped bool
- }
- // Label constructs label widget.
- func Label(label string) *LabelWidget {
- return &LabelWidget{
- label: tStr(label),
- wrapped: false,
- }
- }
- // Labelf allows to add formatted label.
- func Labelf(format string, args ...any) *LabelWidget {
- return Label(fmt.Sprintf(format, args...))
- }
- // Wrapped determinates if label is frapped.
- func (l *LabelWidget) Wrapped(wrapped bool) *LabelWidget {
- l.wrapped = wrapped
- return l
- }
- // Font sets specific font (does like Style().SetFont).
- func (l *LabelWidget) Font(font *FontInfo) *LabelWidget {
- l.fontInfo = font
- return l
- }
- // Build implements Widget interface.
- func (l *LabelWidget) Build() {
- if l.wrapped {
- PushTextWrapPos()
- defer PopTextWrapPos()
- }
- if l.fontInfo != nil {
- if PushFont(l.fontInfo) {
- defer PopFont()
- }
- }
- imgui.Text(l.label)
- }
|