From 5da5664bb4cf4fdbbb4a4321eeac54d4dd9c9c4d Mon Sep 17 00:00:00 2001 From: Graeme Geldenhuys Date: Wed, 24 Aug 2011 11:59:14 +0200 Subject: reworked TfpgWidget.MsgKeyPress() to correctly handle keyboard shortcuts. processing order is now as follows; - widget that keypress occured it trys to handle the event. - then to keyboard shortcut processing for the widget's children - then work back towards the top-level form giving chance for keyboard navigation (tabstop) processing. eg: pressing Tab key - then let the top level form to keyboard shortcut processing eg: allowing MainMenu to process the event. - then allow the top level for to process OnKeyPress if such an event handler is implemented. - then if the top level form is not the MainForm, and the current top level form is not shown model, allow the application.mainform to process the keyshortcut in it's main menu. --- src/corelib/fpg_widget.pas | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/corelib/fpg_widget.pas b/src/corelib/fpg_widget.pas index 44e8b3bd..a734555a 100644 --- a/src/corelib/fpg_widget.pas +++ b/src/corelib/fpg_widget.pas @@ -212,6 +212,10 @@ var uMouseDownSourceWidget: TfpgWidget; { widget Left MButton was pressed on } +type + TfpgFormFriend = class(TfpgBaseForm) + end; + function FindKeyboardFocus: TfpgWidget; begin Result := nil; @@ -572,10 +576,17 @@ begin ss := msg.params.keyboard.shiftstate; consumed := False; + { can we handle it ourselves? } HandleKeyPress(key, ss, consumed); + + { process our children } + if not consumed then + DoKeyShortcut(self, key, ss, consumed, True); + if not consumed then begin - { work it's way to one before top level form - forms are not focusable remember } + { Work its way to the top level form. The recursive calling of + HandleKeyPress() also gives tab-to-change-focus a chance to work. } wg := Parent; wlast := wg; while (not consumed) and (wg <> nil) do @@ -584,18 +595,37 @@ begin wlast := wg; wg := wg.Parent; end; + wg := wlast; end; - { we should now be at the top level form } - if (not consumed) and (wlast <> nil) then + + + if not consumed then begin - if (wlast is TfpgForm) and Assigned(wlast.OnKeyPress) then - wlast.OnKeyPress(self, key, ss, consumed); + { Now let the top level form do keyboard shortcut processing. } + if Assigned(wg) then + wg.DoKeyShortcut(self, key, ss, consumed); + + { Forms aren't focusable, so Form.HandleKeyPress() will not suffice. Give + the Form a chance to fire its OnKeyPress event. } + if not consumed then + begin + if (wg is TfpgForm) and Assigned(TfpgForm(wg).OnKeyPress) then + wg.OnKeyPress(self, key, ss, consumed); + end; + + { now try the Application MainForm - if not the same as top-level form } + if not consumed then + begin + { only do this if the top-level form is not Modal } + if (wg is TfpgForm) and (TfpgForm(wg).WindowType <> wtModalForm) then + if wg <> fpgApplication.MainForm then + TfpgFormFriend(fpgApplication.MainForm).DoKeyShortcut(self, key, ss, consumed); + end; end; + { now finaly, lets give fpgApplication a chance } if (not consumed) and Assigned(fpgApplication.OnKeyPress) then - begin fpgApplication.OnKeyPress(self, key, ss, consumed); - end; end; procedure TfpgWidget.MsgKeyRelease(var msg: TfpgMessageRec); -- cgit v1.2.3-70-g09d2