mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00

* Merge with heidi related changes (basically only SingleLineMode) * Readd missing file changelog.htm to keep that file list consistent with the downloaded one * Merge our own compiler detection again * Disable including a further compiler includefile jedi.inc
722 lines
18 KiB
ObjectPascal
722 lines
18 KiB
ObjectPascal
{-------------------------------------------------------------------------------
|
|
The contents of this file are subject to the Mozilla Public License
|
|
Version 1.1 (the "License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
http://www.mozilla.org/MPL/
|
|
|
|
Software distributed under the License is distributed on an "AS IS" basis,
|
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
|
the specific language governing rights and limitations under the License.
|
|
|
|
The Original Code is: SynEdit.pas, released 2000-04-07.
|
|
The Original Code is based on mwCustomEdit.pas by Martin Waldenburg, part of
|
|
the mwEdit component suite.
|
|
Portions created by Martin Waldenburg are Copyright (C) 1998 Martin Waldenburg.
|
|
All Rights Reserved.
|
|
|
|
Contributors to the SynEdit and mwEdit projects are listed in the
|
|
Contributors.txt file.
|
|
|
|
Alternatively, the contents of this file may be used under the terms of the
|
|
GNU General Public License Version 2 or later (the "GPL"), in which case
|
|
the provisions of the GPL are applicable instead of those above.
|
|
If you wish to allow use of your version of this file only under the terms
|
|
of the GPL and not to allow others to use your version of this file
|
|
under the MPL, indicate your decision by deleting the provisions above and
|
|
replace them with the notice and other provisions required by the GPL.
|
|
If you do not delete the provisions above, a recipient may use your version
|
|
of this file under either the MPL or the GPL.
|
|
|
|
$Id: kTextDrawer.pas,v 1.10.2.3 2008/09/14 16:25:03 maelh Exp $
|
|
|
|
You may retrieve the latest version of this file at the SynEdit home page,
|
|
located at http://SynEdit.SourceForge.net
|
|
|
|
Known Issues:
|
|
-------------------------------------------------------------------------------}
|
|
unit kTextDrawer;
|
|
|
|
{$I SynEdit.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Types,
|
|
Qt,
|
|
QGraphics,
|
|
QForms,
|
|
QControls,
|
|
Classes,
|
|
QStdCtrls;
|
|
|
|
const
|
|
ETO_OPAQUE = 1;
|
|
ETO_CLIPPED = 2;
|
|
|
|
CYHSCROLL = 16;
|
|
CXVSCROLL = 16;
|
|
MaxShortInt = High(ShortInt);
|
|
|
|
// system metics
|
|
SM_CXDRAG = 1;
|
|
SM_CYDRAG = 2;
|
|
|
|
type
|
|
UINT = DWORD;
|
|
|
|
// this is to get around some weirdness with the Kylix font code
|
|
// where the style given by the font object isn't correct
|
|
TFontHolder = class
|
|
style: TFontStyles;
|
|
font: TFont;
|
|
|
|
constructor Create(aFont: TFont; aStyle: TFontStyles);
|
|
end;
|
|
|
|
TheTextDrawer = class(TObject)
|
|
private
|
|
// Font information
|
|
fBaseFont: TFont;
|
|
|
|
// current font and properties
|
|
fCurrentStyle: TFontStyles;
|
|
fCurrentFont: TFont;
|
|
fCurrentColor: TColor;
|
|
|
|
// current font attributes
|
|
FBkColor: TColor;
|
|
fCharWidth: integer;
|
|
fCharHeight: integer;
|
|
fakeBold: boolean; // true if the font can't be bold
|
|
|
|
// Begin/EndDrawing calling count
|
|
FDrawingCount: Integer;
|
|
fCanvas: TCanvas;
|
|
|
|
fFontList: TList;
|
|
function GetFont(Index: integer): TFont;
|
|
function GetFontCount: integer;
|
|
function GetFontStyle(Index: integer): TFontStyles;
|
|
function FindFont(aStyle: TFontStyles; aColor: TColor): TFont;
|
|
|
|
property Fonts[Index: integer]: TFont read getFont;
|
|
property FontCount: integer read getFontCount;
|
|
property FontStyle[Index: integer]: TFontStyles read GetFontStyle;
|
|
protected
|
|
procedure UpdateCurrentFont;
|
|
procedure UpdateFontMetrics;
|
|
procedure ClearFontList;
|
|
public
|
|
constructor Create(CalcExtentBaseStyle: TFontStyles; ABaseFont: TFont); virtual;
|
|
destructor Destroy; override;
|
|
function GetCharWidth: Integer; virtual;
|
|
function GetCharHeight: Integer; virtual;
|
|
procedure BeginDrawing(ACanvas : TCanvas); overload; virtual;
|
|
|
|
procedure EndDrawing; virtual;
|
|
procedure TextOut(X, Y: Integer; Text: PWideChar; Length: Integer); virtual;
|
|
procedure ExtTextOut(X, Y: Integer; fuOptions: UINT; const ARect: TRect;
|
|
Text: PWideChar; Length: Integer); virtual;
|
|
procedure SetBaseFont(Value: TFont); virtual;
|
|
procedure SetBaseStyle(const Value: TFontStyles); virtual;
|
|
procedure SetStyle(Value: TFontStyles); virtual;
|
|
procedure SetForeColor(Value: TColor); virtual;
|
|
procedure SetBackColor(Value: TColor); virtual;
|
|
procedure SetCharExtra(Value: Integer); virtual;
|
|
property CharWidth: Integer read GetCharWidth;
|
|
property CharHeight: Integer read GetCharHeight;
|
|
property BaseFont: TFont write SetBaseFont;
|
|
property BaseStyle: TFontStyles write SetBaseStyle;
|
|
property ForeColor: TColor write SetForeColor;
|
|
property BackColor: TColor write SetBackColor;
|
|
property Style: TFontStyles write SetStyle;
|
|
end;
|
|
|
|
TCaret = class(TComponent)
|
|
private
|
|
FActive: Boolean;
|
|
FRect: TRect;
|
|
FInternalShowCount: Integer;
|
|
FOwnerCanvas: TControlCanvas;
|
|
FShowCount: Integer;
|
|
procedure ForceInternalInvisible;
|
|
procedure ForceInternalVisible;
|
|
function GetTopLeft: TPoint;
|
|
procedure Paint;
|
|
procedure SetTopLeft(const Value: TPoint);
|
|
procedure InternalHide;
|
|
procedure InternalShow;
|
|
function Visible: Boolean;
|
|
public
|
|
constructor Create(AOwner: TWidgetControl; Width, Height: Integer); reintroduce;
|
|
destructor Destroy; override;
|
|
procedure Hide;
|
|
procedure Show;
|
|
procedure Toggle;
|
|
property Active: Boolean read FActive;
|
|
property OwnerCanvas: TControlCanvas read FOwnerCanvas;
|
|
property TopLeft: TPoint read GetTopLeft write SetTopLeft;
|
|
end;
|
|
|
|
TSynEditScrollBar = class(TScrollBar)
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
end;
|
|
|
|
procedure InternalFillRect(Canvas: TCanvas; rect: TRect);
|
|
function GetSystemMetrics(Metric: Integer): Integer;
|
|
|
|
procedure CreateCaret(Control: TWidgetControl; dummy, Width, Height: Integer);
|
|
procedure SetCaretPos(X, Y: Integer);
|
|
procedure ShowCaret(Control: TWidgetControl);
|
|
procedure HideCaret(Control: TWidgetControl);
|
|
procedure DestroyCaret;
|
|
procedure ScrollWindow(Control: TWidgetControl; DeltaX, DeltaY: Integer; Rect: PRect);
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF SYN_KYLIX}
|
|
libc,
|
|
{$ENDIF}
|
|
QExtCtrls;
|
|
|
|
type
|
|
TCaretManager = class
|
|
private
|
|
fBlinkTimer: TTimer;
|
|
fCurrentCaret: TCaret;
|
|
procedure HandleTimer(Sender : TObject);
|
|
procedure SetCurrentCaret(const Value: TCaret);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure ResetTimer;
|
|
property CurrentCaret: TCaret read fCurrentCaret write SetCurrentCaret;
|
|
end;
|
|
|
|
var
|
|
CaretManager: TCaretManager;
|
|
|
|
function FindCaret(Control: TWidgetControl): TCaret;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := nil;
|
|
|
|
for i := 0 to Control.ComponentCount - 1 do
|
|
if Control.Components[i] is TCaret then
|
|
begin
|
|
Result := TCaret(Control.Components[i]);
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
procedure CreateCaret(Control: TWidgetControl; dummy, Width, Height: Integer);
|
|
var
|
|
Caret: TCaret;
|
|
begin
|
|
Caret := FindCaret(Control);
|
|
if Assigned(Caret) then
|
|
Caret.Free;
|
|
Caret := TCaret.Create(Control, Width, Height);
|
|
|
|
CaretManager.CurrentCaret := Caret;
|
|
end;
|
|
|
|
procedure DestroyCaret;
|
|
begin
|
|
if CaretManager.CurrentCaret <> nil then
|
|
begin
|
|
CaretManager.CurrentCaret.Free;
|
|
CaretManager.CurrentCaret := nil;
|
|
end;
|
|
end;
|
|
|
|
procedure ScrollWindow(Control: TWidgetControl; DeltaX, DeltaY: Integer; Rect: PRect);
|
|
var
|
|
Caret: TCaret;
|
|
NewTopLeft: TPoint;
|
|
CaretWasActive: Boolean;
|
|
begin
|
|
Caret := FindCaret(Control);
|
|
CaretWasActive := False;
|
|
if Assigned(Caret) then
|
|
begin
|
|
CaretWasActive := Caret.Active;
|
|
if CaretWasActive then Caret.Hide;
|
|
NewTopLeft := Point(Caret.TopLeft.X + DeltaX, Caret.TopLeft.Y + DeltaY);
|
|
if NewTopLeft.X < Rect.Left then
|
|
NewTopLeft.X := -Caret.FRect.Left - 1;
|
|
if NewTopLeft.Y < Rect.Top then
|
|
NewTopLeft.Y := -Caret.FRect.Bottom - 1;
|
|
Caret.TopLeft := NewTopLeft;
|
|
end;
|
|
QWidget_Scroll(Control.Handle, DeltaX, DeltaY, Rect);
|
|
if Assigned(Caret) and CaretWasActive then Caret.Show;
|
|
end;
|
|
|
|
procedure SetCaretPos(X, Y: Integer);
|
|
var
|
|
Caret: TCaret;
|
|
begin
|
|
Caret := CaretManager.CurrentCaret;
|
|
if Assigned(Caret) then
|
|
Caret.TopLeft := Point(X, Y);
|
|
end;
|
|
|
|
procedure ShowCaret(Control: TWidgetControl);
|
|
var
|
|
Caret: TCaret;
|
|
begin
|
|
Caret := FindCaret(Control);
|
|
if Assigned(Caret) then
|
|
Caret.Show;
|
|
end;
|
|
|
|
procedure HideCaret(Control: TWidgetControl);
|
|
var
|
|
Caret: TCaret;
|
|
begin
|
|
Caret := FindCaret(Control);
|
|
if Assigned(Caret) then
|
|
Caret.Hide;
|
|
end;
|
|
|
|
procedure InternalFillRect(canvas: TCanvas; rect: TRect);
|
|
begin
|
|
canvas.FillRect(rect);
|
|
end;
|
|
|
|
function GetSystemMetrics(metric: integer): integer;
|
|
begin
|
|
case metric of
|
|
SM_CXDRAG: result := 2;
|
|
SM_CYDRAG: result := 2;
|
|
else
|
|
result := -1;
|
|
end;
|
|
end;
|
|
|
|
{ TheTextDrawer }
|
|
|
|
procedure TheTextDrawer.BeginDrawing(ACanvas: TCanvas);
|
|
begin
|
|
if fDrawingCount = 0 then
|
|
begin
|
|
UpdateCurrentFont;
|
|
fCanvas := ACanvas;
|
|
fCanvas.Font := fCurrentFont;
|
|
|
|
fCanvas.Brush.Color := FBkColor;
|
|
end;
|
|
|
|
inc(FDrawingCount);
|
|
end;
|
|
|
|
procedure TheTextDrawer.ClearFontList;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to FontCount - 1 do
|
|
begin
|
|
Fonts[i].Free;
|
|
TFontHolder(fFontList[i]).Free;
|
|
end;
|
|
|
|
fFontList.Clear;
|
|
end;
|
|
|
|
constructor TheTextDrawer.Create(CalcExtentBaseStyle: TFontStyles; ABaseFont: TFont);
|
|
begin
|
|
fBaseFont := TFont.Create;
|
|
fFontList := TList.Create;
|
|
|
|
BaseFont := ABaseFont;
|
|
BaseStyle := CalcExtentBaseStyle;
|
|
end;
|
|
|
|
destructor TheTextDrawer.Destroy;
|
|
begin
|
|
fBaseFont.Free;
|
|
ClearFontList;
|
|
fFontList.Free;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TheTextDrawer.EndDrawing;
|
|
begin
|
|
if FDrawingCount > 0 then
|
|
dec(FDrawingCount);
|
|
|
|
if FDrawingCount = 0 then
|
|
fCanvas := nil;
|
|
end;
|
|
|
|
procedure TheTextDrawer.ExtTextOut(X, Y: Integer; fuOptions: UINT;
|
|
const ARect: TRect; Text: PWideChar; Length: Integer);
|
|
begin
|
|
if fCanvas <> nil then
|
|
begin
|
|
// fCanvas.Brush.Color := random($ffffff);
|
|
fCanvas.Brush.Style := bsSolid;
|
|
fCanvas.FillRect(ARect);
|
|
|
|
if Text <> nil then
|
|
begin
|
|
if Length = -1 then
|
|
fCanvas.TextRect(ARect, X, Y, Text)
|
|
else
|
|
fCanvas.TextRect(ARect, X, Y, copy(Text, 1, Length));
|
|
|
|
if fakeBold then
|
|
if Length = -1 then
|
|
fCanvas.TextRect(ARect, X + 1, Y, Text)
|
|
else
|
|
fCanvas.TextRect(ARect, X + 1, Y, copy(Text, 1, Length));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TheTextDrawer.FindFont(aStyle: TFontStyles; aColor: TColor): TFont;
|
|
var
|
|
i: integer;
|
|
begin
|
|
Result := nil;
|
|
|
|
for i := 0 to FontCount - 1 do
|
|
if (FontStyle[i] = aStyle) and (Fonts[i].Color = aColor) then
|
|
begin
|
|
Result := Fonts[i];
|
|
break;
|
|
end;
|
|
|
|
if Result = nil then
|
|
begin
|
|
Result := TFont.Create;
|
|
Result.Assign(fBaseFont);
|
|
Result.Style := aStyle;
|
|
Result.Color := aColor;
|
|
fFontList.Add(TFontHolder.Create(Result, aStyle));
|
|
end;
|
|
end;
|
|
|
|
function TheTextDrawer.GetCharHeight: Integer;
|
|
begin
|
|
Result := fCharHeight;
|
|
end;
|
|
|
|
function TheTextDrawer.GetCharWidth: Integer;
|
|
begin
|
|
Result := fCharWidth;
|
|
end;
|
|
|
|
function TheTextDrawer.GetFont(Index: integer): TFont;
|
|
begin
|
|
Result := TFontHolder(fFontList[Index]).font;
|
|
end;
|
|
|
|
function TheTextDrawer.GetFontCount: integer;
|
|
begin
|
|
Result := fFontList.Count;
|
|
end;
|
|
|
|
function TheTextDrawer.GetFontStyle(Index: integer): TFontStyles;
|
|
begin
|
|
Result := TFontHolder(fFontList[Index]).style;
|
|
end;
|
|
|
|
procedure TheTextDrawer.SetBackColor(Value: TColor);
|
|
begin
|
|
if FBkColor <> Value then
|
|
begin
|
|
FBkColor := Value;
|
|
|
|
if fCanvas <> nil then
|
|
fCanvas.Brush.Color := Value;
|
|
end;
|
|
end;
|
|
|
|
procedure TheTextDrawer.SetBaseFont(Value: TFont);
|
|
begin
|
|
if Value <> nil then
|
|
begin
|
|
fBaseFont.Assign(Value);
|
|
UpdateFontMetrics;
|
|
UpdateCurrentFont;
|
|
end;
|
|
end;
|
|
|
|
procedure TheTextDrawer.SetBaseStyle(const Value: TFontStyles);
|
|
begin
|
|
fBaseFont.Style := Value;
|
|
UpdateFontMetrics;
|
|
end;
|
|
|
|
procedure TheTextDrawer.SetCharExtra(Value: Integer);
|
|
begin
|
|
// do nothing
|
|
end;
|
|
|
|
procedure TheTextDrawer.SetForeColor(Value: TColor);
|
|
begin
|
|
fCurrentColor := Value;
|
|
UpdateCurrentFont;
|
|
end;
|
|
|
|
procedure TheTextDrawer.SetStyle(Value: TFontStyles);
|
|
begin
|
|
fCurrentStyle := Value;
|
|
UpdateCurrentFont;
|
|
end;
|
|
|
|
procedure TheTextDrawer.TextOut(X, Y: Integer; Text: PWideChar;
|
|
Length: Integer);
|
|
begin
|
|
if fCanvas <> nil then
|
|
begin
|
|
fCanvas.Brush.Style := bsSolid;
|
|
|
|
if Text <> nil then
|
|
begin
|
|
if Length = -1 then
|
|
fCanvas.TextOut(X, Y, Text)
|
|
else
|
|
fCanvas.TextOut(X, Y, copy(Text, 1, Length));
|
|
|
|
|
|
if fakeBold then
|
|
if Length = -1 then
|
|
fCanvas.TextOut(X + 1, Y, Text)
|
|
else
|
|
fCanvas.TextOut(X + 1, Y, copy(Text, 1, Length));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TheTextDrawer.UpdateCurrentFont;
|
|
begin
|
|
fCurrentFont := FindFont(fCurrentStyle, fCurrentColor);
|
|
QFont_setFixedPitch(fCurrentFont.Handle, True);
|
|
|
|
if fCanvas <> nil then
|
|
fCanvas.Font.Assign(fCurrentFont);
|
|
|
|
// Make sure that we can draw bold text even if the current font
|
|
// doesn't want to do it
|
|
fakeBold := (fsBold in fCurrentStyle) and not (fsBold in fCurrentFont.Style);
|
|
end;
|
|
|
|
procedure TheTextDrawer.UpdateFontMetrics;
|
|
var
|
|
fm: QFontMetricsH;
|
|
ch: WideChar;
|
|
w: Integer;
|
|
fi: QFontInfoH;
|
|
family: UnicodeString;
|
|
begin
|
|
fi := QFontInfo_create(fBaseFont.Handle);
|
|
try
|
|
// make sure that the font object is refering to the same
|
|
// font that Qt is actually using, otherwise the width functions
|
|
// don't seem to work properly :(
|
|
if not QFontInfo_exactMatch(fi) then
|
|
begin
|
|
fBaseFont.Size := QFontInfo_pointSize(fi);
|
|
QFontInfo_family(fi, @family);
|
|
fBaseFont.Name := family;
|
|
end;
|
|
finally
|
|
QFontInfo_destroy(fi);
|
|
end;
|
|
|
|
fm := QFontMetrics_create(fBaseFont.Handle);
|
|
try
|
|
ch := 'W';
|
|
|
|
w := QFontMetrics_width(fm, @ch);
|
|
fCharWidth := w;
|
|
fCharHeight := QFontMetrics_height(fm);
|
|
finally
|
|
QFontMetrics_destroy(fm);
|
|
end;
|
|
|
|
ClearFontList;
|
|
end;
|
|
|
|
{ TCaret }
|
|
|
|
constructor TCaret.Create(AOwner: TWidgetControl; Width, Height: Integer);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FRect.Right := Width;
|
|
FRect.Bottom := Height;
|
|
FOwnerCanvas := TControlCanvas.Create;
|
|
TControlCanvas(FOwnerCanvas).Control := AOwner;
|
|
end;
|
|
|
|
destructor TCaret.Destroy;
|
|
begin
|
|
if CaretManager.CurrentCaret = Self then
|
|
CaretManager.CurrentCaret := nil;
|
|
FActive := False;
|
|
ForceInternalInvisible;
|
|
inherited Destroy;
|
|
FOwnerCanvas.Free;
|
|
end;
|
|
|
|
procedure TCaret.ForceInternalInvisible;
|
|
begin
|
|
while FInternalShowCount >= 1 do InternalHide;
|
|
end;
|
|
|
|
procedure TCaret.ForceInternalVisible;
|
|
begin
|
|
while FInternalShowCount <= 0 do InternalShow;
|
|
end;
|
|
|
|
function TCaret.GetTopLeft: TPoint;
|
|
begin
|
|
Result := FRect.TopLeft;
|
|
end;
|
|
|
|
procedure TCaret.Hide;
|
|
begin
|
|
dec(FShowCount);
|
|
if FShowCount = 0 then
|
|
begin
|
|
FActive := False;
|
|
ForceInternalInvisible;
|
|
end;
|
|
end;
|
|
|
|
procedure TCaret.InternalHide;
|
|
begin
|
|
dec(FInternalShowCount);
|
|
if FInternalShowCount = 0 then
|
|
Paint;
|
|
end;
|
|
|
|
procedure TCaret.InternalShow;
|
|
begin
|
|
inc(FInternalShowCount);
|
|
if FInternalShowCount = 1 then
|
|
Paint;
|
|
end;
|
|
|
|
procedure TCaret.Paint;
|
|
var
|
|
OldCopyMode: TCopyMode;
|
|
begin
|
|
if Assigned(Owner)then
|
|
with OwnerCanvas do
|
|
begin
|
|
OldCopyMode := CopyMode;
|
|
CopyMode := cmDstInvert;
|
|
CopyRect(FRect, OwnerCanvas, FRect);
|
|
CopyMode := OldCopyMode;
|
|
end;
|
|
end;
|
|
|
|
procedure TCaret.SetTopLeft(const Value: TPoint);
|
|
begin
|
|
if (FRect.Left = Value.X) and (FRect.Top = Value.Y) then exit;
|
|
|
|
if FActive then InternalHide;
|
|
FRect.Right := FRect.Right + (Value.X - FRect.Left);
|
|
FRect.Left := Value.X;
|
|
FRect.Bottom := FRect.Bottom + (Value.Y - FRect.Top);
|
|
FRect.Top := Value.Y;
|
|
if FActive then
|
|
begin
|
|
ForceInternalVisible;
|
|
CaretManager.ResetTimer;
|
|
end;
|
|
end;
|
|
|
|
procedure TCaret.Show;
|
|
begin
|
|
if FShowCount < 1 then
|
|
begin
|
|
inc(FShowCount);
|
|
if FShowCount = 1 then
|
|
begin
|
|
FActive := True;
|
|
ForceInternalVisible;
|
|
CaretManager.ResetTimer;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TCaret.Toggle;
|
|
begin
|
|
if Active then
|
|
if Visible then InternalHide else InternalShow;
|
|
end;
|
|
|
|
function TCaret.Visible: Boolean;
|
|
begin
|
|
Result := FInternalShowCount > 0;
|
|
end;
|
|
|
|
{ TFontHolder }
|
|
|
|
constructor TFontHolder.Create(aFont: TFont; aStyle: TFontStyles);
|
|
begin
|
|
Font := aFont;
|
|
Style:= aStyle;
|
|
end;
|
|
|
|
{ TCaretManager }
|
|
|
|
constructor TCaretManager.Create;
|
|
begin
|
|
fBlinkTimer := TTimer.Create(nil);
|
|
fBlinkTimer.Enabled := False;
|
|
fBlinkTimer.Interval := QApplication_cursorFlashTime div 2;
|
|
fBlinkTimer.OnTimer := HandleTimer;
|
|
end;
|
|
|
|
destructor TCaretManager.Destroy;
|
|
begin
|
|
fBlinkTimer.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TCaretManager.HandleTimer(Sender: TObject);
|
|
begin
|
|
if Assigned(CurrentCaret) then
|
|
CurrentCaret.Toggle;
|
|
end;
|
|
|
|
procedure TCaretManager.ResetTimer;
|
|
begin
|
|
fBlinkTimer.Enabled := False;
|
|
fBlinkTimer.Enabled := True;
|
|
end;
|
|
|
|
procedure TCaretManager.SetCurrentCaret(const Value: TCaret);
|
|
begin
|
|
if fCurrentCaret <> Value then
|
|
begin
|
|
fCurrentCaret := Value;
|
|
fBlinkTimer.Enabled := (CurrentCaret <> nil) and CurrentCaret.Active;
|
|
end;
|
|
end;
|
|
|
|
{ TSynEditScrollBar }
|
|
|
|
constructor TSynEditScrollBar.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
ControlStyle := ControlStyle + [csNoFocus];
|
|
TabStop := False;
|
|
Visible := False;
|
|
end;
|
|
|
|
initialization
|
|
CaretManager := TCaretManager.Create;
|
|
finalization
|
|
CaretManager.Free;
|
|
end. |