git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@38 05c56307-c608-d34a-929d-697000501d7a
3081 lines
95 KiB
ObjectPascal
3081 lines
95 KiB
ObjectPascal
{********************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ ExpressScheduler }
|
|
{ }
|
|
{ Copyright (c) 2003-2009 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSSCHEDULER AND ALL ACCOMPANYING }
|
|
{ VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{********************************************************************}
|
|
|
|
unit cxSchedulerDateNavigator;
|
|
|
|
{$I cxVer.Inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
Types,
|
|
{$ELSE}
|
|
MultiMon,
|
|
{$ENDIF}
|
|
Windows, SysUtils, Classes, Controls, Graphics, ExtCtrls,
|
|
cxSchedulerCustomControls, cxSchedulerUtils, cxContainer, cxClasses,
|
|
cxGraphics, cxLookAndFeelPainters, cxStyles, cxControls, cxDateUtils;
|
|
|
|
const
|
|
// hit test codes
|
|
htcCalendar = 2;
|
|
htcDayCaptions = 3;
|
|
htcMonthName = 4;
|
|
htcNextMonth = 5;
|
|
htcPrevMonth = 6;
|
|
htcWeekSelectionBar = 7;
|
|
|
|
// style indexes
|
|
cxdnBackground = 0;
|
|
cxdnContent = 1;
|
|
cxdnHeader = 2;
|
|
cxdnSelection = 3;
|
|
//for PS
|
|
cxcsDateNavigatorFirst = cxdnBackground;
|
|
cxcsDateNavigatorLast = cxdnSelection;
|
|
|
|
cxDaysCalendarMaxColCount = 8;
|
|
cxMaxMonthViewInfoDays = 6 * 7;
|
|
cxMaxWeekCount = 6;
|
|
|
|
type
|
|
TcxSchedulerDateNavigatorDayNumberViewInfo = class;
|
|
TcxSchedulerDateNavigatorMonthHeaderViewInfo = class;
|
|
TcxSchedulerDateNavigatorMonthContentViewInfo = class;
|
|
TcxSchedulerDateNavigatorMonthViewInfo = class;
|
|
TcxSchedulerDateNavigatorViewInfo = class;
|
|
TcxSchedulerDateNavigator = class;
|
|
TcxSchedulerDateNavigatorViewInfoClass = class of TcxSchedulerDateNavigatorViewInfo;
|
|
|
|
{ TcxSchedulerDateNavigatorPainter }
|
|
|
|
TcxSchedulerDateNavigatorPainter = class(TcxSchedulerSubControlPainter)
|
|
private
|
|
FHeaderParams: TcxViewParams; //for callback procedure
|
|
FDateNavigator: TcxSchedulerDateNavigator;
|
|
FHeaderTransparent: Boolean;
|
|
procedure CheckDrawFrame(const ABounds: TRect; ADate: TDateTime);
|
|
function DrawHeaderBackground(ACanvas: TcxCanvas; const ABounds: TRect): Boolean;
|
|
protected
|
|
procedure DoDrawDayCaptions(AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo); virtual;
|
|
procedure DoDrawDayNumbers(AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo); virtual;
|
|
procedure DoDrawMonthContent(AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo); virtual;
|
|
procedure DoDrawMonthHeader(AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo); virtual;
|
|
procedure DrawBackground; virtual;
|
|
procedure DrawDayNumber(ADayInfo: TcxSchedulerDateNavigatorDayNumberViewInfo);
|
|
procedure DrawMonthHeader(AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo); virtual;
|
|
procedure DrawSeparators(AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo); virtual;
|
|
procedure DrawWeekNumbers(AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo); virtual;
|
|
property DateNavigator: TcxSchedulerDateNavigator read FDateNavigator;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); override;
|
|
procedure Paint; override;
|
|
end;
|
|
|
|
TcxSchedulerDateNavigatorPainterClass = class of TcxSchedulerDateNavigatorPainter;
|
|
|
|
{ TcxSchedulerDateNavigatorCaptionViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorCaptionViewInfo = class
|
|
private
|
|
FBounds: TRect;
|
|
FSaveParams: TcxViewParams;
|
|
FText: string;
|
|
FTransparent: Boolean;
|
|
FViewParams: TcxViewParams;
|
|
protected
|
|
procedure RestoreParams;
|
|
procedure SaveParams(ATransparent: Boolean);
|
|
|
|
property Text: string read FText write FText;
|
|
property Transparent: Boolean read FTransparent write FTransparent;
|
|
public
|
|
property Bounds: TRect read FBounds;
|
|
property ViewParams: TcxViewParams read FViewParams write FViewParams;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorDayNumberViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorDayNumberViewInfo = class(TcxSchedulerDateNavigatorCaptionViewInfo)
|
|
private
|
|
FBold: Boolean;
|
|
FDate: TDateTime;
|
|
FGrayed: Boolean;
|
|
FSelected: Boolean;
|
|
FSelectionSideBounds: TRect;
|
|
public
|
|
property Bold: Boolean read FBold write FBold;
|
|
property Bounds;
|
|
property Date: TDateTime read FDate;
|
|
property Grayed: Boolean read FGrayed;
|
|
property Selected: Boolean read FSelected;
|
|
property SelectionSideBounds: TRect read FSelectionSideBounds;
|
|
property Text;
|
|
property Transparent;
|
|
property ViewParams;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorDayCaptionViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorDayCaptionViewInfo = class(TcxSchedulerDateNavigatorCaptionViewInfo)
|
|
private
|
|
FIndex: Byte;
|
|
public
|
|
property Bounds;
|
|
property Index: Byte read FIndex;
|
|
property Text;
|
|
property Transparent;
|
|
property ViewParams;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorMonthHeaderViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorMonthHeaderViewInfo = class(TcxSchedulerDateNavigatorCaptionViewInfo)
|
|
private
|
|
FArrows: TcxHeaderArrows;
|
|
FNeighbors: TcxNeighbors;
|
|
FOwner: TcxSchedulerDateNavigatorMonthViewInfo;
|
|
FMonthNameBounds: TRect;
|
|
function GetMonth: Integer;
|
|
function GetMonthNameBounds: TRect;
|
|
function GetYear: Integer;
|
|
protected
|
|
procedure Calculate(const ABounds: TRect); virtual;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerDateNavigatorMonthViewInfo);
|
|
property Arrows: TcxHeaderArrows read FArrows;
|
|
property Bounds;
|
|
property Month: Integer read GetMonth;
|
|
property Neighbors: TcxNeighbors read FNeighbors;
|
|
property MonthNameBounds: TRect read FMonthNameBounds;
|
|
property Owner: TcxSchedulerDateNavigatorMonthViewInfo read FOwner;
|
|
property Text;
|
|
property Transparent;
|
|
property ViewParams;
|
|
property Year: Integer read GetYear;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorMonthContentViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorMonthContentViewInfo = class
|
|
private
|
|
FBounds: TRect;
|
|
FCol: Integer;
|
|
FRow: Integer;
|
|
FDateNavigator: TcxSchedulerDateNavigator;
|
|
FDays: array[0..cxMaxMonthViewInfoDays - 1] of TcxSchedulerDateNavigatorDayNumberViewInfo;
|
|
FDayCount: Integer;
|
|
FDayCaptions: array[0..6] of TcxSchedulerDateNavigatorDayCaptionViewInfo;
|
|
FFont: TFont;
|
|
FFontCharset: TFontCharset;
|
|
FHorzSeparatorBound: TRect;
|
|
FMonth: Integer;
|
|
FOwner: TcxSchedulerDateNavigatorMonthViewInfo;
|
|
FSaveParams: TcxViewParams;
|
|
FSelectedParams: TcxViewParams;
|
|
FTransparent: Boolean;
|
|
FVertSeparatorBound: TRect;
|
|
FViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
FViewParams: TcxViewParams;
|
|
FWeekBounds: array[0..5] of TRect;
|
|
FWeekCount: Integer;
|
|
FWeekTexts: array[0..5] of string;
|
|
FWeekSelectionBarBounds: TRect;
|
|
FYear: Integer;
|
|
procedure CreateDayInfos;
|
|
procedure CreateDayCaptionInfos;
|
|
procedure DestroyDayInfos;
|
|
procedure DestroyDayCaptionInfos;
|
|
function GetDayCaptionInfo(Index: Byte): TcxSchedulerDateNavigatorDayCaptionViewInfo;
|
|
function GetDayRectFromColAndRow(ACol, ARow: Integer): TRect;
|
|
function GetDayNumberViewInfo(Index: Byte): TcxSchedulerDateNavigatorDayNumberViewInfo;
|
|
function GetGrayed(ADate: TDateTime): Boolean;
|
|
function GetSelectionSideBounds(const ADayBounds: TRect; ACol: Integer): TRect;
|
|
function IsValidDayIndex(Index: Byte): Boolean;
|
|
function IsValidDayCaptionIndex(Index: Byte): Boolean;
|
|
function IsValidWeekIndex(Index: Byte): Boolean;
|
|
procedure SetWeekText(Index: Byte; const Value: string);
|
|
protected
|
|
procedure CalcAndAddDayInfo(ADate: TDateTime; const ABounds: TRect;
|
|
const ASelectionSideBounds: TRect);
|
|
procedure Calculate(ACol, ARow, AYear, AMonth: Integer); virtual;
|
|
procedure CalcDays; virtual;
|
|
procedure CalcDayCaptions; virtual;
|
|
procedure CalcParams; virtual;
|
|
procedure CalcSeparatorsBound; virtual;
|
|
function GetDateViewParams(ADate: TDateTime; ASelected: Boolean): TcxViewParams; virtual;
|
|
function GetDayText(ADate: TDateTime): string; virtual;
|
|
function GetDayCaptionText(Index: Byte): string; virtual;
|
|
function GetWeekBound(Index: Byte): TRect; virtual;
|
|
function GetWeekText(Index: Byte): string; virtual;
|
|
procedure RestoreParams;
|
|
procedure SaveParams;
|
|
procedure UpdateElementsAfterCustomDraw(ACanvas: TcxCanvas);
|
|
|
|
property DateNavigator: TcxSchedulerDateNavigator read FDateNavigator;
|
|
property Font: TFont read FFont;
|
|
property FontCharset: TFontCharset read FFontCharset;
|
|
property Owner: TcxSchedulerDateNavigatorMonthViewInfo read FOwner;
|
|
property ViewInfo: TcxSchedulerDateNavigatorViewInfo read FViewInfo;
|
|
property WeekSelectionBarBounds: TRect read FWeekSelectionBarBounds;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerDateNavigatorMonthViewInfo); virtual;
|
|
destructor Destroy; override;
|
|
|
|
property Bounds: TRect read FBounds;
|
|
property Col: Integer read FCol;
|
|
property DayCount: Integer read FDayCount;
|
|
property Days[Index: Byte]: TcxSchedulerDateNavigatorDayNumberViewInfo read GetDayNumberViewInfo;
|
|
property DayCaptions[Index: Byte]: TcxSchedulerDateNavigatorDayCaptionViewInfo read GetDayCaptionInfo;
|
|
property HorzSeparatorBound: TRect read FHorzSeparatorBound;
|
|
property Month: Integer read FMonth;
|
|
property Row: Integer read FRow;
|
|
property SelectedParams: TcxViewParams read FSelectedParams;
|
|
property Transparent: Boolean read FTransparent write FTransparent;
|
|
property VertSeparatorBound: TRect read FVertSeparatorBound;
|
|
property ViewParams: TcxViewParams read FViewParams;
|
|
property WeekCount: Integer read FWeekCount;
|
|
property WeekBounds[Index: Byte]: TRect read GetWeekBound;
|
|
property WeekTexts[Index: Byte]: string read GetWeekText write SetWeekText;
|
|
property Year: Integer read FYear;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorMonthViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorMonthViewInfo = class
|
|
private
|
|
FBounds: TRect;
|
|
FCol: Integer;
|
|
FRow: Integer;
|
|
FContent: TcxSchedulerDateNavigatorMonthContentViewInfo;
|
|
FHeader: TcxSchedulerDateNavigatorMonthHeaderViewInfo;
|
|
FMonth: Integer;
|
|
FOwner: TcxSchedulerDateNavigatorViewInfo;
|
|
FYear: Integer;
|
|
protected
|
|
procedure Calculate(ACol, ARow, AYear, AMonth: Integer); virtual;
|
|
function GetHeaderArrows: TcxHeaderArrows;
|
|
function GetHeaderNeighbors: TcxNeighbors;
|
|
|
|
property Owner: TcxSchedulerDateNavigatorViewInfo read FOwner;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerDateNavigatorViewInfo); virtual;
|
|
destructor Destroy; override;
|
|
|
|
property Bounds: TRect read FBounds;
|
|
property Col: Integer read FCol;
|
|
property Content: TcxSchedulerDateNavigatorMonthContentViewInfo read FContent;
|
|
property Header: TcxSchedulerDateNavigatorMonthHeaderViewInfo read FHeader;
|
|
property Month: Integer read FMonth;
|
|
property Row: Integer read FRow;
|
|
property Year: Integer read FYear;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorViewInfo }
|
|
|
|
TcxSchedulerDateNavigatorViewInfo = class(TcxSchedulerSubControlViewInfo)
|
|
private
|
|
FCalendarBounds: TRect;
|
|
FColCount: Integer;
|
|
FColWidth: Integer;
|
|
FContentParams: TcxViewParams;
|
|
FDayCaptionsHeight: Integer;
|
|
FHeaderBorderSize: Integer;
|
|
FHeaderHeight: Integer;
|
|
FHeaderParams: TcxViewParams;
|
|
FMonthSize: TSize;
|
|
FMonthViewInfoList: TList;
|
|
FOwner: TcxSchedulerDateNavigator;
|
|
FRowCount: Integer;
|
|
FRowHeight: Integer;
|
|
FSelectedParams: TcxViewParams;
|
|
FSideWidth: Integer;
|
|
procedure DestroyMonthViewInfoList;
|
|
function GetMonthViewInfo(ACol, ARow: Integer): TcxSchedulerDateNavigatorMonthViewInfo;
|
|
protected
|
|
procedure DoCalculate; override;
|
|
procedure CalculateCalendarBounds;
|
|
procedure CalculateMonthViewInfos;
|
|
procedure CalculateViewParams;
|
|
procedure CheckMonthViewInfoCount;
|
|
function GetCol(X: Integer): Integer;
|
|
function GetHeaderRect(ACol, ARow: Integer): TRect;
|
|
function GetInternalRect(ACol, ARow: Integer): TRect;
|
|
function GetLeftArrowRect: TRect;
|
|
function GetMonthRect(ACol, ARow: Integer): TRect;
|
|
function GetRightArrowRect: TRect;
|
|
function GetRow(Y: Integer): Integer;
|
|
procedure CalcInternalSizes;
|
|
property CalendarBounds: TRect read FCalendarBounds;
|
|
property ColCount: Integer read FColCount;
|
|
property ColWidth: Integer read FColWidth;
|
|
property ContentParams: TcxViewParams read FContentParams;
|
|
property DayCaptionsHeight: Integer read FDayCaptionsHeight;
|
|
property HeaderBorderSize: Integer read FHeaderBorderSize;
|
|
property HeaderHeight: Integer read FHeaderHeight;
|
|
property HeaderParams: TcxViewParams read FHeaderParams;
|
|
property Owner: TcxSchedulerDateNavigator read FOwner;
|
|
property RowCount: Integer read FRowCount;
|
|
property RowHeight: Integer read FRowHeight;
|
|
property SelectedParams: TcxViewParams read FSelectedParams;
|
|
property SideWidth: Integer read FSideWidth;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); override;
|
|
destructor Destroy; override;
|
|
property MonthSize: TSize read FMonthSize;
|
|
property MonthViewInfo[ACol, ARow: Integer]: TcxSchedulerDateNavigatorMonthViewInfo read GetMonthViewInfo;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorStyles }
|
|
|
|
TcxSchedulerDateNavigatorStyles = class(TcxStyles)
|
|
private
|
|
function GetDateNavigator: TcxSchedulerDateNavigator;
|
|
protected
|
|
procedure Changed(AIndex: Integer); override;
|
|
procedure GetDefaultViewParams(Index: Integer; AData: TObject; out AParams: TcxViewParams); override;
|
|
public
|
|
constructor Create(AOwner: TPersistent); override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
function GetBackgroundParams: TcxViewParams;
|
|
function GetContentParams: TcxViewParams;
|
|
function GetHeaderParams: TcxViewParams;
|
|
function GetSelectionParams: TcxViewParams;
|
|
property DateNavigator: TcxSchedulerDateNavigator read GetDateNavigator;
|
|
published
|
|
property Background: TcxStyle index cxdnBackground read GetValue write SetValue;
|
|
property Content: TcxStyle index cxdnContent read GetValue write SetValue;
|
|
property Header: TcxStyle index cxdnHeader read GetValue write SetValue;
|
|
property Selection: TcxStyle index cxdnSelection read GetValue write SetValue;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorHitTest }
|
|
|
|
TcxSchedulerDateNavigatorHitTest = class(TcxSchedulerSubControlHitTest)
|
|
private
|
|
FMonthViewInfo: TcxSchedulerDateNavigatorMonthViewInfo;
|
|
function GetFirstWeekSelectableDate: TDateTime;
|
|
function GetOwner: TcxSchedulerDateNavigator;
|
|
function GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
protected
|
|
procedure Clear; override;
|
|
procedure DoCalculate; override;
|
|
procedure CalcMonth; virtual;
|
|
function CheckDayCaptions: Boolean;
|
|
function CheckMonthHeader: Boolean;
|
|
function CheckWeekSelectionBar: Boolean;
|
|
|
|
property Owner: TcxSchedulerDateNavigator read GetOwner;
|
|
property ViewInfo: TcxSchedulerDateNavigatorViewInfo read GetViewInfo;
|
|
public
|
|
property HitAtCalendar: Boolean index htcCalendar read GetBitState;
|
|
property HitAtDayCaptions: Boolean index htcDayCaptions read GetBitState;
|
|
property HitAtMonthName: Boolean index htcMonthName read GetBitState;
|
|
property HitAtNextMonth: Boolean index htcNextMonth read GetBitState;
|
|
property HitAtPrevMonth: Boolean index htcPrevMonth read GetBitState;
|
|
property HitAtTime;
|
|
property HitAtWeekSelectionBar: Boolean index htcWeekSelectionBar read GetBitState;
|
|
property MonthViewInfo: TcxSchedulerDateNavigatorMonthViewInfo read FMonthViewInfo;
|
|
property Time;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorController }
|
|
|
|
TcxSchedulerDateNavigatorController = class(TcxSchedulerSubControlController)
|
|
private
|
|
FDragDate: TDateTime;
|
|
FExtSelect: Boolean;
|
|
FIgnoreMouseMove: Boolean;
|
|
FSaveSelectionIsWeeks: Boolean;
|
|
FSaveSelectionList: TcxSchedulerDateList;
|
|
FSelFinish: TDateTime;
|
|
FSelStart: TDateTime;
|
|
FSingleSelection: Boolean;
|
|
FTimer: TTimer;
|
|
FUnselect: Boolean;
|
|
function GetHitTest: TcxSchedulerDateNavigatorHitTest;
|
|
function GetOwner: TcxSchedulerDateNavigator;
|
|
function GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
procedure SetDragDate(const Value: TDateTime);
|
|
procedure StartTimer(AFuture: Boolean);
|
|
procedure StopTimer;
|
|
procedure TimerProc(Sender: TObject);
|
|
protected
|
|
//overriden
|
|
procedure DoCancelMode; override;
|
|
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); override;
|
|
function GetCursor(X, Y: Integer): TCursor; override;
|
|
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseLeave; override;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
|
|
//methods
|
|
procedure CalculateSelection(AConcatenate: Boolean); virtual;
|
|
procedure ProcessSelectionOnMouseDown(AShift: TShiftState);
|
|
procedure ProcessSelectionOnMouseMove(AShift: TShiftState);
|
|
property HitTest: TcxSchedulerDateNavigatorHitTest read GetHitTest;
|
|
property Owner: TcxSchedulerDateNavigator read GetOwner;
|
|
property ViewInfo: TcxSchedulerDateNavigatorViewInfo read GetViewInfo;
|
|
public
|
|
constructor Create(AOwner: TcxSchedulerSubControl); override;
|
|
destructor Destroy; override;
|
|
property DragDate: TDateTime read FDragDate write SetDragDate;
|
|
end;
|
|
|
|
TcxSchedulerPeriodChangedEvent = procedure(Sender: TObject;
|
|
const AStart, AFinish: TDateTime) of object;
|
|
|
|
TcxSchedulerDateNavigatorCustomDrawBackgroundEvent = procedure (Sender: TObject;
|
|
ACanvas: TcxCanvas; const ABounds: TRect; var AViewParams: TcxViewParams;
|
|
var ADone: Boolean) of object;
|
|
TcxSchedulerDateNavigatorCustomDrawDayNumberEvent = procedure (Sender: TObject;
|
|
ACanvas: TcxCanvas; AViewInfo: TcxSchedulerDateNavigatorDayNumberViewInfo;
|
|
var ADone: Boolean) of object;
|
|
TcxSchedulerDateNavigatorCustomDrawDayCaptionEvent = procedure (Sender: TObject;
|
|
ACanvas: TcxCanvas; AViewInfo: TcxSchedulerDateNavigatorDayCaptionViewInfo;
|
|
var ADone: Boolean) of object;
|
|
TcxSchedulerDateNavigatorCustomDrawContentEvent = procedure (Sender: TObject;
|
|
ACanvas: TcxCanvas; AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo;
|
|
var ADone: Boolean) of object;
|
|
TcxSchedulerDateNavigatorCustomDrawHeaderEvent = procedure (Sender: TObject;
|
|
ACanvas: TcxCanvas; AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo;
|
|
var ADone: Boolean) of object;
|
|
|
|
TcxSchedulerDateNavigator = class(TcxSchedulerCustomDateNavigator)
|
|
private
|
|
FActualFirstWeekOfYear: TcxFirstWeekOfYear;
|
|
FColCount: Integer;
|
|
FFirstDate: TDateTime;
|
|
FFirstWeekOfYear: TcxFirstWeekOfYear;
|
|
FLastDate: TDateTime;
|
|
FListBox: TcxCustomPopupWindow;
|
|
FListBoxDelta: Integer;
|
|
FRealFirstDate: TDateTime;
|
|
FRealLastDate: TDateTime;
|
|
FRowCount: Integer;
|
|
FSelectionIsWeeks: Boolean;
|
|
FSelectPeriod: Boolean;
|
|
FShowDatesContainingEventsInBold: Boolean;
|
|
FShowWeekNumbers: Boolean;
|
|
FStyles: TcxSchedulerDateNavigatorStyles;
|
|
FToday: TDateTime;
|
|
// custom draw
|
|
FOnCustomDrawBackground: TcxSchedulerDateNavigatorCustomDrawBackgroundEvent;
|
|
FOnCustomDrawContent: TcxSchedulerDateNavigatorCustomDrawContentEvent;
|
|
FOnCustomDrawDayCaption: TcxSchedulerDateNavigatorCustomDrawDayCaptionEvent;
|
|
FOnCustomDrawDayNumber: TcxSchedulerDateNavigatorCustomDrawDayNumberEvent;
|
|
FOnCustomDrawHeader: TcxSchedulerDateNavigatorCustomDrawHeaderEvent;
|
|
FOnPeriodChanged: TcxSchedulerPeriodChangedEvent;
|
|
FOnSelectionChanged: TcxSchedulerPeriodChangedEvent;
|
|
function GetActualFirstWeekOfYear: TcxFirstWeekOfYear;
|
|
function GetController: TcxSchedulerDateNavigatorController;
|
|
function GetDate: TDateTime;
|
|
function GetHitTest: TcxSchedulerDateNavigatorHitTest;
|
|
function GetLastDate: TDateTime;
|
|
function GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
procedure SetColCount(Value: Integer);
|
|
procedure SetDate(Value: TDateTime);
|
|
procedure SetFirstWeekOfYear(Value: TcxFirstWeekOfYear);
|
|
procedure SetRowCount(Value: Integer);
|
|
procedure SetSelectPeriod(Value: Boolean);
|
|
procedure SetShowDatesContainingEventsInBold(Value: Boolean);
|
|
procedure SetShowWeekNumbers(Value: Boolean);
|
|
procedure SetStyles(const Value: TcxSchedulerDateNavigatorStyles);
|
|
protected
|
|
IsLocked: Boolean;
|
|
// store interface
|
|
procedure GetProperties(AProperties: TStrings); override;
|
|
procedure GetPropertyValue(const AName: string; var AValue: Variant); override;
|
|
procedure SetPropertyValue(const AName: string; const AValue: Variant); override;
|
|
//
|
|
function AllowDesignHitTest(X, Y: Integer; Shift: TShiftState): Boolean; override;
|
|
procedure CheckSizes; override;
|
|
procedure CreateSubClasses; override;
|
|
function CreateController: TcxSchedulerSubControlController; override;
|
|
function CreateHitTest: TcxSchedulerSubControlHitTest; override;
|
|
function CreatePainter: TcxSchedulerSubControlPainter; override;
|
|
function CreateViewInfo: TcxSchedulerSubControlViewInfo; override;
|
|
procedure DestroySubClasses; override;
|
|
procedure DoLayoutChanged; override;
|
|
//methods
|
|
function CanDrawSelectionSide: Boolean;
|
|
procedure CheckSelectionBounds; virtual;
|
|
procedure DoSelectionChanged; virtual;
|
|
procedure DoPeriodChangedEvent; override;
|
|
procedure DoSelectionChangedEvent; override;
|
|
procedure DoScrollSelection(AScrollDelta: Integer); override;
|
|
procedure DoScrollSelection(AForward: Boolean;
|
|
ANeedDate: TDateTime; AIsByPage: Boolean); override;
|
|
procedure EnsureSelectionVisible;
|
|
function IsDateSelected(ADate: TDateTime): Boolean; virtual;
|
|
function IsDateHasEvent(ADate: TDateTime): Boolean; virtual;
|
|
procedure FormatChanged; override;
|
|
function GetMonthSize: TSize; override;
|
|
function GetRealFirstDate: TDateTime; override;
|
|
function GetRealLastDate: TDateTime; override;
|
|
function GetShowDatesContainingEventsInBold: Boolean; override;
|
|
procedure RefreshDays;
|
|
procedure SetFirstDate(Value: TDateTime); virtual;
|
|
procedure ShowMonthPopup(AMonthInfo: TcxSchedulerDateNavigatorMonthViewInfo); virtual;
|
|
procedure StepToPast;
|
|
procedure StepToFuture;
|
|
procedure UpdateCalculatedValues; virtual;
|
|
procedure UpdateDragging; override;
|
|
procedure UpdateSelection; override;
|
|
// support custom draw
|
|
procedure AfterCustomDraw(ACanvas: TcxCanvas; var AParams: TcxViewParams); virtual;
|
|
procedure BeforeCustomDraw(ACanvas: TcxCanvas; const AParams: TcxViewParams); virtual;
|
|
function DoCustomDrawBackground(ACanvas: TcxCanvas;
|
|
const ABounds: TRect; var AViewParams: TcxViewParams): Boolean; virtual;
|
|
function DoCustomDrawDayNumber(ACanvas: TcxCanvas;
|
|
ADayInfo: TcxSchedulerDateNavigatorDayNumberViewInfo): Boolean; virtual;
|
|
function DoCustomDrawDayCaption(ACanvas: TcxCanvas;
|
|
ADayCaptionInfo: TcxSchedulerDateNavigatorDayCaptionViewInfo): Boolean; virtual;
|
|
function DoCustomDrawContent(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo): Boolean; virtual;
|
|
function DoCustomDrawHeader(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo): Boolean; virtual;
|
|
|
|
property Controller: TcxSchedulerDateNavigatorController read GetController;
|
|
property ViewInfo: TcxSchedulerDateNavigatorViewInfo read GetViewInfo;
|
|
public
|
|
constructor Create(AOwner: TcxCustomScheduler); override;
|
|
procedure SetIntegralSizes; override;
|
|
|
|
property ActualFirstWeekOfYear: TcxFirstWeekOfYear read FActualFirstWeekOfYear;
|
|
property Date: TDateTime read GetDate write SetDate;
|
|
property FirstDate: TDateTime read FFirstDate write SetFirstDate;
|
|
property HitTest: TcxSchedulerDateNavigatorHitTest read GetHitTest;
|
|
property LastDate: TDateTime read FLastDate;
|
|
property RealFirstDate: TDateTime read FRealFirstDate;
|
|
property RealLastDate: TDateTime read FRealLastDate;
|
|
property SelectionIsWeeks: Boolean read FSelectionIsWeeks write FSelectionIsWeeks;
|
|
property SelectionList: TcxSchedulerDateList read GetSelection;
|
|
property SelectPeriod: Boolean read FSelectPeriod write SetSelectPeriod;
|
|
published
|
|
property ColCount: Integer read FColCount write SetColCount default 1;
|
|
property FirstWeekOfYear: TcxFirstWeekOfYear
|
|
read FFirstWeekOfYear write SetFirstWeekOfYear default fwySystem;
|
|
property RowCount: Integer read FRowCount write SetRowCount default 1;
|
|
property ShowDatesContainingEventsInBold: Boolean
|
|
read FShowDatesContainingEventsInBold write SetShowDatesContainingEventsInBold default True;
|
|
property ShowWeekNumbers: Boolean read FShowWeekNumbers write SetShowWeekNumbers default True;
|
|
property Styles: TcxSchedulerDateNavigatorStyles read FStyles write SetStyles;
|
|
property Visible default True;
|
|
|
|
property OnCustomDrawBackground: TcxSchedulerDateNavigatorCustomDrawBackgroundEvent
|
|
read FOnCustomDrawBackground write FOnCustomDrawBackground;
|
|
property OnCustomDrawDayCaption: TcxSchedulerDateNavigatorCustomDrawDayCaptionEvent
|
|
read FOnCustomDrawDayCaption write FOnCustomDrawDayCaption;
|
|
property OnCustomDrawDayNumber: TcxSchedulerDateNavigatorCustomDrawDayNumberEvent
|
|
read FOnCustomDrawDayNumber write FOnCustomDrawDayNumber;
|
|
property OnCustomDrawContent: TcxSchedulerDateNavigatorCustomDrawContentEvent
|
|
read FOnCustomDrawContent write FOnCustomDrawContent;
|
|
property OnCustomDrawHeader: TcxSchedulerDateNavigatorCustomDrawHeaderEvent
|
|
read FOnCustomDrawHeader write FOnCustomDrawHeader;
|
|
property OnPeriodChanged: TcxSchedulerPeriodChangedEvent read FOnPeriodChanged
|
|
write FOnPeriodChanged;
|
|
property OnSelectionChanged: TcxSchedulerPeriodChangedEvent read FOnSelectionChanged
|
|
write FOnSelectionChanged;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DELPHI6}
|
|
DateUtils,
|
|
{$ENDIF}
|
|
cxGeometry, Forms, cxFormats, cxLibraryConsts;
|
|
|
|
const
|
|
cxDateStartNavigatorTime = 400;
|
|
cxDateNavigatorTime = 200;
|
|
cxdnTextFlags = cxSingleLine + cxAlignVCenter + cxAlignRight;
|
|
|
|
var
|
|
DayNames: array[1..7] of string;
|
|
|
|
procedure GetLocaleSettings;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 1 to 7 do
|
|
DayNames[I] := ShortDayNames[I][1];
|
|
end;
|
|
|
|
function Max(A, B: Integer): Integer;
|
|
begin
|
|
if A > B then Result := A else Result := B;
|
|
end;
|
|
|
|
function Min(A, B: Integer): Integer;
|
|
begin
|
|
if A < B then Result := A else Result := B;
|
|
end;
|
|
|
|
procedure DecMonth(var AYear, AMonth: Word);
|
|
begin
|
|
if AMonth = 1 then
|
|
begin
|
|
Dec(AYear);
|
|
AMonth := 12;
|
|
end
|
|
else Dec(AMonth);
|
|
end;
|
|
|
|
procedure IncMonth(var AYear, AMonth: Word);
|
|
begin
|
|
if AMonth = 12 then
|
|
begin
|
|
Inc(AYear);
|
|
AMonth := 1;
|
|
end
|
|
else Inc(AMonth);
|
|
end;
|
|
|
|
procedure ChangeMonth(var AYear, AMonth: Word; Delta: Integer);
|
|
var
|
|
Month: Integer;
|
|
begin
|
|
Inc(AYear, Delta div 12);
|
|
Month := AMonth;
|
|
Inc(Month, Delta mod 12);
|
|
if Month < 1 then
|
|
begin
|
|
Dec(AYear);
|
|
Month := 12 + Month;
|
|
end;
|
|
if Month > 12 then
|
|
begin
|
|
Inc(AYear);
|
|
Month := Month - 12;
|
|
end;
|
|
AMonth := Month;
|
|
end;
|
|
|
|
function GetDateElement(ADate: TDateTime; Index: Integer): Integer;
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
DecodeDate(ADate, AYear, AMonth, ADay);
|
|
case Index of
|
|
1: Result := AYear;
|
|
2: Result := AMonth;
|
|
3: Result := ADay;
|
|
else Result := -1;
|
|
end;
|
|
end;
|
|
|
|
function DaysPerMonth(AYear, AMonth: Integer): Integer;
|
|
const
|
|
DaysInMonth: array[1..12] of Integer =
|
|
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
|
|
begin
|
|
Result := DaysInMonth[AMonth];
|
|
if (AMonth = 2) and IsLeapYear(AYear) then Inc(Result);
|
|
end;
|
|
|
|
function CheckDay(AYear, AMonth, ADay: Integer): Integer;
|
|
begin
|
|
if ADay < 1 then Result := 1
|
|
else
|
|
if ADay > DaysPerMonth(AYear, AMonth) then
|
|
Result := DaysPerMonth(AYear, AMonth)
|
|
else Result := ADay;
|
|
end;
|
|
|
|
function ColOfDate(ADate: TDateTime; StartOfWeek: TcxDayOfWeek): Integer;
|
|
begin
|
|
Result := DayOfWeek(ADate) - StartOfWeek - 1;
|
|
if Result < 0 then Inc(Result, 7);
|
|
end;
|
|
|
|
type
|
|
|
|
{ TcxSchedulerMonthListBox }
|
|
|
|
TcxSchedulerMonthListBox = class(TcxCustomPopupWindow)
|
|
private
|
|
FOwner: TcxSchedulerDateNavigator;
|
|
FOrigin: TPoint;
|
|
FTopDate: TDateTime;
|
|
FItemHeight: Integer;
|
|
FItemIndex: Integer;
|
|
FItems: TStrings;
|
|
FTimer: TTimer;
|
|
FSign: Integer;
|
|
function GetDate: TDateTime;
|
|
function GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
procedure SetItemIndex(Value: Integer);
|
|
procedure SetTopDate(Value: TDateTime);
|
|
procedure DoTimer(Sender: TObject);
|
|
protected
|
|
function CalculatePosition: TPoint; override;
|
|
procedure CreateParams(var Params: TCreateParams); override;
|
|
procedure DoShowed; override;
|
|
procedure FontChanged;
|
|
procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
|
|
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer); override;
|
|
procedure Paint; override;
|
|
property ItemHeight: Integer read FItemHeight;
|
|
property ItemIndex: Integer read FItemIndex write SetItemIndex;
|
|
property Items: TStrings read FItems;
|
|
property Owner: TcxSchedulerDateNavigator read FOwner;
|
|
property TopDate: TDateTime read FTopDate write SetTopDate;
|
|
property ViewInfo: TcxSchedulerDateNavigatorViewInfo read GetViewInfo;
|
|
public
|
|
procedure BeforeDestruction; override;
|
|
constructor Create(AOwner: TcxSchedulerDateNavigator); reintroduce;
|
|
procedure CloseUp; override;
|
|
procedure SetupMonth(R: TRect; ADate: TDateTime);
|
|
property Date: TDateTime read GetDate;
|
|
end;
|
|
|
|
function GetDesktopRect: TRect;
|
|
begin
|
|
{$IFDEF DELPHI6}
|
|
Result := Screen.DesktopRect;
|
|
{$ELSE}
|
|
with Result do
|
|
begin
|
|
Top := GetSystemMetrics(SM_YVIRTUALSCREEN);
|
|
Left := GetSystemMetrics(SM_XVIRTUALSCREEN);
|
|
Bottom := Top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
Right := Left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
constructor TcxSchedulerMonthListBox.Create(AOwner: TcxSchedulerDateNavigator);
|
|
begin
|
|
inherited Create(AOwner.Scheduler);
|
|
OwnerParent := AOwner.Scheduler.Parent;
|
|
FOwner := AOwner;
|
|
IsTopMost := True;
|
|
CaptureFocus := False;
|
|
ControlStyle := [csCaptureMouse, csOpaque];
|
|
FTopDate := NullDate;
|
|
FTimer := TTimer.Create(nil);
|
|
FTimer.Enabled := False;
|
|
FTimer.Interval := 200;
|
|
FTimer.OnTimer := DoTimer;
|
|
Adjustable := False;
|
|
BorderStyle := pbsFlat;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.BeforeDestruction;
|
|
begin
|
|
FTimer.Free;
|
|
FTimer := nil;
|
|
inherited BeforeDestruction;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.CloseUp;
|
|
var
|
|
ADate: TDateTime;
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
FTimer.Enabled := False;
|
|
if GetCaptureControl = Self then SetCaptureControl(nil);
|
|
inherited CloseUp;
|
|
ADate := GetDate;
|
|
with Owner do
|
|
begin
|
|
if ADate <> NullDate then
|
|
begin
|
|
DecodeDate(ADate, AYear, AMonth, ADay);
|
|
ChangeMonth(AYear, AMonth, -FListBoxDelta);
|
|
FirstDate := EncodeDate(AYear, AMonth, 1);
|
|
end;
|
|
Controller.DoCancelMode;
|
|
end;
|
|
Owner.EndUpdate;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.SetupMonth(R: TRect; ADate: TDateTime);
|
|
begin
|
|
Font.Assign(ViewInfo.ContentParams.Font);
|
|
FontChanged;
|
|
R.TopLeft := Owner.Scheduler.ClientToScreen(R.TopLeft);
|
|
R.BottomRight := Owner.Scheduler.ClientToScreen(R.BottomRight);
|
|
R := cxRectOffset(R, Owner.Bounds.TopLeft);
|
|
TopDate := ADate;
|
|
FOrigin.X := Max(GetDesktopRect.Left,
|
|
(R.Left + R.Right) div 2 - Width div 2);
|
|
FOrigin.Y := Max(GetDesktopRect.Top,
|
|
(R.Top + R.Bottom) div 2 - Height div 2);
|
|
FItemIndex := 3;
|
|
end;
|
|
|
|
function TcxSchedulerMonthListBox.GetDate: TDateTime;
|
|
var
|
|
Year, Month, Day: Word;
|
|
begin
|
|
if ItemIndex = -1 then
|
|
Result := NullDate
|
|
else
|
|
begin
|
|
DecodeDate(TopDate, Year, Month, Day);
|
|
ChangeMonth(Year, Month, ItemIndex);
|
|
Result := EncodeDate(Year, Month, 1);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerMonthListBox.GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
begin
|
|
Result := Owner.ViewInfo;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.SetItemIndex(Value: Integer);
|
|
var
|
|
PrevItemIndex: Integer;
|
|
|
|
procedure InvalidateItemRect(Index: Integer);
|
|
var
|
|
R: TRect;
|
|
begin
|
|
if Index = -1 then Exit;
|
|
with R do
|
|
begin
|
|
Left := BorderWidths[bLeft];
|
|
Top := Index * ItemHeight + BorderWidths[bTop];
|
|
Right := Width - BorderWidths[bRight];
|
|
Bottom := Top + ItemHeight;
|
|
end;
|
|
InvalidateRect(Handle, @R, False);
|
|
end;
|
|
|
|
begin
|
|
if not HandleAllocated then Exit;
|
|
if FItemIndex <> Value then
|
|
begin
|
|
PrevItemIndex := FItemIndex;
|
|
FItemIndex := Value;
|
|
InvalidateItemRect(PrevItemIndex);
|
|
InvalidateItemRect(FItemIndex);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.SetTopDate(Value: TDateTime);
|
|
begin
|
|
if FTopDate <> Value then
|
|
begin
|
|
FTopDate := Value;
|
|
Repaint;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.DoTimer(Sender: TObject);
|
|
var
|
|
Year, Month, Day: Word;
|
|
begin
|
|
DecodeDate(TopDate, Year, Month, Day);
|
|
ChangeMonth(Year, Month, FSign);
|
|
TopDate := EncodeDate(Year, Month, 1);
|
|
end;
|
|
|
|
function TcxSchedulerMonthListBox.CalculatePosition: TPoint;
|
|
begin
|
|
Result.X := Min(cxRectWidth(GetDesktopRect) - Width, FOrigin.X);
|
|
Result.Y := Min(cxRectHeight(GetDesktopRect) - Height, FOrigin.Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.CreateParams(var Params: TCreateParams);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
with Params do
|
|
WindowClass.Style := WindowClass.Style or CS_SAVEBITS;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.DoShowed;
|
|
begin
|
|
SetCaptureControl(Self);
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.FontChanged;
|
|
begin
|
|
Canvas.Font.Assign(Font);
|
|
FItemHeight := ViewInfo.HeaderHeight - 2;
|
|
SetBounds(Left, Top,
|
|
BorderWidths[bLeft] + BorderWidths[bRight] + 6 * ViewInfo.ColWidth,
|
|
BorderWidths[bTop] + BorderWidths[bBottom] + 7 * FItemHeight);
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.MouseUp(Button: TMouseButton; Shift: TShiftState;
|
|
X, Y: Integer);
|
|
begin
|
|
CloseUp;
|
|
inherited MouseUp(Button, Shift, X, Y);
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.MouseMove(Shift: TShiftState; X, Y: Integer);
|
|
const
|
|
Times: array[0..3] of UINT = (500, 250, 100, 50);
|
|
var
|
|
Delta: Integer;
|
|
Interval: Integer;
|
|
begin
|
|
if cxRectPtIn(ClientRect, X, Y) then
|
|
begin
|
|
FTimer.Enabled := False;
|
|
ItemIndex := Y div ItemHeight;
|
|
end
|
|
else
|
|
begin
|
|
ItemIndex := -1;
|
|
if Y < 0 then Delta := Y
|
|
else
|
|
if Y >= ClientHeight then
|
|
Delta := 1 + Y - ClientHeight
|
|
else
|
|
begin
|
|
FTimer.Enabled := False;
|
|
Exit;
|
|
end;
|
|
FSign := Delta div Abs(Delta);
|
|
Interval := Abs(Delta) div ItemHeight;
|
|
if Interval > 3 then Interval := 3;
|
|
if not FTimer.Enabled or (Times[Interval] <> FTimer.Interval) then
|
|
begin
|
|
FTimer.Interval := Times[Interval];
|
|
FTimer.Enabled := True;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerMonthListBox.Paint;
|
|
const
|
|
Colors: array[Boolean] of TColor = (clWindow, clWindowText);
|
|
var
|
|
I: Integer;
|
|
Year, Month, Day: Word;
|
|
R: TRect;
|
|
S: string;
|
|
begin
|
|
Canvas.FrameRect(ClientRect, clBlack);
|
|
DecodeDate(TopDate, Year, Month, Day);
|
|
with R do
|
|
begin
|
|
Left := BorderWidths[bLeft];
|
|
Top := BorderWidths[bTop];
|
|
Right := Width - BorderWidths[bRight];
|
|
Bottom := Top + ItemHeight;
|
|
end;
|
|
for I := 0 to 6 do
|
|
begin
|
|
with Canvas do
|
|
begin
|
|
if I = ItemIndex then
|
|
begin
|
|
Font.Color := ViewInfo.SelectedParams.TextColor;
|
|
Brush.Color := ViewInfo.SelectedParams.Color;
|
|
FillRect(R);
|
|
end
|
|
else
|
|
begin
|
|
Font.Color := ViewInfo.ContentParams.TextColor;
|
|
FillRect(R, ViewInfo.ContentParams);
|
|
end;
|
|
S := Owner.DateTimeHelper.MonthYearToStr(Month, Year);
|
|
Canvas.Brush.Style := bsClear;
|
|
Inc(R.Right); // synchronize with header
|
|
DrawText(S, R, cxAlignCenter or cxSingleLine, True);
|
|
Dec(R.Right);
|
|
Canvas.Brush.Style := bsSolid;
|
|
end;
|
|
IncMonth(Year, Month);
|
|
OffsetRect(R, 0, ItemHeight);
|
|
end;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorController }
|
|
|
|
constructor TcxSchedulerDateNavigatorController.Create(AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FSaveSelectionList := TcxSchedulerDateList.Create;
|
|
end;
|
|
|
|
destructor TcxSchedulerDateNavigatorController.Destroy;
|
|
begin
|
|
StopTimer;
|
|
FSaveSelectionList.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.DoCancelMode;
|
|
begin
|
|
StopTimer;
|
|
FIgnoreMouseMove := False;
|
|
FSingleSelection := False;
|
|
FDragDate := NullDate;
|
|
Screen.Cursor := crDefault;
|
|
Owner.RefreshDays;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.DragOver(
|
|
Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
|
|
begin
|
|
Accept := Accept and HitTest.HitAtTime;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorController.GetCursor(X, Y: Integer): TCursor;
|
|
begin
|
|
if Owner.SelectPeriod and HitTest.HitAtWeekSelectionBar then
|
|
Result := crCalendarMirrorArrow
|
|
else
|
|
Result := crDefault;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.MouseDown(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
|
|
procedure ProcessHeader;
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
if HitAtPrevMonth then
|
|
begin
|
|
Owner.StepToPast;
|
|
StartTimer(False);
|
|
end
|
|
else if HitAtNextMonth then
|
|
begin
|
|
Owner.StepToFuture;
|
|
StartTimer(True);
|
|
end
|
|
else if HitAtMonthName then
|
|
Owner.ShowMonthPopup(MonthViewInfo);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
FIgnoreMouseMove := False;
|
|
FSingleSelection := False;
|
|
FSaveSelectionIsWeeks := False;
|
|
if Button = mbLeft then
|
|
begin
|
|
Owner.CancelUpdates; // for a possible changed capture
|
|
Owner.BeginUpdate;
|
|
FExtSelect := Owner.SelectPeriod and (ssCtrl in Shift);
|
|
FUnselect := FExtSelect;
|
|
FSaveSelectionList.Assign(Owner.SelectionList);
|
|
if not (ssDouble in Shift) then
|
|
ProcessSelectionOnMouseDown(Shift);
|
|
ProcessHeader;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.MouseLeave;
|
|
begin
|
|
inherited MouseLeave;
|
|
DoCancelMode;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.MouseMove(
|
|
Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
if FIgnoreMouseMove or (FTimer <> nil) then Exit;
|
|
if (ssLeft in Shift) and (GetCaptureControl = Owner.Scheduler) then
|
|
ProcessSelectionOnMouseMove(Shift);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.MouseUp(
|
|
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
|
begin
|
|
DoCancelMode;
|
|
if Button = mbLeft then
|
|
begin
|
|
if (Owner.SelectionList.Count > 0) and
|
|
cxRectPtIn(ViewInfo.GetInternalRect(ViewInfo.GetCol(X), ViewInfo.GetRow(Y)), X, Y) then
|
|
begin
|
|
if Owner.SelectionList[Owner.SelectionList.Count - 1] < Owner.FirstDate then
|
|
Owner.StepToPast;
|
|
if Owner.SelectionList[0] > Owner.LastDate then
|
|
Owner.StepToFuture;
|
|
end;
|
|
Owner.DoSelectionChanged;
|
|
Owner.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.CalculateSelection(AConcatenate: Boolean);
|
|
|
|
procedure GetBoundParameters(out AStart, AFinish, AMax, AMin: Integer);
|
|
begin
|
|
//DELPHI8! check Trunc()
|
|
AStart := Trunc(FSelStart);
|
|
AFinish := Trunc(FSelFinish);
|
|
if Owner.SelectionIsWeeks then
|
|
begin
|
|
if AStart < AFinish then
|
|
begin
|
|
Dec(AStart, ColOfDate(AStart, Byte(StartOfWeek)));
|
|
Inc(AFinish, 6 - ColOfDate(AFinish, Byte(StartOfWeek)));
|
|
end
|
|
else
|
|
begin
|
|
Dec(AFinish, ColOfDate(AFinish, Byte(StartOfWeek)));
|
|
Inc(AStart, 6 - ColOfDate(AStart, Byte(StartOfWeek)));
|
|
end;
|
|
AMax := cxMaxWeekCount * 7;
|
|
AMin := 7;
|
|
end
|
|
else
|
|
begin
|
|
AMax := 14;
|
|
AMin := 1;
|
|
end;
|
|
end;
|
|
|
|
var
|
|
AIndex, ADelta, AStart, AFinish, AMax, AMin: Integer;
|
|
begin
|
|
GetBoundParameters(AStart, AFinish, AMax, AMin);
|
|
if FUnselect and (Owner.SelectionList.Count <= AMin) then Exit;
|
|
Owner.SelectionList.Clear;
|
|
if AConcatenate then Owner.SelectionList.Assign(FSaveSelectionList);
|
|
ADelta := 2 * Byte(AStart < AFinish) - 1;
|
|
while (AStart <> AFinish + ADelta) do
|
|
begin
|
|
AIndex := Owner.SelectionList.IndexOf(AStart);
|
|
if AIndex < 0 then
|
|
begin
|
|
if not FUnselect and (Owner.SelectionList.Count < AMax) then
|
|
Owner.SelectionList.Add(AStart);
|
|
end
|
|
else
|
|
if FUnselect and (Owner.SelectionList.Count > AMin) then
|
|
Owner.SelectionList.Delete(AIndex);
|
|
Inc(AStart, ADelta);
|
|
end;
|
|
Owner.RefreshDays;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.ProcessSelectionOnMouseDown(
|
|
AShift: TShiftState);
|
|
|
|
procedure SelectDate(ADate: TDateTime);
|
|
begin
|
|
with Owner.SelectionList do
|
|
begin
|
|
if (ExistDate(ADate) and FUnselect and (Count = 1)) or
|
|
(FExtSelect and (Count > 14)) then
|
|
begin
|
|
FIgnoreMouseMove := True;
|
|
Exit;
|
|
end;
|
|
end;
|
|
FSelStart := ADate;
|
|
FSelFinish := ADate;
|
|
Owner.SelectionIsWeeks := False;
|
|
CalculateSelection(FExtSelect);
|
|
end;
|
|
|
|
procedure SelectWeek(ADate: TDateTime);
|
|
begin
|
|
if not Owner.SelectPeriod or (Owner.SelectionIsWeeks and FUnselect and
|
|
(Owner.SelectionList.Count = 7)) then Exit;
|
|
if not Owner.SelectionIsWeeks then
|
|
begin
|
|
FUnselect := False;
|
|
Owner.SelectionList.Clear;
|
|
end;
|
|
FSaveSelectionIsWeeks := Owner.SelectionIsWeeks;
|
|
FSelStart := ADate;
|
|
FSelFinish := FSelStart + 6;
|
|
CalculateSelection(FExtSelect and Owner.SelectionIsWeeks);
|
|
Owner.SelectionIsWeeks := True;
|
|
end;
|
|
|
|
var
|
|
ADate: TDateTime;
|
|
begin
|
|
ADate := HitTest.Time;
|
|
if ADate = NullDate then Exit;
|
|
FUnselect := FUnselect and Owner.SelectionList.ExistDate(ADate);
|
|
if Owner.SelectPeriod and (ssShift in AShift) then
|
|
begin
|
|
FSelStart := Owner.SelectionList[0];
|
|
FSelFinish := ADate;
|
|
Owner.SelectionIsWeeks := HitTest.HitAtWeekSelectionBar or (Owner.SelectionList.Count > 14);
|
|
CalculateSelection(not Owner.SelectionIsWeeks);
|
|
end
|
|
else
|
|
if HitTest.HitAtTime then
|
|
SelectDate(ADate)
|
|
else if HitTest.HitAtWeekSelectionBar then
|
|
SelectWeek(ADate)
|
|
else if HitTest.HitAtControl and not HitTest.HitAtCalendar then
|
|
begin
|
|
FSingleSelection := True;
|
|
SelectDate(ADate);
|
|
end;
|
|
if not (ssLeft in AShift) then
|
|
Owner.DoSelectionChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.ProcessSelectionOnMouseMove(
|
|
AShift: TShiftState);
|
|
|
|
procedure ProcessDate(ADate: TDateTime);
|
|
begin
|
|
if FSingleSelection then
|
|
begin
|
|
FSelStart := ADate;
|
|
FSelFinish := ADate;
|
|
CalculateSelection(FExtSelect);
|
|
end
|
|
else
|
|
if ADate <> FSelFinish then
|
|
begin
|
|
FSelFinish := ADate;
|
|
if not Owner.SelectPeriod then FSelStart := FSelFinish;
|
|
//DELPHI8! check Trunc()
|
|
if not FExtSelect and
|
|
(Abs(Trunc(FSelStart) - Trunc(ADate)) + 1 > cxDaysCalendarMaxColCount) then
|
|
Owner.SelectionIsWeeks := True;
|
|
CalculateSelection(FExtSelect and not Owner.SelectionIsWeeks);
|
|
end;
|
|
end;
|
|
|
|
procedure ProcessWeek(ADate: TDateTime);
|
|
begin
|
|
if Owner.SelectionIsWeeks and Owner.SelectPeriod and (ADate <> FSelFinish) then
|
|
begin
|
|
FSelFinish := ADate;
|
|
CalculateSelection(FExtSelect and FSaveSelectionIsWeeks);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if not HitTest.HitAtControl then
|
|
begin
|
|
FSelFinish := NullDate;
|
|
Owner.SelectionList.Assign(FSaveSelectionList);
|
|
Owner.RefreshDays;
|
|
end
|
|
else if HitTest.HitAtTime then
|
|
ProcessDate(HitTest.Time)
|
|
else if HitTest.HitAtWeekSelectionBar then
|
|
ProcessWeek(HitTest.Time);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorController.GetHitTest: TcxSchedulerDateNavigatorHitTest;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorHitTest(inherited HitTest);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorController.GetOwner: TcxSchedulerDateNavigator;
|
|
begin
|
|
Result := TcxSchedulerDateNavigator(inherited Owner);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorController.GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
begin
|
|
Result := Owner.ViewInfo;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.SetDragDate(const Value: TDateTime);
|
|
begin
|
|
if FDragDate <> Value then
|
|
begin
|
|
FDragDate := Value;
|
|
Owner.Invalidate;
|
|
//Owner.RefreshDays;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.StartTimer(AFuture: Boolean);
|
|
begin
|
|
if Assigned(FTimer) then Exit;
|
|
FTimer := TTimer.Create(nil);
|
|
FTimer.Interval := cxDateStartNavigatorTime;
|
|
FTimer.Tag := Ord(AFuture);
|
|
FTimer.OnTimer := TimerProc;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.StopTimer;
|
|
begin
|
|
FreeAndNil(FTimer);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorController.TimerProc(Sender: TObject);
|
|
var
|
|
P: TPoint;
|
|
begin
|
|
GetCursorPos(P);
|
|
HitTest.HitPoint := Owner.Scheduler.ScreenToClient(P);
|
|
case TTimer(Sender).Tag of
|
|
0: if HitTest.HitAtPrevMonth then
|
|
Owner.StepToPast;
|
|
else
|
|
if HitTest.HitAtNextMonth then
|
|
Owner.StepToFuture;
|
|
end;
|
|
FTimer.Interval := cxDateNavigatorTime;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigator }
|
|
|
|
constructor TcxSchedulerDateNavigator.Create(AOwner: TcxCustomScheduler);
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
inherited Create(AOwner);
|
|
FRealFirstDate := NullDate;
|
|
FRealLastDate := NullDate;
|
|
FToday := SysUtils.Date;
|
|
DecodeDate(FToday, AYear, AMonth, ADay);
|
|
FFirstDate := EncodeDate(AYear, AMonth, 1);
|
|
FFirstWeekOfYear := fwySystem;
|
|
FActualFirstWeekOfYear := GetActualFirstWeekOfYear;
|
|
FShowDatesContainingEventsInBold := True;
|
|
FSelectPeriod := True;
|
|
FColCount := 1;
|
|
FRowCount := 1;
|
|
FShowWeekNumbers := True;
|
|
UpdateCalculatedValues;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetIntegralSizes;
|
|
begin
|
|
ViewInfo.CalcInternalSizes;
|
|
SetBounds(Left, Top,
|
|
ColCount * ViewInfo.MonthSize.cx,
|
|
RowCount * ViewInfo.MonthSize.cy);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.GetProperties(AProperties: TStrings);
|
|
begin
|
|
if not Visible then Exit;
|
|
with AProperties do
|
|
begin
|
|
if Scheduler.OptionsCustomize.IntegralSizing then
|
|
begin
|
|
Add('DNColCount');
|
|
Add('DNRowCount');
|
|
end
|
|
else
|
|
begin
|
|
Add('DNWidth');
|
|
Add('DNHeight');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.GetPropertyValue(const AName: string;
|
|
var AValue: Variant);
|
|
begin
|
|
if not Visible then Exit;
|
|
if AName = 'DNColCount' then
|
|
AValue := ColCount
|
|
else
|
|
if AName = 'DNRowCount' then
|
|
AValue := RowCount
|
|
else
|
|
if AName = 'DNWidth' then
|
|
AValue := Width
|
|
else
|
|
if AName = 'DNHeight' then
|
|
AValue := Height
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetPropertyValue(const AName: string;
|
|
const AValue: Variant);
|
|
begin
|
|
if not Visible then Exit;
|
|
if Scheduler.OptionsCustomize.IntegralSizing then
|
|
begin
|
|
if AName = 'DNColCount' then
|
|
ColCount := AValue
|
|
else
|
|
if AName = 'DNRowCount' then
|
|
RowCount := AValue
|
|
end
|
|
else
|
|
begin
|
|
if AName = 'DNWidth' then
|
|
Width := AValue
|
|
else
|
|
if AName = 'DNHeight' then
|
|
Height := AValue;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.AllowDesignHitTest(X, Y: Integer;
|
|
Shift: TShiftState): Boolean;
|
|
begin
|
|
inherited AllowDesignHitTest(X, Y, Shift);
|
|
Result := HitTest.HitAtCalendar;
|
|
if Result then
|
|
begin
|
|
Result := HitTest.HitAtTime or HitTest.HitAtWeekSelectionBar or
|
|
HitTest.HitAtMonthName or HitTest.HitAtNextMonth or HitTest.HitAtPrevMonth;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.CheckSizes;
|
|
begin
|
|
if Scheduler.OptionsCustomize.IntegralSizing then
|
|
SetIntegralSizes
|
|
else
|
|
begin
|
|
ViewInfo.CalcInternalSizes;
|
|
SetBounds(Left, Top,
|
|
Max(ViewInfo.MonthSize.cx, FSavedSize.cx),
|
|
Max(ViewInfo.MonthSize.cy, FSavedSize.cy));
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.CreateSubClasses;
|
|
begin
|
|
inherited CreateSubClasses;
|
|
FStyles := TcxSchedulerDateNavigatorStyles.Create(Self);
|
|
FListBox := TcxSchedulerMonthListBox.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.CreateController: TcxSchedulerSubControlController;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorController.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.CreateHitTest: TcxSchedulerSubControlHitTest;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorHitTest.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.CreatePainter: TcxSchedulerSubControlPainter;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorPainter.Create(Self);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.CreateViewInfo: TcxSchedulerSubControlViewInfo;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorViewInfo.Create(Self);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DestroySubClasses;
|
|
begin
|
|
FreeAndNil(FStyles);
|
|
inherited DestroySubClasses;
|
|
FreeAndNil(FListBox);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DoLayoutChanged;
|
|
begin
|
|
BeginUpdate;
|
|
try
|
|
UpdateCalculatedValues;
|
|
ViewInfo.Calculate;
|
|
FRowCount := ViewInfo.RowCount;
|
|
FColCount := ViewInfo.ColCount;
|
|
finally
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.CanDrawSelectionSide: Boolean;
|
|
begin
|
|
Result := not ShowWeekNumbers and SelectionIsWeeks;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.CheckSelectionBounds;
|
|
var
|
|
ASelectionCount: Integer;
|
|
AFirstSelectedDate: TDateTime;
|
|
|
|
procedure ShiftSelection(AForward: Boolean);
|
|
var
|
|
ADate: TDateTime;
|
|
AYear, AMonth, ADay: Word;
|
|
I: Integer;
|
|
begin
|
|
if AForward then ADate := LastDate else ADate := FirstDate;
|
|
DecodeDate(ADate, AYear, AMonth, ADay);
|
|
if SelectionIsWeeks then
|
|
ADate := ADate - ColOfDate(ADate, Byte(StartOfWeek))
|
|
else
|
|
ADate := EncodeDate(AYear, AMonth,
|
|
CheckDay(AYear, AMonth, GetDateElement(AFirstSelectedDate, 3)));
|
|
SelectionList.Clear;
|
|
for I := 0 to ASelectionCount - 1 do
|
|
begin
|
|
SelectionList.Add(ADate);
|
|
ADate := ADate + 1;
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
ASelectionCount := SelectionList.Count;
|
|
if ASelectionCount > 0 then
|
|
begin
|
|
AFirstSelectedDate := SelectionList[0];
|
|
if (AFirstSelectedDate < FirstDate) then
|
|
ShiftSelection(False)
|
|
else
|
|
if AFirstSelectedDate > LastDate then
|
|
ShiftSelection(True);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DoSelectionChanged;
|
|
begin
|
|
if IsLocked then Exit;
|
|
IsLocked := True;
|
|
try
|
|
SelectionList.Changed := False;
|
|
PeriodChanged;
|
|
finally
|
|
IsLocked := False;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DoPeriodChangedEvent;
|
|
begin
|
|
if Assigned(FOnPeriodChanged) then
|
|
FOnPeriodChanged(Self, RealFirstDate, RealLastDate);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DoSelectionChangedEvent;
|
|
begin
|
|
if Assigned(FOnSelectionChanged) then
|
|
FOnSelectionChanged(Self, SelectionList[0], SelectionList[SelectionList.Count - 1]);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DoScrollSelection(AScrollDelta: Integer);
|
|
begin
|
|
if AScrollDelta = 0 then Exit;
|
|
IsLocked := True;
|
|
try
|
|
while AScrollDelta <> 0 do
|
|
begin
|
|
ScrollSelection(AScrollDelta < 0, NullDate, False);
|
|
Inc(AScrollDelta, Byte(AScrollDelta < 0) * 2 - 1);
|
|
end;
|
|
finally
|
|
IsLocked := False;
|
|
DoSelectionChanged;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.DoScrollSelection(AForward: Boolean;
|
|
ANeedDate: TDateTime; AIsByPage: Boolean);
|
|
|
|
procedure ScrollWeeks;
|
|
var
|
|
I, J, ANumPass: Integer;
|
|
ADate: TDateTime;
|
|
begin
|
|
if AIsByPage then
|
|
ANumPass := SelectionList.Count div 7
|
|
else
|
|
ANumPass := 1;
|
|
for J := 1 to ANumPass do
|
|
if AForward then
|
|
begin
|
|
ADate := SelectionList[SelectionList.Count - 1] + 1;
|
|
for I := 0 to 6 do
|
|
begin
|
|
SelectionList.Add(ADate + I);
|
|
SelectionList.Delete(0);
|
|
end
|
|
end
|
|
else
|
|
begin
|
|
ADate := SelectionList[0] - 7;
|
|
for I := 0 to 6 do
|
|
begin
|
|
SelectionList.Add(ADate + I);
|
|
SelectionList.Delete(SelectionList.Count - 1);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure ScrollDays;
|
|
begin
|
|
if AForward then
|
|
begin
|
|
SelectionList.Add(SelectionList[SelectionList.Count - 1] + 1);
|
|
SelectionList.Delete(0);
|
|
end
|
|
else
|
|
begin
|
|
SelectionList.Add(SelectionList[0] - 1);
|
|
SelectionList.Delete(SelectionList.Count - 1);
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
if (SelectionList.Count = 0) or SelectionList.ExistDate(ANeedDate) then Exit;
|
|
if SelectionIsWeeks then
|
|
ScrollWeeks
|
|
else
|
|
ScrollDays;
|
|
EnsureSelectionVisible;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.EnsureSelectionVisible;
|
|
var
|
|
AMinDate, AMaxDate: TDateTime;
|
|
begin
|
|
if SelectionList.Count = 0 then Exit;
|
|
if SelectionIsWeeks then
|
|
begin
|
|
AMinDate := RealFirstDate;
|
|
AMaxDate := RealLastDate;
|
|
end
|
|
else
|
|
begin
|
|
AMinDate := FirstDate;
|
|
AMaxDate := LastDate;
|
|
end;
|
|
if SelectionList[0] > AMaxDate then
|
|
FirstDate := RealLastDate
|
|
else
|
|
if SelectionList[0] < AMinDate then
|
|
FirstDate := RealFirstDate
|
|
else
|
|
DoSelectionChanged;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.IsDateSelected(ADate: TDateTime): Boolean;
|
|
begin
|
|
Result := SelectionList.ExistDate(ADate);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.IsDateHasEvent(ADate: TDateTime): Boolean;
|
|
begin
|
|
Result := ShowDatesContainingEventsInBold and EventDays.ExistDate(ADate);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.FormatChanged;
|
|
begin
|
|
FActualFirstWeekOfYear := GetActualFirstWeekOfYear;
|
|
GetLocaleSettings;
|
|
RefreshDays;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetMonthSize: TSize;
|
|
begin
|
|
Result := ViewInfo.MonthSize;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetShowDatesContainingEventsInBold: Boolean;
|
|
begin
|
|
Result := FShowDatesContainingEventsInBold;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.RefreshDays;
|
|
begin
|
|
ViewInfo.CalculateMonthViewInfos;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetFirstDate(Value: TDateTime);
|
|
begin
|
|
//DELPHI8! check
|
|
Value := DateOf(Value) - (GetDateElement(Value, 3) - 1);
|
|
if FFirstDate <> Value then
|
|
begin
|
|
BeginUpdate;
|
|
FFirstDate := Value;
|
|
UpdateCalculatedValues;
|
|
CheckSelectionBounds;
|
|
ViewInfo.Calculate;
|
|
DoSelectionChanged;
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.ShowMonthPopup(
|
|
AMonthInfo: TcxSchedulerDateNavigatorMonthViewInfo);
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
if AMonthInfo = nil then Exit;
|
|
DecodeDate(FirstDate, AYear, AMonth, ADay);
|
|
FListBoxDelta := AMonthInfo.Row * ColCount + AMonthInfo.Col;
|
|
ChangeMonth(AYear, AMonth, FListBoxDelta - 3);
|
|
TcxSchedulerMonthListBox(FListBox).SetupMonth(
|
|
AMonthInfo.Header.MonthNameBounds, EncodeDate(AYear, AMonth, 1));
|
|
FListBox.Popup(FListBox)
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.StepToPast;
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
DecodeDate(FirstDate, AYear, AMonth, ADay);
|
|
DecMonth(AYear, AMonth);
|
|
FirstDate := EncodeDate(AYear, AMonth, 1);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.StepToFuture;
|
|
var
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
DecodeDate(FirstDate, AYear, AMonth, ADay);
|
|
IncMonth(AYear, AMonth);
|
|
FirstDate := EncodeDate(AYear, AMonth, 1);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.UpdateCalculatedValues;
|
|
begin
|
|
FToday := SysUtils.Date;
|
|
FLastDate := GetLastDate;
|
|
FRealFirstDate := GetRealFirstDate;
|
|
FRealLastDate := GetRealLastDate;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.UpdateDragging;
|
|
var
|
|
ADate: TDateTime;
|
|
begin
|
|
with HitTest do
|
|
begin
|
|
if HitAtTime then ADate := Time else ADate := NullDate;
|
|
Controller.DragDate := ADate;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.UpdateSelection;
|
|
var
|
|
ADate: TDateTime;
|
|
begin
|
|
if SelectionList.Count > 0 then
|
|
begin
|
|
if SelectionIsWeeks then
|
|
ADate := SelectionList[SelectionList.Count div 2]
|
|
else
|
|
ADate := SelectionList[0]
|
|
end
|
|
else
|
|
begin
|
|
ADate := FToday;
|
|
SelectionList.Add(FToday)
|
|
end;
|
|
if (ADate < FirstDate) or (ADate > LastDate) then
|
|
FirstDate := ADate;
|
|
DoSelectionChanged;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.AfterCustomDraw(ACanvas: TcxCanvas;
|
|
var AParams: TcxViewParams);
|
|
begin
|
|
with ACanvas do
|
|
begin
|
|
AParams.Color := Brush.Color;
|
|
AParams.Font := Font;
|
|
AParams.TextColor := Font.Color;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.BeforeCustomDraw(ACanvas: TcxCanvas;
|
|
const AParams: TcxViewParams);
|
|
begin
|
|
with ACanvas do
|
|
begin
|
|
Brush.Color := AParams.Color;
|
|
Font := AParams.Font;
|
|
Font.Color := AParams.TextColor;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.DoCustomDrawBackground(ACanvas: TcxCanvas;
|
|
const ABounds: TRect; var AViewParams: TcxViewParams): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnCustomDrawBackground) then
|
|
begin
|
|
BeforeCustomDraw(ACanvas, AViewParams);
|
|
FOnCustomDrawBackground(Self, ACanvas, ABounds, AViewParams, Result);
|
|
if not Result then
|
|
AfterCustomDraw(ACanvas, AViewParams);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.DoCustomDrawDayNumber(ACanvas: TcxCanvas; ADayInfo: TcxSchedulerDateNavigatorDayNumberViewInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnCustomDrawDayNumber) then
|
|
begin
|
|
BeforeCustomDraw(ACanvas, ADayInfo.FViewParams);
|
|
FOnCustomDrawDayNumber(Self, ACanvas, ADayInfo, Result);
|
|
if not Result then
|
|
AfterCustomDraw(ACanvas, ADayInfo.FViewParams);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.DoCustomDrawDayCaption(ACanvas: TcxCanvas;
|
|
ADayCaptionInfo: TcxSchedulerDateNavigatorDayCaptionViewInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnCustomDrawDayCaption) then
|
|
begin
|
|
BeforeCustomDraw(ACanvas, ADayCaptionInfo.ViewParams);
|
|
FOnCustomDrawDayCaption(Self, ACanvas, ADayCaptionInfo, Result);
|
|
if not Result then
|
|
AfterCustomDraw(ACanvas, ADayCaptionInfo.FViewParams);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.DoCustomDrawContent(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnCustomDrawContent) then
|
|
begin
|
|
BeforeCustomDraw(ACanvas, AViewInfo.ViewParams);
|
|
FOnCustomDrawContent(Self, ACanvas, AViewInfo, Result);
|
|
if not Result then
|
|
begin
|
|
AfterCustomDraw(ACanvas, AViewInfo.FViewParams);
|
|
AViewInfo.UpdateElementsAfterCustomDraw(ACanvas);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.DoCustomDrawHeader(ACanvas: TcxCanvas;
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo): Boolean;
|
|
begin
|
|
Result := False;
|
|
if Assigned(FOnCustomDrawHeader) then
|
|
begin
|
|
BeforeCustomDraw(ACanvas, AViewInfo.ViewParams);
|
|
FOnCustomDrawHeader(Self, ACanvas, AViewInfo, Result);
|
|
if not Result then
|
|
AfterCustomDraw(ACanvas, AViewInfo.FViewParams);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetActualFirstWeekOfYear: TcxFirstWeekOfYear;
|
|
begin
|
|
if FFirstWeekOfYear = fwySystem then
|
|
Result := TcxFirstWeekOfYear(
|
|
StrToInt(GetLocaleChar(GetUserDefaultLCID, LOCALE_IFIRSTWEEKOFYEAR, '0')) + 1)
|
|
else
|
|
Result := FFirstWeekOfYear;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetController: TcxSchedulerDateNavigatorController;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorController(inherited Controller);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetDate: TDateTime;
|
|
begin
|
|
if SelectionList.Count = 0 then
|
|
Result := NullDate
|
|
else
|
|
Result := SelectionList[0];
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetHitTest: TcxSchedulerDateNavigatorHitTest;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorHitTest(inherited HitTest);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetLastDate: TDateTime;
|
|
var
|
|
Year, Month, Day: Word;
|
|
begin
|
|
DecodeDate(FirstDate, Year, Month, Day);
|
|
ChangeMonth(Year, Month, ColCount * RowCount - 1);
|
|
Result := EncodeDate(Year, Month, DaysPerMonth(Year, Month));
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetRealFirstDate: TDateTime;
|
|
var
|
|
ACol: Integer;
|
|
begin
|
|
Result := FFirstDate;
|
|
ACol := ColOfDate(FirstDate, Byte(StartOfWeek));
|
|
if ACol = 0 then
|
|
Result := Result - 7
|
|
else
|
|
Result := Result - ACol;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetRealLastDate: TDateTime;
|
|
var
|
|
Year, Month, Day: Word;
|
|
ACol: Integer;
|
|
begin
|
|
Result := FLastDate;
|
|
DecodeDate(Result, Year, Month, Day);
|
|
ACol := ColOfDate(EncodeDate(Year, Month, 1), Byte(StartOfWeek));
|
|
Result := Result + 6 * 7 - DaysPerMonth(Year, Month) - ACol;
|
|
if (ACol = 0) and (ColCount * RowCount = 1) then Result := Result - 7;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigator.GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
begin
|
|
Result := TcxSchedulerDateNavigatorViewInfo(inherited ViewInfo);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetColCount(Value: Integer);
|
|
begin
|
|
if Value < 1 then Value := 1;
|
|
if FColCount <> Value then
|
|
begin
|
|
FColCount := Value;
|
|
ViewInfo.CalcInternalSizes;
|
|
Width := Value * ViewInfo.MonthSize.cx;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetDate(Value: TDateTime);
|
|
begin
|
|
if Value <> NullDate then
|
|
begin
|
|
SelectionList.Clear;
|
|
if (Value < FirstDate) or (Value > LastDate) then
|
|
FirstDate := Value;
|
|
SelectionIsWeeks := False;
|
|
SelectionList.Add(Value);
|
|
RefreshDays;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetFirstWeekOfYear(
|
|
Value: TcxFirstWeekOfYear);
|
|
begin
|
|
if Value <> FFirstWeekOfYear then
|
|
begin
|
|
FFirstWeekOfYear := Value;
|
|
FActualFirstWeekOfYear := GetActualFirstWeekOfYear;
|
|
if ShowWeekNumbers then
|
|
RefreshDays;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetRowCount(Value: Integer);
|
|
begin
|
|
if Value < 1 then Value := 1;
|
|
if FRowCount <> Value then
|
|
begin
|
|
FRowCount := Value;
|
|
ViewInfo.CalcInternalSizes;
|
|
Height := Value * ViewInfo.MonthSize.cy;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetSelectPeriod(Value: Boolean);
|
|
begin
|
|
if FSelectPeriod <> Value then
|
|
begin
|
|
FSelectPeriod := Value;
|
|
if not Value then
|
|
Date := Date;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetShowDatesContainingEventsInBold(Value: Boolean);
|
|
begin
|
|
if FShowDatesContainingEventsInBold <> Value then
|
|
begin
|
|
FShowDatesContainingEventsInBold := Value;
|
|
RefreshDays;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetShowWeekNumbers(Value: Boolean);
|
|
begin
|
|
if FShowWeekNumbers <> Value then
|
|
begin
|
|
FShowWeekNumbers := Value;
|
|
RefreshDays;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigator.SetStyles(
|
|
const Value: TcxSchedulerDateNavigatorStyles);
|
|
begin
|
|
FStyles.Assign(Value);
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorPainter }
|
|
|
|
constructor TcxSchedulerDateNavigatorPainter.Create(AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FDateNavigator := TcxSchedulerDateNavigator(AOwner);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.Paint;
|
|
var
|
|
I, J: Integer;
|
|
AMonthInfo: TcxSchedulerDateNavigatorMonthViewInfo;
|
|
begin
|
|
Canvas.FillRect(DateNavigator.ViewInfo.CalendarBounds,
|
|
DateNavigator.Styles.GetContentParams);
|
|
for I := 0 to DateNavigator.ColCount - 1 do
|
|
for J := 0 to DateNavigator.RowCount - 1 do
|
|
begin
|
|
AMonthInfo := DateNavigator.ViewInfo.MonthViewInfo[I, J];
|
|
DoDrawMonthContent(AMonthInfo.Content);
|
|
DoDrawMonthHeader(AMonthInfo.Header);
|
|
DoDrawDayCaptions(AMonthInfo.Content);
|
|
DoDrawDayNumbers(AMonthInfo.Content);
|
|
DrawSeparators(AMonthInfo.Content);
|
|
if DateNavigator.ShowWeekNumbers then
|
|
DrawWeekNumbers(AMonthInfo.Content);
|
|
end;
|
|
Canvas.ExcludeClipRect(DateNavigator.ViewInfo.CalendarBounds);
|
|
DrawBackground;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DoDrawDayCaptions(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo);
|
|
var
|
|
I: Integer;
|
|
AInfo: TcxSchedulerDateNavigatorDayCaptionViewInfo;
|
|
begin
|
|
for I := 0 to 6 do
|
|
begin
|
|
AInfo := AViewInfo.DayCaptions[I];
|
|
AInfo.SaveParams(AViewInfo.Transparent);
|
|
if not DateNavigator.DoCustomDrawDayCaption(Canvas, AInfo) then
|
|
begin
|
|
cxApplyViewParams(Canvas, AInfo.ViewParams);
|
|
if not AInfo.Transparent then
|
|
Canvas.FillRect(AInfo.Bounds, AInfo.ViewParams);
|
|
Canvas.Brush.Style := bsClear;
|
|
Canvas.DrawText(AInfo.Text, cxRectOffset(AInfo.Bounds, -2, 0), cxdnTextFlags);
|
|
Canvas.Brush.Style := bsSolid;
|
|
end;
|
|
AInfo.RestoreParams;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DoDrawDayNumbers(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo);
|
|
var
|
|
I: Integer;
|
|
ADayInfo: TcxSchedulerDateNavigatorDayNumberViewInfo;
|
|
begin
|
|
for I := 0 to AViewInfo.FDayCount - 1 do
|
|
begin
|
|
ADayInfo := AViewInfo.FDays[I];
|
|
ADayInfo.SaveParams(AViewInfo.Transparent and not ADayInfo.Selected);
|
|
if not DateNavigator.DoCustomDrawDayNumber(Canvas, ADayInfo) then
|
|
DrawDayNumber(ADayInfo);
|
|
ADayInfo.RestoreParams;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DoDrawMonthContent(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo);
|
|
begin
|
|
AViewInfo.SaveParams;
|
|
if not DateNavigator.DoCustomDrawContent(Canvas, AViewInfo) then
|
|
// use owner's bounds
|
|
Canvas.FillRect(AViewInfo.Owner.Bounds, AViewInfo.ViewParams);
|
|
AViewInfo.RestoreParams;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DoDrawMonthHeader(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo);
|
|
begin
|
|
AViewInfo.SaveParams(False);
|
|
if not DateNavigator.DoCustomDrawHeader(Canvas, AViewInfo) then
|
|
begin
|
|
FHeaderTransparent := AViewInfo.Transparent;
|
|
DrawMonthHeader(AViewInfo);
|
|
end;
|
|
AViewInfo.RestoreParams;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DrawDayNumber(
|
|
ADayInfo: TcxSchedulerDateNavigatorDayNumberViewInfo);
|
|
begin
|
|
cxApplyViewParams(Canvas, ADayInfo.ViewParams);
|
|
with Canvas do
|
|
begin
|
|
if DateNavigator.ShowDatesContainingEventsInBold then
|
|
begin
|
|
if ADayInfo.Bold then
|
|
Font.Style := Font.Style + [fsBold]
|
|
else
|
|
Font.Style := Font.Style - [fsBold];
|
|
end;
|
|
if not ADayInfo.Transparent then
|
|
begin
|
|
FillRect(ADayInfo.Bounds, ADayInfo.ViewParams);
|
|
if not cxRectIsEmpty(ADayInfo.SelectionSideBounds) then
|
|
FillRect(ADayInfo.SelectionSideBounds);
|
|
end;
|
|
CheckDrawFrame(ADayInfo.Bounds, ADayInfo.Date);
|
|
Brush.Style := bsClear;
|
|
DrawText(ADayInfo.Text, cxRectOffset(ADayInfo.Bounds, -2, 0), cxdnTextFlags);
|
|
Brush.Style := bsSolid;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DrawBackground;
|
|
var
|
|
AViewParams: TcxViewParams;
|
|
begin
|
|
with DateNavigator do
|
|
begin
|
|
AViewParams := Styles.GetBackgroundParams;
|
|
if not DoCustomDrawBackground(Canvas, ClientRect, AViewParams) then
|
|
Canvas.FillRect(ClientRect, AViewParams);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DrawMonthHeader(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthHeaderViewInfo);
|
|
begin
|
|
FHeaderParams := AViewInfo.ViewParams;
|
|
DateNavigator.LookAndFeelPainter.DrawMonthHeader(Canvas, AViewInfo.Bounds,
|
|
AViewInfo.Text, AViewInfo.Neighbors, FHeaderParams, AViewInfo.Arrows,
|
|
DateNavigator.ViewInfo.SideWidth, DrawHeaderBackground);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DrawSeparators(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo);
|
|
begin
|
|
with Canvas do
|
|
begin
|
|
SetBrushColor(clBtnShadow);
|
|
FillRect(AViewInfo.HorzSeparatorBound);
|
|
if DateNavigator.ShowWeekNumbers then
|
|
begin
|
|
FillRect(cxRectSetWidth(AViewInfo.VertSeparatorBound, 1));
|
|
SetBrushColor(clBtnHighlight);
|
|
FillRect(cxRectSetWidth(AViewInfo.VertSeparatorBound,
|
|
AViewInfo.VertSeparatorBound.Left + 1, 1));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.DrawWeekNumbers(
|
|
AViewInfo: TcxSchedulerDateNavigatorMonthContentViewInfo);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
with Canvas do
|
|
begin
|
|
Brush.Style := bsClear;
|
|
Font := AViewInfo.ViewParams.Font;
|
|
Font.Color := AViewInfo.ViewParams.TextColor;
|
|
Font.Size := MulDiv(AViewInfo.ViewParams.Font.Size, 2, 3);
|
|
with AViewInfo do
|
|
for I := 0 to FWeekCount - 1 do
|
|
DrawText(FWeekTexts[I], FWeekBounds[I], cxdnTextFlags);
|
|
Brush.Style := bsSolid;
|
|
Font.Size := AViewInfo.ViewParams.Font.Size;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorPainter.CheckDrawFrame(
|
|
const ABounds: TRect; ADate: TDateTime);
|
|
begin
|
|
if ADate = DateNavigator.Controller.DragDate then
|
|
Canvas.FrameRect(ABounds, clWindowText, 2)
|
|
else
|
|
if ADate = DateNavigator.FToday then
|
|
begin
|
|
Canvas.SetBrushColor(clMaroon);
|
|
Canvas.FrameRect(ABounds);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorPainter.DrawHeaderBackground(ACanvas: TcxCanvas;
|
|
const ABounds: TRect): Boolean;
|
|
begin
|
|
Result := True;
|
|
if not FHeaderTransparent then
|
|
ACanvas.FillRect(ABounds, FHeaderParams);
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorCaptionViewInfo }
|
|
|
|
procedure TcxSchedulerDateNavigatorCaptionViewInfo.RestoreParams;
|
|
begin
|
|
FViewParams := FSaveParams;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorCaptionViewInfo.SaveParams(ATransparent: Boolean);
|
|
begin
|
|
FSaveParams := FViewParams;
|
|
FTransparent := ATransparent;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorMonthHeaderViewInfo }
|
|
|
|
constructor TcxSchedulerDateNavigatorMonthHeaderViewInfo.Create(
|
|
AOwner: TcxSchedulerDateNavigatorMonthViewInfo);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthHeaderViewInfo.Calculate(const ABounds: TRect);
|
|
begin
|
|
FBounds := ABounds;
|
|
FText := Owner.Owner.DateTimeHelper.MonthYearToStr(Month, Year);
|
|
FArrows := Owner.GetHeaderArrows;
|
|
FNeighbors := Owner.GetHeaderNeighbors;
|
|
FMonthNameBounds := GetMonthNameBounds;
|
|
FViewParams := Owner.Owner.HeaderParams;
|
|
FTransparent := False;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthHeaderViewInfo.GetMonth: Integer;
|
|
begin
|
|
Result := Owner.Month;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthHeaderViewInfo.GetMonthNameBounds: TRect;
|
|
begin
|
|
Result := Bounds;
|
|
with Result do
|
|
begin
|
|
Inc(Left, Owner.Owner.ColWidth);
|
|
Dec(Right, Owner.Owner.ColWidth);
|
|
Dec(Bottom);
|
|
Inc(Top);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthHeaderViewInfo.GetYear: Integer;
|
|
begin
|
|
Result := Owner.Year;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorMonthContentViewInfo }
|
|
|
|
constructor TcxSchedulerDateNavigatorMonthContentViewInfo.Create(
|
|
AOwner: TcxSchedulerDateNavigatorMonthViewInfo);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
FViewInfo := AOwner.Owner;
|
|
FDateNavigator := AOwner.Owner.Owner;
|
|
FFont := TFont.Create;
|
|
CreateDayInfos;
|
|
CreateDayCaptionInfos;
|
|
end;
|
|
|
|
destructor TcxSchedulerDateNavigatorMonthContentViewInfo.Destroy;
|
|
begin
|
|
DestroyDayCaptionInfos;
|
|
DestroyDayInfos;
|
|
FFont.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CalcAndAddDayInfo(ADate: TDateTime;
|
|
const ABounds: TRect; const ASelectionSideBounds: TRect);
|
|
var
|
|
ASelected: Boolean;
|
|
begin
|
|
ASelected := DateNavigator.IsDateSelected(ADate);
|
|
with FDays[FDayCount] do
|
|
begin
|
|
FBold := DateNavigator.IsDateHasEvent(ADate);
|
|
FBounds := ABounds;
|
|
FDate := ADate;
|
|
FGrayed := GetGrayed(ADate);
|
|
FSelected := ASelected;
|
|
if ASelected and DateNavigator.CanDrawSelectionSide then
|
|
FSelectionSideBounds := ASelectionSideBounds
|
|
else
|
|
FSelectionSideBounds := cxNullRect;
|
|
FText := IntToStr(GetDateElement(ADate, 3));
|
|
FViewParams := GetDateViewParams(ADate, ASelected);
|
|
if FGrayed then FViewParams.TextColor := clGrayText;
|
|
end;
|
|
Inc(FDayCount);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.Calculate(
|
|
ACol, ARow, AYear, AMonth: Integer);
|
|
begin
|
|
FBounds := ViewInfo.GetInternalRect(ACol, ARow);
|
|
FRow := ARow;
|
|
FCol := ACol;
|
|
FYear := AYear;
|
|
FMonth := AMonth;
|
|
CalcParams;
|
|
CalcDayCaptions;
|
|
CalcDays;
|
|
with FWeekSelectionBarBounds do
|
|
begin
|
|
Left := Bounds.Left;
|
|
Top := Bounds.Top + ViewInfo.DayCaptionsHeight;
|
|
Right := Left + ViewInfo.SideWidth;
|
|
Bottom := Top + ViewInfo.RowHeight * FWeekCount;
|
|
end;
|
|
CalcSeparatorsBound;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CalcDays;
|
|
var
|
|
R: TRect;
|
|
I, J, ADayBase, ADaysPerMonth: Integer;
|
|
ADate, ADateBase: TDateTime;
|
|
AHasDate: Boolean;
|
|
|
|
procedure CheckCalcWeekNumber(const R: TRect);
|
|
begin
|
|
if DateNavigator.ShowWeekNumbers then
|
|
begin
|
|
FWeekBounds[FWeekCount] := cxRect(R.Left - ViewInfo.SideWidth,
|
|
R.Top - 1, R.Left - 3, R.Bottom);
|
|
FWeekTexts[FWeekCount] := IntToStr(GetWeekNumber(ADate,
|
|
DateNavigator.StartOfWeek, DateNavigator.FActualFirstWeekOfYear));
|
|
end;
|
|
Inc(FWeekCount);
|
|
end;
|
|
|
|
function GetDate(out ADate: TDateTime): Boolean;
|
|
var
|
|
ACurDay: Integer;
|
|
begin
|
|
ACurDay := ADayBase + J * 7 + I;
|
|
Result := not ((ACurDay < 1) and (FCol + FRow <> 0) or
|
|
(ACurDay > ADaysPerMonth) and ((FCol <> ViewInfo.ColCount - 1) or
|
|
(FRow <> ViewInfo.RowCount - 1)));
|
|
ADate := ADateBase + ACurDay;
|
|
end;
|
|
|
|
begin
|
|
FDayCount := 0;
|
|
FWeekCount := 0;
|
|
ADateBase := EncodeDate(FYear, FMonth, 1) - 1;
|
|
ADayBase := 1 - ColOfDate(ADateBase + 1, Byte(DateNavigator.StartOfWeek));
|
|
if (ADayBase = 1) and (FCol + FRow = 0) then Dec(ADayBase, 7);
|
|
ADaysPerMonth := DaysPerMonth(FYear, FMonth);
|
|
for I := 0 to 6 do
|
|
for J := 0 to 5 do
|
|
begin
|
|
AHasDate := GetDate(ADate);
|
|
R := GetDayRectFromColAndRow(I, J);
|
|
if (I = 0) and not ((J = 5) and not AHasDate) then
|
|
CheckCalcWeekNumber(R);
|
|
if AHasDate then
|
|
CalcAndAddDayInfo(ADate, R, GetSelectionSideBounds(R, I));
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CalcDayCaptions;
|
|
var
|
|
I: Integer;
|
|
R: TRect;
|
|
begin
|
|
with R do
|
|
begin
|
|
Top := Bounds.Top;
|
|
Bottom := Top + ViewInfo.DayCaptionsHeight - 2;
|
|
Right := Bounds.Left + ViewInfo.SideWidth;
|
|
end;
|
|
for I := 0 to 6 do
|
|
begin
|
|
with R do
|
|
begin
|
|
Left := Right;
|
|
Right := Left + ViewInfo.ColWidth;
|
|
end;
|
|
FDayCaptions[I].FBounds := R;
|
|
FDayCaptions[I].FIndex := I;
|
|
FDayCaptions[I].FText := GetDayCaptionText(I);
|
|
FDayCaptions[I].FViewParams := ViewParams;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CalcParams;
|
|
begin
|
|
FViewParams := ViewInfo.ContentParams;
|
|
FSelectedParams := ViewInfo.SelectedParams;
|
|
FFontCharset := FViewParams.Font.Charset;
|
|
if FFontCharset = DEFAULT_CHARSET then
|
|
FFontCharset := GetDefFontCharset;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CalcSeparatorsBound;
|
|
begin
|
|
with FHorzSeparatorBound do
|
|
begin
|
|
Left := Bounds.Left + ViewInfo.SideWidth;
|
|
Right := Bounds.Right - ViewInfo.SideWidth + 1;
|
|
Top := Bounds.Top + ViewInfo.DayCaptionsHeight - 2;
|
|
Bottom := Top + 1;
|
|
end;
|
|
if DateNavigator.ShowWeekNumbers then
|
|
begin
|
|
with FVertSeparatorBound do
|
|
begin
|
|
Left := WeekSelectionBarBounds.Right;
|
|
Right := Left + 2;
|
|
Top := WeekSelectionBarBounds.Top - 1;
|
|
Bottom := WeekSelectionBarBounds.Bottom;
|
|
end
|
|
end
|
|
else
|
|
FVertSeparatorBound := cxNullRect;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetDateViewParams(ADate: TDateTime;
|
|
ASelected: Boolean): TcxViewParams;
|
|
begin
|
|
if ASelected then
|
|
Result := SelectedParams
|
|
else
|
|
Result := ViewParams;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetDayCaptionText(Index: Byte): string;
|
|
var
|
|
ADayIndex: Integer;
|
|
begin
|
|
if IsValidDayCaptionIndex(Index) then
|
|
begin
|
|
ADayIndex := Byte(DateNavigator.StartOfWeek) + 1 + Index;
|
|
if ADayIndex > 7 then Dec(ADayIndex, 7);
|
|
if FFontCharset in [ARABIC_CHARSET, CHINESEBIG5_CHARSET, GB2312_CHARSET] then
|
|
Result := AnsiLastChar(ShortDayNames[ADayIndex])
|
|
else
|
|
Result := WideString(ShortDayNames[ADayIndex])[1];
|
|
end
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetWeekBound(Index: Byte): TRect;
|
|
begin
|
|
if IsValidWeekIndex(Index) then
|
|
Result := FWeekBounds[Index]
|
|
else
|
|
Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetDayText(ADate: TDateTime): string;
|
|
begin
|
|
if ADate <> NullDate then
|
|
Result := IntToStr(GetDateElement(ADate, 3))
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetWeekText(Index: Byte): string;
|
|
begin
|
|
if IsValidWeekIndex(Index) then
|
|
Result := FWeekTexts[Index]
|
|
else
|
|
Result := '';
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.RestoreParams;
|
|
begin
|
|
FViewParams := FSaveParams;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.SaveParams;
|
|
begin
|
|
FTransparent := False;
|
|
FSaveParams := FViewParams;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.UpdateElementsAfterCustomDraw(
|
|
ACanvas: TcxCanvas);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
FFont.Assign(ACanvas.Font);
|
|
for I := 0 to 6 do
|
|
with FDayCaptions[I] do
|
|
begin
|
|
FViewParams.Color := Self.ViewParams.Color;
|
|
FViewParams.TextColor := Self.ViewParams.TextColor;
|
|
FViewParams.Font := FFont;
|
|
end;
|
|
for I := 0 to FDayCount - 1 do
|
|
with FDays[I] do
|
|
if not Selected then
|
|
begin
|
|
if not Grayed then
|
|
FViewParams.TextColor := Self.ViewParams.TextColor;
|
|
FViewParams.Color := Self.ViewParams.Color;
|
|
FViewParams.Font := FFont;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CreateDayInfos;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to cxMaxMonthViewInfoDays - 1 do
|
|
FDays[I] := TcxSchedulerDateNavigatorDayNumberViewInfo.Create;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.CreateDayCaptionInfos;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to 6 do
|
|
FDayCaptions[I] := TcxSchedulerDateNavigatorDayCaptionViewInfo.Create;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.DestroyDayInfos;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to cxMaxMonthViewInfoDays - 1 do
|
|
FDays[I].Free;
|
|
FDayCount := 0;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.DestroyDayCaptionInfos;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to 6 do
|
|
FDayCaptions[I].Free;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetDayCaptionInfo(
|
|
Index: Byte): TcxSchedulerDateNavigatorDayCaptionViewInfo;
|
|
begin
|
|
if IsValidDayCaptionIndex(Index) then
|
|
Result := FDayCaptions[Index]
|
|
else
|
|
Result := nil;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetDayRectFromColAndRow(
|
|
ACol, ARow: Integer): TRect;
|
|
begin
|
|
with Result do
|
|
begin
|
|
Left := Bounds.Left + ViewInfo.SideWidth + ACol * ViewInfo.ColWidth + 2;
|
|
Top := Bounds.Top + ViewInfo.DayCaptionsHeight + ARow * ViewInfo.RowHeight;
|
|
Right := Left + ViewInfo.ColWidth;
|
|
Bottom := Top + ViewInfo.RowHeight;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetDayNumberViewInfo(
|
|
Index: Byte): TcxSchedulerDateNavigatorDayNumberViewInfo;
|
|
begin
|
|
if IsValidDayIndex(Index) then
|
|
Result := FDays[Index]
|
|
else
|
|
begin
|
|
Result.Text := '';
|
|
FillChar(Result, SizeOf(Result), 0);
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetGrayed(ADate: TDateTime): Boolean;
|
|
begin
|
|
Result := (ADate < DateNavigator.FirstDate) and (FCol + FRow = 0) or
|
|
(ADate > DateNavigator.LastDate) and (FCol = ViewInfo.ColCount - 1) and
|
|
(FRow = ViewInfo.RowCount - 1);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.GetSelectionSideBounds(
|
|
const ADayBounds: TRect; ACol: Integer): TRect;
|
|
begin
|
|
if ((ACol = 0) or (ACol = 6)) and not DateNavigator.ShowWeekNumbers then
|
|
begin
|
|
Result := ADayBounds;
|
|
with Result do
|
|
if ACol = 0 then
|
|
begin
|
|
Right := Left;
|
|
Left := Right - ViewInfo.ColWidth div 2;
|
|
end
|
|
else
|
|
begin
|
|
Left := Right;
|
|
Right := Left + ViewInfo.ColWidth div 2;
|
|
end;
|
|
end
|
|
else Result := cxNullRect;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.IsValidDayIndex(Index: Byte): Boolean;
|
|
begin
|
|
Result := Index < FDayCount;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.IsValidDayCaptionIndex(Index: Byte): Boolean;
|
|
begin
|
|
Result := Index in [0..6];
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthContentViewInfo.IsValidWeekIndex(Index: Byte): Boolean;
|
|
begin
|
|
Result := Index < FWeekCount;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthContentViewInfo.SetWeekText(Index: Byte; const Value: string);
|
|
begin
|
|
if IsValidWeekIndex(Index) then
|
|
FWeekTexts[Index] := Value;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorMonthViewInfo }
|
|
|
|
constructor TcxSchedulerDateNavigatorMonthViewInfo.Create(
|
|
AOwner: TcxSchedulerDateNavigatorViewInfo);
|
|
begin
|
|
inherited Create;
|
|
FOwner := AOwner;
|
|
FHeader := TcxSchedulerDateNavigatorMonthHeaderViewInfo.Create(Self);
|
|
FContent := TcxSchedulerDateNavigatorMonthContentViewInfo.Create(Self);
|
|
end;
|
|
|
|
destructor TcxSchedulerDateNavigatorMonthViewInfo.Destroy;
|
|
begin
|
|
FContent.Free;
|
|
FHeader.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorMonthViewInfo.Calculate(ACol, ARow,
|
|
AYear, AMonth: Integer);
|
|
begin
|
|
FBounds := Owner.GetMonthRect(ACol, ARow);
|
|
FRow := ARow;
|
|
FCol := ACol;
|
|
FYear := AYear;
|
|
FMonth := AMonth;
|
|
Header.Calculate(Owner.GetHeaderRect(ACol, ARow));
|
|
Content.Calculate(ACol, ARow, AYear, AMonth);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthViewInfo.GetHeaderArrows: TcxHeaderArrows;
|
|
const
|
|
Arrows: array[Boolean, Boolean] of TcxHeaderArrows =
|
|
((haNone, haRight), (haLeft, haBoth));
|
|
begin
|
|
if Row = 0 then
|
|
Result := Arrows[Col = 0, Col = Owner.ColCount - 1]
|
|
else
|
|
Result := haNone;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorMonthViewInfo.GetHeaderNeighbors: TcxNeighbors;
|
|
begin
|
|
if Owner.ColCount = 1 then
|
|
Result := []
|
|
else if Col = 0 then
|
|
Result := [nRight]
|
|
else if Col = Owner.ColCount - 1 then
|
|
Result := [nLeft]
|
|
else
|
|
Result := [nLeft, nRight];
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorStyles }
|
|
|
|
constructor TcxSchedulerDateNavigatorStyles.Create(AOwner: TPersistent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
BitmapInViewParams := True;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorStyles.Assign(Source: TPersistent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if Source is TcxSchedulerDateNavigatorStyles then
|
|
begin
|
|
for I := cxdnBackground to cxdnSelection do
|
|
SetValue(I, TcxSchedulerDateNavigatorStyles(Source).GetValue(I))
|
|
end;
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorStyles.Changed(AIndex: Integer);
|
|
begin
|
|
DateNavigator.CheckSizes;
|
|
DateNavigator.Refresh;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorStyles.GetBackgroundParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxdnBackground, nil, nil, Result);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorStyles.GetContentParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxdnContent, nil, nil, Result);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorStyles.GetHeaderParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxdnHeader, nil, nil, Result);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorStyles.GetSelectionParams: TcxViewParams;
|
|
begin
|
|
GetViewParams(cxdnSelection, nil, nil, Result);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorStyles.GetDefaultViewParams(
|
|
Index: Integer; AData: TObject; out AParams: TcxViewParams);
|
|
|
|
function Painter: TcxCustomLookAndFeelPainterClass;
|
|
begin
|
|
Result := DateNavigator.LookAndFeelPainter;
|
|
end;
|
|
|
|
begin
|
|
AParams.Bitmap := nil;
|
|
AParams.Font := DateNavigator.Scheduler.Font;
|
|
case Index of
|
|
cxdnHeader:
|
|
begin
|
|
AParams.Color := Painter.DefaultHeaderColor;
|
|
AParams.TextColor := Painter.DefaultHeaderTextColor;
|
|
end;
|
|
cxdnBackground, cxdnContent:
|
|
begin
|
|
AParams.Color := Painter.DefaultSchedulerBackgroundColor;
|
|
AParams.TextColor := Painter.DefaultSchedulerTextColor;
|
|
end;
|
|
cxdnSelection:
|
|
begin
|
|
AParams.Font := GetContentParams.Font;
|
|
AParams.Color := Painter.DefaultDateNavigatorSelectionColor;
|
|
AParams.TextColor := Painter.DefaultDateNavigatorSelectionTextColor;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorStyles.GetDateNavigator: TcxSchedulerDateNavigator;
|
|
begin
|
|
Result := TcxSchedulerDateNavigator(inherited Owner);
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorHitTest }
|
|
|
|
procedure TcxSchedulerDateNavigatorHitTest.Clear;
|
|
begin
|
|
inherited Clear;
|
|
FTime := NullDate;
|
|
FMonthViewInfo := nil;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorHitTest.DoCalculate;
|
|
var
|
|
ACol, ARow: Integer;
|
|
ADay, AYear, AMonth: Word;
|
|
begin
|
|
inherited DoCalculate;
|
|
if cxRectPtIn(ViewInfo.CalendarBounds, HitPoint) then
|
|
begin
|
|
SetBitState(htcCalendar, True);
|
|
ACol := ViewInfo.GetCol(HitX);
|
|
ARow := ViewInfo.GetRow(HitY);
|
|
DecodeDate(Owner.FirstDate, AYear, AMonth, ADay);
|
|
ChangeMonth(AYear, AMonth, ARow * ViewInfo.ColCount + ACol);
|
|
FTime := EncodeDate(AYear, AMonth, 1);
|
|
FMonthViewInfo := ViewInfo.MonthViewInfo[ACol, ARow];
|
|
CalcMonth;
|
|
end;
|
|
{$IFDEF DEBUG}
|
|
if FHitDate <> NullDate then
|
|
Application.MainForm.Caption := DateToStr(FHitDate)
|
|
else
|
|
Application.MainForm.Caption := 'NullDate'
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorHitTest.CalcMonth;
|
|
var
|
|
R: TRect;
|
|
ADate: TDateTime;
|
|
begin
|
|
if CheckMonthHeader or CheckWeekSelectionBar or CheckDayCaptions then Exit;
|
|
R := MonthViewInfo.Content.Bounds;
|
|
with R do
|
|
begin
|
|
Inc(Top, ViewInfo.DayCaptionsHeight);
|
|
Inc(Left, ViewInfo.SideWidth + 2);
|
|
Dec(Right, ViewInfo.SideWidth);
|
|
end;
|
|
if cxRectPtIn(R, HitPoint) then
|
|
begin
|
|
SetBitState(htcTime, True);
|
|
ADate := GetFirstWeekSelectableDate +
|
|
((HitY - R.Top) div ViewInfo.RowHeight) * 7 + ((HitX - R.Left) div ViewInfo.ColWidth);
|
|
if (ADate < FTime) and (MonthViewInfo.Col + MonthViewInfo.Row > 0) then Exit;
|
|
FTime := FTime + DaysPerMonth(MonthViewInfo.Year, MonthViewInfo.Month) - 1;
|
|
if (ADate > FTime) and not ((MonthViewInfo.Col = Owner.ColCount - 1) and
|
|
(MonthViewInfo.Row = Owner.RowCount - 1)) then Exit;
|
|
FTime := ADate;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorHitTest.CheckDayCaptions: Boolean;
|
|
var
|
|
R: TRect;
|
|
begin
|
|
R := MonthViewInfo.Bounds;
|
|
with R do
|
|
begin
|
|
Inc(Left, ViewInfo.SideWidth);
|
|
Dec(Right, ViewInfo.SideWidth);
|
|
Bottom := Top + ViewInfo.DayCaptionsHeight;
|
|
end;
|
|
Result := cxRectPtIn(R, HitPoint);
|
|
if Result then
|
|
SetBitState(htcDayCaptions, True);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorHitTest.CheckMonthHeader: Boolean;
|
|
begin
|
|
Result := False;
|
|
if cxRectPtIn(MonthViewInfo.Header.MonthNameBounds, HitPoint) then
|
|
begin
|
|
SetBitState(htcMonthName, True);
|
|
Result := True;
|
|
end
|
|
else
|
|
if cxRectPtIn(ViewInfo.GetLeftArrowRect, HitPoint) then
|
|
begin
|
|
SetBitState(htcPrevMonth, True);
|
|
Result := True;
|
|
end
|
|
else
|
|
if cxRectPtIn(ViewInfo.GetRightArrowRect, HitPoint) then
|
|
begin
|
|
SetBitState(htcNextMonth, True);
|
|
Result := True;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorHitTest.CheckWeekSelectionBar: Boolean;
|
|
var
|
|
AContent: TcxSchedulerDateNavigatorMonthContentViewInfo;
|
|
begin
|
|
AContent := MonthViewInfo.Content;
|
|
Result := cxRectPtIn(AContent.WeekSelectionBarBounds, HitPoint);
|
|
if Result then
|
|
begin
|
|
SetBitState(htcWeekSelectionBar, True);
|
|
FTime := GetFirstWeekSelectableDate +
|
|
((HitY - AContent.WeekSelectionBarBounds.Top) div ViewInfo.RowHeight) * 7;
|
|
end;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorHitTest.GetFirstWeekSelectableDate: TDateTime;
|
|
begin
|
|
Result := FTime - ColOfDate(FTime, Byte(Owner.StartOfWeek));
|
|
if (MonthViewInfo.Col + MonthViewInfo.Row = 0) and
|
|
(ColOfDate(Owner.FirstDate, Byte(Owner.StartOfWeek)) = 0) then
|
|
Result := Result - 7;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorHitTest.GetOwner: TcxSchedulerDateNavigator;
|
|
begin
|
|
Result := TcxSchedulerDateNavigator(inherited Owner);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorHitTest.GetViewInfo: TcxSchedulerDateNavigatorViewInfo;
|
|
begin
|
|
Result := Owner.ViewInfo;
|
|
end;
|
|
|
|
{ TcxSchedulerDateNavigatorViewInfo }
|
|
|
|
constructor TcxSchedulerDateNavigatorViewInfo.Create(AOwner: TcxSchedulerSubControl);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FOwner := TcxSchedulerDateNavigator(AOwner);
|
|
FMonthViewInfoList := TList.Create;
|
|
end;
|
|
|
|
destructor TcxSchedulerDateNavigatorViewInfo.Destroy;
|
|
begin
|
|
DestroyMonthViewInfoList;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.DoCalculate;
|
|
begin
|
|
CalcInternalSizes;
|
|
CalculateCalendarBounds;
|
|
CheckMonthViewInfoCount;
|
|
CalculateMonthViewInfos;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.CalculateCalendarBounds;
|
|
begin
|
|
FCalendarBounds := Owner.ClientRect;
|
|
FColCount := Max(1, Min(cxDaysCalendarMaxColCount, Owner.Width div MonthSize.cx));
|
|
FRowCount := Max(1, Owner.Height div MonthSize.cy);
|
|
FCalendarBounds := cxRect(0, 0, ColCount * MonthSize.cx, RowCount * MonthSize.cy);
|
|
FCalendarBounds := cxRectOffset(FCalendarBounds,
|
|
(Owner.Width - cxRectWidth(CalendarBounds)) div 2,
|
|
(Owner.Height - cxRectHeight(CalendarBounds)) div 2);
|
|
if FCalendarBounds.Left < 0 then
|
|
FCalendarBounds := cxRectSetLeft(FCalendarBounds, 0);
|
|
if FCalendarBounds.Top < 0 then
|
|
FCalendarBounds := cxRectSetTop(FCalendarBounds, 0);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.CalculateMonthViewInfos;
|
|
var
|
|
I, J: Integer;
|
|
AYear, AMonth, ADay: Word;
|
|
begin
|
|
DecodeDate(Owner.FirstDate, AYear, AMonth, ADay);
|
|
for J := 0 to RowCount - 1 do
|
|
for I := 0 to ColCount - 1 do
|
|
begin
|
|
MonthViewInfo[I, J].Calculate(I, J, AYear, AMonth);
|
|
ChangeMonth(AYear, AMonth, 1);
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.CalculateViewParams;
|
|
begin
|
|
with Owner.Styles do
|
|
begin
|
|
FContentParams := GetContentParams;
|
|
FHeaderParams := GetHeaderParams;
|
|
FSelectedParams := GetSelectionParams;
|
|
end;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.CheckMonthViewInfoCount;
|
|
var
|
|
I, ACount: Integer;
|
|
begin
|
|
ACount := RowCount * ColCount;
|
|
for I := FMonthViewInfoList.Count - 1 downto ACount do
|
|
begin
|
|
TcxSchedulerDateNavigatorMonthViewInfo(FMonthViewInfoList[I]).Free;
|
|
FMonthViewInfoList.Delete(I);
|
|
end;
|
|
for I := FMonthViewInfoList.Count to ACount - 1 do
|
|
FMonthViewInfoList.Add(TcxSchedulerDateNavigatorMonthViewInfo.Create(Self));
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetCol(X: Integer): Integer;
|
|
begin
|
|
Result := (X - CalendarBounds.Left) div MonthSize.cx;
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetHeaderRect(ACol, ARow: Integer): TRect;
|
|
begin
|
|
with MonthSize do
|
|
Result := cxRectOffset(cxRect(0, 0, cx, FHeaderHeight),
|
|
CalendarBounds.Left + ACol * cx, CalendarBounds.Top + ARow * cy);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetInternalRect(ACol, ARow: Integer): TRect;
|
|
begin
|
|
with MonthSize do
|
|
Result := cxRectOffset(cxRect(0, FHeaderHeight, cx, cy),
|
|
CalendarBounds.Left + ACol * cx, CalendarBounds.Top + ARow * cy);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetLeftArrowRect: TRect;
|
|
begin
|
|
Result := cxRectBounds(CalendarBounds.Left + 1, CalendarBounds.Top + 1,
|
|
FColWidth - 2, FHeaderHeight - 2);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetMonthRect(
|
|
ACol, ARow: Integer): TRect;
|
|
begin
|
|
with MonthSize do
|
|
Result := cxRectOffset(cxRect(0, 0, cx, cy),
|
|
CalendarBounds.Left + ACol * cx, CalendarBounds.Top + ARow * cy);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetRightArrowRect: TRect;
|
|
begin
|
|
Result := cxRectBounds(CalendarBounds.Right - FColWidth,
|
|
CalendarBounds.Top + HeaderBorderSize, FColWidth - HeaderBorderSize,
|
|
FHeaderHeight - HeaderBorderSize);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetRow(Y: Integer): Integer;
|
|
begin
|
|
Result := (Y - CalendarBounds.Top) div MonthSize.cy;
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.CalcInternalSizes;
|
|
var
|
|
ASymbolSize: TSize;
|
|
begin
|
|
CalculateViewParams;
|
|
FHeaderBorderSize := LookAndFeelPainter.ButtonBorderSize;
|
|
FHeaderBorderSize := 1;
|
|
ASymbolSize := cxTextExtent(ContentParams.Font, '0');
|
|
FColWidth := 3 * ASymbolSize.cx - 1;
|
|
FSideWidth := 2 * ASymbolSize.cx;
|
|
FRowHeight := ASymbolSize.cy + 2;
|
|
FDayCaptionsHeight := FRowHeight + 1;
|
|
FHeaderHeight := cxTextHeight(HeaderParams.Font) + 5;
|
|
FMonthSize.cx := (2 * FSideWidth + 7 * FColWidth);
|
|
FMonthSize.cy := (FHeaderHeight + FDayCaptionsHeight + 6 * FRowHeight + 1);
|
|
end;
|
|
|
|
procedure TcxSchedulerDateNavigatorViewInfo.DestroyMonthViewInfoList;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to FMonthViewInfoList.Count - 1 do
|
|
TcxSchedulerDateNavigatorMonthViewInfo(FMonthViewInfoList[I]).Free;
|
|
FreeAndNil(FMonthViewInfoList);
|
|
end;
|
|
|
|
function TcxSchedulerDateNavigatorViewInfo.GetMonthViewInfo(
|
|
ACol, ARow: Integer): TcxSchedulerDateNavigatorMonthViewInfo;
|
|
begin
|
|
if (ARow < 0) or (ARow >= RowCount) or (ACol < 0) or (ACol >= ColCount) then
|
|
Result := nil
|
|
else
|
|
Result := TcxSchedulerDateNavigatorMonthViewInfo(
|
|
FMonthViewInfoList[ARow * ColCount + ACol]);
|
|
end;
|
|
|
|
initialization
|
|
GetLocaleSettings;
|
|
|
|
end.
|