//go:build cgo package desktop import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/widget" "github.com/kamelion/ratatoskr-go/internal/storage" "github.com/kamelion/ratatoskr-go/internal/ui" ) // TaskListPanel — Fyne-реализация ui.TaskListPanel (спец 12.8, 12.10): список // задач (левая панель окна). // // Внутри — widget.List над собственным буфером []storage.Task (снимки из Store). // Состояние выбора живёт в окне: окно зовёт Select, чтобы подсветить строку. type TaskListPanel struct { list *widget.List tasks []storage.Task } // NewTaskListPanel создаёт TaskListPanel. func NewTaskListPanel() *TaskListPanel { p := &TaskListPanel{} p.list = widget.NewList( func() int { return len(p.tasks) }, func() fyne.CanvasObject { return widget.NewLabel("loading…") }, func(id widget.ListItemID, o fyne.CanvasObject) { if id < 0 || id >= len(p.tasks) { return } o.(*widget.Label).SetText(ui.TaskTitle(p.tasks[id])) }, ) return p } // Widget возвращает виджет списка для встраивания в окно (левая панель). func (p *TaskListPanel) Widget() fyne.CanvasObject { return p.list } // SetTasks заменяет снимок списка и перерисовывает виджет (спец 12.10). func (p *TaskListPanel) SetTasks(tasks []storage.Task) { p.tasks = tasks p.list.Refresh() } // Select подсвечивает строку задачи id; если её нет — снимает выделение. func (p *TaskListPanel) Select(id int64) { idx := -1 for i, t := range p.tasks { if t.ID == id { idx = i break } } if idx < 0 { p.list.UnselectAll() return } p.list.Select(widget.ListItemID(idx)) } // OnSelect регистрирует колбэк клика по строке (спец 12.10). func (p *TaskListPanel) OnSelect(fn func(id int64)) { p.list.OnSelected = func(id widget.ListItemID) { if fn != nil && id >= 0 && id < len(p.tasks) { fn(p.tasks[id].ID) } } } // compile-time проверка реализации контракта. var _ ui.TaskListPanel = (*TaskListPanel)(nil)