/* XOWA: the XOWA Offline Wiki Application Copyright (C) 2012 gnosygnu@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package gplx.gfui; import gplx.*; class IptEventMgr implements GfoInvkAble { @gplx.Internal protected static void ExecKeyDown(GfuiElem sender, IptEvtDataKey keyState) { keyHandled = false; keyStateCur = keyState; // cache for simultaneous ipt events (ex: key.ctrl + mouse.left) IptEventData iptData = IptEventData.new_(sender, IptEventType_.KeyDown, keyState.Key(), keyState, mouseStateCur); // if (keyState.Key().Eq(IptKey_.add_(IptKey_.F1))) { // Tfds.Write(keyState.Key(), keyState.Key().Val()); // } sender.IptBnds().Process(iptData); SendData(iptData); keyHandled = keyState.Handled(); // WORKAROUND (WinForms): cache keyHandled b/c KeyDown.Handled=true does not make KeyPress.Handled=true; } @gplx.Internal protected static void ExecKeyPress(GfuiElem sender, IptEvtDataKeyHeld keyPressState) { // Tfds.Write(keyPressState.KeyChar()); if (keyHandled) {keyPressState.Handled_set(true); return;} IptEventData iptData = IptEventData.new_(sender, IptEventType_.KeyPress, IptKeyStrMgr._.FetchByKeyPress((int)(byte)keyPressState.KeyChar()), keyStateCur, keyPressState, mouseStateCur); sender.IptBnds().Process(iptData); SendData(iptData); } @gplx.Internal protected static void ExecKeyUp(GfuiElem sender, IptEvtDataKey keyState) { keyStateCur = IptEvtDataKey.Null; // keyStateCur no longer needed; set to Null if (keyHandled) {keyState.Handled_set(true); return;} IptEventData iptData = IptEventData.new_(sender, IptEventType_.KeyUp, keyState.Key(), keyState, mouseStateCur); sender.IptBnds().Process(iptData); SendData(iptData); } @gplx.Internal protected static void ExecMouseDown(GfuiElem sender, IptEvtDataMouse mouseState) { mouseStateCur = mouseState; // cache for simultaneous ipt events (ex: key.ctrl + mouse.left) if (sender.IptBnds().Has(IptEventType_.MousePress)) { if (mousePressTimer == null) mousePressTimer = TimerAdp.new_(EventSink2, Tmr_cmd, 100, false); senderCur = sender; mousePressTimer.Enabled_on(); } IptEventData iptData = IptEventData.new_(sender, IptEventType_.MouseDown, mouseState.Button(), keyStateCur, mouseState); sender.IptBnds().Process(iptData); SendData(iptData); } @gplx.Internal protected static void ExecMouseMove(GfuiElem sender, IptEvtDataMouse mouseState) { IptEventData iptData = IptEventData.new_(sender, IptEventType_.MouseMove, IptMouseMove.AnyDirection, keyStateCur, mouseState); sender.IptBnds().Process(iptData); // SendData(iptData); // TOMBSTONE: do not send mouseMove events for PERF and DESIGN reasons } @gplx.Internal protected static void ExecMouseUp(GfuiElem sender, IptEvtDataMouse mouseState) { mouseStateCur = IptEvtDataMouse.Null; // mouseStateCur no longer needed; set to Null if (mousePressTimer != null) mousePressTimer.Enabled_off(); IptEventData iptData = IptEventData.new_(sender, IptEventType_.MouseUp, mouseState.Button(), keyStateCur, mouseState); sender.IptBnds().Process(iptData); SendData(iptData); } @gplx.Internal protected static void ExecMouseWheel(GfuiElem sender, IptEvtDataMouse mouseState) { IptEventData iptData = IptEventData.new_(sender, IptEventType_.MouseWheel, mouseState.Wheel(), keyStateCur, mouseState); sender.IptBnds().Process(iptData); SendData(iptData); } @gplx.Internal protected static void ExecMousePress(GfuiElem sender, IptEvtDataMouse mouseState) { IptEventData iptData = IptEventData.new_(sender, IptEventType_.MousePress, mouseState.Button(), keyStateCur, mouseState); sender.IptBnds().Process(iptData); SendData(iptData); } static void MousePressTick() { IptEventMgr.ExecMousePress(senderCur, mouseStateCur); } static void SendData(IptEventData iptData) { if (StopFwd(iptData)) return; GfsCtx ctx = GfsCtx.new_(); GfoMsg m = GfoMsg_.new_cast_(GfuiElemKeys.IptRcvd_evt).Add("iptData", iptData); GfoEvMgr_.PubMsg(iptData.Sender(), ctx, GfuiElemKeys.IptRcvd_evt, m); } public static boolean StopFwd(IptEventData iptData) { // check if (a) control bubbles event; (b) iptData.Handled return !IptEventType_.Has(iptData.Sender().IptBnds().EventsToFwd(), iptData.EventType()) || iptData.Handled(); } static boolean keyHandled = false; static IptEvtDataKey keyStateCur = IptEvtDataKey.Null; static IptEvtDataMouse mouseStateCur = IptEvtDataMouse.Null; static TimerAdp mousePressTimer; static GfuiElem senderCur; public static final IptEventMgr EventSink2 = new IptEventMgr(); IptEventMgr() {} public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) { if (ctx.Match(k, Tmr_cmd)) MousePressTick(); else return GfoInvkAble_.Rv_unhandled; return this; } public static final String Tmr_cmd = "Tmr"; }