Skip to content

Commit

Permalink
Action: Support Condition for enabled/visible management; Implement v…
Browse files Browse the repository at this point in the history
…isibility handling for actions in Menu and ToolBar; declarative: Change ContextMenuActions and friends to ContextMenuItems
  • Loading branch information
lxn committed Apr 30, 2013
1 parent 7df9a9a commit 4e5c8f8
Show file tree
Hide file tree
Showing 35 changed files with 821 additions and 628 deletions.
105 changes: 86 additions & 19 deletions action.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
package walk

type actionChangedHandler interface {
onActionChanged(action *Action) (err error)
onActionChanged(action *Action) error
onActionVisibleChanged(action *Action) error
}

var (
Expand All @@ -17,18 +18,22 @@ var (
)

type Action struct {
menu *Menu
triggeredPublisher EventPublisher
changedHandlers []actionChangedHandler
text string
toolTip string
image *Bitmap
enabled bool
visible bool
checkable bool
checked bool
exclusive bool
id uint16
menu *Menu
triggeredPublisher EventPublisher
changedHandlers []actionChangedHandler
text string
toolTip string
image *Bitmap
enabledCondition Condition
enabledConditionChangedHandle int
visibleCondition Condition
visibleConditionChangedHandle int
enabled bool
visible bool
checkable bool
checked bool
exclusive bool
id uint16
}

func NewAction() *Action {
Expand Down Expand Up @@ -84,10 +89,18 @@ func (a *Action) SetChecked(value bool) (err error) {
}

func (a *Action) Enabled() bool {
if a.enabledCondition != nil {
return a.enabledCondition.Satisfied()
}

return a.enabled
}

func (a *Action) SetEnabled(value bool) (err error) {
if a.enabledCondition != nil {
return newError("EnabledCondition != nil")
}

if value != a.enabled {
old := a.enabled

Expand All @@ -102,6 +115,24 @@ func (a *Action) SetEnabled(value bool) (err error) {
return
}

func (a *Action) EnabledCondition() Condition {
return a.enabledCondition
}

func (a *Action) SetEnabledCondition(c Condition) {
if a.enabledCondition != nil {
a.enabledCondition.Changed().Detach(a.enabledConditionChangedHandle)
}

a.enabledCondition = c

if c != nil {
a.enabledConditionChangedHandle = c.Changed().Attach(func() {
a.raiseChanged()
})
}
}

func (a *Action) Exclusive() bool {
return a.exclusive
}
Expand Down Expand Up @@ -179,24 +210,50 @@ func (a *Action) SetToolTip(value string) (err error) {
}

func (a *Action) Visible() bool {
if a.visibleCondition != nil {
return a.visibleCondition.Satisfied()
}

return a.visible
}

func (a *Action) SetVisible(value bool) (err error) {
if a.visibleCondition != nil {
return newError("VisibleCondition != nil")
}

if value != a.visible {
old := a.visible

a.visible = value

if err = a.raiseChanged(); err != nil {
if err = a.raiseVisibleChanged(); err != nil {
a.visible = old
a.raiseChanged()
a.raiseVisibleChanged()
}
}

return
}

func (a *Action) VisibleCondition() Condition {
return a.visibleCondition
}

func (a *Action) SetVisibleCondition(c Condition) {
if a.visibleCondition != nil {
a.visibleCondition.Changed().Detach(a.visibleConditionChangedHandle)
}

a.visibleCondition = c

if c != nil {
a.visibleConditionChangedHandle = c.Changed().Attach(func() {
a.raiseVisibleChanged()
})
}
}

func (a *Action) Triggered() *Event {
return a.triggeredPublisher.Event()
}
Expand All @@ -218,12 +275,22 @@ func (a *Action) removeChangedHandler(handler actionChangedHandler) {
}
}

func (a *Action) raiseChanged() (err error) {
func (a *Action) raiseChanged() error {
for _, handler := range a.changedHandlers {
if err = handler.onActionChanged(a); err != nil {
return
if err := handler.onActionChanged(a); err != nil {
return err
}
}

return
return nil
}

func (a *Action) raiseVisibleChanged() error {
for _, handler := range a.changedHandlers {
if err := handler.onActionVisibleChanged(a); err != nil {
return err
}
}

return nil
}
37 changes: 28 additions & 9 deletions actionlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
package walk

type actionListObserver interface {
onInsertingAction(index int, action *Action) error
onRemovingAction(index int, action *Action) error
onInsertedAction(action *Action) error
onRemovingAction(action *Action) error
onClearingActions() error
}

Expand Down Expand Up @@ -58,18 +58,35 @@ func (l *ActionList) Index(action *Action) int {
return -1
}

func (l *ActionList) Insert(index int, action *Action) error {
observer := l.observer
if observer != nil {
if err := observer.onInsertingAction(index, action); err != nil {
return err
func (l *ActionList) indexInObserver(action *Action) int {
var idx int

for _, a := range l.actions {
if a == action {
return idx
}
if a.Visible() {
idx++
}
}

return -1
}

func (l *ActionList) Insert(index int, action *Action) error {
l.actions = append(l.actions, nil)
copy(l.actions[index+1:], l.actions[index:])
l.actions[index] = action

observer := l.observer
if observer != nil {
if err := observer.onInsertedAction(action); err != nil {
l.actions = append(l.actions[:index], l.actions[index+1:]...)

return err
}
}

return nil
}

Expand Down Expand Up @@ -101,8 +118,10 @@ func (l *ActionList) RemoveAt(index int) error {
observer := l.observer
if observer != nil {
action := l.actions[index]
if err := observer.onRemovingAction(index, action); err != nil {
return err
if action.Visible() {
if err := observer.onRemovingAction(action); err != nil {
return err
}
}
}

Expand Down
52 changes: 43 additions & 9 deletions declarative/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package declarative

import (
"errors"
"fmt"
)

import (
Expand All @@ -16,10 +17,12 @@ type Action struct {
AssignTo **walk.Action
Text string
Image interface{}
Enabled Property
Visible Property
OnTriggered walk.EventHandler
}

func (a Action) createAction(menu *walk.Menu) (*walk.Action, error) {
func (a Action) createAction(builder *Builder, menu *walk.Menu) (*walk.Action, error) {
action := walk.NewAction()

if err := action.SetText(a.Text); err != nil {
Expand All @@ -29,6 +32,33 @@ func (a Action) createAction(menu *walk.Menu) (*walk.Action, error) {
return nil, err
}

if a.Enabled != nil {
if b, ok := a.Enabled.(bool); ok {
if err := action.SetEnabled(b); err != nil {
return nil, err
}
} else if s := builder.conditionOrProperty(a.Enabled); s != nil {
if c, ok := s.(walk.Condition); ok {
action.SetEnabledCondition(c)
} else {
return nil, fmt.Errorf("value of invalid type bound to Action.Enabled: %T", s)
}
}
}
if a.Visible != nil {
if b, ok := a.Visible.(bool); ok {
if err := action.SetVisible(b); err != nil {
return nil, err
}
} else if s := builder.conditionOrProperty(a.Visible); s != nil {
if c, ok := s.(walk.Condition); ok {
action.SetVisibleCondition(c)
} else {
return nil, fmt.Errorf("value of invalid type bound to Action.Visible: %T", s)
}
}
}

if a.OnTriggered != nil {
action.Triggered().Attach(a.OnTriggered)
}
Expand All @@ -47,17 +77,17 @@ func (a Action) createAction(menu *walk.Menu) (*walk.Action, error) {
}

type ActionRef struct {
Action *walk.Action
Action **walk.Action
}

func (ar ActionRef) createAction(menu *walk.Menu) (*walk.Action, error) {
func (ar ActionRef) createAction(builder *Builder, menu *walk.Menu) (*walk.Action, error) {
if menu != nil {
if err := menu.Actions().Add(ar.Action); err != nil {
if err := menu.Actions().Add(*ar.Action); err != nil {
return nil, err
}
}

return ar.Action, nil
return *ar.Action, nil
}

type Menu struct {
Expand All @@ -68,7 +98,7 @@ type Menu struct {
Items []MenuItem
}

func (m Menu) createAction(menu *walk.Menu) (*walk.Action, error) {
func (m Menu) createAction(builder *Builder, menu *walk.Menu) (*walk.Action, error) {
if menu == nil {
var err error
if menu, err = walk.NewMenu(); err != nil {
Expand All @@ -94,7 +124,7 @@ func (m Menu) createAction(menu *walk.Menu) (*walk.Action, error) {
}

for _, item := range m.Items {
if _, err := item.createAction(subMenu); err != nil {
if _, err := item.createAction(builder, subMenu); err != nil {
return nil, err
}
}
Expand All @@ -112,7 +142,7 @@ func (m Menu) createAction(menu *walk.Menu) (*walk.Action, error) {
type Separator struct {
}

func (s Separator) createAction(menu *walk.Menu) (*walk.Action, error) {
func (s Separator) createAction(builder *Builder, menu *walk.Menu) (*walk.Action, error) {
action := walk.NewAction()

if err := action.SetText("-"); err != nil {
Expand Down Expand Up @@ -161,10 +191,14 @@ func setActionImage(action *walk.Action, image interface{}) (err error) {
}

func CreateActions(items ...MenuItem) ([]*walk.Action, error) {
return createActions(NewBuilder(nil), items...)
}

func createActions(builder *Builder, items ...MenuItem) ([]*walk.Action, error) {
var actions []*walk.Action

for _, item := range items {
action, err := item.createAction(nil)
action, err := item.createAction(builder, nil)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 4e5c8f8

Please sign in to comment.