mvvmtk

package module
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: BSD-3-Clause Imports: 2 Imported by: 0

README

mvvmtk

Go Reference

Binding glue between go-widgets/mvvm (Observable / Command / ObservableList) and go-widgets/toolkit widgets.

Why a separate module

mvvm is deliberately toolkit-agnostic: it binds through a pointer to a widget's value field and a pointer to its callback slot, and never imports any widget package. toolkit, in turn, never imports mvvm. mvvmtk is the one module that knows both, so an app wires a ViewModel to a widget in a single call and never touches widget state fields directly.

unbind := mvvmtk.BindText(entry, vm.Query, win.Invalidate) // entry.Text ⇄ vm.Query
defer unbind()

Each helper is a thin, correct wrapper over the generic mvvm adapters (BindField / OneWay / BindList / BindCommand) with the widget's real field and callback names filled in — no business logic. Every helper returns an unbind func() that detaches the binding and restores any prior callback.

Helpers

Helper Widget field(s) Direction
BindText(*SearchEntry, *Observable[string], invalidate) Text / OnChange two-way
BindEntryText(*Entry, *Observable[string], invalidate) Text / OnChange two-way
BindChecked(*CheckButton, *Observable[bool], invalidate) Checked / OnToggle two-way
BindSelectedIndex(*DropDown, *Observable[int], invalidate) Selected / OnSelect two-way
BindSpin(*SpinButton, *Observable[int], invalidate) Value / OnChange two-way
BindListSelection(*ListBox, *Observable[int], invalidate) Selected / OnActivate two-way
BindViewSwitcher(*ViewSwitcher, *Observable[int], invalidate) Current / OnChange two-way
BindLabel(*Label, *Observable[string], invalidate) Text one-way
BindProgress(*ProgressBar, *Observable[float64], invalidate) Fraction one-way
BindListItems[T](*ListBox, *ObservableList[T], project, invalidate) Items list → widget
BindDropDownOptions[T](*DropDown, *ObservableList[T], project, invalidate) Options list → widget
BindViews[T](*ViewSwitcher, *ObservableList[T], project, invalidate) Views list → widget
BindCommand(*Button, *Command, invalidate) OnClick + Style greying command
BindTree[T](*TreeTable, *ObservableList[T], project, invalidate) Root forest list → widget

BindCommand reflects CanExecute by greying the button — swapping its Style to ButtonSecondary when the command cannot execute and restoring the original Style when it can — because a Button has no boolean "disabled" field.

BindTree rebuilds a TreeTable.Root ([]*TreeTableNode forest) from the list; the caller's project owns each node's Cells/Children.

Install

go get github.com/go-widgets/mvvmtk

License

BSD-3-Clause. See LICENSE. Copyright (c) 2026 the go-widgets/mvvmtk authors.

Documentation

Overview

Package mvvmtk is the binding glue between github.com/go-widgets/mvvm (Observable / Command / ObservableList) and github.com/go-widgets/toolkit widgets.

mvvm is deliberately toolkit-agnostic: it binds through a pointer to a widget's value field and a pointer to its callback slot, and never imports any widget package. toolkit, in turn, never imports mvvm. This module is the one place that knows BOTH, so an app can wire a ViewModel to a widget in a single call and never touch widget state fields directly:

unbind := mvvmtk.BindText(entry, vm.Query, win.Invalidate)

Each helper is a thin, correct wrapper over the generic mvvm adapters (BindField / OneWay / BindList / BindCommand) with the widget's real field and callback names filled in — no business logic. Every helper returns an unbind func that detaches the binding and restores any prior callback.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BindAccordion added in v0.2.0

func BindAccordion(a *toolkit.Accordion, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindAccordion two-way-binds an Accordion.s exclusive-mode Expanded section index to an int observable (via the Accordion.Expanded() Observable; -1 when all are collapsed). A Multiple-mode accordion does not track a single index.

func BindAgendaRename added in v0.2.0

func BindAgendaRename(s *toolkit.AgendaSidebar, l *mvvm.ObservableList[string], invalidate func()) (unbind func())

BindAgendaRename two-way-binds an AgendaSidebar's calendar names to a string ObservableList (callback AgendaSidebar.OnRename(i, name)). An inline rename pushes the new name into the list at that index; a list change writes the names back onto the matching calendars (up to the shorter length, leaving each calendar's Color/Hidden untouched). The list is the source of truth: the sidebar's names are seeded from it. Returns an unbind that restores the prior OnRename and detaches.

func BindCarousel added in v0.2.0

func BindCarousel(c *toolkit.Carousel, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindCarousel two-way-binds a Carousel's Current slide to an int observable (via the Carousel.Current() Observable).

func BindChecked

func BindChecked(cb *toolkit.CheckButton, obs *mvvm.Observable[bool], invalidate func()) (unbind func())

BindChecked two-way-binds a CheckButton's Checked to a bool observable (via the CheckButton.Checked() Observable).

func BindColor added in v0.2.0

func BindColor(c *toolkit.ColorChooser, obs *mvvm.Observable[toolkit.RGBA], invalidate func()) (unbind func())

BindColor two-way-binds a ColorChooser's Color to an RGBA observable (fields ColorChooser.Color / ColorChooser.OnChange). ColorPicker, which exposes no Color field, is bound with BindColorPicker instead.

func BindColorPicker added in v0.2.0

func BindColorPicker(cp *toolkit.ColorPicker, obs *mvvm.Observable[toolkit.RGBA], invalidate func()) (unbind func())

BindColorPicker two-way-binds a ColorPicker's colour to an RGBA observable via its Color() / SetColor() accessors (it has no exported colour field) and its OnChange(c) callback. ColorChooser, which does expose a Color field, uses the field-based BindColor instead.

func BindComboText added in v0.2.0

func BindComboText(c *toolkit.ComboBox, obs *mvvm.Observable[string], invalidate func()) (unbind func())

BindComboText two-way-binds a ComboBox's Text to a string observable (via the ComboBox.Text() Observable).

func BindCommand

func BindCommand(b *toolkit.Button, c *mvvm.Command, invalidate func()) (unbind func())

BindCommand wires a Command to a Button: it composes Execute into the button's OnClick and reflects executability by greying the button — swapping its Style to ButtonSecondary when the command cannot execute and restoring the original Style when it can (a Button has no boolean "disabled" field, so this backend-specific greying is how CanExecute surfaces). invalidate (may be nil) requests a repaint on each executability change. The returned unbind restores the prior OnClick and detaches.

func BindCycle added in v0.2.0

func BindCycle(c *toolkit.CycleButton, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindCycle two-way-binds a CycleButton.s Index to an int observable (via the CycleButton.Index() Observable). A host that also wants the option string reads CycleButton.Value() itself.

func BindDate added in v0.2.0

func BindDate(c *toolkit.Calendar, obs *mvvm.Observable[Date], invalidate func()) (unbind func())

BindDate two-way-binds a Calendar's selected date to a Date observable via its SetDate(y, m, d) seed and OnSelect(y, m, d) callback. OnSelect's three-argument signature is not func(Date), so BindField cannot drive it.

func BindDatePicker added in v0.2.0

func BindDatePicker(dp *toolkit.DatePicker, obs *mvvm.Observable[Date], invalidate func()) (unbind func())

BindDatePicker two-way-binds a DatePicker's date to a Date observable via its SetDate(y, m, d) seed and OnChange(y, m, d) callback — the DatePicker analogue of BindDate (a DatePicker reports its date through OnChange, a Calendar through OnSelect).

func BindDropDownOptions

func BindDropDownOptions[T any](d *toolkit.DropDown, l *mvvm.ObservableList[T], project func(T) string, invalidate func()) (unbind func())

BindDropDownOptions binds an ObservableList to a DropDown's Options slice (field DropDown.Options), projecting each element to its option string.

func BindEntryText

func BindEntryText(e *toolkit.Entry, obs *mvvm.Observable[string], invalidate func()) (unbind func())

BindEntryText two-way-binds an Entry.s Text to a string observable (via the Entry.Text() Observable).

func BindExpander added in v0.2.0

func BindExpander(e *toolkit.Expander, obs *mvvm.Observable[bool], invalidate func()) (unbind func())

BindExpander two-way-binds an Expander's Expanded to a bool observable (via the Expander.Expanded() Observable).

func BindGanttSelection added in v0.2.0

func BindGanttSelection(g *toolkit.Gantt, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindGanttSelection two-way-binds a Gantt's Selected task to an int observable (via the Gantt.Selected() Observable).

func BindLabel

func BindLabel(l *toolkit.Label, obs *mvvm.Observable[string], invalidate func()) (unbind func())

BindLabel one-way-binds a string observable to a Label's Text (field Label.Text; a Label has no edit callback).

func BindListItems

func BindListItems[T any](lb *toolkit.ListBox, l *mvvm.ObservableList[T], project func(T) string, invalidate func()) (unbind func())

BindListItems binds an ObservableList to a ListBox's Items slice (field ListBox.Items), projecting each element to its row string.

func BindListSelection

func BindListSelection(lb *toolkit.ListBox, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindListSelection two-way-binds a ListBox's Selected row to an int observable (via the ListBox.Selected() Observable).

func BindMenuChecks added in v0.2.0

func BindMenuChecks(m *toolkit.Menu, l *mvvm.ObservableList[bool], invalidate func()) (unbind func())

BindMenuChecks two-way-binds a Menu's item checked states to a bool ObservableList (callback Menu.OnItemToggle(i, checked)). Toggling a checkable or radio row pushes its new state into the list at that index; a list change writes the flags back onto the matching items (up to the shorter length). The list is the source of truth: the menu's Checked flags are seeded from it. Returns an unbind that restores the prior OnItemToggle and detaches.

func BindNotebook added in v0.2.0

func BindNotebook(n *toolkit.Notebook, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindNotebook two-way-binds a Notebook's Active tab to an int observable (via the Notebook.Active() Observable).

func BindPagination added in v0.2.0

func BindPagination(pg *toolkit.Pagination, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindPagination two-way-binds a Pagination's Current page to an int observable (via the Pagination.Current() Observable).

func BindPagingToolbar added in v0.2.0

func BindPagingToolbar(pt *toolkit.PagingToolbar, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindPagingToolbar two-way-binds a PagingToolbar's Page to an int observable (via the PagingToolbar.Page() Observable).

func BindProgress

func BindProgress(p *toolkit.ProgressBar, obs *mvvm.Observable[float64], invalidate func()) (unbind func())

BindProgress one-way-binds a float64 observable to a ProgressBar's Fraction (field ProgressBar.Fraction; a ProgressBar has no edit callback). Callers keep the value in the widget's [0,1] domain.

func BindRadio added in v0.2.0

func BindRadio(r *toolkit.RadioButton, obs *mvvm.Observable[bool], invalidate func()) (unbind func())

BindRadio two-way-binds a standalone RadioButton's Checked to a bool observable (via the RadioButton.Checked() Observable). For a set of mutually-exclusive radios use BindRadioGroup, which binds the group's Active index; this helper is for a single, group-less radio behaving like a check.

func BindRadioGroup added in v0.2.0

func BindRadioGroup(g *toolkit.RadioGroup, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindRadioGroup two-way-binds a RadioGroup's Active member to an int observable (via the RadioGroup.Active() Observable). This binds the whole group (which member is checked); BindRadio binds a single group-less radio.

func BindRange added in v0.2.0

func BindRange(rs *toolkit.RangeSlider, obs *mvvm.Observable[[2]float64], invalidate func()) (unbind func())

BindRange two-way-binds a RangeSlider's [Low, High] pair to a [2]float64 observable (fields RangeSlider.Low / RangeSlider.High, callback RangeSlider.OnChange(low, high)). The tuple is a single [2]float64 so a two-handle drag round-trips atomically; index 0 is Low, index 1 is High.

func BindRating added in v0.2.0

func BindRating(r *toolkit.Rating, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindRating two-way-binds a Rating's Value to an int observable (via the Rating.Value() Observable).

func BindScale added in v0.2.0

func BindScale(s *toolkit.Scale, obs *mvvm.Observable[float64], invalidate func()) (unbind func())

BindScale two-way-binds a Scale's Value to a float64 observable (via the Scale.Value() Observable).

func BindSelectedIndex

func BindSelectedIndex(d *toolkit.DropDown, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindSelectedIndex two-way-binds a DropDown's Selected index to an int observable (via the DropDown.Selected() Observable).

func BindSpin

func BindSpin(s *toolkit.SpinButton, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindSpin two-way-binds a SpinButton's Value to an int observable (via the SpinButton.Value() Observable).

func BindSwitch added in v0.2.0

func BindSwitch(s *toolkit.Switch, obs *mvvm.Observable[bool], invalidate func()) (unbind func())

BindSwitch two-way-binds a Switch's On to a bool observable (via the Switch.On() Observable).

func BindTableSelection added in v0.2.0

func BindTableSelection(t *toolkit.Table, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindTableSelection two-way-binds a Table's Selected row to an int observable (via the Table.Selected() Observable). While MultiSelect is on, Selected doubles as the anchor row, so the same edge tracks a range-anchor move.

func BindText

func BindText(e *toolkit.SearchEntry, obs *mvvm.Observable[string], invalidate func()) (unbind func())

BindText two-way-binds a SearchEntry's Text to a string observable (via the SearchEntry.Text() Observable).

func BindTextView added in v0.2.0

func BindTextView(tv *toolkit.TextView, obs *mvvm.Observable[string], invalidate func()) (unbind func())

BindTextView two-way-binds a TextView's text to a string observable through its Text() / SetText() accessors (it has no exported Text field) and its OnChange callback (which carries no value, so the view→VM edge reads Text() when it fires). This is the accessor-based binding pattern.

func BindTime added in v0.2.0

func BindTime(tp *toolkit.TimePicker, obs *mvvm.Observable[TimeOfDay], invalidate func()) (unbind func())

BindTime two-way-binds a TimePicker's [Hour, Minute] to a TimeOfDay observable (fields TimePicker.Hour / TimePicker.Minute, callback TimePicker.OnChange(hour, minute)). The pair round-trips atomically as one TimeOfDay.

func BindToggle added in v0.2.0

func BindToggle(t *toolkit.ToggleButton, obs *mvvm.Observable[bool], invalidate func()) (unbind func())

BindToggle two-way-binds a ToggleButton's Pressed to a bool observable (via the ToggleButton.Pressed() Observable).

func BindTree

func BindTree[T any](tt *toolkit.TreeTable, l *mvvm.ObservableList[T], project func(T) *toolkit.TreeTableNode, invalidate func()) (unbind func())

BindTree binds an ObservableList to a TreeTable's Root forest: on every list change it rebuilds Root (field TreeTable.Root, a []*TreeTableNode forest — not a flat []string, so mvvm.BindList can't drive it) by projecting each element to a node, then calls invalidate. project owns building each node's Cells and Children; this helper only wires the rebuild-on-change. The returned unbind detaches the list subscription.

func BindViewSwitcher

func BindViewSwitcher(v *toolkit.ViewSwitcher, obs *mvvm.Observable[int], invalidate func()) (unbind func())

BindViewSwitcher two-way-binds a ViewSwitcher's Current segment to an int observable (via the ViewSwitcher.Current() Observable).

func BindViews

func BindViews[T any](v *toolkit.ViewSwitcher, l *mvvm.ObservableList[T], project func(T) string, invalidate func()) (unbind func())

BindViews binds an ObservableList to a ViewSwitcher's Views slice (field ViewSwitcher.Views), projecting each element to its segment label.

Types

type Date added in v0.2.0

type Date struct {
	Year  int
	Month int // 1..12
	Day   int
}

Date is a plain calendar date, the value BindDate / BindDatePicker observe. It is comparable, so mvvm.NewObservable[Date] works and equal Sets are deduped.

type TimeOfDay added in v0.2.0

type TimeOfDay struct {
	Hour   int // 0..23
	Minute int // 0..59
}

TimeOfDay is a 24-hour wall-clock time, the value BindTime observes. It is comparable, so mvvm.NewObservable[TimeOfDay] works and equal Sets are deduped.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL