SynCompletion: Improved positioning

git-svn-id: trunk@28012 -
This commit is contained in:
martin 2010-10-31 16:27:17 +00:00
parent a4f2917fbd
commit cf7da2876f
3 changed files with 62 additions and 27 deletions

View File

@ -271,7 +271,9 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Execute(s: string; x, y: integer);
procedure Execute(s: string; x, y: integer); overload;
procedure Execute(s: string; TopLeft: TPoint); overload;
procedure Execute(s: string; TokenRect: TRect); overload; // Excute below or above the token // may be extended to adjust left corner too
procedure Deactivate;
function IsActive: boolean;
function TheForm: TSynBaseCompletionForm;
@ -481,6 +483,7 @@ begin
inherited Create(AOwner);
FItemList := TStringList.Create;
BorderStyle := bsNone;
FormStyle := fsSystemStayOnTop;
Scroll := TScrollBar.Create(self);
Scroll.Kind := sbVertical;
{$IFNDEF SYN_LAZARUS}
@ -529,6 +532,7 @@ begin
Color:=clNone;
FBackgroundColor:=clWhite;
FHint := TSynBaseCompletionHint.Create(Self);
FHint.FormStyle := fsSystemStayOnTop;;
FHintTimer := TTimer.Create(nil);
FHintTimer.OnTimer := {$IFDEF FPC}@{$ENDIF}OnHintTimer;
FHintTimer.Interval := 0;
@ -593,7 +597,7 @@ begin
M := Monitor;
P := ClientToScreen(Point(0, (AIndex - Scroll.Position) * FFontHeight));
case FLongLineHintType of
sclpExtendHalfLeft: MinLeft := Max(M.Left, P.X - ClientWidth div 2);
sclpExtendHalfLeft: MinLeft := Max(M.Left, P.X - ClientWidth div 2); // ClientWidth may be too much, if part of the ClientWidth extends to another screen.
sclpExtendUnlimitedLeft: MinLeft := M.Left;
else MinLeft := P.X;
end;
@ -751,7 +755,8 @@ begin
//Writeln('[TSynBaseCompletionForm.Paint]');
// update scroll bar
Scroll.Visible := ItemList.Count > NbLinesInWindow;
Scroll.Enabled := ItemList.Count > NbLinesInWindow;
Scroll.Visible := (ItemList.Count > NbLinesInWindow) or ShowSizeDrag;
if Scroll.Visible then
begin
@ -1194,6 +1199,41 @@ begin
Form.Position := Form.Position;
end;
procedure TSynBaseCompletion.Execute(s: string; TopLeft: TPoint);
begin
Execute(s, TopLeft.x, TopLeft.y);
end;
procedure TSynBaseCompletion.Execute(s: string; TokenRect: TRect);
var
SpaceBelow, SpaceAbove: Integer;
Mon: TMonitor;
begin
{$IFnDEF LCLGTK2}
Mon := Screen.MonitorFromPoint(TokenRect.TopLeft);
if Mon <> nil then
TokenRect.Left := Min(TokenRect.Left, Mon.Left + Mon.Width - Form.Width);
{$ENDIF}
SpaceBelow := Mon.Height - TokenRect.Bottom;
SpaceAbove := TokenRect.Top - Mon.Top;
if Form.Height < SpaceBelow then
Execute(s, TokenRect.Left, TokenRect.Bottom)
else
if Form.Height < SpaceAbove then
Execute(s, TokenRect.Left, TokenRect.Top - Form.Height)
else
begin
if SpaceBelow > SpaceAbove then begin
Form.NbLinesInWindow := Max(SpaceBelow div Form.FontHeight, 3); // temporary height
Execute(s, TokenRect.Left, TokenRect.Bottom);
end else begin
Form.NbLinesInWindow := Max(SpaceAbove div Form.FontHeight, 3); // temporary height
Execute(s, TokenRect.Left, TokenRect.Top - Form.Height);
end;;
end;
end;
function TSynBaseCompletion.GetCurrentString: string;
begin
result := Form.CurrentString;

View File

@ -820,6 +820,7 @@ type
procedure RegisterStatusChangedHandler(AStatusChangeProc: TStatusChangeEvent; AChanges: TSynStatusChanges);
procedure UnRegisterStatusChangedHandler(AStatusChangeProc: TStatusChangeEvent);
// RowColumnToPixels: Physical coords
function RowColumnToPixels(
{$IFDEF SYN_LAZARUS}const {$ENDIF}RowCol: TPoint): TPoint;
function SearchReplace(const ASearch, AReplace: string;

View File

@ -877,11 +877,12 @@ type
FActiveCompletionPlugin: TSourceEditorCompletionPlugin;
function GetDefaultCompletionForm: TSourceEditCompletion;
procedure FreeCompletionPlugins;
function GetScreenRectForToken(AnEditor: TCustomSynEdit; PhysColumn, PhysRow, EndColumn: Integer): TRect;
protected
function GetActiveCompletionPlugin: TSourceEditorCompletionPlugin; override;
function GetCompletionBoxPosition: integer; override;
function GetCompletionPlugins(Index: integer): TSourceEditorCompletionPlugin; override;
function FindIdentCompletionPlugin(SrcEdit: TSourceEditor; JumpToError: boolean;
function FindIdentCompletionPlugin(SrcEdit: TSourceEditor; JumpToError: boolean;
var s: string; var BoxX, BoxY: integer;
var UseWordCompletion: boolean): boolean;
property DefaultCompletionForm: TSourceEditCompletion
@ -3925,11 +3926,11 @@ end;
procedure TSourceEditor.StartIdentCompletionBox(JumpToError: boolean);
var
I: Integer;
P: TPoint;
TextS, TextS2: String;
LogCaret: TPoint;
UseWordCompletion: Boolean;
Completion: TSourceEditCompletion;
CompletionRect: TRect;
begin
{$IFDEF VerboseIDECompletionBox}
debugln(['TSourceEditor.StartIdentCompletionBox JumpToError: ',JumpToError]);
@ -3950,20 +3951,17 @@ begin
dec(i);
TextS2 := Trim(copy(TextS, i + 1, LogCaret.X - i - 1));
end;
with FEditor do begin
P := Point(CaretXPix - length(TextS2)*CharWidth,CaretYPix + LineHeight + 1);
P.X:=Max(0,Min(P.X,ClientWidth-Completion.Width));
P := ClientToScreen(p);
end;
UseWordCompletion:=false;
CompletionRect := Manager.GetScreenRectForToken(FEditor, FEditor.CaretX-length(TextS2), FEditor.CaretY, FEditor.CaretX-1);
if not Manager.FindIdentCompletionPlugin
(Self, JumpToError, TextS2, P.X, P.Y, UseWordCompletion)
(Self, JumpToError, TextS2, CompletionRect.Top, CompletionRect.Left, UseWordCompletion)
then
exit;
if UseWordCompletion then
Completion.CurrentCompletionType:=ctWordCompletion;
Completion.Execute(TextS2,P.X,P.Y);
Completion.Execute(TextS2, CompletionRect);
{$IFDEF VerboseIDECompletionBox}
debugln(['TSourceEditor.StartIdentCompletionBox END Completion.TheForm.Visible=',Completion.TheForm.Visible]);
{$ENDIF}
@ -3975,7 +3973,6 @@ var
LogCaret: TPoint;
i: Integer;
TextS2: String;
P: TPoint;
Completion: TSourceEditCompletion;
begin
if (FEditor.ReadOnly) then exit;
@ -3993,12 +3990,8 @@ begin
dec(i);
TextS2 := Trim(copy(TextS, i + 1, LogCaret.X - i - 1));
end;
with FEditor do begin
P := Point(CaretXPix - length(TextS2)*CharWidth,CaretYPix + LineHeight + 1);
P.X:=Max(0,Min(P.X,ClientWidth - Completion.Width));
P := ClientToScreen(p);
end;
Completion.Execute(TextS2,P.X,P.Y);
Completion.Execute
(TextS2, Manager.GetScreenRectForToken(FEditor, FEditor.CaretX-length(TextS2), FEditor.CaretY, FEditor.CaretX-1));
end;
procedure TSourceEditor.IncreaseIgnoreCodeBufferLock;
@ -7838,6 +7831,13 @@ begin
FCompletionPlugins.Clear;
end;
function TSourceEditorManagerBase.GetScreenRectForToken(AnEditor: TCustomSynEdit;
PhysColumn, PhysRow, EndColumn: Integer): TRect;
begin
Result.TopLeft := AnEditor.ClientToScreen(AnEditor.RowColumnToPixels(Point(PhysColumn, PhysRow)));
Result.BottomRight := AnEditor.ClientToScreen(AnEditor.RowColumnToPixels(Point(EndColumn+1, PhysRow+1)));
end;
function TSourceEditorManagerBase.GetMarklingProducers(Index: integer
): TSourceMarklingProducer;
begin
@ -8707,21 +8707,15 @@ end;
procedure TSourceEditorManager.OnCodeTemplateTokenNotFound(Sender: TObject;
AToken: string; AnEditor: TCustomSynEdit; var Index: integer);
var
P:TPoint;
begin
//writeln('TSourceNotebook.OnCodeTemplateTokenNotFound ',AToken,',',AnEditor.ReadOnly,',',DefaultCompletionForm.CurrentCompletionType=ctNone);
if (AnEditor.ReadOnly=false) and
(DefaultCompletionForm.CurrentCompletionType=ctNone)
then begin
DefaultCompletionForm.CurrentCompletionType:=ctTemplateCompletion;
with AnEditor do begin
P := Point(CaretXPix - length(AToken)*CharWidth,CaretYPix + LineHeight + 1);
P.X:=Max(0,Min(P.X,ClientWidth-DefaultCompletionForm.Width));
P := ClientToScreen(p);
end;
DefaultCompletionForm.Editor:=AnEditor;
DefaultCompletionForm.Execute(AToken,P.X,P.Y);
DefaultCompletionForm.Execute
(AToken, GetScreenRectForToken(AnEditor, AnEditor.CaretX-length(AToken), AnEditor.CaretY, AnEditor.CaretX-1));
end;
end;