callite: Refactor drawing routines to avoid flicker.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6950 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2019-05-26 13:05:38 +00:00
parent fe9d27d72c
commit 5e2c0d3122
5 changed files with 127 additions and 37 deletions

View File

@ -1,15 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<Version Value="11"/> <Version Value="12"/>
<PathDelim Value="\"/> <PathDelim Value="\"/>
<General> <General>
<Flags>
<CompatibilityMode Value="True"/>
</Flags>
<SessionStorage Value="InProjectDir"/> <SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="testCalLite"/> <Title Value="testCalLite"/>
<Scaled Value="True"/>
<UseAppBundle Value="False"/> <UseAppBundle Value="False"/>
<ResourceType Value="res"/> <ResourceType Value="res"/>
<UseXPManifest Value="True"/> <UseXPManifest Value="True"/>
<XPManifest>
<DpiAware Value="True"/>
</XPManifest>
</General> </General>
<i18n> <i18n>
<EnableI18N LFM="False"/> <EnableI18N LFM="False"/>

View File

@ -9,6 +9,7 @@ uses
begin begin
RequireDerivedFormResource := True; RequireDerivedFormResource := True;
Application.Scaled:=True;
Application.Initialize; Application.Initialize;
Application.CreateForm(TForm1, Form1); Application.CreateForm(TForm1, Form1);
Application.Run; Application.Run;

View File

@ -1,10 +1,10 @@
object Form1: TForm1 object Form1: TForm1
Left = 700 Left = 700
Height = 845 Height = 746
Top = 122 Top = 122
Width = 851 Width = 851
Caption = 'Examples of the TCalendaLite component' Caption = 'Examples of the TCalendaLite component'
ClientHeight = 845 ClientHeight = 746
ClientWidth = 851 ClientWidth = 851
Color = clWindow Color = clWindow
Font.CharSet = ANSI_CHARSET Font.CharSet = ANSI_CHARSET
@ -12,16 +12,16 @@ object Form1: TForm1
LCLVersion = '2.1.0.0' LCLVersion = '2.1.0.0'
object PSettings: TPanel object PSettings: TPanel
Left = 0 Left = 0
Height = 448 Height = 432
Top = 0 Top = 0
Width = 851 Width = 851
Align = alTop Align = alTop
ClientHeight = 448 ClientHeight = 432
ClientWidth = 851 ClientWidth = 851
TabOrder = 0 TabOrder = 0
object cgOptions: TCheckGroup object cgOptions: TCheckGroup
Left = 24 Left = 24
Height = 392 Height = 384
Top = 40 Top = 40
Width = 160 Width = 160
AutoFill = True AutoFill = True
@ -34,7 +34,7 @@ object Form1: TForm1
ChildSizing.ShrinkVertical = crsScaleChilds ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1 ChildSizing.ControlsPerLine = 1
ClientHeight = 372 ClientHeight = 364
ClientWidth = 156 ClientWidth = 156
Items.Strings = ( Items.Strings = (
'coBoldDayNames' 'coBoldDayNames'
@ -118,7 +118,7 @@ object Form1: TForm1
object rgLanguage: TRadioGroup object rgLanguage: TRadioGroup
Left = 200 Left = 200
Height = 216 Height = 216
Top = 216 Top = 208
Width = 160 Width = 160
AutoFill = True AutoFill = True
Caption = 'Language to use' Caption = 'Language to use'
@ -149,7 +149,7 @@ object Form1: TForm1
end end
object rgStartingDOW: TRadioGroup object rgStartingDOW: TRadioGroup
Left = 200 Left = 200
Height = 168 Height = 160
Top = 40 Top = 40
Width = 160 Width = 160
AutoFill = True AutoFill = True
@ -161,7 +161,7 @@ object Form1: TForm1
ChildSizing.ShrinkVertical = crsScaleChilds ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1 ChildSizing.ControlsPerLine = 1
ClientHeight = 148 ClientHeight = 140
ClientWidth = 156 ClientWidth = 156
Items.Strings = ( Items.Strings = (
'Sunday' 'Sunday'
@ -177,11 +177,11 @@ object Form1: TForm1
end end
object GroupBox1: TGroupBox object GroupBox1: TGroupBox
Left = 376 Left = 376
Height = 392 Height = 384
Top = 40 Top = 40
Width = 160 Width = 160
Caption = 'Colors' Caption = 'Colors'
ClientHeight = 372 ClientHeight = 364
ClientWidth = 156 ClientWidth = 156
TabOrder = 6 TabOrder = 6
object CbArrowBorder: TColorButton object CbArrowBorder: TColorButton
@ -490,7 +490,7 @@ object Form1: TForm1
end end
object SelDateListbox: TListBox object SelDateListbox: TListBox
Left = 560 Left = 560
Height = 152 Height = 120
Top = 280 Top = 280
Width = 274 Width = 274
Columns = 3 Columns = 3
@ -632,15 +632,15 @@ object Form1: TForm1
} }
OnClick = sbResetButtonHeightClick OnClick = sbResetButtonHeightClick
end end
end
object Label1: TLabel object Label1: TLabel
Left = 15 Left = 562
Height = 15 Height = 15
Top = 818 Top = 408
Width = 34 Width = 34
Caption = 'Label1' Caption = 'Label1'
ParentColor = False ParentColor = False
end end
end
object FontDialog: TFontDialog object FontDialog: TFontDialog
MinFontSize = 0 MinFontSize = 0
MaxFontSize = 0 MaxFontSize = 0

View File

@ -216,8 +216,6 @@ begin
copyCal.Languages := demoCal.Languages; copyCal.Languages := demoCal.Languages;
exit; exit;
if demoCal.Languages = lgCustom then begin if demoCal.Languages = lgCustom then begin
demoCal.DayNames := 'S,M,T,W,T,F,S'; demoCal.DayNames := 'S,M,T,W,T,F,S';
demoCal.MonthNames := 'Ja,Fe,Mr,Ap,Ma,Jn,Jl,Au,Sp,Oc,Nv,Dc'; demoCal.MonthNames := 'Ja,Fe,Mr,Ap,Ma,Jn,Jl,Au,Sp,Oc,Nv,Dc';

View File

@ -41,7 +41,7 @@ unit CalendarLite;
interface interface
uses uses
Classes, SysUtils, LResources, LCLVersion, Classes, SysUtils, LResources, LCLVersion, LMessages,
Forms, Controls, Graphics, Dialogs, Types, ExtCtrls, Menus; Forms, Controls, Graphics, Dialogs, Types, ExtCtrls, Menus;
{$if lcl_fullversion >= 1080000} {$if lcl_fullversion >= 1080000}
@ -129,6 +129,7 @@ type
TCalDrawer = class TCalDrawer = class
private private
FBoundsRect: TRect; FBoundsRect: TRect;
FBuffer: TBitmap;
FCanvas: TCanvas; FCanvas: TCanvas;
FCellSize: TSize; FCellSize: TSize;
FColPositions: TColArray; FColPositions: TColArray;
@ -141,6 +142,7 @@ type
FTextStyle: TTextStyle; FTextStyle: TTextStyle;
procedure CalcSettings; procedure CalcSettings;
procedure DrawArrow(ARect: TRect; AHead: TArrowhead; ADirec: TArrowDirection); procedure DrawArrow(ARect: TRect; AHead: TArrowhead; ADirec: TArrowDirection);
procedure DrawBackground;
procedure DrawDayCells; procedure DrawDayCells;
procedure DrawDayLabels; procedure DrawDayLabels;
procedure DrawTodayRow; procedure DrawTodayRow;
@ -158,9 +160,12 @@ type
procedure GotoYear(AYear: word); procedure GotoYear(AYear: word);
procedure LeftClick(APoint: TPoint; Shift: TShiftState); procedure LeftClick(APoint: TPoint; Shift: TShiftState);
procedure RightClick; procedure RightClick;
procedure SetBoundsRect(ARect: TRect);
public public
constructor Create(ACanvas: TCanvas); constructor Create(AOwner: TCalendarLite);
procedure Draw; procedure Draw;
property BoundsRect: TRect read FBoundsRect write SetBoundsRect;
property Buffer: TBitmap read FBuffer;
end; end;
@ -195,6 +200,7 @@ type
TCalendarLite = class(TCustomControl) TCalendarLite = class(TCustomControl)
private private
FBufferValid: Boolean;
FCalDrawer: TCalDrawer; FCalDrawer: TCalDrawer;
FColors: TCalColors; FColors: TCalColors;
FDate: TDateTime; FDate: TDateTime;
@ -270,8 +276,13 @@ type
procedure MouseLeave; override; procedure MouseLeave; override;
procedure MouseMove(Shift: TShiftState; X,Y: Integer); override; procedure MouseMove(Shift: TShiftState; X,Y: Integer); override;
function SelMode(Shift: TShiftState): TCalSelMode; function SelMode(Shift: TShiftState): TCalSelMode;
procedure SetBiDiMode(AValue: TBiDiMode); override;
procedure SetParentBiDiMode(AValue: Boolean); override;
procedure Paint; override; procedure Paint; override;
procedure Resize; override;
procedure UpdateBiDiMode;
procedure UpdateBuffer;
procedure UseDayName(ADayOfWeek: TDayOfWeek; const AValue: String); procedure UseDayName(ADayOfWeek: TDayOfWeek; const AValue: String);
procedure UseDayNames(const AValue: String); procedure UseDayNames(const AValue: String);
procedure UseDisplayTexts(const AValue: String); procedure UseDisplayTexts(const AValue: String);
@ -281,7 +292,6 @@ type
{ Hints } { Hints }
procedure ShowHintWindow(APoint: TPoint; ADate: TDate); procedure ShowHintWindow(APoint: TPoint; ADate: TDate);
procedure HideHintWindow; procedure HideHintWindow;
public public
constructor Create(anOwner: TComponent); override; constructor Create(anOwner: TComponent); override;
destructor Destroy; override; destructor Destroy; override;
@ -661,10 +671,12 @@ end;
{ TCalDrawer } { TCalDrawer }
constructor TCalDrawer.Create(ACanvas: TCanvas); constructor TCalDrawer.Create(AOwner: TCalendarLite);
begin begin
inherited Create; inherited Create;
FCanvas:= ACanvas; FBuffer := TBitmap.Create;
FOwner := AOwner;
FCanvas := FBuffer.Canvas;
FTextStyle:= DefTextStyle; FTextStyle:= DefTextStyle;
end; end;
@ -735,6 +747,7 @@ begin
if not Assigned(FCanvas) then Exit; if not Assigned(FCanvas) then Exit;
DecodeDate(FOwner.FDate, FThisYear, FThisMonth, FThisDay); DecodeDate(FOwner.FDate, FThisYear, FThisMonth, FThisDay);
CalcSettings; CalcSettings;
DrawBackground;
DrawTopRow; DrawTopRow;
DrawDayLabels; DrawDayLabels;
DrawTodayRow; DrawTodayRow;
@ -813,6 +826,18 @@ begin
end; end;
end; end;
procedure TCalDrawer.DrawBackground;
begin
FBuffer.Canvas.Brush.Color := FOwner.Colors.BackgroundColor;
if (coShowBorder in FOwner.Options) then
begin
FCanvas.Pen.Color := FOwner.FColors.BorderColor;
FCanvas.Pen.Style := psSolid;
FCanvas.Rectangle(0, 0, FBuffer.Width, FBuffer.Height);
end else
FBuffer.Canvas.FillRect(0, 0, FBuffer.Width, FBuffer.Height);
end;
procedure TCalDrawer.DrawDayCells; procedure TCalDrawer.DrawDayCells;
var var
remDays: integer = 0; remDays: integer = 0;
@ -1337,6 +1362,14 @@ begin
end; end;
end; end;
procedure TCalDrawer.SetBoundsRect(ARect: TRect);
begin
if FBoundsRect = ARect then exit;
FBoundsRect := ARect;
FBuffer.SetSize(FBoundsRect.Width, FBoundsRect.Height);
Draw;
end;
{ TCalColors } { TCalColors }
@ -1368,6 +1401,7 @@ procedure TCalColors.SetColor(AIndex: Integer; AValue: TColor);
begin begin
if FColors[AIndex] = AValue then exit; if FColors[AIndex] = AValue then exit;
FColors[AIndex] := AValue; FColors[AIndex] := AValue;
FOwner.FBufferValid := false;
FOwner.Invalidate; FOwner.Invalidate;
end; end;
@ -1380,7 +1414,7 @@ begin
FFormatSettings := DefaultFormatSettings; FFormatSettings := DefaultFormatSettings;
FSelDates := TCalDateList.Create; FSelDates := TCalDateList.Create;
FColors := TCalColors.Create(self); FColors := TCalColors.Create(self);
Color := clWhite; //Color := clWhite;
FStartingDayOfWeek:= dowSunday; FStartingDayOfWeek:= dowSunday;
with GetControlClassDefaultSize do with GetControlClassDefaultSize do
SetInitialBounds(0, 0, cx, cy); SetInitialBounds(0, 0, cx, cy);
@ -1391,7 +1425,7 @@ begin
Constraints.MinHeight := ScaleX(DefMinHeight, DESIGNTIME_PPI); Constraints.MinHeight := ScaleX(DefMinHeight, DESIGNTIME_PPI);
Constraints.MinWidth := ScaleY(DefMinWidth, DESIGNTIME_PPI); Constraints.MinWidth := ScaleY(DefMinWidth, DESIGNTIME_PPI);
{$endif} {$endif}
Canvas.Brush.Style := bsSolid; //Canvas.Brush.Style := bsSolid;
TabStop := true; TabStop := true;
SetDefaultDayNames; SetDefaultDayNames;
// FCustomDayNames := GetDayNames; // FCustomDayNames := GetDayNames;
@ -1400,8 +1434,7 @@ begin
SetDefaultDisplayTexts; SetDefaultDisplayTexts;
FCustomDisplayTexts := GetDisplayTexts; FCustomDisplayTexts := GetDisplayTexts;
FPopupMenu := TPopupMenu.Create(Self); FPopupMenu := TPopupMenu.Create(Self);
FCalDrawer := TCalDrawer.Create(Canvas); FCalDrawer := TCalDrawer.Create(Self);
FCalDrawer.FOwner:= Self;
FDblClickTimer := TTimer.Create(self); FDblClickTimer := TTimer.Create(self);
FDblClickTimer.Enabled := false; FDblClickTimer.Enabled := false;
FDblClickTimer.Interval := DBLCLICK_INTERVAL; FDblClickTimer.Interval := DBLCLICK_INTERVAL;
@ -1504,10 +1537,13 @@ begin
if MonthOf(FDate) <> oldMonth then if MonthOf(FDate) <> oldMonth then
MonthChange; MonthChange;
FBufferValid := false;
{
with FCalDrawer do begin with FCalDrawer do begin
FCanvas.Brush.Color := Colors.BackgroundColor; FCanvas.Brush.Color := Colors.BackgroundColor;
FCanvas.FillRect(FBoundsRect); FCanvas.FillRect(FBoundsRect);
end; end;
}
Invalidate; Invalidate;
end; end;
@ -1628,6 +1664,8 @@ begin
mbLeft : FCalDrawer.LeftClick(FClickPoint, FClickShift); mbLeft : FCalDrawer.LeftClick(FClickPoint, FClickShift);
mbRight : FCalDrawer.RightClick; mbRight : FCalDrawer.RightClick;
end; end;
FBufferValid := false;
Invalidate;
end; end;
function TCalendarLite.IsSelected(ADate: TDate): Boolean; function TCalendarLite.IsSelected(ADate: TDate): Boolean;
@ -1737,9 +1775,10 @@ var
begin begin
if Assigned(FCalDrawer) then if Assigned(FCalDrawer) then
begin begin
if ParentColor then if not FBufferValid then
Colors.BackgroundColor := Parent.Color; UpdateBuffer;
Canvas.Draw(0, 0, FCalDrawer.Buffer);
(*
if ParentFont then if ParentFont then
begin begin
if (Parent.Font <> FCalDrawer.FCanvas.Font) if (Parent.Font <> FCalDrawer.FCanvas.Font)
@ -1755,6 +1794,9 @@ begin
FCalDrawer.FTextStyle.RightToLeft := False; FCalDrawer.FTextStyle.RightToLeft := False;
end; end;
if ParentColor then
Canvas.Brush.Color := Parent.Color
else
Canvas.Brush.Color:= Colors.BackGroundColor; Canvas.Brush.Color:= Colors.BackGroundColor;
Canvas.FillRect(ClientRect); Canvas.FillRect(ClientRect);
if (coShowBorder in FOptions) then if (coShowBorder in FOptions) then
@ -1769,11 +1811,25 @@ begin
if (coShowBorder in FOptions) then InflateRect(r, -1, -1); if (coShowBorder in FOptions) then InflateRect(r, -1, -1);
FCalDrawer.FBoundsRect:= r; FCalDrawer.FBoundsRect:= r;
FCalDrawer.Draw; FCalDrawer.Draw;
*)
end; end;
inherited Paint; inherited Paint;
end; end;
procedure TCalendarLite.Resize;
begin
FBufferValid := false;
inherited;
end;
procedure TCalendarLite.UpdateBuffer;
begin
FCalDrawer.BoundsRect:= ClientRect;
FCalDrawer.Draw;
FBufferValid := true;
end;
procedure TCalendarLite.PopulateHolidayPopupMenu; procedure TCalendarLite.PopulateHolidayPopupMenu;
var var
item: TMenuItem; item: TMenuItem;
@ -1879,6 +1935,7 @@ procedure TCalendarLite.SetButtonHeight(const AValue: Integer);
begin begin
if FButtonHeight = AValue then exit; if FButtonHeight = AValue then exit;
FButtonHeight := AValue; FButtonHeight := AValue;
FBufferValid := false;
Invalidate; Invalidate;
end; end;
@ -1886,6 +1943,7 @@ procedure TCalendarLite.SetButtonWidth(const AValue: Integer);
begin begin
if FButtonWidth = AValue then exit; if FButtonWidth = AValue then exit;
FButtonWidth := AValue; FButtonWidth := AValue;
FBufferValid := false;
Invalidate; Invalidate;
end; end;
@ -1922,6 +1980,8 @@ begin
DateChange; DateChange;
if MonthOf(FDate) <> oldMonth then if MonthOf(FDate) <> oldMonth then
MonthChange; MonthChange;
FBufferValid := false;
FBufferValid := false;
Invalidate; Invalidate;
end; end;
@ -2078,6 +2138,12 @@ begin
Result := smNextSingle; Result := smNextSingle;
end; end;
procedure TCalendarLite.SetBiDiMode(AValue: TBiDiMode);
begin
inherited;
UpdateBiDiMode;
end;
procedure TCalendarLite.SetMultiSelect(AValue: Boolean); procedure TCalendarLite.SetMultiSelect(AValue: Boolean);
begin begin
if AValue = FMultiSelect then if AValue = FMultiSelect then
@ -2088,10 +2154,17 @@ begin
FPrevDate := FDate; FPrevDate := FDate;
end; end;
procedure TCalendarLite.SetParentBiDiMode(AValue: Boolean);
begin
inherited;
UpdateBiDiMode;
end;
procedure TCalendarLite.SetStartingDayOfWeek(AValue: TDayOfWeek); procedure TCalendarLite.SetStartingDayOfWeek(AValue: TDayOfWeek);
begin begin
if FStartingDayOfWeek = AValue then Exit; if FStartingDayOfWeek = AValue then Exit;
FStartingDayOfWeek := AValue; FStartingDayOfWeek := AValue;
FBufferValid := false;
Invalidate; Invalidate;
end; end;
@ -2105,6 +2178,7 @@ begin
end; end;
if Length(FCalDrawer.FRowPositions) <> LastRow+1 then if Length(FCalDrawer.FRowPositions) <> LastRow+1 then
SetLength(FCalDrawer.FRowPositions, LastRow+1); SetLength(FCalDrawer.FRowPositions, LastRow+1);
FBufferValid := false;
Invalidate; Invalidate;
end; end;
@ -2112,6 +2186,7 @@ procedure TCalendarLite.SetWeekendDays(AValue: TDaysOfWeek);
begin begin
if FWeekendDays = AValue then Exit; if FWeekendDays = AValue then Exit;
FWeekendDays := AValue; FWeekendDays := AValue;
FBufferValid := false;
Invalidate; Invalidate;
end; end;
@ -2125,6 +2200,16 @@ begin
InternalClick; InternalClick;
end; end;
procedure TCalendarLite.UpdateBiDiMode;
begin
case (BiDiMode = bdLeftToRight) of
False: if not FCalDrawer.FTextStyle.RightToLeft then
FCalDrawer.FTextStyle.RightToLeft := True;
True : if FCalDrawer.FTextStyle.RightToLeft then
FCalDrawer.FTextStyle.RightToLeft := False;
end;
end;
procedure TCalendarlite.UseDayName(ADayOfWeek: TDayOfWeek; const AValue: String); procedure TCalendarlite.UseDayName(ADayOfWeek: TDayOfWeek; const AValue: String);
var var
p: Integer; p: Integer;