mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-20 14:42:33 +02:00
SynCompletion: Customize hint handling for long lines in drop-down window
git-svn-id: trunk@25826 -
This commit is contained in:
parent
c334353214
commit
cc05c07cf1
@ -42,7 +42,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
LCLProc, LCLIntf, LCLType, SynEditMiscProcs,
|
LCLProc, LCLIntf, LCLType, SynEditMiscProcs,
|
||||||
Classes, Graphics, Forms, Controls, StdCtrls, Menus,
|
Classes, Graphics, Forms, Controls, StdCtrls, ExtCtrls, Menus,
|
||||||
SysUtils, SynEditKeyCmds, SynEditHighlighter,
|
SysUtils, SynEditKeyCmds, SynEditHighlighter,
|
||||||
SynEdit;
|
SynEdit;
|
||||||
|
|
||||||
@ -71,6 +71,7 @@ type
|
|||||||
TSynBaseCompletionHint = class(THintWindow)
|
TSynBaseCompletionHint = class(THintWindow)
|
||||||
private
|
private
|
||||||
FCompletionForm: TSynBaseCompletionForm;
|
FCompletionForm: TSynBaseCompletionForm;
|
||||||
|
FDisplayRect: TRect;
|
||||||
FIndex: Integer;
|
FIndex: Integer;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
@ -78,8 +79,16 @@ type
|
|||||||
AData: Pointer): TRect; override;
|
AData: Pointer): TRect; override;
|
||||||
procedure Paint; override;
|
procedure Paint; override;
|
||||||
property Index: Integer read FIndex write FIndex;
|
property Index: Integer read FIndex write FIndex;
|
||||||
|
property DisplayRect: TRect read FDisplayRect write FDisplayRect;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
TSynComletionLongHintType = (sclpNone,
|
||||||
|
sclpExtendRightOnly,
|
||||||
|
sclpExtendHalfLeft,
|
||||||
|
sclpExtendUnlimitedLeft
|
||||||
|
);
|
||||||
|
|
||||||
{ TSynBaseCompletionForm }
|
{ TSynBaseCompletionForm }
|
||||||
|
|
||||||
TSynBaseCompletionForm = class(TForm)
|
TSynBaseCompletionForm = class(TForm)
|
||||||
@ -106,6 +115,9 @@ type
|
|||||||
FTextColor: TColor;
|
FTextColor: TColor;
|
||||||
FTextSelectedColor: TColor;
|
FTextSelectedColor: TColor;
|
||||||
FHint: TSynBaseCompletionHint;
|
FHint: TSynBaseCompletionHint;
|
||||||
|
FHintTimer: TTimer;
|
||||||
|
FLongLineHintTime: Integer;
|
||||||
|
FLongLineHintType: TSynComletionLongHintType;
|
||||||
procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
|
procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
|
||||||
procedure SetCurrentString(const Value: string);
|
procedure SetCurrentString(const Value: string);
|
||||||
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||||||
@ -133,10 +145,12 @@ type
|
|||||||
fCurrentEditor: TComponent;
|
fCurrentEditor: TComponent;
|
||||||
FOnMeasureItem: TSynBaseCompletionMeasureItem;
|
FOnMeasureItem: TSynBaseCompletionMeasureItem;
|
||||||
FOnPositionChanged: TNotifyEvent;
|
FOnPositionChanged: TNotifyEvent;
|
||||||
|
procedure SetLongLineHintTime(const AValue: Integer);
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: Tcomponent); override;
|
constructor Create(AOwner: Tcomponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure ShowItemHint(AIndex: Integer);
|
procedure ShowItemHint(AIndex: Integer);
|
||||||
|
procedure OnHintTimer(Sender: TObject);
|
||||||
published
|
published
|
||||||
property CurrentString: string read FCurrentString write SetCurrentString;
|
property CurrentString: string read FCurrentString write SetCurrentString;
|
||||||
property OnKeyPress: TKeyPressEvent read FOnKeyPress write FOnKeyPress;
|
property OnKeyPress: TKeyPressEvent read FOnKeyPress write FOnKeyPress;
|
||||||
@ -165,6 +179,10 @@ type
|
|||||||
property TextColor: TColor read FTextColor write FTextColor;
|
property TextColor: TColor read FTextColor write FTextColor;
|
||||||
property TextSelectedColor: TColor
|
property TextSelectedColor: TColor
|
||||||
read FTextSelectedColor write FTextSelectedColor;
|
read FTextSelectedColor write FTextSelectedColor;
|
||||||
|
property LongLineHintTime: Integer read FLongLineHintTime
|
||||||
|
write SetLongLineHintTime default 0;
|
||||||
|
property LongLineHintType: TSynComletionLongHintType read FLongLineHintType
|
||||||
|
write FLongLineHintType default sclpExtendRightOnly;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSynBaseCompletion }
|
{ TSynBaseCompletion }
|
||||||
@ -177,6 +195,8 @@ type
|
|||||||
FWidth: Integer;
|
FWidth: Integer;
|
||||||
function GetCaseSensitive: boolean;
|
function GetCaseSensitive: boolean;
|
||||||
function GetClSelect: TColor;
|
function GetClSelect: TColor;
|
||||||
|
function GetLongLineHintTime: Integer;
|
||||||
|
function GetLongLineHintType: TSynComletionLongHintType;
|
||||||
function GetOnMeasureItem: TSynBaseCompletionMeasureItem;
|
function GetOnMeasureItem: TSynBaseCompletionMeasureItem;
|
||||||
function GetOnPositionChanged: TNotifyEvent;
|
function GetOnPositionChanged: TNotifyEvent;
|
||||||
procedure SetCaseSensitive(const AValue: boolean);
|
procedure SetCaseSensitive(const AValue: boolean);
|
||||||
@ -191,6 +211,8 @@ type
|
|||||||
function GetPosition: Integer;
|
function GetPosition: Integer;
|
||||||
procedure SetCurrentString(const Value: string);
|
procedure SetCurrentString(const Value: string);
|
||||||
procedure SetItemList(const Value: TStrings);
|
procedure SetItemList(const Value: TStrings);
|
||||||
|
procedure SetLongLineHintTime(const AValue: Integer);
|
||||||
|
procedure SetLongLineHintType(const AValue: TSynComletionLongHintType);
|
||||||
procedure SetNbLinesInWindow(const Value: Integer);
|
procedure SetNbLinesInWindow(const Value: Integer);
|
||||||
procedure SetOnCancel(const Value: TNotifyEvent);
|
procedure SetOnCancel(const Value: TNotifyEvent);
|
||||||
procedure SetOnKeyPress(const Value: TKeyPressEvent);
|
procedure SetOnKeyPress(const Value: TKeyPressEvent);
|
||||||
@ -251,6 +273,10 @@ type
|
|||||||
property ClSelect: TColor read GetClSelect write SetClSelect;
|
property ClSelect: TColor read GetClSelect write SetClSelect;
|
||||||
property CaseSensitive: boolean read GetCaseSensitive write SetCaseSensitive;
|
property CaseSensitive: boolean read GetCaseSensitive write SetCaseSensitive;
|
||||||
property Width: Integer read FWidth write SetWidth;
|
property Width: Integer read FWidth write SetWidth;
|
||||||
|
property LongLineHintTime: Integer read GetLongLineHintTime
|
||||||
|
write SetLongLineHintTime default 0;
|
||||||
|
property LongLineHintType: TSynComletionLongHintType read GetLongLineHintType
|
||||||
|
write SetLongLineHintType default sclpExtendRightOnly;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSynCompletion }
|
{ TSynCompletion }
|
||||||
@ -367,6 +393,11 @@ begin
|
|||||||
Color:=clNone;
|
Color:=clNone;
|
||||||
FBackgroundColor:=clWhite;
|
FBackgroundColor:=clWhite;
|
||||||
FHint := TSynBaseCompletionHint.Create(Self);
|
FHint := TSynBaseCompletionHint.Create(Self);
|
||||||
|
FHintTimer := TTimer.Create(nil);
|
||||||
|
FHintTimer.OnTimer := {$IFDEF FPC}@{$ENDIF}OnHintTimer;
|
||||||
|
FHintTimer.Interval := 0;
|
||||||
|
FLongLineHintTime := 0;
|
||||||
|
FLongLineHintType := sclpExtendRightOnly;
|
||||||
Visible := false;
|
Visible := false;
|
||||||
ClSelect := clHighlight;
|
ClSelect := clHighlight;
|
||||||
TStringList(FItemList).OnChange := {$IFDEF FPC}@{$ENDIF}StringListChange;
|
TStringList(FItemList).OnChange := {$IFDEF FPC}@{$ENDIF}StringListChange;
|
||||||
@ -383,6 +414,7 @@ begin
|
|||||||
// completion box lost focus
|
// completion box lost focus
|
||||||
// this can happen when a hint window is clicked => ToDo
|
// this can happen when a hint window is clicked => ToDo
|
||||||
Visible := False;
|
Visible := False;
|
||||||
|
FHintTimer.Enabled := False;
|
||||||
FHint.Visible := False;
|
FHint.Visible := False;
|
||||||
if Assigned(OnCancel) then OnCancel(Self);
|
if Assigned(OnCancel) then OnCancel(Self);
|
||||||
if (FCurrentEditor<>nil) and (TCustomSynEdit(fCurrentEditor).HandleAllocated)
|
if (FCurrentEditor<>nil) and (TCustomSynEdit(fCurrentEditor).HandleAllocated)
|
||||||
@ -395,18 +427,26 @@ begin
|
|||||||
bitmap.free;
|
bitmap.free;
|
||||||
Scroll.Free;
|
Scroll.Free;
|
||||||
FItemList.Free;
|
FItemList.Free;
|
||||||
|
FHintTimer.Free;
|
||||||
FHint.Free;
|
FHint.Free;
|
||||||
inherited destroy;
|
inherited destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynBaseCompletionForm.ShowItemHint(AIndex: Integer);
|
procedure TSynBaseCompletionForm.ShowItemHint(AIndex: Integer);
|
||||||
var
|
var
|
||||||
P: TPoint;
|
|
||||||
R: TRect;
|
R: TRect;
|
||||||
|
P: TPoint;
|
||||||
M: TMonitor;
|
M: TMonitor;
|
||||||
|
MinLeft: Integer;
|
||||||
begin
|
begin
|
||||||
if Visible and (AIndex >= 0) and (AIndex < ItemList.Count) then
|
FHintTimer.Enabled := False;
|
||||||
begin
|
if Visible and (AIndex >= 0) and (AIndex < ItemList.Count) and
|
||||||
|
(FLongLineHintType <> sclpNone)
|
||||||
|
then begin
|
||||||
|
if not(FHint.IsVisible and (FHint.Index = AIndex)) then begin
|
||||||
|
if (FHint.Index <> AIndex) and (FLongLineHintTime > 0) then
|
||||||
|
FHint.Hide;
|
||||||
|
|
||||||
// CalcHintRect uses the current index
|
// CalcHintRect uses the current index
|
||||||
FHint.Index := AIndex;
|
FHint.Index := AIndex;
|
||||||
// calculate the size
|
// calculate the size
|
||||||
@ -420,15 +460,39 @@ begin
|
|||||||
// calculate the position
|
// calculate the position
|
||||||
M := Monitor;
|
M := Monitor;
|
||||||
P := ClientToScreen(Point(0, (AIndex - Scroll.Position) * FFontHeight));
|
P := ClientToScreen(Point(0, (AIndex - Scroll.Position) * FFontHeight));
|
||||||
P.X := Max(M.Left, Min(P.X, M.Left + M.Width - R.Right - 1));
|
case FLongLineHintType of
|
||||||
|
sclpExtendHalfLeft: MinLeft := Max(M.Left, P.X - ClientWidth div 2);
|
||||||
|
sclpExtendUnlimitedLeft: MinLeft := M.Left;
|
||||||
|
else MinLeft := P.X;
|
||||||
|
end;
|
||||||
|
P.X := Max(MinLeft,
|
||||||
|
Min(P.X, // Start at drop-down Left boundary
|
||||||
|
M.Left + M.Width - R.Right - 1 // Or push left, if hitting right Monitor border
|
||||||
|
)
|
||||||
|
);
|
||||||
P.Y := Max(M.Top, Min(P.Y, M.Top + M.Height - R.Bottom - 1));
|
P.Y := Max(M.Top, Min(P.Y, M.Top + M.Height - R.Bottom - 1));
|
||||||
R.Right := Min(r.Right, M.Left + M.Width - 1);
|
// actually Width and Height
|
||||||
R.Bottom := Min(r.Bottom, M.Top + M.Height - 1);
|
R.Right := Min(r.Right, M.Left + M.Width - 1 - P.X);
|
||||||
|
R.Bottom := Min(r.Bottom, M.Top + M.Height - 1 - P.Y);
|
||||||
|
|
||||||
FHint.ActivateHint(Bounds(P.X, P.Y, R.Right, R.Bottom), ItemList[AIndex]);
|
FHint.DisplayRect := Bounds(P.X, P.Y, R.Right, R.Bottom);
|
||||||
FHint.Invalidate;
|
|
||||||
|
if FLongLineHintTime > 0 then
|
||||||
|
FHintTimer.Enabled := True
|
||||||
|
else
|
||||||
|
OnHintTimer(nil);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else FHint.Hide;
|
else begin
|
||||||
|
FHint.Hide;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynBaseCompletionForm.OnHintTimer(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FHintTimer.Enabled := False;
|
||||||
|
FHint.ActivateHint(FHint.DisplayRect, ItemList[FHint.Index]);
|
||||||
|
FHint.Invalidate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynBaseCompletionForm.KeyDown(var Key: Word;
|
procedure TSynBaseCompletionForm.KeyDown(var Key: Word;
|
||||||
@ -759,6 +823,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynBaseCompletionForm.SetLongLineHintTime(const AValue: Integer);
|
||||||
|
begin
|
||||||
|
if FLongLineHintTime = AValue then exit;
|
||||||
|
FLongLineHintTime := AValue;
|
||||||
|
FHintTimer.Interval := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSynBaseCompletionForm.SetItemList(const Value: TStrings);
|
procedure TSynBaseCompletionForm.SetItemList(const Value: TStrings);
|
||||||
begin
|
begin
|
||||||
FItemList.Assign(Value);
|
FItemList.Assign(Value);
|
||||||
@ -957,6 +1028,16 @@ begin
|
|||||||
form.ItemList := Value;
|
form.ItemList := Value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynBaseCompletion.SetLongLineHintTime(const AValue: Integer);
|
||||||
|
begin
|
||||||
|
Form.LongLineHintTime := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynBaseCompletion.SetLongLineHintType(const AValue: TSynComletionLongHintType);
|
||||||
|
begin
|
||||||
|
Form.LongLineHintType := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TSynBaseCompletion.SetNbLinesInWindow(const Value: Integer);
|
procedure TSynBaseCompletion.SetNbLinesInWindow(const Value: Integer);
|
||||||
begin
|
begin
|
||||||
form.NbLinesInWindow := Value;
|
form.NbLinesInWindow := Value;
|
||||||
@ -1004,6 +1085,16 @@ begin
|
|||||||
Result := Form.ClSelect;
|
Result := Form.ClSelect;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TSynBaseCompletion.GetLongLineHintTime: Integer;
|
||||||
|
begin
|
||||||
|
Result := Form.LongLineHintTime;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TSynBaseCompletion.GetLongLineHintType: TSynComletionLongHintType;
|
||||||
|
begin
|
||||||
|
Result := Form.LongLineHintType;
|
||||||
|
end;
|
||||||
|
|
||||||
function TSynBaseCompletion.GetCaseSensitive: boolean;
|
function TSynBaseCompletion.GetCaseSensitive: boolean;
|
||||||
begin
|
begin
|
||||||
Result := Form.CaseSensitive;
|
Result := Form.CaseSensitive;
|
||||||
|
Loading…
Reference in New Issue
Block a user