diff --git a/lcl/interfaces/qt/qtwidgets.pas b/lcl/interfaces/qt/qtwidgets.pas index e8167fbafd..7dd88e035a 100644 --- a/lcl/interfaces/qt/qtwidgets.pas +++ b/lcl/interfaces/qt/qtwidgets.pas @@ -31,7 +31,7 @@ uses // Free Pascal Classes, SysUtils, Types, // LCL - LMessages, Forms, Controls, LCLType, LCLProc, ComCtrls, ExtCtrls, StdCtrls, Menus; + LMessages, Buttons, Forms, Controls, LCLType, LCLProc, ComCtrls, ExtCtrls, StdCtrls, Menus; type { TQtWidget } @@ -75,6 +75,7 @@ type function windowFlags: QtWindowFlags; procedure setWidth(p1: Integer); procedure setHeight(p1: Integer); + procedure setTabOrder(p1, p2: TQtWidget); end; { TQtAbstractButton } @@ -112,6 +113,7 @@ type public constructor Create(const AWinControl: TWinControl; const AParams: TCreateParams); override; destructor Destroy; override; + procedure setTabOrders; public function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override; procedure SlotWindowStateChange; cdecl; @@ -370,6 +372,15 @@ type implementation +{ Helper functions } + +function SortListByTabOrder(Item1: Pointer; Item2: Pointer): Integer; +begin + if TWinControl(Item1).TabOrder = TWinControl(Item2).TabOrder then Result := 0 + else if TWinControl(Item1).TabOrder < TWinControl(Item2).TabOrder then Result := -1 + else if TWinControl(Item1).TabOrder > TWinControl(Item2).TabOrder then Result := 1; +end; + { TQtWidget } {------------------------------------------------------------------------------ @@ -443,7 +454,7 @@ begin // WriteLn(Integer(QEvent_type(Event))); {.$endif} - QEvent_ignore(Event); + QEvent_accept(Event); case QEvent_type(Event) of QEventShow: SlotShow(True); @@ -461,6 +472,8 @@ begin QEventResize: SlotResize; QEventPaint: SlotPaint(Event); QEventContextMenu: SlotContextMenu; + else + QEvent_ignore(Event); end; { GtkWidgetSet.SetCallback(LM_WINDOWPOSCHANGED, AGTKObject, AComponent); @@ -640,13 +653,19 @@ begin QEventMouseButtonPress: Msg.Msg := LM_PRESSED; QEventMouseButtonRelease: begin - Msg.Msg := LM_CLICKED; + { Clicking on buttons operates differently, because QEventMouseButtonRelease + is sent if you click a control, drag the mouse out of it and release, but + buttons should not be clicked on this case. } + if not (LCLObject is TCustomButton) then + begin + Msg.Msg := LM_CLICKED; - try - LCLObject.WindowProc(TLMessage(Msg)); - except - Application.HandleException(nil); - end; + try + LCLObject.WindowProc(TLMessage(Msg)); + except + Application.HandleException(nil); + end; + end; Msg.Msg := LM_RELEASED; end; @@ -879,6 +898,11 @@ begin QWidget_setGeometry(Widget, @R); end; +procedure TQtWidget.setTabOrder(p1, p2: TQtWidget); +begin + QWidget_setTabOrder(p1.Widget, p2.Widget); +end; + {------------------------------------------------------------------------------ Function: TQtWidget.QtKeyToLCLKey Params: None @@ -1336,9 +1360,6 @@ begin // Main menu bar MenuBar := TQtMenuBar.Create(Widget); - -{ // Accepts keyboard and mouse events - QWidget_setFocusPolicy(Widget, QtStrongFocus);} end; {------------------------------------------------------------------------------ @@ -1357,6 +1378,59 @@ begin inherited Destroy; end; +{------------------------------------------------------------------------------ + Function: TQtMainWindow.setTabOrders + Params: None + Returns: Nothing + + Sets the tab order of all controls on a form. + ------------------------------------------------------------------------------} +procedure TQtMainWindow.setTabOrders; +var + i: Integer; + Form: TForm; + List: TList; +begin + List := TList.Create; + + Form := TForm(LCLObject); + + { Creates a list with childs of the form that are available to receive Tab focus } + for i := 0 to Form.ComponentCount - 1 do + begin + if Form.Components[i] is TWinControl then + if TWinControl(Form.Components[i]).TabStop then + List.Add(Form.Components[i]); + end; + + List.Sort(SortListByTabOrder); + + for i := 0 to List.Count - 2 do + begin + setTabOrder(TQtWidget(TWinControl(List.Items[i]).Handle), + TQtWidget(TWinControl(List.Items[i + 1]).Handle)); + + {$ifdef VerboseQt} + WriteLn('Setting Tab Order first: ', TWinControl(List.Items[i]).Name, ' second: ', + TWinControl(List.Items[i + 1]).Name); + {$endif} + end; + + { The last element points to the first } + if List.Count > 0 then + begin + setTabOrder(TQtWidget(TWinControl(List.Items[List.Count - 1]).Handle), + TQtWidget(TWinControl(List.Items[0]).Handle)); + + {$ifdef VerboseQt} + WriteLn('Setting Tab Order first: ', TWinControl(List.Items[List.Count - 1]).Name, ' second: ', + TWinControl(List.Items[0]).Name); + {$endif} + end; + + List.Free; +end; + {------------------------------------------------------------------------------ Function: TQtMainWindow.EventFilter Params: None diff --git a/lcl/interfaces/qt/qtwinapi.inc b/lcl/interfaces/qt/qtwinapi.inc index fab4cef781..34491ba800 100644 --- a/lcl/interfaces/qt/qtwinapi.inc +++ b/lcl/interfaces/qt/qtwinapi.inc @@ -1535,7 +1535,10 @@ begin TQtDeviceContext(DC).font.family(@FontFamily); - { Defaults to a TrueType font } + { Defaults to a TrueType font. + Note that the meaning of the FIXED_PITCH constant is the opposite of + the name implies, according to MSDN docs. Just a small inconsistency + on Windows API that we have to mimic. } if TQtDeviceContext(DC).font.fixedPitch then TM.tmPitchAndFamily := TRUETYPE_FONTTYPE else TM.tmPitchAndFamily := FIXED_PITCH or TRUETYPE_FONTTYPE; diff --git a/lcl/interfaces/qt/qtwsbuttons.pp b/lcl/interfaces/qt/qtwsbuttons.pp index 96c429f318..d5e33a1ff5 100644 --- a/lcl/interfaces/qt/qtwsbuttons.pp +++ b/lcl/interfaces/qt/qtwsbuttons.pp @@ -107,6 +107,16 @@ begin QObject_hook_hook_events(Hook, Method); + // OnClick Event + + QAbstractButton_clicked2_Event(Method) := QtPushButton.SlotClicked; + + QAbstractButton_hook_hook_clicked2(QAbstractButton_hook_create(QtPushButton.Widget), Method); + + // Focus + + QWidget_setFocusPolicy(QtPushButton.Widget, QtStrongFocus); + // Returns the Handle Result := THandle(QtPushButton); @@ -182,6 +192,16 @@ begin QObject_hook_hook_events(Hook, Method); + // OnClick Event + + QAbstractButton_clicked2_Event(Method) := QtPushButton.SlotClicked; + + QAbstractButton_hook_hook_clicked2(QAbstractButton_hook_create(QtPushButton.Widget), Method); + + // Focus + + QWidget_setFocusPolicy(QtPushButton.Widget, QtStrongFocus); + // Returns the Handle Result := THandle(QtPushButton); diff --git a/lcl/interfaces/qt/qtwscontrols.pp b/lcl/interfaces/qt/qtwscontrols.pp index 19c9c43a6a..989e44771b 100644 --- a/lcl/interfaces/qt/qtwscontrols.pp +++ b/lcl/interfaces/qt/qtwscontrols.pp @@ -213,24 +213,32 @@ end; Returns: Nothing - Shows or hides a wi/dget. + Shows or hides a widget. ------------------------------------------------------------------------------} class procedure TQtWSWinControl.ShowHide(const AWinControl: TWinControl); begin + {$ifdef VerboseQt} + WriteLn('Trace:> [TQtWSWinControl.ShowHide]'); + {$endif} + if AWinControl = nil then exit; if not AWinControl.HandleAllocated then exit; + { if the widget is a form, this is a place to set the Tab order } + if (AWinControl is TForm) and AWinControl.HandleObjectShouldBeVisible then + TQtMainWindow(AWinControl.Handle).SetTabOrders; + if AWinControl.HandleObjectShouldBeVisible then QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, True) else QWidget_setVisible(TQtWidget(AWinControl.Handle).Widget, False); {$ifdef VerboseQt} - Write('TQtWSWinControl.ShowHide '); + Write('Trace:< [TQtWSWinControl.ShowHide] '); if AWinControl is TForm then Write('Is TForm, '); - if AWinControl.Visible then WriteLn('Visible: True') + if AWinControl.HandleObjectShouldBeVisible then WriteLn('Visible: True') else WriteLn('Visible: False'); {$endif} end; diff --git a/lcl/interfaces/qt/qtwsstdctrls.pp b/lcl/interfaces/qt/qtwsstdctrls.pp index 7b831bf8f2..8b49f894b8 100644 --- a/lcl/interfaces/qt/qtwsstdctrls.pp +++ b/lcl/interfaces/qt/qtwsstdctrls.pp @@ -886,7 +886,7 @@ var begin QtCheckBox := TQtCheckBox.Create(AWinControl, AParams); -// SetSlots(QtStaticText); + // Focus QWidget_setFocusPolicy(QtCheckBox.Widget, QtStrongFocus); @@ -1004,6 +1004,8 @@ begin QObject_hook_hook_events(Hook, Method);} + // Focus + QWidget_setFocusPolicy(QtRadioButton.Widget, QtStrongFocus); // Returns the Handle