LCL-GTK3: Implement TextHint for TCustomEdit. Issue #37802, patch from Anton Kavalenka.

git-svn-id: trunk@63911 -
This commit is contained in:
juha 2020-09-23 19:19:26 +00:00
parent 440fd1ab17
commit 86323528a8
4 changed files with 103 additions and 13 deletions

View File

@ -760,19 +760,18 @@ const
GTK_INPUT_HINT_INHIBIT_OSK: TGtkInputHints = 128; GTK_INPUT_HINT_INHIBIT_OSK: TGtkInputHints = 128;
type type
TGtkInputPurpose = Integer; TGtkInputPurpose = (
const
{ GtkInputPurpose } { GtkInputPurpose }
GTK_INPUT_PURPOSE_FREE_FORM: TGtkInputPurpose = 0; GTK_INPUT_PURPOSE_FREE_FORM = 0,
GTK_INPUT_PURPOSE_ALPHA: TGtkInputPurpose = 1; GTK_INPUT_PURPOSE_ALPHA = 1,
GTK_INPUT_PURPOSE_DIGITS: TGtkInputPurpose = 2; GTK_INPUT_PURPOSE_DIGITS = 2,
GTK_INPUT_PURPOSE_NUMBER: TGtkInputPurpose = 3; GTK_INPUT_PURPOSE_NUMBER = 3,
GTK_INPUT_PURPOSE_PHONE: TGtkInputPurpose = 4; GTK_INPUT_PURPOSE_PHONE = 4,
GTK_INPUT_PURPOSE_URL: TGtkInputPurpose = 5; GTK_INPUT_PURPOSE_URL = 5,
GTK_INPUT_PURPOSE_EMAIL: TGtkInputPurpose = 6; GTK_INPUT_PURPOSE_EMAIL = 6,
GTK_INPUT_PURPOSE_NAME: TGtkInputPurpose = 7; GTK_INPUT_PURPOSE_NAME = 7,
GTK_INPUT_PURPOSE_PASSWORD: TGtkInputPurpose = 8; GTK_INPUT_PURPOSE_PASSWORD = 8,
GTK_INPUT_PURPOSE_PIN: TGtkInputPurpose = 9; GTK_INPUT_PURPOSE_PIN = 9);
type type
TGtkImageType = Integer; TGtkImageType = Integer;

View File

@ -124,6 +124,7 @@ type
procedure DCRedraw(CanvasHandle: HDC); override; procedure DCRedraw(CanvasHandle: HDC); override;
procedure DCSetAntialiasing(CanvasHandle: HDC; AEnabled: Boolean); override; procedure DCSetAntialiasing(CanvasHandle: HDC; AEnabled: Boolean); override;
procedure SetDesigning(AComponent: TComponent); override; procedure SetDesigning(AComponent: TComponent); override;
function GetLCLCapability(ACapability: TLCLCapability): PtrUInt; override;
function CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle; override; function CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle; override;
function DestroyTimer(TimerHandle: THandle): boolean; override; function DestroyTimer(TimerHandle: THandle): boolean; override;
@ -211,6 +212,16 @@ begin
Result := HWND(Gtk3WidgetFromGtkWidget(AWidget)); Result := HWND(Gtk3WidgetFromGtkWidget(AWidget));
end; 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 gtk3object.inc}
{$i gtk3winapi.inc} {$i gtk3winapi.inc}
{$i gtk3lclintf.inc} {$i gtk3lclintf.inc}

View File

@ -209,6 +209,7 @@ type
procedure SetAlignment(AValue: TAlignment); procedure SetAlignment(AValue: TAlignment);
protected protected
function EatArrowKeys(const AKey: Word): Boolean; override; function EatArrowKeys(const AKey: Word): Boolean; override;
procedure InsertText(const atext:pchar;len:gint;var pos:gint;edt:TGtk3Entry);cdecl;
function getText: String; override; function getText: String; override;
procedure setText(const AValue: String); override; procedure setText(const AValue: String); override;
function CreateWidget(const Params: TCreateParams):PGtkWidget; override; function CreateWidget(const Params: TCreateParams):PGtkWidget; override;
@ -217,8 +218,12 @@ type
procedure SetEchoMode(AVisible: Boolean); procedure SetEchoMode(AVisible: Boolean);
procedure SetMaxLength(AMaxLength: Integer); procedure SetMaxLength(AMaxLength: Integer);
procedure SetPasswordChar(APasswordChar: Char); procedure SetPasswordChar(APasswordChar: Char);
procedure SetNumbersOnly(ANumbersOnly:boolean);
procedure SetTextHint(const AHint:string);
function GetTextHint:string;
function IsWidgetOk: Boolean; override; function IsWidgetOk: Boolean; override;
property Alignment: TAlignment read GetAlignment write SetAlignment; property Alignment: TAlignment read GetAlignment write SetAlignment;
property TextHint:string read GetTextHint write SetTextHint;
end; end;
{ TGtk3SpinEdit } { TGtk3SpinEdit }
@ -2649,6 +2654,7 @@ var
ARect: TGdkRectangle; ARect: TGdkRectangle;
ARgba: TGdkRGBA; ARgba: TGdkRGBA;
i: TGtkStateType; i: TGtkStateType;
mh,nh,mw,nw:gint;
begin begin
FFocusableByMouse := False; FFocusableByMouse := False;
FCentralWidget := nil; FCentralWidget := nil;
@ -2671,6 +2677,13 @@ begin
height := LCLObject.Height; height := LCLObject.Height;
end; end;
FWidget^.set_allocation(@ARect); 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; end;
LCLIntf.SetProp(HWND(Self),'lclwidget',Self); LCLIntf.SetProp(HWND(Self),'lclwidget',Self);
@ -3387,6 +3400,23 @@ begin
Result := AKey in [VK_UP, VK_DOWN]; Result := AKey in [VK_UP, VK_DOWN];
end; 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; function TGtk3Entry.getText: String;
begin begin
if IsValidHandle and IsWidgetOk then if IsValidHandle and IsWidgetOk then
@ -3412,7 +3442,13 @@ end;
procedure TGtk3Entry.InitializeWidget; procedure TGtk3Entry.InitializeWidget;
begin begin
inherited InitializeWidget; 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, 'deleted-text', TGCallback(@Gtk3EntryDeletedText), Self, nil, 0);
//g_signal_connect_data(PGtkEntry(FWidget)^.get_buffer, 'inserted-text', TGCallback(@Gtk3EntryInsertedText), Self, nil, 0); //g_signal_connect_data(PGtkEntry(FWidget)^.get_buffer, 'inserted-text', TGCallback(@Gtk3EntryInsertedText), Self, nil, 0);
end; end;
@ -3430,6 +3466,30 @@ begin
end; end;
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); procedure TGtk3Entry.SetEchoMode(AVisible: Boolean);
begin begin
if IsWidgetOK then if IsWidgetOK then
@ -6562,6 +6622,8 @@ begin
g_signal_connect_data(btn,'clicked', g_signal_connect_data(btn,'clicked',
TGCallback(@TGtk3Button.ButtonClicked), LCLObject, nil, 0); TGCallback(@TGtk3Button.ButtonClicked), LCLObject, nil, 0);
LCLObject.ControlStyle:=LCLObject.ControlStyle+[csClickEvents];
FMargin := -1; FMargin := -1;
FLayout := GTK_POS_LEFT; FLayout := GTK_POS_LEFT;
FSpacing := 2; // default gtk3 spacing is 2 FSpacing := 2; // default gtk3 spacing is 2

View File

@ -164,10 +164,12 @@ type
class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override; class procedure SetEchoMode(const ACustomEdit: TCustomEdit; NewMode: TEchoMode); override;
class procedure SetHideSelection(const ACustomEdit: TCustomEdit; NewHideSelection: Boolean); override; class procedure SetHideSelection(const ACustomEdit: TCustomEdit; NewHideSelection: Boolean); override;
class procedure SetMaxLength(const ACustomEdit: TCustomEdit; NewLength: integer); 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 SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char); override;
class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override; class procedure SetReadOnly(const ACustomEdit: TCustomEdit; NewReadOnly: boolean); override;
class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override; class procedure SetSelStart(const ACustomEdit: TCustomEdit; NewStart: integer); override;
class procedure SetSelLength(const ACustomEdit: TCustomEdit; NewLength: 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 Cut(const ACustomEdit: TCustomEdit); override;
class procedure Copy(const ACustomEdit: TCustomEdit); override; class procedure Copy(const ACustomEdit: TCustomEdit); override;
@ -767,6 +769,14 @@ begin
TGtk3Entry(ACustomEdit.Handle).SetMaxLength(NewLength); TGtk3Entry(ACustomEdit.Handle).SetMaxLength(NewLength);
end; 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); class procedure TGtk3WSCustomEdit.SetPasswordChar(const ACustomEdit: TCustomEdit; NewChar: char);
begin begin
if not WSCheckHandleAllocated(ACustomEdit, 'SetPasswordChar') then if not WSCheckHandleAllocated(ACustomEdit, 'SetPasswordChar') then
@ -799,6 +809,14 @@ begin
TGtk3Editable(ACustomEdit.Handle).EndUpdate; TGtk3Editable(ACustomEdit.Handle).EndUpdate;
end; 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); class procedure TGtk3WSCustomEdit.Cut(const ACustomEdit: TCustomEdit);
begin begin
ACustomEdit.CopyToClipboard; ACustomEdit.CopyToClipboard;