*
*/
public class KeyboardShortcut extends com.itmill.toolkit.Application implements
- Handler {
+Handler {
private Window main;
private Button a;
private AbstractField f;
+ Action[] actions = new Action[] {
+ new ShortcutAction("Button a action",
+ ShortcutAction.KeyCode.A, new int[] {
+ ShortcutAction.ModifierKey.CTRL,
+ ShortcutAction.ModifierKey.SHIFT }),
+ new ShortcutAction("Button z action",
+ ShortcutAction.KeyCode.Z, new int[] {
+ ShortcutAction.ModifierKey.CTRL,
+ ShortcutAction.ModifierKey.SHIFT }),
+ new ShortcutAction("Button x action",
+ ShortcutAction.KeyCode.X, new int[] {
+ ShortcutAction.ModifierKey.CTRL,
+ ShortcutAction.ModifierKey.SHIFT }),
+ new ShortcutAction("Restart ",
+ ShortcutAction.KeyCode.ESCAPE, null)
+ };
+
public void init() {
main = new Window("Keyboard shortcuts demo");
setTheme("corporate");
main
- .addComponent(new Label(
- "<h3>Test application for shortcut actions</h3>"
- + "<p><b>Notes:</b><br />"
- + "<b>This feature is under development and it's API may still change.</b><br />"
- + "<b>If events do not work, <b>set focus to Textfield first.</b><br />"
- + "<b>Browsers may have reserved the keyboard combinations used in "
- + "this demo for other purposes.</b><br /></p>",
- Label.CONTENT_RAW));
+ .addComponent(new Label(
+ "<h3>Test application for shortcut actions</h3>"
+ + "<p><b>Notes:</b><br />"
+ + "<b>This feature is under development and it's API may still change.</b><br />"
+ + "<b>If events do not work, <b>set focus to Textfield first.</b><br />"
+ + "<b>Browsers may have reserved the keyboard combinations used in "
+ + "this demo for other purposes.</b><br /></p>",
+ Label.CONTENT_XHTML));
main
- .addComponent(new Label(
- "ESC restarts program, ctrl-shift-a clicks A button, "
- + "ctrl-shift-z clicks Z button, ctrl-shift-x clicks X button"));
+ .addComponent(new Label(
+ "ESC restarts program, ctrl-shift-a clicks A button, "
+ + "ctrl-shift-z clicks Z button, ctrl-shift-x clicks X button"));
// Restart button
close = new Button("restart", this, "close");
- close.addActionHandler(this);
+
main.addComponent(close);
a = new Button("Button A", this, "buttonAHandler");
- a.addActionHandler(this);
z = new Button("Button Z", this, "buttonZHandler");
- z.addActionHandler(this);
x = new Button("Button X", this, "buttonXHandler");
- x.addActionHandler(this);
f = new TextField("Textfield");
main.addComponent(x);
main.addComponent(f);
+ main.addActionHandler(this);
+
f.focus();
}
public Action[] getActions(Object target, Object sender) {
- Action[] actions = new Action[1];
- if (sender == a) {
- actions[0] = (Action) new ShortcutAction("Button a action",
- ShortcutAction.KeyCode.A, new int[] {
- ShortcutAction.ModifierKey.CTRL,
- ShortcutAction.ModifierKey.SHIFT });
- } else if (sender == z) {
- actions[0] = (Action) (new ShortcutAction("Button z action",
- ShortcutAction.KeyCode.Z, new int[] {
- ShortcutAction.ModifierKey.CTRL,
- ShortcutAction.ModifierKey.SHIFT }));
-
- } else if (sender == x) {
- actions[0] = (Action) new ShortcutAction("Button x action",
- ShortcutAction.KeyCode.X, new int[] {
- ShortcutAction.ModifierKey.CTRL,
- ShortcutAction.ModifierKey.SHIFT });
- } else {
- // restart button
- actions[0] = new ShortcutAction("Restart ",
- ShortcutAction.KeyCode.ESCAPE, null);
- }
return actions;
}
public void handleAction(Action action, Object sender, Object target) {
- if (target == a)
+ if (action == actions[0])
this.buttonAHandler();
- if (target == z)
+ if (action == actions[1])
this.buttonZHandler();
- if (target == x)
+ if (action == actions[2])
this.buttonXHandler();
- if (target == close)
+ if (action == actions[3])
this.close();
}
return s;
}
+ public int[] getIntArrayAttribute(String name) {
+ JSONArray a = (JSONArray) ((JSONObject) json.get(1)).get(name);
+ int[] s = new int[a.size()];
+ for (int i = 0; i < a.size(); i++)
+ s[i] = Integer.parseInt(((JSONString) a.get(i)).stringValue());
+ return s;
+ }
+
public HashSet getStringArrayAttributeAsSet(String string) {
JSONArray a = getArrayVariable(string);
HashSet s = new HashSet();
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+public class IShortcutAction {
+
+ private ShortcutKeyCombination sc;
+ private String caption;
+ private String key;
+
+ public IShortcutAction(String key, ShortcutKeyCombination sc, String caption) {
+ this.sc = sc;
+ this.key = key;
+ this.caption = caption;
+ }
+
+ public ShortcutKeyCombination getShortcutCombination() {
+ return sc;
+ }
+
+ public String getCaption() {
+ return caption;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+}
package com.itmill.toolkit.terminal.gwt.client.ui;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
private HashSet subWindows = new HashSet();
+ private ArrayList actions = new ArrayList();
+ private ApplicationConnection client;
+
+ private String id;
+
+ public IView() {
+ super();
+ sinkEvents(Event.KEYEVENTS);
+ }
public String getTheme() {
return theme;
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ this.client = client;
+
+ this.id = uidl.getId();
// Start drawing from scratch
clear();
subWindows.add(w);
}
((Paintable)w).updateFromUIDL(childUidl, client);
+ } else if ("actions".equals(childUidl.getTag())) {
+ updateActionMap(childUidl);
}
}
}
}
+ private void updateActionMap(UIDL c) {
+ actions.clear();
+ Iterator it = c.getChildIterator();
+ while(it.hasNext()) {
+ UIDL action = (UIDL) it.next();
+
+ int[] modifiers = null;
+ if(action.hasAttribute("mk"))
+ modifiers = action.getIntArrayAttribute("mk");
+
+ ShortcutKeyCombination kc = new ShortcutKeyCombination(
+ action.getIntAttribute("kc"),
+ modifiers);
+ String key = action.getStringAttribute("key");
+ String caption = action.getStringAttribute("caption");
+ actions.add(new IShortcutAction(key,kc, caption));
+ }
+ }
+
+ public void onBrowserEvent(Event event) {
+ if(DOM.eventGetType(event) == Event.ONKEYDOWN) {
+ handleKeyEvent(event);
+ }
+ super.onBrowserEvent(event);
+ }
+
+ private void handleKeyEvent(Event event) {
+ client.console.log("keyEvent");
+
+ ShortcutKeyCombination kc = new ShortcutKeyCombination();
+ kc.altKey = DOM.eventGetAltKey(event);
+ kc.ctrlKey = DOM.eventGetCtrlKey(event);
+ kc.shiftKey = DOM.eventGetShiftKey(event);
+ kc.keyCode = DOM.eventGetKeyCode(event);
+ Iterator it = actions.iterator();
+ while(it.hasNext()) {
+ IShortcutAction a = (IShortcutAction) it.next();
+ if(a.getShortcutCombination().equals(kc)) {
+ client.updateVariable(id, "action", a.getKey(), true);
+ }
+ }
+ }
+
}
+
+
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+public class ShortcutKeyCombination {
+
+ public static final int SHIFT = 16;
+ public static final int CTRL = 17;
+ public static final int ALT = 18;
+
+
+
+ int keyCode = 0;
+ boolean altKey = false;
+ boolean ctrlKey = false;
+ boolean shiftKey = false;
+ boolean metaKey = false;
+
+ public ShortcutKeyCombination() {
+ }
+
+ ShortcutKeyCombination(int kc, int[] modifiers) {
+ keyCode = kc;
+ if(modifiers != null) {
+ for (int i = 0; i < modifiers.length; i++) {
+ switch (modifiers[i]) {
+ case ALT:
+ altKey = true;
+ break;
+ case CTRL:
+ ctrlKey = true;
+ break;
+ case SHIFT:
+ shiftKey = true;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ public boolean equals(ShortcutKeyCombination other) {
+ if( this.keyCode == other.keyCode &&
+ this.altKey == other.altKey &&
+ this.ctrlKey == other.ctrlKey &&
+ this.shiftKey == other.shiftKey)
+ return true;
+ return false;
+ }
+}
\ No newline at end of file
* @VERSION@
* @since 3.0
*/
-public class Button extends AbstractField implements Action.Container {
+public class Button extends AbstractField {
/* Private members ************************************************* */
boolean switchMode = false;
- /** List of action handlers */
- private LinkedList actionHandlers = null;
-
- /** Action mapper */
- private KeyMapper actionMapper = null;
/**
* Creates a new push button. The value of the push button is allways false
}
target.addVariable(this, "state", state);
- // Actions
- if (actionHandlers != null) {
- Set actionSet = new LinkedHashSet();
- for (Iterator ahi = actionHandlers.iterator(); ahi.hasNext();) {
- Action[] aa = ((Action.Handler) ahi.next()).getActions(this,
- this);
- if (aa != null)
- for (int ai = 0; ai < aa.length; ai++) {
- actionSet.add(aa[ai]);
- }
- }
-
- target.startTag("actions");
- target.addVariable(this, "action", "");
- for (Iterator i = actionSet.iterator(); i.hasNext();) {
- try {
- ShortcutAction a = (ShortcutAction) i.next();
- target.startTag("action");
- if (a.getCaption() != null)
- target.addAttribute("caption", a.getCaption());
- if (a.getIcon() != null)
- target.addAttribute("icon", a.getIcon());
- target.addAttribute("key", actionMapper.key(a));
- target.addAttribute("keycode", a.getKeyCode());
- if (a.getModifiers() != null) {
- int[] modifiers = a.getModifiers();
- target.addAttribute("modifiers", modifiers.length);
- for (int j = 0; j < modifiers.length; j++) {
- target.addAttribute("modifier" + j, modifiers[j]);
- }
- }
- target.endTag("action");
- } catch (Exception e) {
- // ignore non-shorcut actions for button
- }
- }
- target.endTag("actions");
- }
}
/**
setValue(new Boolean(false));
}
}
- // Actions
- // TODO this is pretty much copy-pasted from tree, may be simplified
- if (variables.containsKey("action")) {
-
- StringTokenizer st = new StringTokenizer((String) variables
- .get("action"), ",");
- if (st.countTokens() == 2) {
- Action action = (Action) actionMapper.get(st.nextToken());
- if (action != null && actionHandlers != null)
- for (Iterator i = actionHandlers.iterator(); i.hasNext();)
- ((Action.Handler) i.next()).handleAction(action, this,
- this);
- }
- }
-
}
/**
fireEvent(new Button.ClickEvent(this));
}
- /**
- * Adds an action handler.
- *
- * @see com.itmill.toolkit.event.Action.Container#addActionHandler(Action.Handler)
- */
- public void addActionHandler(Action.Handler actionHandler) {
-
- if (actionHandler != null) {
-
- if (actionHandlers == null) {
- actionHandlers = new LinkedList();
- actionMapper = new KeyMapper();
- }
-
- if (!actionHandlers.contains(actionHandler)) {
- actionHandlers.add(actionHandler);
- requestRepaint();
- }
- }
- }
-
- /**
- * Removes an action handler.
- *
- * @see com.itmill.toolkit.event.Action.Container#removeActionHandler(Action.Handler)
- */
- public void removeActionHandler(Action.Handler actionHandler) {
-
- if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
-
- actionHandlers.remove(actionHandler);
-
- if (actionHandlers.isEmpty()) {
- actionHandlers = null;
- actionMapper = null;
- }
-
- requestRepaint();
- }
- }
}
package com.itmill.toolkit.ui;
import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import com.itmill.toolkit.event.Action;
+import com.itmill.toolkit.event.ShortcutAction;
+import com.itmill.toolkit.event.Action.Handler;
+import com.itmill.toolkit.terminal.KeyMapper;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.Scrollable;
*/
public class Panel extends AbstractComponentContainer implements Sizeable,
Scrollable, ComponentContainer.ComponentAttachListener,
- ComponentContainer.ComponentDetachListener {
+ ComponentContainer.ComponentDetachListener, Action.Container {
/**
* Layout of the panel.
* Scrolling mode.
*/
private boolean scrollable = false;
+
+ /** List of action handlers */
+ private LinkedList actionHandlers = null;
+
+ /** Action mapper */
+ private KeyMapper actionMapper = null;
/**
* Creates a new empty panel. Ordered layout is used.
target.addVariable(this, "scrollleft", getScrollOffsetX());
target.addVariable(this, "scrolldown", getScrollOffsetY());
}
+
+
+ if (actionHandlers != null && !actionHandlers.isEmpty()) {
+ target.addVariable(this, "action", "");
+ target.startTag("actions");
+
+ for (Iterator ahi = actionHandlers.iterator(); ahi.hasNext();) {
+ Action[] aa = ((Action.Handler) ahi.next()).getActions(null, this);
+ if (aa != null) {
+ for (int ai = 0; ai < aa.length; ai++) {
+ Action a = aa[ai];
+ target.startTag("action");
+ String akey = actionMapper.key(aa[ai]);
+ target.addAttribute("key", akey);
+ if (a.getCaption() != null)
+ target.addAttribute("caption", a.getCaption());
+ if (a.getIcon() != null)
+ target.addAttribute("icon", a.getIcon());
+ if (a instanceof ShortcutAction) {
+ ShortcutAction sa = (ShortcutAction) a;
+ target.addAttribute("kc", sa.getKeyCode());
+ int[] modifiers = sa.getModifiers();
+ if(modifiers != null) {
+ String[] smodifiers = new String[modifiers.length];
+ for (int i = 0; i < modifiers.length; i++)
+ smodifiers[i] = String.valueOf(modifiers[i]);
+ target.addAttribute("mk", smodifiers);
+ }
+ }
+ target.endTag("action");
+ }
+ }
+ }
+ target.endTag("actions");
+ }
}
/**
setScrollOffsetX(newScrollX.intValue());
if (newScrollY != null && newScrollY.intValue() != getScrollOffsetY())
setScrollOffsetY(newScrollY.intValue());
+
+ // Actions
+ if (variables.containsKey("action")) {
+ String key = (String) variables.get("action");
+ Action action = (Action) actionMapper.get(key);
+ if (action != null && actionHandlers != null)
+ for (Iterator i = actionHandlers.iterator(); i.hasNext();)
+ ((Action.Handler) i.next()).handleAction(action, this,
+ this);
+ }
+
}
/**
layout.removeAllComponents();
}
+ public void addActionHandler(Handler actionHandler) {
+ if (actionHandler != null) {
+
+ if (actionHandlers == null) {
+ actionHandlers = new LinkedList();
+ actionMapper = new KeyMapper();
+ }
+
+ if (!actionHandlers.contains(actionHandler)) {
+ actionHandlers.add(actionHandler);
+ requestRepaint();
+ }
+ }
+
+ }
+
+ /**
+ * Removes an action handler.
+ *
+ * @see com.itmill.toolkit.event.Action.Container#removeActionHandler(Action.Handler)
+ */
+ public void removeActionHandler(Action.Handler actionHandler) {
+
+ if (actionHandlers != null && actionHandlers.contains(actionHandler)) {
+
+ actionHandlers.remove(actionHandler);
+
+ if (actionHandlers.isEmpty()) {
+ actionHandlers = null;
+ actionMapper = null;
+ }
+
+ requestRepaint();
+ }
+ }
+
}