diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index 33be614f..5b1603fc 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -164,8 +164,10 @@ class Action { _id = a._id; _label = a._label; _iconId = a._iconId; - _state = a._state.clone(); - _defaultState = a._defaultState.clone(); + if (a._state) + _state = a._state.clone(); + if (a._defaultState) + _defaultState = a._defaultState.clone(); _accelerators.length = a._accelerators.length; for(int i = 0; i < _accelerators.length; i++) _accelerators[i] = a._accelerators[i]; diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 04bee0a4..09b2d1a2 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -818,6 +818,14 @@ class Window { return res || processed || _mainWidget.needDraw; } + /// calls update actions recursively + protected void dispatchWidgetUpdateActionStateRecursive(Widget root) { + if (root is null) + return; + root.updateActionState(true); + for (int i = 0; i < root.childCount; i++) + dispatchWidgetUpdateActionStateRecursive(root.child(i)); + } /// checks content widgets for necessary redraw and/or layout protected void checkUpdateNeeded(Widget root, ref bool needDraw, ref bool needLayout, ref bool animationActive) { if (root is null) @@ -842,6 +850,14 @@ class Window { } /// checks content widgets for necessary redraw and/or layout bool checkUpdateNeeded(ref bool needDraw, ref bool needLayout, ref bool animationActive) { + if (_actionsUpdateRequested) { + // call update action check - as requested + if (_mainWidget !is null) + dispatchWidgetUpdateActionStateRecursive(_mainWidget); + foreach(p; _popups) + dispatchWidgetUpdateActionStateRecursive(p); + _actionsUpdateRequested = false; + } needDraw = needLayout = animationActive = false; if (_mainWidget is null) return false; diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index 005a8891..76fe7cf8 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -626,23 +626,48 @@ class Widget { @property void action(const Action action) { _action = action.clone; } /// action to emit on click @property void action(Action action) { _action = action; } - /// ask for update state of some action (unles force=true, checks window flag - void updateActionState(Action a, bool force = false) { + /// ask for update state of some action (unles force=true, checks window flag actionsUpdateRequested), returns true if action state is changed + bool updateActionState(Action a, bool force = false) { if (Window w = window) { if (!force && !w.actionsUpdateRequested()) - return; + return false; + const ActionState oldState = a.state; if (w.dispatchActionStateRequest(a, this)) { // state is updated } else { a.state = a.defaultState; } + if (a.state != oldState) + return true; } + return false; } /// call to update state for action (if action is assigned for widget) void updateActionState(bool force = false) { if (!_action) return; - updateActionState(_action, force); + if (updateActionState(_action, force)) + handleActionStateChanged(); + } + /// called when state of action assigned on widget is changed + void handleActionStateChanged() { + // override to update enabled state, visibility and checked state + // default processing: copy flags to this widget + updateStateFromAction(_action); + } + /// apply enabled, visibile and checked state for this widget from action's state + void updateStateFromAction(Action a) { + const ActionState s = a.state; + if (s.enabled != enabled) { + enabled = s.enabled; + } + if (s.checked != checked) { + checked = s.checked; + } + bool v = _visibility == Visibility.Visible; + if (s.visible != v) { + visibility = s.visible ? Visibility.Visible : Visibility.Gone; + } } protected bool _focusGroup;