erm/vendor/github.com/lxn/walk/widgetlist.go
2021-07-30 23:29:20 +01:00

172 lines
3.2 KiB
Go

// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package walk
import (
"github.com/lxn/win"
)
type widgetListObserver interface {
onInsertingWidget(index int, widget Widget) error
onInsertedWidget(index int, widget Widget) error
onRemovingWidget(index int, widget Widget) error
onRemovedWidget(index int, widget Widget) error
onClearingWidgets() error
onClearedWidgets() error
}
type WidgetList struct {
items []*WidgetBase
observer widgetListObserver
widgetInRemoval *WidgetBase
}
func newWidgetList(observer widgetListObserver) *WidgetList {
return &WidgetList{observer: observer}
}
func (l *WidgetList) Add(item Widget) error {
return l.Insert(len(l.items), item)
}
func (l *WidgetList) At(index int) Widget {
return l.items[index].window.(Widget)
}
func (l *WidgetList) Clear() error {
observer := l.observer
if observer != nil {
if err := observer.onClearingWidgets(); err != nil {
return err
}
}
oldItems := l.items
l.items = l.items[:0]
if observer != nil {
if err := observer.onClearedWidgets(); err != nil {
l.items = oldItems
return err
}
}
for _, item := range oldItems {
item.form = nil
}
return nil
}
func (l *WidgetList) Index(item Widget) int {
wb := item.AsWidgetBase()
for i, widget := range l.items {
if widget == wb {
return i
}
}
return -1
}
func (l *WidgetList) Contains(item Widget) bool {
return l.Index(item) > -1
}
func (l *WidgetList) indexHandle(handle win.HWND) int {
for i, widget := range l.items {
if widget.Handle() == handle {
return i
}
}
return -1
}
func (l *WidgetList) containsHandle(handle win.HWND) bool {
return l.indexHandle(handle) > -1
}
func (l *WidgetList) insertIntoSlice(index int, item Widget) {
l.items = append(l.items, nil)
copy(l.items[index+1:], l.items[index:])
l.items[index] = item.AsWidgetBase()
}
func (l *WidgetList) Insert(index int, item Widget) error {
if l.Contains(item) {
return newError("cannot insert same widget multiple times")
}
observer := l.observer
if observer != nil {
if err := observer.onInsertingWidget(index, item); err != nil {
return err
}
}
l.insertIntoSlice(index, item)
if observer != nil {
if err := observer.onInsertedWidget(index, item); err != nil {
l.items = append(l.items[:index], l.items[index+1:]...)
return err
}
}
return nil
}
func (l *WidgetList) Len() int {
return len(l.items)
}
func (l *WidgetList) Remove(item Widget) error {
index := l.Index(item)
if index == -1 {
return nil
}
return l.RemoveAt(index)
}
func (l *WidgetList) RemoveAt(index int) error {
item := l.items[index]
if item == l.widgetInRemoval {
return nil
}
observer := l.observer
widget := item.window.(Widget)
if observer != nil {
l.widgetInRemoval = item
defer func() {
l.widgetInRemoval = nil
}()
if err := observer.onRemovingWidget(index, widget); err != nil {
return err
}
}
l.items = append(l.items[:index], l.items[index+1:]...)
if observer != nil {
if err := observer.onRemovedWidget(index, widget); err != nil {
l.insertIntoSlice(index, widget)
return err
}
}
item.form = nil
return nil
}