// Copyright (C) 2009 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.gwtexpui.globalkey.client; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.Widget; public class GlobalKey { public static final KeyPressHandler STOP_PROPAGATION = new KeyPressHandler() { @Override public void onKeyPress(final KeyPressEvent event) { event.stopPropagation(); } }; private static State global; static State active; private static CloseHandler<PopupPanel> restoreGlobal; private static Timer restoreTimer; static { KeyResources.I.css().ensureInjected(); } private static void initEvents() { if (active == null) { DocWidget.get().addKeyPressHandler(new KeyPressHandler() { @Override public void onKeyPress(final KeyPressEvent event) { final KeyCommandSet s = active.live; if (s != active.all) { active.live = active.all; restoreTimer.cancel(); } s.onKeyPress(event); } }); restoreTimer = new Timer() { @Override public void run() { active.live = active.all; } }; global = new State(null); active = global; } } private static void initDialog() { if (restoreGlobal == null) { restoreGlobal = new CloseHandler<PopupPanel>() { @Override public void onClose(final CloseEvent<PopupPanel> event) { active = global; } }; } } static void temporaryWithTimeout(final KeyCommandSet s) { active.live = s; restoreTimer.schedule(250); } public static void dialog(final PopupPanel panel) { initEvents(); initDialog(); assert panel.isShowing(); assert active == global; active = new State(panel); active.add(new HidePopupPanelCommand(0, KeyCodes.KEY_ESCAPE, panel)); panel.addCloseHandler(restoreGlobal); panel.addDomHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) { panel.hide(); } } }, KeyDownEvent.getType()); } public static HandlerRegistration addApplication(final Widget widget, final KeyCommand appKey) { initEvents(); final State state = stateFor(widget); state.add(appKey); return new HandlerRegistration() { @Override public void removeHandler() { state.remove(appKey); } }; } public static HandlerRegistration add(final Widget widget, final KeyCommandSet cmdSet) { initEvents(); final State state = stateFor(widget); state.add(cmdSet); return new HandlerRegistration() { @Override public void removeHandler() { state.remove(cmdSet); } }; } private static State stateFor(Widget w) { while (w != null) { if (w == active.root) { return active; } w = w.getParent(); } return global; } public static void filter(final KeyCommandFilter filter) { active.filter(filter); if (active != global) { global.filter(filter); } } private GlobalKey() { } static class State { final Widget root; final KeyCommandSet app; final KeyCommandSet all; KeyCommandSet live; State(final Widget r) { root = r; app = new KeyCommandSet(KeyConstants.I.applicationSection()); app.add(ShowHelpCommand.INSTANCE); all = new KeyCommandSet(); all.add(app); live = all; } void add(final KeyCommand k) { app.add(k); all.add(k); } void remove(final KeyCommand k) { app.remove(k); all.remove(k); } void add(final KeyCommandSet s) { all.add(s); } void remove(final KeyCommandSet s) { all.remove(s); } void filter(final KeyCommandFilter f) { all.filter(f); } } }