Added real keyboard shortcut support for menu items
This commit is contained in:
parent
66fcfce8af
commit
2cf388e674
6 changed files with 77 additions and 35 deletions
|
@ -16,10 +16,35 @@ var Element = {
|
|||
var obj = {
|
||||
parents: [Element, PropertyElement, ghost],
|
||||
_node: props.wrapNode(ghost._node_ghost),
|
||||
_bindings: [],
|
||||
};
|
||||
return obj;
|
||||
},
|
||||
|
||||
bindShortcut: func(s, f) {
|
||||
if (!isa(s, keyboard.Shortcut)) {
|
||||
s = keyboard.Shortcut.new(s);
|
||||
}
|
||||
foreach (var b; me._bindings) {
|
||||
if (b.shortcut.equals(s)) {
|
||||
b.f = f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
append(me._bindings, keyboard.Binding.new(s, f));
|
||||
if (size(me._bindings) == 1) {
|
||||
obj.addEventListener("keydown", func(e) obj.onKeyPressed(e));
|
||||
}
|
||||
},
|
||||
|
||||
onKeyPressed: func(e) {
|
||||
foreach (var b; me._bindings) {
|
||||
if (b.shortcut.match(keyboard.findKeyName(e.keyCode), e.shiftKey, e.ctrlKey, e.altKey, e.metaKey)) {
|
||||
b.fire(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getType: func () {
|
||||
return me._node.getName();
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
gui.MenuItem = {
|
||||
# @description Create a new menu item widget
|
||||
# @cfg_field text: str Text of the new menu item
|
||||
# @cfg_field shortcut: str String representation of the keyboard shortcut for the item
|
||||
# @cfg_field shortcut: str String representation of the keyboard shortcut for the item
|
||||
# @cfg_field cb: callable Function / method to call when the item is clicked
|
||||
# @cfg_field icon: str Path of an icon to be displayed (relative to the path in `canvas.style._dir_widgets`)
|
||||
# @cfg_field enabled: bool Initial state of the menu item: enabled (1) or disabled (0)
|
||||
|
@ -24,7 +24,7 @@ gui.MenuItem = {
|
|||
var cfg = Config.new(cfg);
|
||||
var m = gui.Widget.new(gui.MenuItem);
|
||||
m._text = cfg.get("text", "Menu item");
|
||||
m._shortcut = cfg.get("shortcut", "");
|
||||
m._shortcut = cfg.get("shortcut", nil);
|
||||
m._cb = cfg.get("cb", nil);
|
||||
m._icon = cfg.get("icon", nil);
|
||||
m._enabled = cfg.get("enabled", 1);
|
||||
|
@ -38,9 +38,9 @@ gui.MenuItem = {
|
|||
m.setLayoutSizeHint([64, 24]);
|
||||
m.setLayoutMaximumSize([1024, 24]);
|
||||
|
||||
m._view.setText(m, m._text);
|
||||
m._view.setIcon(m._icon);
|
||||
m._view.setShortcut(m, m._shortcut);
|
||||
m.setText(m._text);
|
||||
m.setIcon(m._icon);
|
||||
m.setShortcut(m._shortcut);
|
||||
return m;
|
||||
},
|
||||
|
||||
|
@ -110,11 +110,21 @@ gui.MenuItem = {
|
|||
},
|
||||
|
||||
setShortcut: func(shortcut) {
|
||||
me._shortcut = shortcut;
|
||||
me._view.setShortcut(me, shortcut);
|
||||
me._shortcut = keyboard.Shortcut.new(shortcut);
|
||||
if (me._parent_menu != nil and me._parent_menu._canvas_item != nil and me._cb != nil) {
|
||||
me._parent_menu._canvas_item.bindShortcut(me._shortcut, me._cb);
|
||||
}
|
||||
me._view.setShortcut(me, me._shortcut);
|
||||
return me.update();
|
||||
},
|
||||
|
||||
_setParentMenu: func(m) {
|
||||
me._parent_menu = m;
|
||||
if (me._parent_menu != nil and me._parent_menu._canvas_item != nil and me._cb != nil) {
|
||||
me._parent_menu._canvas_item.bindShortcut(me._shortcut, me._cb);
|
||||
}
|
||||
},
|
||||
|
||||
setIcon: func(icon) {
|
||||
me._icon = icon;
|
||||
me._view.setIcon(icon);
|
||||
|
@ -153,16 +163,24 @@ gui.Menu = {
|
|||
m._root = m._canvas.createGroup();
|
||||
m._layout = VBoxLayout.new();
|
||||
m._layout.setSpacing(0);
|
||||
m._canvas_item = nil;
|
||||
m.setLayout(m._layout);
|
||||
m.hide();
|
||||
|
||||
return m;
|
||||
},
|
||||
|
||||
setCanvasItem: func(item) {
|
||||
me._canvas_item = item;
|
||||
for (var i = 0; i < me._layout.count(); i += 1) {
|
||||
me._layout.itemAt(i)._setParentMenu(me);
|
||||
}
|
||||
},
|
||||
|
||||
# @description Add the given menu item to the menu (normally a `canvas.gui.MenuItem`, but can be any `canvas.gui.Widget` in theory)
|
||||
# @return canvas.gui.Menu Return me to enable method chaining
|
||||
addItem: func(item) {
|
||||
item._parent_menu = me;
|
||||
item._setParentMenu(me);
|
||||
me._layout.addItem(item);
|
||||
me.setSize(me._layout.minimumSize()[0], me._layout.minimumSize()[1]);
|
||||
return me;
|
||||
|
@ -175,7 +193,7 @@ gui.Menu = {
|
|||
# @param icon: str optional Path to the icon (relative to canvas.style._dir_widgets) or nil if none should be displayed
|
||||
# @param enabled: bool optional Whether the item should be enabled (1) or disabled (0)
|
||||
# @return canvas.gui.MenuItem The item that was created
|
||||
createItem: func(text = nil, cb = nil, shortcut = "", icon = nil, enabled = 1) {
|
||||
createItem: func(text = nil, cb = nil, shortcut = nil, icon = nil, enabled = 1) {
|
||||
if (text == nil) {
|
||||
die("cannot create a menu item without text");
|
||||
}
|
||||
|
@ -198,7 +216,7 @@ gui.Menu = {
|
|||
if (menu == nil) {
|
||||
die("cannot create a submenu item without submenu");
|
||||
}
|
||||
var item = gui.MenuItem.new(me._root, me.style, {text: text, cb: nil, shortcut: "", icon: icon, enabled: enabled});
|
||||
var item = gui.MenuItem.new(me._root, me.style, {text: text, cb: nil, shortcut: nil, icon: icon, enabled: enabled});
|
||||
item.setMenu(menu);
|
||||
me.addItem(item);
|
||||
return item;
|
||||
|
|
|
@ -141,6 +141,9 @@ gui.Widget = {
|
|||
{
|
||||
me._view._root.setVisible(visible);
|
||||
},
|
||||
bindShortcut: func(s, f) {
|
||||
me._view._root.bindShortcut(s, f);
|
||||
},
|
||||
_setView: func(view)
|
||||
{
|
||||
me._view = view;
|
||||
|
@ -170,6 +173,11 @@ gui.Widget = {
|
|||
me._trigger("mouse-leave");
|
||||
me._onStateChange();
|
||||
});
|
||||
root.addEventListener("keypress", func(e) {
|
||||
if (me._focused) {
|
||||
root.onKeyPressed(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
_trigger: func(type, data = nil)
|
||||
{
|
||||
|
|
|
@ -900,7 +900,7 @@ DefaultStyle.widgets["menu-item"] = {
|
|||
},
|
||||
|
||||
setShortcut: func(model, shortcut) {
|
||||
me._shortcut.setText(shortcut);
|
||||
me._shortcut.setText(shortcut.repr());
|
||||
return me._updateLayoutSizes(model);
|
||||
},
|
||||
|
||||
|
|
|
@ -16,11 +16,12 @@ gui.widgets.LineEdit = {
|
|||
m._selection_end = 0;
|
||||
|
||||
m.context_menu = gui.Menu.new();
|
||||
m.context_menu.createItem(text: "Copy", cb: func() { m.copy(); }, shortcut: "Ctrl+C");
|
||||
m.context_menu.createItem(text: "Cut", cb: func() { m.cut(); }, shortcut: "Ctrl+X");
|
||||
m.context_menu.createItem(text: "Paste", cb: func() { m.paste(); }, shortcut: "Ctrl+V");
|
||||
m.context_menu.createItem(text: "Clear", cb: func() { m.clear(); }, shortcut: "Ctrl+D");
|
||||
m.context_menu.createItem(text: "Select all", cb: func() { m.selectAll(); }, shortcut: "Ctrl+A");
|
||||
m.context_menu.createItem(text: "Copy", cb: func() { m.copy(); }, shortcut: "<Ctrl>+C");
|
||||
m.context_menu.createItem(text: "Cut", cb: func() { m.cut(); }, shortcut: "<Ctrl>+X");
|
||||
m.context_menu.createItem(text: "Paste", cb: func() { m.paste(); }, shortcut: "<Ctrl>+V");
|
||||
m.context_menu.createItem(text: "Clear", cb: func() { m.clear(); }, shortcut: "<Ctrl>+D");
|
||||
m.context_menu.createItem(text: "Select all", cb: func() { m.selectAll(); }, shortcut: "<Ctrl>+A");
|
||||
m.context_menu.setCanvasItem(m);
|
||||
|
||||
return m;
|
||||
},
|
||||
|
@ -182,7 +183,11 @@ gui.widgets.LineEdit = {
|
|||
call(gui.Widget._setView, [view], me);
|
||||
|
||||
var el = view._root;
|
||||
el.addEventListener("keypress", func (e) me.insert(e.key));
|
||||
el.addEventListener("keypress", func (e) {
|
||||
if (!e.ctrlKey and !e.altKey and !e.metaKey) {
|
||||
me.insert(e.key);
|
||||
}
|
||||
});
|
||||
el.addEventListener("keydown", func (e)
|
||||
{
|
||||
if( me._view == nil )
|
||||
|
@ -202,19 +207,6 @@ gui.widgets.LineEdit = {
|
|||
me.home();
|
||||
else if( e.key == "End" )
|
||||
me.end();
|
||||
else if (e.ctrlKey) {
|
||||
if (e.keyCode == `c`) {
|
||||
me.copy();
|
||||
} elsif (e.keyCode == `v`) {
|
||||
me.paste();
|
||||
} elsif (e.keyCode == `x`) {
|
||||
me.cut();
|
||||
} elsif (e.keyCode == `d`) {
|
||||
me.clear();
|
||||
} elsif (e.keyCode == `a`) {
|
||||
me.selectAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
el.addEventListener("click", func(e) {
|
||||
if (e.button == 2) {
|
||||
|
|
|
@ -357,10 +357,10 @@ var Shortcut = {
|
|||
return 0;
|
||||
}
|
||||
var match = 1;
|
||||
match &= veccontains(me.modifiers, ModifierKeys["Shift"]) == shift;
|
||||
match &= veccontains(me.modifiers, ModifierKeys["Ctrl"]) == ctrl;
|
||||
match &= veccontains(me.modifiers, ModifierKeys["Alt"]) == alt;
|
||||
match &= veccontains(me.modifiers, ModifierKeys["Meta"]) == meta;
|
||||
match &= contains(me.modifiers, ModifierKeys["Shift"]) == shift;
|
||||
match &= contains(me.modifiers, ModifierKeys["Ctrl"]) == ctrl;
|
||||
match &= contains(me.modifiers, ModifierKeys["Alt"]) == alt;
|
||||
match &= contains(me.modifiers, ModifierKeys["Meta"]) == meta;
|
||||
match &= size(keys) == size(me.keys);
|
||||
if (!match) {
|
||||
return 0;
|
||||
|
@ -376,7 +376,6 @@ var Shortcut = {
|
|||
return "";
|
||||
}
|
||||
var names = [];
|
||||
debug.dump(me.modifiers);
|
||||
foreach (var mod; me.modifiers) {
|
||||
append(names, findKeyName(mod));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue