From 205a10bfc39043cf410959ba367dfd70632c106e Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 31 Jan 2015 19:21:13 +0000 Subject: [PATCH] SynEdit: Prepare alternative caret git-svn-id: trunk@47575 - --- components/synedit/syneditpointclasses.pas | 197 ++++++++++++++++++++- 1 file changed, 190 insertions(+), 7 deletions(-) diff --git a/components/synedit/syneditpointclasses.pas b/components/synedit/syneditpointclasses.pas index cbb9d271fa..7d837f1c11 100644 --- a/components/synedit/syneditpointclasses.pas +++ b/components/synedit/syneditpointclasses.pas @@ -36,7 +36,7 @@ unit SynEditPointClasses; interface uses - Classes, SysUtils, Controls, LCLProc, LCLType, LCLIntf, + Classes, SysUtils, Controls, LCLProc, LCLType, LCLIntf, ExtCtrls, Graphics, {$IFDEF SYN_MBCSSUPPORT} Imm, {$ENDIF} @@ -326,6 +326,58 @@ type TSynCaretType = (ctVerticalLine, ctHorizontalLine, ctHalfBlock, ctBlock, ctCostum); TSynCaretLockFlags = set of (sclfUpdateDisplay, sclfUpdateDisplayType); + { TSynEditScreenCaretPainter } + + TSynEditScreenCaretPainter = class + private + function GetHandle: HWND; + protected + FHandleOwner: TWinControl; + procedure Init; virtual; + property Handle: HWND read GetHandle; + public + constructor Create(AHandleOwner: TWinControl); + function CreateCaret(w, h: Integer): Boolean; virtual; abstract; + function DestroyCaret: Boolean; virtual; abstract; + function HideCaret: Boolean; virtual; abstract; + function ShowCaret: Boolean; virtual; abstract; + function SetCaretPosEx(x, y: Integer): Boolean; virtual; abstract; + end; + + { TSynEditScreenCaretPainterSystem } + + TSynEditScreenCaretPainterSystem = class(TSynEditScreenCaretPainter) + public + function CreateCaret(w, h: Integer): Boolean; override; + function DestroyCaret: Boolean; override; + function HideCaret: Boolean; override; + function ShowCaret: Boolean; override; + function SetCaretPosEx(x, y: Integer): Boolean; override; + end; + + { TSynEditScreenCaretPainterInternal } + + TSynEditScreenCaretPainterInternal = class(TSynEditScreenCaretPainter) + private + FTimer: TTimer; + FLeft, FTop, FHeight, FWidth: Integer; + FIsDrawn: Boolean; + FShowing: Boolean; + FSavePen: TPen; + + procedure DoTimer(Sender: TObject); + procedure Paint; + protected + procedure Init; override; + public + destructor Destroy; override; + function CreateCaret(w, h: Integer): Boolean; override; + function DestroyCaret: Boolean; override; + function HideCaret: Boolean; override; + function ShowCaret: Boolean; override; + function SetCaretPosEx(x, y: Integer): Boolean; override; + end; + { TSynEditScreenCaret } TSynEditScreenCaret = class @@ -342,6 +394,7 @@ type FOnExtraLineCharsChanged: TNotifyEvent; FVisible: Boolean; FHandleOwner: TWinControl; + FCaretPainter: TSynEditScreenCaretPainter; function GetHandle: HWND; function GetHandleAllocated: Boolean; procedure SetCharHeight(const AValue: Integer); @@ -405,6 +458,88 @@ type implementation +{ TSynEditScreenCaretPainterInternal } + +procedure TSynEditScreenCaretPainterInternal.DoTimer(Sender: TObject); +begin + if not FTimer.Enabled and FShowing then exit; + Paint; +end; + +procedure TSynEditScreenCaretPainterInternal.Paint; +var + c: TCanvas; +begin + FIsDrawn := not FIsDrawn; + + c := TCustomControl(FHandleOwner).Canvas; + FSavePen.Assign(c.Pen); + + c.MoveTo(FLeft, FTop); + c.Pen.Mode := pmNotXOR; + c.Pen.Style := psSolid; + c.Pen.Color := clBlack; + c.pen.EndCap := pecFlat; + c.pen.Width := FWidth; + c.LineTo(FLeft,FTop+FHeight); + + c.Pen.Assign(FSavePen); +end; + +procedure TSynEditScreenCaretPainterInternal.Init; +begin + FTimer := TTimer.Create(nil); + FTimer.Enabled := False; + FTimer.Interval := 500; + FTimer.OnTimer := @DoTimer; + + FSavePen := TPen.Create; + inherited Init; +end; + +destructor TSynEditScreenCaretPainterInternal.Destroy; +begin + FreeAndNil(FTimer); + FreeAndNil(FSavePen); + inherited Destroy; +end; + +function TSynEditScreenCaretPainterInternal.CreateCaret(w, h: Integer): Boolean; +begin + FWidth := w; + FHeight := h; +end; + +function TSynEditScreenCaretPainterInternal.DestroyCaret: Boolean; +begin + // +end; + +function TSynEditScreenCaretPainterInternal.HideCaret: Boolean; +begin + FShowing := False; + FTimer.Enabled := False; + if FIsDrawn then Paint; +end; + +function TSynEditScreenCaretPainterInternal.ShowCaret: Boolean; +begin + FShowing := True; + FTimer.Enabled := True; + if not FIsDrawn then Paint; +end; + +function TSynEditScreenCaretPainterInternal.SetCaretPosEx(x, y: Integer): Boolean; +var + s: Boolean; +begin + s := FShowing; + HideCaret; + FLeft := x; + FTop := y; + if s then ShowCaret; +end; + { TSynEditBaseCaret } function TSynEditBaseCaret.GetBytePos: Integer; @@ -2222,11 +2357,58 @@ begin StartLineBytePos := StartLineBytePos; end; +{ TSynEditScreenCaretPainter } + +function TSynEditScreenCaretPainter.GetHandle: HWND; +begin + Result := FHandleOwner.Handle; +end; + +procedure TSynEditScreenCaretPainter.Init; +begin + // +end; + +constructor TSynEditScreenCaretPainter.Create(AHandleOwner: TWinControl); +begin + inherited Create; + FHandleOwner := AHandleOwner; + Init; +end; + +{ TSynEditScreenCaretPainterSystem } + +function TSynEditScreenCaretPainterSystem.CreateCaret(w, h: Integer): Boolean; +begin + Result := LCLIntf.CreateCaret(Handle, 0, w, h); +end; + +function TSynEditScreenCaretPainterSystem.DestroyCaret: Boolean; +begin + Result := LCLIntf.DestroyCaret(Handle); +end; + +function TSynEditScreenCaretPainterSystem.HideCaret: Boolean; +begin + Result := LCLIntf.HideCaret(Handle); +end; + +function TSynEditScreenCaretPainterSystem.ShowCaret: Boolean; +begin + Result := LCLIntf.ShowCaret(Handle); +end; + +function TSynEditScreenCaretPainterSystem.SetCaretPosEx(x, y: Integer): Boolean; +begin + Result := LCLIntf.SetCaretPosEx(Handle, x, y); +end; + { TSynEditScreenCaret } constructor TSynEditScreenCaret.Create(AHandleOwner: TWinControl); begin inherited Create; + FCaretPainter := TSynEditScreenCaretPainterSystem.Create(AHandleOwner); FLockCount := -1; ResetCaretTypeSizes; FHandleOwner := AHandleOwner; @@ -2243,6 +2425,7 @@ end; destructor TSynEditScreenCaret.Destroy; begin DestroyCaret; + FreeAndNil(FCaretPainter); inherited Destroy; end; @@ -2257,7 +2440,7 @@ begin {$IFDeF SynCaretDebug} debugln(['SynEditCaret DestroyCaret for HandleOwner=',FHandleOwner, ' DebugShowCount=', FDebugShowCount, ' FVisible=', FVisible, ' FCurrentVisible=', FCurrentVisible]); {$ENDIF} - LCLIntf.DestroyCaret(Handle); + FCaretPainter.DestroyCaret; end; FCurrentCreated := False; FCurrentVisible := False; @@ -2528,9 +2711,9 @@ begin FDebugShowCount := 0; {$ENDIF} //if FCurrentCreated then - // LCLIntf.DestroyCaret(Handle); + // FCaretPainter.DestroyCaret(Handle); // // Create caret includes destroy - CreateCaret(Handle, 0, w, h); + FCaretPainter.CreateCaret(w, h); FCurrentCreated := True; FCurrentVisible := False; FCurrentClippedWidth := w; @@ -2541,7 +2724,7 @@ begin {$IFDeF SynCaretDebug} debugln(['SynEditCaret SetPos for HandleOwner=',FHandleOwner, ' x=', x, ' y=',y]); {$ENDIF} - SetCaretPosEx(Handle, x, y); + FCaretPainter.SetCaretPosEx(x, y); FCurrentPosX := x; FCurrentPosY := y; end; @@ -2550,7 +2733,7 @@ begin debugln(['SynEditCaret ShowCaret for HandleOwner=',FHandleOwner, ' FDebugShowCount=',FDebugShowCount, ' FVisible=', FVisible, ' FCurrentVisible=', FCurrentVisible]); inc(FDebugShowCount); {$ENDIF} - if LCLIntf.ShowCaret(Handle) then + if FCaretPainter.ShowCaret then FCurrentVisible := True else begin {$IFDeF SynCaretDebug} @@ -2571,7 +2754,7 @@ begin debugln(['SynEditCaret HideCaret for HandleOwner=',FHandleOwner, ' FDebugShowCount=',FDebugShowCount, ' FVisible=', FVisible, ' FCurrentVisible=', FCurrentVisible]); dec(FDebugShowCount); {$ENDIF} - if LCLIntf.HideCaret(Handle) then + if FCaretPainter.HideCaret then FCurrentVisible := False else begin {$IFDeF SynCaretDebug}