update actions - continue

This commit is contained in:
Vadim Lopatin 2015-01-31 08:03:58 +03:00
parent 055979b9e7
commit 9e0d20c814
3 changed files with 80 additions and 14 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;