diff --git a/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas b/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas index 65b17a578b..61f6b09b2b 100644 --- a/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas +++ b/lcl/interfaces/gtk3/gtk3bindings/lazgtk3.pas @@ -760,19 +760,18 @@ const GTK_INPUT_HINT_INHIBIT_OSK: TGtkInputHints = 128; type - TGtkInputPurpose = Integer; -const + TGtkInputPurpose = ( { GtkInputPurpose } - GTK_INPUT_PURPOSE_FREE_FORM: TGtkInputPurpose = 0; - GTK_INPUT_PURPOSE_ALPHA: TGtkInputPurpose = 1; - GTK_INPUT_PURPOSE_DIGITS: TGtkInputPurpose = 2; - GTK_INPUT_PURPOSE_NUMBER: TGtkInputPurpose = 3; - GTK_INPUT_PURPOSE_PHONE: TGtkInputPurpose = 4; - GTK_INPUT_PURPOSE_URL: TGtkInputPurpose = 5; - GTK_INPUT_PURPOSE_EMAIL: TGtkInputPurpose = 6; - GTK_INPUT_PURPOSE_NAME: TGtkInputPurpose = 7; - GTK_INPUT_PURPOSE_PASSWORD: TGtkInputPurpose = 8; - GTK_INPUT_PURPOSE_PIN: TGtkInputPurpose = 9; + GTK_INPUT_PURPOSE_FREE_FORM = 0, + GTK_INPUT_PURPOSE_ALPHA = 1, + GTK_INPUT_PURPOSE_DIGITS = 2, + GTK_INPUT_PURPOSE_NUMBER = 3, + GTK_INPUT_PURPOSE_PHONE = 4, + GTK_INPUT_PURPOSE_URL = 5, + GTK_INPUT_PURPOSE_EMAIL = 6, + GTK_INPUT_PURPOSE_NAME = 7, + GTK_INPUT_PURPOSE_PASSWORD = 8, + GTK_INPUT_PURPOSE_PIN = 9); type TGtkImageType = Integer; diff --git a/lcl/interfaces/gtk3/gtk3int.pas b/lcl/interfaces/gtk3/gtk3int.pas index c39d1f713f..bf050544ce 100644 --- a/lcl/interfaces/gtk3/gtk3int.pas +++ b/lcl/interfaces/gtk3/gtk3int.pas @@ -124,6 +124,7 @@ type procedure DCRedraw(CanvasHandle: HDC); override; procedure DCSetAntialiasing(CanvasHandle: HDC; AEnabled: Boolean); override; procedure SetDesigning(AComponent: TComponent); override; + function GetLCLCapability(ACapability: TLCLCapability): PtrUInt; override; function CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle; override; function DestroyTimer(TimerHandle: THandle): boolean; override; @@ -211,6 +212,16 @@ begin Result := HWND(Gtk3WidgetFromGtkWidget(AWidget)); end; +function TGtk3WidgetSet.GetLCLCapability(ACapability: TLCLCapability): PtrUInt; +begin + case ACapability of + lcTextHint: Result := LCL_CAPABILITY_YES; + else + Result := inherited GetLCLCapability(ACapability); + end; +end; + + {$i gtk3object.inc} {$i gtk3winapi.inc} {$i gtk3lclintf.inc} diff --git a/lcl/interfaces/gtk3/gtk3widgets.pas b/lcl/interfaces/gtk3/gtk3widgets.pas index 7fa7051108..bfc4657fc8 100644 --- a/lcl/interfaces/gtk3/gtk3widgets.pas +++ b/lcl/interfaces/gtk3/gtk3widgets.pas @@ -209,6 +209,7 @@ type procedure SetAlignment(AValue: TAlignment); protected function EatArrowKeys(const AKey: Word): Boolean; override; + procedure InsertText(const atext:pchar;len:gint;var pos:gint;edt:TGtk3Entry);cdecl; function getText: String; override; procedure setText(const AValue: String); override; function CreateWidget(const Params: TCreateParams):PGtkWidget; override; @@ -217,8 +218,12 @@ type procedure SetEchoMode(AVisible: Boolean); procedure SetMaxLength(AMaxLength: Integer); procedure SetPasswordChar(APasswordChar: Char); + procedure SetNumbersOnly(ANumbersOnly:boolean); + procedure SetTextHint(const AHint:string); + function GetTextHint:string; function IsWidgetOk: Boolean; override; property Alignment: TAlignment read GetAlignment write SetAlignment; + property TextHint:string read GetTextHint write SetTextHint; end; { TGtk3SpinEdit } @@ -2649,6 +2654,7 @@ var ARect: TGdkRectangle; ARgba: TGdkRGBA; i: TGtkStateType; + mh,nh,mw,nw:gint; begin FFocusableByMouse := False; FCentralWidget := nil; @@ -2671,6 +2677,13 @@ begin height := LCLObject.Height; end; FWidget^.set_allocation(@ARect); + + fWidget^.get_preferred_height(@mh,@nh); + fWidget^.get_preferred_width(@mw,@nw); + + LCLObject.Constraints.MinHeight:=mh; + LCLObject.Constraints.MinWidth:=mw; + end; LCLIntf.SetProp(HWND(Self),'lclwidget',Self); @@ -3387,6 +3400,23 @@ begin Result := AKey in [VK_UP, VK_DOWN]; end; +procedure TGtk3Entry.InsertText(const atext:pchar;len:gint;var pos:gint;edt:TGtk3Entry);cdecl; +var + i:integer; +begin + if TCustomEdit(edt.LCLObject).NumbersOnly then + begin + for i := 0 to len-1 do + begin + if not (atext[i] in ['0'..'9']) then + begin + g_signal_stop_emission_by_name(Self, 'insert-text'); + exit; + end; + end; + end; +end; + function TGtk3Entry.getText: String; begin if IsValidHandle and IsWidgetOk then @@ -3412,7 +3442,13 @@ end; procedure TGtk3Entry.InitializeWidget; begin inherited InitializeWidget; - g_signal_connect_data(PGtkEntry(FWidget), 'changed', TGCallback(@Gtk3EntryChanged), Self, nil, 0); + + Self.SetTextHint(TCustomEdit(Self.LCLObject).TextHint); + Self.SetNumbersOnly(TCustomEdit(Self.LCLObject).NumbersOnly); + + g_signal_connect_data(FWidget, 'changed', TGCallback(@Gtk3EntryChanged), Self, nil, 0); + g_signal_connect_data(FWidget, 'insert-text', TGCallback(@TGtk3Entry.InsertText), Self, nil, 0); + //g_signal_connect_data(PGtkEntry(FWidget)^.get_buffer, 'deleted-text', TGCallback(@Gtk3EntryDeletedText), Self, nil, 0); //g_signal_connect_data(PGtkEntry(FWidget)^.get_buffer, 'inserted-text', TGCallback(@Gtk3EntryInsertedText), Self, nil, 0); end; @@ -3430,6 +3466,30 @@ begin end; end; +procedure TGtk3Entry.SetNumbersOnly(ANumbersOnly:boolean); +const + ips:array[boolean]of TGtkInputPurpose=(GTK_INPUT_PURPOSE_FREE_FORM,GTK_INPUT_PURPOSE_NUMBER); +begin + // this is not enough for numeric input - it is just a hint for GUI + if IsWidgetOK then + PGtkEntry(FWidget)^.set_input_purpose(ips[ANumbersOnly]); +end; + +procedure TGtk3Entry.SetTextHint(const AHint: string); +begin + if IsWidgetOK then + PGtkEntry(FWidget)^.set_placeholder_text(PgChar(AHint)); +end; + +function TGtk3Entry.GetTextHint:string; + +begin + if IsWidgetOK then + Result:=PGtkEntry(FWidget)^.get_placeholder_text() + else + Result:=''; +end; + procedure TGtk3Entry.SetEchoMode(AVisible: Boolean); begin if IsWidgetOK then @@ -6562,6 +6622,8 @@ begin g_signal_connect_data(btn,'clicked', TGCallback(@TGtk3Button.ButtonClicked), LCLObject, nil, 0); + LCLObject.ControlStyle:=LCLObject.ControlStyle+[csClickEvents]; + FMargin := -1; FLayout := GTK_POS_LEFT; FSpacing := 2; // default gtk3 spacing is 2 diff --git a/lcl/interfaces/gtk3/gtk3wsstdctrls.pp b/lcl/interfaces/gtk3/gtk3wsstdctrls.pp index 0c234f8a5a..44d7513aca 100644 --- a/lcl/interfaces/gtk3/gtk3wsstdctrls.pp +++ b/lcl/interfaces/gtk3/gtk3wsstdctrls.pp @@ -164,10 +164,12 @@ type class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override; class procedure SetHideSelection(const ACustomEdit: TCustomEdit; NewHideSelection: Boolean); override; class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; + class procedure SetNumbersOnly(const ACustomEdit: TCustomEdit; NewNumbersOnly: Boolean); override; class procedure SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override; class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override; class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override; class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: integer); override; + class procedure SetTextHint(const ACustomEdit: TCustomEdit; const ATextHint: string); override; class procedure Cut(const ACustomEdit: TCustomEdit); override; class procedure Copy(const ACustomEdit: TCustomEdit); override; @@ -767,6 +769,14 @@ begin TGtk3Entry(ACustomEdit.Handle).SetMaxLength(NewLength); end; +class procedure TGtk3WSCustomEdit.SetNumbersOnly( + const ACustomEdit: TCustomEdit; NewNumbersOnly: Boolean); +begin + if not WSCheckHandleAllocated(ACustomEdit, 'NumbersOnly') then + Exit; + TGtk3Entry(ACustomEdit.Handle).SetNumbersOnly(NewNumbersOnly); +end; + class procedure TGtk3WSCustomEdit.SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); begin if not WSCheckHandleAllocated(ACustomEdit, 'SetPasswordChar') then @@ -799,6 +809,14 @@ begin TGtk3Editable(ACustomEdit.Handle).EndUpdate; end; +class procedure TGtk3WSCustomEdit.SetTextHint(const ACustomEdit: TCustomEdit; + const ATextHint: string); +begin + if not WSCheckHandleAllocated(ACustomEdit, 'SetTextHint') then + Exit; + TGtk3Entry(ACustomEdit.Handle).SetTextHint(ATextHint); +end; + class procedure TGtk3WSCustomEdit.Cut(const ACustomEdit: TCustomEdit); begin ACustomEdit.CopyToClipboard;