172 lines
3.2 KiB
Go
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
|
||
|
}
|