From 9e0d20c8140965df71bf7e8173ca6534e814530b Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Sat, 31 Jan 2015 08:03:58 +0300 Subject: [PATCH] update actions - continue --- src/dlangui/platforms/common/platform.d | 5 ++- src/dlangui/widgets/editors.d | 49 +++++++++++++++++++------ src/dlangui/widgets/menu.d | 40 ++++++++++++++++++++ 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 92be8941..3ce90e37 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -233,8 +233,9 @@ class Window { res.anchor.x = x; res.anchor.y = y; _popups ~= res; - if (_mainWidget !is null) + if (_mainWidget !is null) { _mainWidget.requestLayout(); + } return res; } /// remove popup @@ -403,7 +404,7 @@ class Window { } _focusedWidget = newFocus; // after focus change, ask for actions update automatically - requestActionsUpdate(); + //requestActionsUpdate(); } return _focusedWidget; } diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index 9383b6f3..26bcbd95 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -387,14 +387,15 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction override bool isActionEnabled(const Action action) { switch (action.id) { case EditorActions.Copy: - case EditorActions.Cut: return !_selectionRange.empty; + case EditorActions.Cut: + return enabled && !_selectionRange.empty; case EditorActions.Paste: - return Platform.instance.getClipboardText().length > 0; + return enabled && Platform.instance.getClipboardText().length > 0; case EditorActions.Undo: - return _content.hasUndo; + return enabled && _content.hasUndo; case EditorActions.Redo: - return _content.hasRedo; + return enabled && _content.hasRedo; default: return super.isActionEnabled(action); } @@ -406,14 +407,15 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction if (_popupMenu.onBeforeOpeningSubmenu.assigned) if (!_popupMenu.onBeforeOpeningSubmenu(_popupMenu)) return; - for (int i = 0; i < _popupMenu.subitemCount; i++) { - MenuItem item = _popupMenu.subitem(i); - if (item.action && isActionEnabled(item.action)) { - item.enabled = true; - } else { - item.enabled = false; - } - } + _popupMenu.updateActionState(this); + //for (int i = 0; i < _popupMenu.subitemCount; i++) { + // MenuItem item = _popupMenu.subitem(i); + // if (item.action && isActionEnabled(item.action)) { + // item.enabled = true; + // } else { + // item.enabled = false; + // } + //} PopupMenu popupMenu = new PopupMenu(_popupMenu); popupMenu.onMenuItemActionListener = this; PopupWidget popup = window.showPopup(popupMenu, this, PopupAlign.Point | PopupAlign.Right, x, y); @@ -560,6 +562,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction ensureCaretVisible(); correctCaretPos(); requestLayout(); + requestActionsUpdate(); } else if (operation.action == EditAction.SaveContent) { // saved } else { @@ -570,6 +573,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction updateMaxLineWidth(); measureVisibleText(); ensureCaretVisible(); + requestActionsUpdate(); } } else { correctCaretPos(); @@ -580,6 +584,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction if (_lastReportedModifiedState != content.modified) { _lastReportedModifiedState = content.modified; onModifiedStateChangeListener(this, content.modified); + requestActionsUpdate(); } } return; @@ -765,6 +770,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction _selectionRange.end = _caretPos; } invalidate(); + requestActionsUpdate(); } protected void updateCaretPositionByMouse(int x, int y, bool selecting) { @@ -815,6 +821,24 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction return true; } + /// override to handle specific actions state (e.g. change enabled state for supported actions) + override bool handleActionStateRequest(const Action a) { + switch (a.id) { + case EditorActions.Copy: + case EditorActions.Cut: + case EditorActions.Paste: + case EditorActions.Undo: + case EditorActions.Redo: + if (isActionEnabled(a)) + a.state = ACTION_STATE_ENABLED; + else + a.state = ACTION_STATE_DISABLE; + return true; + default: + return super.handleActionStateRequest(a); + } + } + override protected bool handleAction(const Action a) { TextPosition oldCaretPos = _caretPos; dstring currentLine = _content[_caretPos.line]; @@ -1084,6 +1108,7 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction _selectionRange.end = _content.lineEnd(_content.length - 1); _caretPos = _selectionRange.end; ensureCaretVisible(); + requestActionsUpdate(); return true; default: break; diff --git a/src/dlangui/widgets/menu.d b/src/dlangui/widgets/menu.d index 2ef845c2..92eb76e7 100644 --- a/src/dlangui/widgets/menu.d +++ b/src/dlangui/widgets/menu.d @@ -229,6 +229,18 @@ class MenuItem { /// prepare for opening of submenu, return true if opening is allowed Signal!(bool, MenuItem) onBeforeOpeningSubmenu; + /// call to update state for action (if action is assigned for widget) + void updateActionState(Widget w) { + if (_action) { + w.updateActionState(_action, true); + _enabled = _action.state.enabled; + _checked = _action.state.checked; + } + for (int i = 0; i < _subitems.length; i++) { + _subitems[i].updateActionState(w); + } + } + this() { _enabled = true; } @@ -338,6 +350,16 @@ class MenuItemWidget : WidgetGroupDefaultDrawing { resetState(State.Checked); } + ///// call to update state for action (if action is assigned for widget) + //override void updateActionState(bool force = false) { + // if (!_item.action) + // return; + // super.updateActionState(_item._action, force); + // _item.enabled = _item._action.state.enabled; + // _item.checked = _item._action.state.checked; + // updateState(); + //} + this(MenuItem item, bool mainMenu) { id="menuitem"; _mainMenu = mainMenu; @@ -421,6 +443,15 @@ class MenuWidgetBase : ListWidget { return _orientation == Orientation.Horizontal; } + /// call to update state for action (if action is assigned for widget) + override void updateActionState(bool force = false) { + for (int i = 0; i < itemCount; i++) { + MenuItemWidget w = cast(MenuItemWidget)itemWidget(i); + if (w) + w.updateActionState(force); + } + } + /// Measure widget according to desired width and height constraints. (Step 1 of two phase layout). override void measure(int parentWidth, int parentHeight) { if (_orientation == Orientation.Horizontal) { @@ -495,8 +526,10 @@ class MenuWidgetBase : ListWidget { _openedPopup = null; } } + PopupMenu popupMenu = new PopupMenu(itemWidget.item, this); PopupWidget popup = window.showPopup(popupMenu, itemWidget, orientation == Orientation.Horizontal ? PopupAlign.Below : PopupAlign.Right); + requestActionsUpdate(); popup.onPopupCloseListener = &onPopupClosed; popup.flags = PopupFlags.CloseOnClickOutside; _openedPopup = popup; @@ -722,6 +755,13 @@ class MainMenu : MenuWidgetBase { selectOnHover = false; } + /// call to update state for action (if action is assigned for widget) + override void updateActionState(bool force) { + Log.d("MainMenu: updateActionState"); + _item.updateActionState(this); + + } + /// override and return true to track key events even when not focused @property override bool wantsKeyTracking() { return true;