SynCompletion: Customize hint handling for long lines in drop-down window

git-svn-id: trunk@25826 -
This commit is contained in:
martin 2010-06-01 22:50:28 +00:00
parent c334353214
commit cc05c07cf1

View File

@ -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;