This repository has been archived on 2024-12-02. You can view files and clone it, but cannot push or open issues or pull requests.
FactuGES/cxSchedulerCustomResourceView.pas_
2007-06-26 08:08:27 +00:00

5617 lines
189 KiB
Plaintext

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressScheduler }
{ }
{ Copyright (c) 2003-2005 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 cxSchedulerCustomResourceView;
{$I cxVer.inc}
interface
uses
Windows, Graphics, SysUtils, StdCtrls, Classes, Forms, Controls, cxClasses, cxGraphics,
{$IFDEF DELPHI6}
DateUtils, Variants,
{$ENDIF} cxGeometry, Math, cxStyles, cxEdit, cxContainer,
cxSchedulerStorage, cxSchedulerUtils, cxSchedulerCustomControls, cxLookAndFeelPainters,
cxDateUtils, ImgList, cxEditUtils;
const
// default values
cxTimeLineWidth: Integer = 7;
cxEventImagesOffset = 1;
cxEventBorderWidth = 1;
cxHitDelta: Integer = 4;
// hittest constants
htcButton = $3;
htcContainer = $4;
htcTimeRuler = $5;
htcTimeZoneLabel = $6;
htcContent = $7;
htcDayHeader = $8;
htcGroupSeparator = $9;
htcResourceHeader = $10;
type
TcxSchedulerCustomViewInfoItem = class;
TcxSchedulerCustomResourceViewViewInfo = class;
TcxSchedulerCustomResourceViewHitTest = class;
TcxSchedulerBackgroundCellViewInfo = class;
TcxSchedulerContentCellViewInfo = class;
TcxSchedulerDayHeaderCellViewInfo = class;
TcxSchedulerEventCellViewInfo = class;
TcxSchedulerGroupSeparatorCellViewInfo = class;
TcxSchedulerHeaderCellViewInfo = class;
TcxSchedulerMoreEventsButtonViewInfo = class;
TcxSchedulerResourceViewInfo = class;
TcxCustomResourceViewAdapter = class;
TcxSchedulerEventLayoutBuilder = class;
TcxSchedulerEventImages = class;
// custom draw event types definition
TcxSchedulerCustomDrawBackgroundEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerBackgroundCellViewInfo; var ADone: Boolean) of object;
TcxSchedulerCustomDrawButtonEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerMoreEventsButtonViewInfo; var ADone: Boolean) of object;
TcxSchedulerCustomDrawDayHeaderEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerDayHeaderCellViewInfo; var ADone: Boolean) of object;
TcxSchedulerCustomDrawResourceHeaderEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerHeaderCellViewInfo; var ADone: Boolean) of object;
TcxSchedulerCustomDrawContentEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerContentCellViewInfo; var ADone: Boolean) of object;
TcxSchedulerCustomDrawEventEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerEventCellViewInfo; var ADone: Boolean) of object;
TcxSchedulerCustomDrawGroupSeparatorEvent = procedure(Sender: TObject; ACanvas: TcxCanvas;
AViewInfo: TcxSchedulerGroupSeparatorCellViewInfo; var ADone: Boolean) of object;
{ IcxSchedulerCommonViewItemsPainter }
IcxSchedulerCommonViewItemsPainter = interface
['{0702AB17-C2F1-479D-B809-C3B972F8A334}']
procedure DoCustomDrawBackground(
AViewInfo: TcxSchedulerBackgroundCellViewInfo; var ADone: Boolean);
procedure DoCustomDrawButton(
AViewInfo: TcxSchedulerMoreEventsButtonViewInfo; var ADone: Boolean);
procedure DoCustomDrawContent(
AViewInfo: TcxSchedulerContentCellViewInfo; var ADone: Boolean);
procedure DoCustomDrawDayHeader(
AViewInfo: TcxSchedulerDayHeaderCellViewInfo; var ADone: Boolean);
procedure DoCustomDrawEvent(
AViewInfo: TcxSchedulerEventCellViewInfo; var ADone: Boolean);
procedure DoCustomDrawGroupSeparator(
AViewInfo: TcxSchedulerGroupSeparatorCellViewInfo; var ADone: Boolean);
procedure DoCustomDrawResourceHeader(
AViewInfo: TcxSchedulerHeaderCellViewInfo; var ADone: Boolean);
end;
{ IcxSchedulerEventImages }
IcxSchedulerEventImages = interface
['{4C5A8F8B-5356-4D2B-9972-507A7D60954A}']
procedure DoInitEventImages(AEvent: TcxSchedulerControlEvent;
AImages: TcxSchedulerEventImages);
function GetImages: TImageList;
function SupportEventImages: Boolean;
end;
{ TcxSchedulerViewInfoCellList }
TcxSchedulerCustomDrawItemProc = procedure(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean) of object;
TcxSchedulerViewInfoCellList = class(TList)
private
function GetItem(AIndex: Integer): TcxSchedulerCustomViewInfoItem;
public
function CalculateHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest): Boolean;
procedure Clear; override;
procedure Draw(ACanvas: TcxCanvas; ADrawItemProc: TcxSchedulerCustomDrawItemProc);
property Items[Index: Integer]: TcxSchedulerCustomViewInfoItem read GetItem; default;
end;
{ TcxSchedulerCustomViewInfoItem }
TcxSchedulerCustomViewInfoItem = class
private
function GetBitmap: TBitmap;
function GetColor: TColor;
function GetDateTimeHelper: TcxSchedulerDateTimeHelperClass;
function GetPainterHelper: TcxSchedulerPainterHelperClass;
function GetTextColor: TColor;
procedure SetBitmap(AValue: TBitmap);
procedure SetColor(AValue: TColor);
procedure SetTextColor(AValue: TColor);
protected
FBackgroundDrawing: Boolean;
FBounds: TRect;
FBorders: TcxBorders;
FCanvas: TcxCanvas;
FClipRect: TRect;
FClipRgn: TcxRegion;
FClipRef: Integer;
FDateTime: TDateTime;
FDisplayText: string;
FHasClipping: Boolean;
FPainter: TcxCustomLookAndFeelPainterClass;
FSavedClipRgn: TcxRegion;
FTransparent: Boolean;
FViewParams: TcxViewParams;
FVisible: Boolean;
FDayBorderColor: TColor;
procedure CalculateCellBounds(const ABounds, AVisibleRect: TRect);
procedure ClippingCreate(AHasClipping: Boolean); virtual;
procedure ClippingRestore;
procedure DoDraw; virtual; abstract;
function DrawBackground(ACanvas: TcxCanvas; const ABounds: TRect): Boolean; virtual;
procedure DrawFrame(const ARect: TRect; ABorders: TcxBorders = [];
ABorderColor: TColor = clDefault; ALineWidth: Integer = 1);
procedure DrawRect(const ARect: TRect; ABorders: TcxBorders = [];
ABorderColor: TColor = clDefault; ALineWidth: Integer = 1);
procedure DrawText(const ARect: TRect; const AText: string;
AFlags: Integer; AFont: TFont = nil; AColor: TColor = clDefault);
function GetFont: TFont; virtual;
function GetHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest; var ABreak: Boolean): Boolean; virtual;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); virtual;
procedure RotateBitmap(ABitmap: TBitmap; ARotationAngle: TcxRotationAngle; AFlipHorizontally: Boolean = False);
// custom draw support
procedure AfterCustomDraw(ACanvas: TcxCanvas); virtual;
procedure BeforeCustomDraw(ACanvas: TcxCanvas); virtual;
// class item settings
property DateTimeHelper: TcxSchedulerDateTimeHelperClass read GetDateTimeHelper;
property DisplayText: string read FDisplayText write FDisplayText;
property PainterHelper: TcxSchedulerPainterHelperClass read GetPainterHelper;
public
constructor Create(APainter: TcxCustomLookAndFeelPainterClass;
const ABounds, AVisibleRect: TRect; const AViewParams: TcxViewParams); virtual;
destructor Destroy; override;
procedure Draw(ACanvas: TcxCanvas); virtual;
property Borders: TcxBorders read FBorders write FBorders;
property Bounds: TRect read FBounds;
property Bitmap: TBitmap read GetBitmap write SetBitmap;
property Canvas: TcxCanvas read FCanvas;
property ClipRect: TRect read FClipRect;
property Color: TColor read GetColor write SetColor;
property Font: TFont read GetFont;
property Painter: TcxCustomLookAndFeelPainterClass read FPainter;
property TextColor: TColor read GetTextColor write SetTextColor;
property Transparent: Boolean read FTransparent write FTransparent;
property ViewParams: TcxViewParams read FViewParams;
property Visible: Boolean read FVisible;
end;
{ TcxSchedulerBackgroundCellViewInfo }
TcxSchedulerBackgroundCellViewInfo = class(TcxSchedulerCustomViewInfoItem)
protected
procedure DoDraw; override;
end;
// TcxSchedulerContentCellViewInfo = class;
TcxSchedulerCustomViewInfoItemClass = class of TcxSchedulerCustomViewInfoItem;
{ TcxSchedulerCustomResourceViewInfoItem }
TcxSchedulerCustomResourceViewInfoItem = class(TcxSchedulerCustomViewInfoItem)
private
FIsResourceAssigned: Boolean;
FTimeFinish: TDateTime;
FResource: TcxSchedulerResourceViewInfo;
protected
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
property DateTime: TDateTime read FDateTime write FDateTime;
property IsResourceAssigned: Boolean read FIsResourceAssigned;
property Resource: TcxSchedulerResourceViewInfo read FResource write FResource;
property TimeFinish: TDateTime read FTimeFinish;
end;
{ TcxSchedulerHeaderCellViewInfo }
TcxSchedulerHeaderCellViewInfo = class(TcxSchedulerCustomResourceViewInfoItem)
private
function GetHeight: Integer;
function GetWidth: Integer;
protected
DisplayBounds: TRect;
FAlignHorz: TAlignment;
FAlignVert: TcxAlignmentVert;
FAutoHeight: Boolean;
FButtonState: TcxButtonState;
FCachedBitmap: TBitmap;
FDrawRotatedBackground: Boolean;
FImageIndex: Integer;
FImagePosition: TcxSchedulerHeaderImagePosition;
FImages: TImageList;
FImageRectAssigned: Boolean;
FImageRect: TRect;
FIsResourceHeader: Boolean;
FMultiLine: Boolean;
FNeighbors: TcxNeighbors;
FRotateBitmap: TBitmap;
FRotateHeader: Boolean;
FRotateText: Boolean;
FSelected: Boolean;
FSelectionColor: TColor;
FSelectionRect: TRect;
FSelectionTextColor: TColor;
FShowEndEllipsis: Boolean;
FTextRect: TRect;
procedure CalculateImageLayout;
procedure CheckNeighbor(APrevCell: TcxSchedulerHeaderCellViewInfo);
function CheckSelection: Boolean; virtual;
procedure DoDraw; override;
procedure DrawCaption(ACanvas: TcxCanvas = nil);
procedure DrawHorizontalHeader; virtual;
function DrawRotateBackground(ACanvas: TcxCanvas; const ABounds: TRect): Boolean; virtual;
procedure DrawVerticalHeader; virtual;
function GetTextOutcxFlags: Integer;
function GetTextOutFlags: Integer;
function HasImage: Boolean;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
procedure TextOut(ACanvas: TcxCanvas; const AText: string; R: TRect);
procedure ValidateSelection;
property Height: Integer read GetHeight;
property Width: Integer read GetWidth;
public
constructor Create(APainter: TcxCustomLookAndFeelPainterClass;
const ABounds, AVisibleRect: TRect; const AViewParams: TcxViewParams); override;
destructor Destroy; override;
procedure Calculate(const AText: string); virtual;
procedure Draw(ACanvas: TcxCanvas); override;
property AlignHorz: TAlignment read FAlignHorz write FAlignHorz;
property AlignVert: TcxAlignmentVert read FAlignVert write FAlignVert;
property AutoHeight: Boolean read FAutoHeight;
property DateTime: TDateTime read FDateTime write FDateTime;
property ImageIndex: Integer read FImageIndex;
property ImagePosition: TcxSchedulerHeaderImagePosition read FImagePosition;
property ImageRect: TRect read FImageRect;
property Images: TImageList read FImages;
property IsResourceHeader: Boolean read FIsResourceHeader;
property MultiLine: Boolean read FMultiLine write FMultiLine;
property Neighbors: TcxNeighbors read FNeighbors write FNeighbors;
property RotateHeader: Boolean read FRotateHeader write FRotateHeader;
property RotateText: Boolean read FRotateText write FRotateText;
property Selected: Boolean read FSelected write FSelected;
property SelectionColor: TColor read FSelectionColor write FSelectionColor;
property SelectionTextColor: TColor read FSelectionTextColor write FSelectionTextColor;
property ShowEndEllipsis: Boolean read FShowEndEllipsis write FShowEndEllipsis;
property TextRect: TRect read FTextRect;
property Bounds;
property DisplayText;
property Painter;
property Resource;
end;
{ TcxSchedulerDayHeaderCellViewInfo }
TcxSchedulerDayHeaderCellViewInfo = class(TcxSchedulerHeaderCellViewInfo)
private
FCompressed: Boolean;
protected
function CheckSelection: Boolean; override;
procedure DoDraw; override;
function DrawBackground(ACanvas: TcxCanvas; const ABounds: TRect): Boolean; override;
public
function ConvertDateToDisplayText(AType: Integer = 0): Integer; virtual;
property Compressed: Boolean read FCompressed write FCompressed;
end;
{ TcxSchedulerWeekDayHeaderCellViewInfo }
TcxSchedulerWeekDayHeaderCellViewInfo = class(TcxSchedulerDayHeaderCellViewInfo)
protected
function GetDayText(AType: Integer): string;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
public
function ConvertDateToDisplayText(AType: Integer = 0): Integer; override;
end;
{ TcxSchedulerContainerCellViewInfo }
TcxSchedulerContainerCellViewInfo = class(TcxSchedulerCustomResourceViewInfoItem)
protected
FLineCount: Integer;
FSelected: Boolean;
procedure DoDraw; override;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
public
property LineCount: Integer read FLineCount write FLineCount;
property DateTime;
property Resource;
property Selected: Boolean read FSelected write FSelected;
end;
{ TcxSchedulerTimeRulerCellViewInfo }
TcxSchedulerTimeRulerCellViewInfo = class(TcxSchedulerCustomViewInfoItem)
private
FLastVisibleHour: Boolean;
function GetBoundsRect(AType: Boolean): TRect;
function GetDisplayText(AType: Boolean): string;
function GetHasAdditionalTimeZone: Boolean;
protected
FAdditionalTimeZone: Integer;
FBounds: array[Boolean] of TRect;
FDisplayTexts: array[Boolean] of string;
FHour: Integer;
FLargeFont: TFont;
FLineCount: Integer;
FShowMinutes: Boolean;
FTimeZone: Integer;
procedure CalculateDisplayInfo;
procedure DoDraw; override;
procedure DrawTimeZone(const ABounds: TRect; const AText: string; AIsCurrent: Boolean); virtual;
procedure DrawTimeZoneLabel(const ABounds: TRect; const AText: string; ABorders: TcxBorders); virtual;
procedure DrawCurrentTime(const AStart: TDateTime; ABounds: TRect);
function GetAdditionalTime: TDateTime;
function GetTimeDisplayText(const ATime: TDateTime): string;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
//
procedure AfterCustomDraw(ACanvas: TcxCanvas); override;
public
class function CalculateWidth(ATimeZoneCount, ALineCount: Integer; AFont1, AFont2: TFont): Integer;
procedure Calculate(const ALabel1, ALabel2: string; ATimeZone, AAdditionalTimeZone: Integer); overload; virtual;
procedure Calculate(AHour, ALineCount: Integer; ATimeZone, AAdditionalTimeZone: Integer; ALargeFont: TFont); overload; virtual;
procedure SetBottom(AValue: Integer);
property AdditionalTimeZone: Integer read FAdditionalTimeZone;
property Bounds[ACurrentTimeZone: Boolean]: TRect read GetBoundsRect;
property DisplayTexts[ACurrentTimeZone: Boolean]: string read GetDisplayText;
property HasAdditionalTimeZone: Boolean read GetHasAdditionalTimeZone;
property Hour: Integer read FHour;
property LargeFont: TFont read FLargeFont;
property LastVisibleHour: Boolean read FLastVisibleHour write FLastVisibleHour;
property LineCount: Integer read FLineCount;
property ShowMinutes: Boolean read FShowMinutes write FShowMinutes;
property TimeZone: Integer read FTimeZone;
end;
{ TcxSchedulerContentCellViewInfo }
TcxSchedulerContentCellViewInfo = class(TcxSchedulerCustomResourceViewInfoItem)
protected
FBorderColor: TColor;
FDontPrint: Boolean;
FLineCount: Integer;
FShowTimeLine: Boolean;
FTimeEvent: TcxSchedulerEventCellViewInfo;
FTimeLineBorders: TcxBorders;
FTimeLineParams: TcxViewParams;
procedure DoDraw; override;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
public
constructor Create(APainter: TcxCustomLookAndFeelPainterClass;
const ABounds, AVisibleRect: TRect; const AViewParams: TcxViewParams); override;
procedure SetTime(const ATimeStart, ATimeFinish: TDateTime);
property BorderColor: TColor read FBorderColor write FBorderColor;
property DontPrint: Boolean read FDontPrint write FDontPrint;
property LineCount: Integer read FLineCount write FLineCount;
property ShowTimeLine: Boolean read FShowTimeLine write FShowTimeLine;
property TimeEvent: TcxSchedulerEventCellViewInfo read FTimeEvent write FTimeEvent;
property TimeLineBorders: TcxBorders read FTimeLineBorders write FTimeLineBorders;
property TimeLineParams: TcxViewParams read FTimeLineParams write FTimeLineParams;
property TimeStart: TDateTime read FDateTime;
property TimeFinish;
property Resource;
end;
TcxSchedulerContentCellViewInfoClass = class of TcxSchedulerContentCellViewInfo;
{ TcxSchedulerBackgroundSlotCellViewInfo }
TcxSchedulerBackgroundSlotCellViewInfo = class(TcxSchedulerContentCellViewInfo)
protected
procedure DoDraw; override;
public
property DisplayText;
end;
{ TcxSchedulerMonthDayContentCellViewInfo }
TcxSchedulerMonthDayContentCellViewInfo = class(TcxSchedulerContentCellViewInfo)
private
FSelected: Boolean;
FSelectionColor: TColor;
FSelectionTextColor: TColor;
FTextHeight: Integer;
function GetIsToday: Boolean;
procedure SetSmallTextFont(AFont: TFont);
protected
FTextRect: TRect;
FSmallFont: Boolean;
FSmallFontCreated: Boolean;
FSmallTextFont: TFont;
procedure DoDraw; override;
function GetLongDisplayText: string; virtual;
property IsToday: Boolean read GetIsToday;
public
destructor Destroy; override;
procedure SetContentState(AsDayOfMonth: Boolean; ASelected: Boolean;
ATextHeight: Integer; const ASelectionParams: TcxViewParams);
function UpdateSelection(ASelected: Boolean): Boolean;
property DisplayText;
property SmallFont: Boolean read FSmallFont;
property SmallTextFont: TFont read FSmallTextFont write SetSmallTextFont;
property Selected: Boolean read FSelected;
property SelectionColor: TColor read FSelectionColor write FSelectionColor;
property SelectionTextColor: TColor read FSelectionTextColor write FSelectionTextColor;
property TextHeight: Integer read FTextHeight write FTextHeight;
end;
TcxSchedulerEventImagesLayout = (eilAuto, eilHorizontal, eilVertical);
{ TcxSchedulerEventViewData }
TcxSchedulerEventViewData = class
public
AlwaysShowTime: Boolean;
AutoHeight: Boolean;
Bitmap: TBitmap;
BorderColor: TColor;
Bounds: TRect;
Canvas: TcxCanvas;
Caption: string;
ContentFinish: TDateTime;
ContentStart: TDateTime;
DrawShadows: Boolean;
EditProperties: TcxCustomEditProperties;
EditStyle: TcxCustomEditStyle;
Event: TcxSchedulerControlEvent;
ImagesLayout: TcxSchedulerEventImagesLayout;
LineHeight: Integer;
MaxHeight: Integer;
Painter: TcxCustomLookAndFeelPainterClass;
Resource: TcxSchedulerResourceViewInfo;
ShowFinishTime: Boolean;
ShowStartTime: Boolean;
ShowTimeAsClock: Boolean;
ShowTimeLine: Boolean;
StartLine: Integer;
TimeLineParams: TcxViewParams;
ViewParams: TcxViewParams;
VisibleRect: TRect;
end;
{ TcxSchedulerEventCellViewInfo }
TcxSchedulerEventCellViewInfo = class(TcxSchedulerCustomViewInfoItem)
private
FEventFinish: TDateTime;
FEventStart: TDateTime;
FIsHeaderEvent: Boolean;
function CalculateMessageHeight(const R: TRect): Integer;
function GetBorderColor: TColor;
function GetCaption: string;
function GetCaptionBounds(const R: TRect): TRect;
function GetContentFinish: TDateTime;
function GetContentStart: TDateTime;
function GetEvent: TcxSchedulerControlEvent;
function GetIsHeaderEvent: Boolean;
function GetMessage: string;
function GetResourceInfo: TcxSchedulerResourceViewInfo;
function GetResourceItem: TcxSchedulerStorageResourceItem;
function GetSelected: Boolean;
function GetShowingState(AIndex: Integer): Boolean;
procedure SetBorderColor(AValue: TColor);
protected
FCaptionRect: TRect;
FEditViewInfo: TcxCustomEditViewInfo;
FFinishRect: TRect;
FFinishText: string;
FHidden: Boolean;
FImages: TcxSchedulerEventImages;
FMessageRect: TRect;
FHintNeeded: Boolean;
FHintNeededCalculated: Boolean;
FSeparatorColor: TColor;
FShowMessage: Boolean;
FStartRect: TRect;
FStartText: string;
FEventTimeRect: TRect;
FTimeLineRect: TRect;
FIsDetailCaption: Boolean;
FIsDetailInfo: Boolean;
ViewData: TcxSchedulerEventViewData;
procedure AssignEditStyle(AEditStyle: TcxCustomEditStyle);
procedure BeforeCustomDraw(ACanvas: TcxCanvas); override;
procedure Calculate;
procedure CalculateBorders; virtual;
procedure CalculateCaptions; virtual;
procedure CalculateDetailInfo; virtual;
procedure CalculateNeedHint;
procedure CalculateEditViewInfo;
procedure CalculateShowTimeAsClock; virtual;
//items layout
function CalculateAutoLayoutImagesAutoHeight(AVisibleImages: TList): Integer;
function CalculateHorizontalImagesAutoHeight: Integer;
procedure CalculateMessageAutoLayout(var AHeight: Integer);
function CalculateVerticalImagesAutoHeight: Integer;
procedure CalculateItemsLayout; virtual;
procedure CalculateDetailViewEventLayout;
procedure CalculateHeaderEventLayout;
procedure CalculateNonDetailEventLayout;
procedure CalculateEventTimeAsClockLayout(const ABounds: TRect;
const ACaptionWidth, AImagesWidth: Integer; var ALeft: Integer); virtual;
procedure CalculateEventTimeAsTextLayout(const ABounds: TRect;
const ACaptionWidth, AImagesWidth: Integer; var ALeft: Integer); virtual;
function CalculateNonDetailEventImages(const ACaptionWidth: Integer;
out AImagesWidth: Integer): TRect; virtual;
function CalculateSingleLineImages(const ABounds: TRect; ARightLimit: Integer = 0): Integer;
function SetItemRect(AShowItem: Boolean; const ABounds: TRect;
AVertOffset: Integer; var APos: Integer): TRect;
//time visibility
procedure CalculateEventTimeVisibility; virtual;
procedure CalculateDetailEventTimeVisibility; virtual;
procedure CalculateNonDetailEventTimeVisibility; virtual;
procedure CalculateVisibility; virtual;
function CanAutoHideStandardImages: Boolean; virtual;
procedure DoDraw; override;
procedure DrawCaption;
procedure DrawContent; virtual;
procedure DrawImages;
procedure DrawMessageSeparator;
procedure DrawTime;
function GetCaptionAutoHeight(const R: TRect): Integer;
function GetEditingRect: TRect; virtual;
function GetForceShowClockInHeaderEvent: Boolean; virtual;
function GetHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest; var ABreak: Boolean): Boolean; override;
function GetImagesBounds: TRect;
function GetImagesVerticalOffset(AImageHeight: Integer; AIsAbsolute: Boolean): Integer;
function GetMessageRect(const ACaptionRect: TRect; AHasImages: Boolean): TRect;
procedure Initialize; virtual;
//hittest
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
procedure InitHitTestForHorzEvent(AHitTest: TcxSchedulerCustomResourceViewHitTest);
procedure InitStandardEventImages;
function IsHorzSizing: Boolean; virtual;
function IsNeedDrawTime: Boolean; virtual;
function IsTimeLineVisible: Boolean; virtual;
function TruncTime(const ATime: TDateTime): TDateTime;
property EventFinish: TDateTime read FEventFinish;
property EventStart: TDateTime read FEventStart;
property IsHeaderEvent: Boolean read FIsHeaderEvent;
property IsDetailCaption: Boolean read FIsDetailCaption;
public
constructor Create(AViewData: TcxSchedulerEventViewData); reintroduce; virtual;
destructor Destroy; override;
procedure Draw(ACanvas: TcxCanvas; ABitmap: TBitmap); reintroduce; overload;
procedure DrawState(ACanvas: TcxCanvas; const ARect: TRect; ABorders: TcxBorders; ABorderColor: TColor); overload;
function MeasureHeight(ACanvas: TcxCanvas): Integer; virtual;
procedure MoveTo(X, Y: Integer); virtual;
property BorderColor: TColor read GetBorderColor write SetBorderColor;
property Caption: string read GetCaption;
property CaptionRect: TRect read FCaptionRect;
property ClipRect: TRect read FClipRect;
property ClipRgn: TcxRegion read FClipRgn write FClipRgn;
property ContentFinish: TDateTime read GetContentFinish;
property ContentStart: TDateTime read GetContentStart;
property EditingRect: TRect read GetEditingRect;
property EditViewInfo: TcxCustomEditViewInfo read FEditViewInfo;
property Event: TcxSchedulerControlEvent read GetEvent;
property EventTimeRect: TRect read FEventTimeRect;
property EventViewData: TcxSchedulerEventViewData read ViewData;
property FinishRect: TRect read FFinishRect;
property FinishText: string read FFinishText;
property Hidden: Boolean read FHidden write FHidden;
property Images: TcxSchedulerEventImages read FImages;
property IsDetailInfo: Boolean read FIsDetailInfo;
property Message: string read GetMessage;
property MessageRect: TRect read FMessageRect;
property ResourceInfo: TcxSchedulerResourceViewInfo read GetResourceInfo;
property ResourceItem: TcxSchedulerStorageResourceItem read GetResourceItem;
property Selected: Boolean read GetSelected;
property SeparatorColor: TColor read FSeparatorColor write FSeparatorColor;
property ShowFinishTime: Boolean index 0 read GetShowingState;
property ShowMessage: Boolean read FShowMessage;
property ShowStartTime: Boolean index 1 read GetShowingState;
property ShowTimeAsClock: Boolean index 2 read GetShowingState;
property ShowTimeLine: Boolean index 3 read GetShowingState;
property StartRect: TRect read FStartRect;
property StartText: string read FStartText;
property TimeLineRect: TRect read FTimeLineRect write FTimeLineRect;
property Visible: Boolean read FVisible;
end;
{ TcxSchedulerMoreEventsButtonViewInfo }
TcxSchedulerMoreEventsButtonClick = procedure (Sender: TcxSchedulerMoreEventsButtonViewInfo) of object;
TcxSchedulerMoreEventsButtonViewInfo = class(TcxSchedulerCustomResourceViewInfoItem)
protected
FIsDown: Boolean;
FOnClick: TcxSchedulerMoreEventsButtonClick;
procedure DoDraw; override;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
property OnClick: TcxSchedulerMoreEventsButtonClick read FOnClick write FOnClick;
public
procedure Click; virtual;
property IsDown: Boolean read FIsDown;
property DateTime;
property Resource;
end;
{ TcxSchedulerGroupSeparatorCellViewInfo }
TcxSchedulerGroupSeparatorCellViewInfo = class(TcxSchedulerCustomViewInfoItem)
private
FDrawRotatedBackground: Boolean;
FRotated: Boolean;
function DrawRotateBackground(ACanvas: TcxCanvas; const ABounds: TRect): Boolean;
protected
FRotateBitmap: TBitmap;
procedure DoDraw; override;
procedure InitHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); override;
public
destructor Destroy; override;
property Rotated: Boolean read FRotated write FRotated;
end;
{ TcxSchedulerResourceViewInfo }
TcxSchedulerResourceViewInfo = class
protected
FCaption: string;
FColor: TColor;
FImageIndex: Integer;
FImagePosition: TcxSchedulerHeaderImagePosition;
FImages: TImageList;
FResourceID: Variant;
FResourceItem: TcxSchedulerStorageResourceItem;
FTextRect: TRect;
public
constructor Create(AResource: TcxSchedulerStorageResourceItem); virtual;
property Caption: string read FCaption;
property Color: TColor read FColor;
property ImageIndex: Integer read FImageIndex;
property ImagePosition: TcxSchedulerHeaderImagePosition read FImagePosition;
property Images: TImageList read FImages;
property ResourceID: Variant read FResourceID;
property ResourceItem: TcxSchedulerStorageResourceItem read FResourceItem;
property TextRect: TRect read FTextRect write FTextRect;
end;
{ TcxSchedulerCustomResourceView }
TcxSchedulerCustomResourceView = class(TcxSchedulerCustomView)
private
FAdapter: TcxCustomResourceViewAdapter;
FGroupingKind: TcxSchedulerGroupingKind;
FEventImagesLayout: TcxSchedulerEventImagesLayout;
FShowEndTime: Boolean;
FShowTimeAsClock: Boolean;
FOnCustomDrawBackground: TcxSchedulerCustomDrawBackgroundEvent;
FOnCustomDrawButton: TcxSchedulerCustomDrawButtonEvent;
FOnCustomDrawContent: TcxSchedulerCustomDrawContentEvent;
FOnCustomDrawDayHeader: TcxSchedulerCustomDrawDayHeaderEvent;
FOnCustomDrawEvent: TcxSchedulerCustomDrawEventEvent;
FOnCustomDrawGroupSeparator: TcxSchedulerCustomDrawGroupSeparatorEvent;
FOnCustomDrawResourceHeader: TcxSchedulerCustomDrawResourceHeaderEvent;
function GetViewInfo: TcxSchedulerCustomResourceViewViewInfo;
procedure SetEventImagesLayout(const AValue: TcxSchedulerEventImagesLayout);
procedure SetGroupingKind(AValue: TcxSchedulerGroupingKind);
procedure SetShowEndTime(const AValue: Boolean);
procedure SetShowTimeAsClock(const AValue: Boolean);
protected
procedure CalculateViewInfo; override;
procedure CheckGroupingKind(AStyle: TcxSchedulerGroupingKind;
var ActuallyStyle: TcxSchedulerGroupingKind); virtual;
function CreateController: TcxSchedulerSubControlController; override;
function CreateHitTest: TcxSchedulerSubControlHitTest; override;
function CreateViewAdapter: TcxCustomResourceViewAdapter; virtual;
procedure CreateSubClasses; override;
procedure DestroySubClasses; override;
procedure DoCustomDrawBackground(
AViewInfo: TcxSchedulerBackgroundCellViewInfo; var ADone: Boolean); virtual;
procedure DoCustomDrawButton(
AViewInfo: TcxSchedulerMoreEventsButtonViewInfo; var ADone: Boolean); virtual;
procedure DoCustomDrawContent(
AViewInfo: TcxSchedulerContentCellViewInfo; var ADone: Boolean); virtual;
procedure DoCustomDrawDayHeader(
AViewInfo: TcxSchedulerDayHeaderCellViewInfo; var ADone: Boolean); virtual;
procedure DoCustomDrawEvent(
AViewInfo: TcxSchedulerEventCellViewInfo; var ADone: Boolean); virtual;
procedure DoCustomDrawGroupSeparator(
AViewInfo: TcxSchedulerGroupSeparatorCellViewInfo; var ADone: Boolean); virtual;
procedure DoCustomDrawResourceHeader(
AViewInfo: TcxSchedulerHeaderCellViewInfo; var ADone: Boolean); virtual;
procedure DoLayoutChanged; override;
function DoShowPopupMenu(X, Y: Integer): Boolean; override;
function FindEventViewInfo(AEvent: TcxSchedulerEvent; const ADate: TDateTime;
AResource: TcxSchedulerStorageResourceItem; var AViewInfo: TcxSchedulerEventCellViewInfo): Boolean;
function GetCommonViewItemsPainter: IcxSchedulerCommonViewItemsPainter; virtual;
function GetCompressWeekEnd: Boolean; virtual;
function GetEditRectForEvent(AEvent: TcxSchedulerControlEvent; const ADate: TDateTime;
AResource: TcxSchedulerStorageResourceItem): TRect; override;
function GetEventVisibility(AEvent: TcxSchedulerControlEvent): Boolean; override;
function GetGroupingKind: TcxSchedulerGroupingKind; override;
procedure InitScrollBarsParameters; override;
function IsShowResources: Boolean; override;
procedure Scroll(AScrollBarKind: TScrollBarKind;
AScrollCode: TScrollCode; var AScrollPos: Integer); override;
property Adapter: TcxCustomResourceViewAdapter read FAdapter write FAdapter;
property EventImagesLayout: TcxSchedulerEventImagesLayout read FEventImagesLayout write SetEventImagesLayout;
property ShowEndTime: Boolean read FShowEndTime write SetShowEndTime default True;
property ShowTimeAsClock: Boolean read FShowTimeAsClock write SetShowTimeAsClock default False;
property ViewInfo: TcxSchedulerCustomResourceViewViewInfo read GetViewInfo;
property OnCustomDrawBackground: TcxSchedulerCustomDrawBackgroundEvent read FOnCustomDrawBackground write FOnCustomDrawBackground;
property OnCustomDrawButton: TcxSchedulerCustomDrawButtonEvent read FOnCustomDrawButton write FOnCustomDrawButton;
property OnCustomDrawContent: TcxSchedulerCustomDrawContentEvent read FOnCustomDrawContent write FOnCustomDrawContent;
property OnCustomDrawDayHeader: TcxSchedulerCustomDrawDayHeaderEvent read FOnCustomDrawDayHeader write FOnCustomDrawDayHeader;
property OnCustomDrawEvent: TcxSchedulerCustomDrawEventEvent read FOnCustomDrawEvent write FOnCustomDrawEvent;
property OnCustomDrawGroupSeparator: TcxSchedulerCustomDrawGroupSeparatorEvent read FOnCustomDrawGroupSeparator write FOnCustomDrawGroupSeparator;
property OnCustomDrawResourceHeader: TcxSchedulerCustomDrawResourceHeaderEvent read FOnCustomDrawResourceHeader write FOnCustomDrawResourceHeader;
public
constructor Create(AOwner: TcxCustomScheduler); override;
procedure Assign(Source: TPersistent); override;
property GroupingKind: TcxSchedulerGroupingKind read FGroupingKind write SetGroupingKind default gkDefault;
end;
{ TcxCustomResourceViewAdapter }
TcxCustomResourceViewAdapter = class
private
FView: TcxSchedulerCustomResourceView;
function GetCells: TcxObjectList;
function GetContentLineHeight: Integer;
function GetPainterHelper: TcxSchedulerPainterHelperClass;
function GetResourceNavigator: TcxSchedulerResourceNavigator;
function GetResources: TcxSchedulerStorageResourceItems;
function GetScheduler: TcxCustomScheduler;
function GetViewInfo: TcxSchedulerCustomResourceViewViewInfo;
protected
function CanCalculate: Boolean; virtual;
function GetCompressWeekends: Boolean; virtual;
function GetDontPrintWeekEnds: Boolean; virtual;
function GetHideSelection: Boolean; virtual;
function GetPageBounds: TRect; virtual;
function GetPagesPerWeek: Byte; virtual;
function GetPrimaryPage: Boolean; virtual;
function GetPrintExactlyOneMonth: Boolean; virtual;
function GetPrintRange(Index: Integer): TDateTime; virtual;
function GetStylesAdapter: IcxSchedulerStylesAdapter; virtual;
function GetView: TcxSchedulerCustomResourceView; virtual;
procedure AfterCalculatePage; virtual;
procedure BeforeCalculatePage; virtual;
procedure DoInitialize(var ASelectedDays: TcxSchedulerDateList;
var AEvents: TcxSchedulerCachedEventList); virtual;
function GetPageHeaderText: string; virtual;
procedure Store; virtual;
procedure Restore; virtual;
property Scheduler: TcxCustomScheduler read GetScheduler;
property PainterHelper: TcxSchedulerPainterHelperClass read GetPainterHelper;
property ResourceNavigator: TcxSchedulerResourceNavigator read GetResourceNavigator;
property ViewInfo: TcxSchedulerCustomResourceViewViewInfo read GetViewInfo;
public
constructor Create(AView: TcxSchedulerCustomResourceView); virtual;
procedure Calculate; overload;
procedure GetPageResources(AResources: TcxObjectList); virtual;
procedure GetPageDays(APageIndex: Integer; ADays: TcxSchedulerDateList);
procedure Invalidate; virtual;
property Cells: TcxObjectList read GetCells;
property ContentLineHeight: Integer read GetContentLineHeight;
property DontPrintWeekEnd: Boolean read GetDontPrintWeekEnds;
property PagesPerWeek: Byte read GetPagesPerWeek;
property PrintExactlyOneMonth: Boolean read GetPrintExactlyOneMonth;
property PrintFrom: TDateTime index 0 read GetPrintRange;
property PrintTo: TDateTime index 1 read GetPrintRange;
property Resources: TcxSchedulerStorageResourceItems read GetResources;
property StylesAdapter: IcxSchedulerStylesAdapter read GetStylesAdapter;
property View: TcxSchedulerCustomResourceView read GetView;
end;
TcxCustomResourceViewAdapterClass = class of TcxCustomResourceViewAdapter;
{ TcxSchedulerEventImages }
TcxSchedulerEventImageType = (eitReminder, eitRecurrence, eitCustomOccurrence, eitCustom);
{ TcxSchedulerEventImageItem }
TcxSchedulerEventImageItem = class(TCollectionItem)
private
FAutoHide: Boolean;
FImageType: TcxSchedulerEventImageType;
FImageIndex: Integer;
FImages: TImageList;
FVisible: Boolean;
function GetHeight: Integer;
function GetWidth: Integer;
protected
FBounds: TRect;
FHidden: Boolean;
public
constructor Create(Collection: TCollection); override;
property AutoHide: Boolean read FAutoHide write FAutoHide;
property Bounds: TRect read FBounds;
property Height: Integer read GetHeight;
property ImageIndex: Integer read FImageIndex;
property ImageType: TcxSchedulerEventImageType read FImageType;
property Images: TImageList read FImages;
property Visible: Boolean read FVisible write FVisible;
property Width: Integer read GetWidth;
end;
{ TcxSchedulerEventImages }
TcxSchedulerEventImages = class(TCollection)
private
FForceVisibleHeight: Integer;
FForceVisibleWidth: Integer;
FImages: TImageList;
FLayout: TcxSchedulerEventImagesLayout;
FItemHeight: Integer;
FItemWidth: Integer;
FTotalVisibleHeight: Integer;
FTotalVisibleWidth: Integer;
FTotalVisibleImageCount: Integer;
FVisibleImageCount: Integer;
function GetImageItem(AIndex: Integer): TcxSchedulerEventImageItem;
protected
function Calculate(const R: TRect): Integer;
procedure CalculateForCols(AVisibleImages: TList; const ATopLeft: TPoint; AColCount: Integer);
function CalculateImages(const R: TRect): Integer;
function CalculateSingleColumnImages(const R: TRect): Integer;
function CalculateSingleLineImages(const R: TRect; ARightLimit: Integer = 0): Integer;
function Offset(ADeltaX, ADeltaY: Integer): Integer;
function CreateVisibleList: TList;
procedure Init(AImages: TImageList);
procedure SetItemBounds(AItem: TcxSchedulerEventImageItem; ALeft, ATop: Integer);
property ItemHeight: Integer read FItemHeight;
property ItemWidth: Integer read FItemWidth;
property ForceVisibleHeight: Integer read FForceVisibleHeight;
property ForceVisibleWidth: Integer read FForceVisibleWidth;
property TotalVisibleHeight: Integer read FTotalVisibleHeight;
property TotalVisibleWidth: Integer read FTotalVisibleWidth;
property TotalVisibleImageCount: Integer read FTotalVisibleImageCount;
property VisibleImageCount: Integer read FVisibleImageCount;
public
constructor Create(ALayout: TcxSchedulerEventImagesLayout);
function Add(AImageIndex: Integer; AutoHide: Boolean = True): TcxSchedulerEventImageItem;
function AddStandardImage(AImageType: TcxSchedulerEventImageType;
AutoHide: Boolean = True): TcxSchedulerEventImageItem;
property Items[Index: Integer]: TcxSchedulerEventImageItem read GetImageItem; default;
property Layout: TcxSchedulerEventImagesLayout read FLayout write FLayout;
end;
{ TcxSchedulerCustomResourceViewViewInfo }
TcxSchedulerCustomResourceViewViewInfo = class(TcxSchedulerCustomViewViewInfo)
private
function GetClones: TcxSchedulerEventList;
function GetDay(AIndex: Integer): TDateTime;
function GetDayCount: Integer;
function GetShowEventsWithoutResource: Boolean;
function GetGroupByDate: Boolean;
function GetGroupByResource: Boolean;
function GetGroupingKind: TcxSchedulerGroupingKind;
function GetHasSeparator: Boolean;
function GetHasVisibleBounds: Boolean;
function GetHiddenSelection: Boolean;
function GetResource(AIndex: Integer): TcxSchedulerResourceViewInfo;
function GetResourceCaption(AIndex: Integer): string;
function GetResourceCount: Integer;
function GetResourceHeaders: TcxSchedulerResourceHeaders;
function GetPrintRange(Index: Integer): TDateTime;
function GetSeparatorWidth: Integer;
function GetView: TcxSchedulerCustomResourceView;
protected
FAdapter: TcxCustomResourceViewAdapter;
FButtons: TcxSchedulerViewInfoCellList;
FCanSelected: Boolean;
FCells: TcxObjectList;
FContentCells: TcxSchedulerViewInfoCellList;
FContentFontHeight: Integer;
FContentLineHeight: Integer;
FDayBorderColor: TColor;
FDayHeaderCells: TcxSchedulerViewInfoCellList;
FDayHeaderHeight: Integer;
FEventCells: TcxSchedulerViewInfoCellList;
FEventImages: IcxSchedulerEventImages;
FGroupSeparatorCells: TcxSchedulerViewInfoCellList;
FGroupSeparatorParams: TcxViewParams;
FGroupingKind: TcxSchedulerGroupingKind;
FHasVisibleBounds: Boolean;
FHeaderContainerCells: TcxSchedulerViewInfoCellList;
FHideClones: Boolean;
FHideSelection: Boolean;
FHideSource: Boolean;
FResources: TcxObjectList;
FResourceHeaderCells: TcxSchedulerViewInfoCellList;
FResourceHeaderHeight: Integer;
FResourceImages: TImageList;
FSelectionParams: TcxViewParams;
FSelStart: TDateTime;
FSelFinish: TDateTime;
FSelResource: TcxSchedulerResourceViewInfo;
FStylesAdapter: IcxSchedulerStylesAdapter;
FTimeLineParams: TcxViewParams;
// for page splitting
FPageBounds: TRect;
FPagesPerWeek: Byte;
FPrimaryPage: Boolean;
FPrintWeekEnds: Boolean;
FUseResourceImages: Boolean;
ScreenCanvas: TcxCanvas;
function AddBackgroundSlot(const ABounds: TRect; ABorders: TcxBorders;
const AText: string = ''): TcxSchedulerBackgroundSlotCellViewInfo; virtual;
function AddButton(ABounds: TRect; const ADateTime: TDateTime;
AResourceIndex: Integer; AIsDown: Boolean): TcxSchedulerMoreEventsButtonViewInfo; virtual;
function AddContentCell(const ARect: TRect; const AStart, AFinish: TDateTime;
AResourceIndex: Integer): TcxSchedulerContentCellViewInfo; virtual;
function AddDayHeader(const ADate: TDateTime; const ABounds: TRect;
AResourceIndex: Integer): TcxSchedulerDayHeaderCellViewInfo; overload; virtual;
function AddDayHeader(const ADate: TDateTime; ATop, ALeft, ARight: Integer;
AResourceIndex: Integer): TcxSchedulerDayHeaderCellViewInfo; overload;
function AddEventCell(
AViewData: TcxSchedulerEventViewData; AImmediateCalculate: Boolean = True): TcxSchedulerEventCellViewInfo; virtual;
function AddGroupHorzSeparator(APos: Integer): TcxSchedulerGroupSeparatorCellViewInfo; virtual;
function AddGroupSeparator(const ABounds: TRect): TcxSchedulerGroupSeparatorCellViewInfo; virtual;
function AddGroupVertSeparator(APos: Integer): TcxSchedulerGroupSeparatorCellViewInfo; virtual;
function AddResourceHeader(const AIndex: Integer;
const ABounds: TRect): TcxSchedulerHeaderCellViewInfo; virtual;
procedure AfterCalculate; override;
procedure AssignResourceID(ACell: TcxSchedulerCustomResourceViewInfoItem; AIndex: Integer);
procedure CalculateMetrics; virtual;
procedure CalculateResourceHeadersAutoHeight(AWidth: Integer); virtual;
function CalculateResourceHeaderWidth: Integer; virtual;
procedure Clear; override;
function ContentCellClass: TcxSchedulerContentCellViewInfoClass; virtual;
procedure CreateCellInstance(AClass: TcxSchedulerCustomViewInfoItemClass;
const ABounds: TRect; const AViewParams: TcxViewParams; var Instance); overload;
procedure CreateCellInstance(AClass: TcxSchedulerCustomViewInfoItemClass;
const ABounds, AVisibleBounds: TRect; const AViewParams: TcxViewParams; var Instance); overload;
function CreateEventViewData(AEvent: TcxSchedulerControlEvent; const ABounds: TRect;
const AStart, AFinish: TDateTime; AResource: TcxSchedulerResourceViewInfo): TcxSchedulerEventViewData; virtual;
function CreateEventCellViewInfo(AViewData: TcxSchedulerEventViewData): TcxSchedulerEventCellViewInfo; virtual;
procedure DoCalculate; override;
procedure DoMoreEventsButtonClick(Sender: TcxSchedulerMoreEventsButtonViewInfo); virtual;
procedure ExtractResources; virtual;
function GetBounds: TRect; override;
function GetContentParams(const ATime: TDateTime;
AResource: TcxSchedulerResourceViewInfo): TcxViewParams; virtual;
function GetDayHeaderHeight: Integer; virtual;
function GetResourceHeaderWidth: Integer;
function GetResourceImagesSize: TSize; virtual;
function GetResourcesContentWidth: Integer; virtual;
function GetSelectionParams(const AParams: TcxViewParams): TcxViewParams;
function GetSeparatorCount: Integer; virtual;
function GetTimeLineParams: TcxViewParams; virtual;
function GetFontHeight(AStyle: TcxStyle): Integer; overload;
function GetFontHeight(const AParams: TcxViewParams): Integer; overload;
function GetPageHeaderText: string; virtual;
function GetResourceItemByIndex(AIndex: Integer): TcxSchedulerStorageResourceItem;
function GetResourceViewInfoByItem(AItem: TcxSchedulerStorageResourceItem): TcxSchedulerResourceViewInfo;
function HasStorage: Boolean;
procedure HideCloneEventsOnDragDrop;
procedure HideSourceEventsOnDragDrop;
function IsTimeSelected(ATime: TDateTime; AResource: TObject): Boolean; virtual;
procedure MakeTimeVisible(const ATime: TDateTime); virtual;
procedure OnMoreEventsButtonClick(Sender: TcxSchedulerMoreEventsButtonViewInfo);
procedure ProcessDateToDisplayText(ArrangeByType: Boolean = False); virtual;
procedure ProcessCheckBorders(AList: TcxSchedulerViewInfoCellList;
AHasCommonArea: Boolean; ANeighbors: TcxNeighbors = [];
AExcludeBorders: TcxBorders = []; AAddBorders: TcxBorders = []);
function SetAdapter(Adapter: TcxCustomResourceViewAdapter): TcxCustomResourceViewAdapter;
procedure SetResourceTextRect(AResource: TcxSchedulerStorageResourceItem; const ARect: TRect);
property View: TcxSchedulerCustomResourceView read GetView;
public
constructor Create(AOwner: TcxSchedulerSubControl); override;
destructor Destroy; override;
procedure Calculate; override;
procedure CalculateHitTest(AHitTest: TcxSchedulerCustomResourceViewHitTest); virtual;
procedure InitScrollBarsParameters; virtual;
procedure ScrollHorizontal(AScrollCode: TScrollCode; var AScrollPos: Integer); virtual;
procedure ScrollVertical(AScrollCode: TScrollCode; var AScrollPos: Integer); virtual;
procedure SetEventsVisibility(AShowSources, AShowClones: Boolean; AForceRepaint: Boolean = False); override;
property Adapter: TcxCustomResourceViewAdapter read FAdapter;
property Buttons: TcxSchedulerViewInfoCellList read FButtons;
property CanSelected: Boolean read FCanSelected;
property Clones: TcxSchedulerEventList read GetClones;
property ContentCells: TcxSchedulerViewInfoCellList read FContentCells;
property ContentLineHeight: Integer read FContentLineHeight;
property DayCount: Integer read GetDayCount;
property DayHeaderCells: TcxSchedulerViewInfoCellList read FDayHeaderCells;
property DayHeaderHeight: Integer read GetDayHeaderHeight;
property Days[Index: Integer]: TDateTime read GetDay;
property EventCells: TcxSchedulerViewInfoCellList read FEventCells;
property ShowEventsWithoutResource: Boolean read GetShowEventsWithoutResource;
property GroupByDate: Boolean read GetGroupByDate;
property GroupByResource: Boolean read GetGroupByResource;
property GroupSeparatorCells: TcxSchedulerViewInfoCellList read FGroupSeparatorCells;
property GroupSeparatorParams: TcxViewParams read FGroupSeparatorParams;
property GroupingKind: TcxSchedulerGroupingKind read FGroupingKind;
property HasSeparator: Boolean read GetHasSeparator;
property HasVisibleBounds: Boolean read FHasVisibleBounds;
property HeaderContainerCells: TcxSchedulerViewInfoCellList read FHeaderContainerCells;
property HideSelection: Boolean read FHideSelection;
property PagesPerWeek: Byte read FPagesPerWeek;
property PrimaryPage: Boolean read FPrimaryPage;
property PrintFrom: TDateTime index 0 read GetPrintRange;
property PrintTo: TDateTime index 1 read GetPrintRange;
property PrintWeekEnds: Boolean read FPrintWeekEnds;
property Resources[AIndex: Integer]: TcxSchedulerResourceViewInfo read GetResource;
property ResourceCaptions[AIndex: Integer]: string read GetResourceCaption;
property ResourceCount: Integer read GetResourceCount;
property ResourceHeaders: TcxSchedulerResourceHeaders read GetResourceHeaders;
property ResourceHeaderCells: TcxSchedulerViewInfoCellList read FResourceHeaderCells;
property ResourceHeaderHeight: Integer read FResourceHeaderHeight;
property ResourceImages: TImageList read FResourceImages;
property SelFinish: TDateTime read FSelFinish;
property SelResource: TcxSchedulerResourceViewInfo read FSelResource;
property SelStart: TDateTime read FSelStart;
property SeparatorWidth: Integer read GetSeparatorWidth;
property StylesAdapter: IcxSchedulerStylesAdapter read FStylesAdapter;
property HiddenSelection: Boolean read GetHiddenSelection;
property UseResourceImages: Boolean read FUseResourceImages;
end;
{ TcxSchedulerCustomResourceViewNavigation }
TcxSchedulerCustomResourceViewNavigation = class(TcxSchedulerViewNavigation)
private
function GetIsFirstResource: Boolean;
function GetIsLastResource: Boolean;
function GetGroupingKind: TcxSchedulerGroupingKind;
function GetResourceObject: TcxSchedulerResourceViewinfo;
function GetViewInfo: TcxSchedulerCustomResourceViewViewInfo;
protected
function GetNextResource(AGoToForward: Boolean): TcxSchedulerStorageResourceItem;
function GetResourceItem: TcxSchedulerStorageResourceItem; override;
function GetResourceFromViewInfo(AInfo: TcxSchedulerResourceViewInfo): TcxSchedulerStorageResourceItem;
function RoundTime(const ADateTime: TDateTime): TDateTime;
public
procedure ValidateSelection(var ASelStart, ASelFinish: TDateTime;
var AResource: TcxSchedulerStorageResourceItem); override;
property IsFirstResource: Boolean read GetIsFirstResource;
property IsLastResource: Boolean read GetIsLastResource;
property GroupingKind: TcxSchedulerGroupingKind read GetGroupingKind;
property ResourceItem: TcxSchedulerStorageResourceItem read GetResourceItem;
property ResourceObject: TcxSchedulerResourceViewInfo read GetResourceObject;
property ViewInfo: TcxSchedulerCustomResourceViewViewInfo read GetViewInfo;
end;
{ TcxSchedulerCustomResourceViewController }
TcxSchedulerCustomResourceViewController = class(TcxSchedulerViewController)
private
function GetHitTest: TcxSchedulerCustomResourceViewHitTest;
protected
function CreateNavigation: TcxSchedulerViewNavigation; override;
function GetCursor(X, Y: Integer): TCursor; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
property HitTest: TcxSchedulerCustomResourceViewHitTest read GetHitTest;
end;
{ TcxSchedulerCustomResourceViewHitTest }
TcxSchedulerCustomResourceViewHitTest = class(TcxSchedulerViewHitTest)
private
function GetContentCell: TcxSchedulerContentCellViewInfo;
function GetHeaderCell: TcxSchedulerHeaderCellViewInfo;
function GetView: TcxSchedulerCustomResourceView;
protected
FButton: TcxSchedulerMoreEventsButtonViewInfo;
FDragKind: TcxEventDragKind;
FEventCell: TcxSchedulerEventCellViewInfo;
FHitObject: TObject;
FTimeZone: Integer;
function CanMoveEvent(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
function CanResizeEvent(AEvent: TcxSchedulerControlEvent): Boolean; virtual;
procedure Clear; override;
procedure DoCalculate; override;
function GetHitEvent: TcxSchedulerControlEvent; override;
procedure SetHitTime(AItemFlag: Integer; const ATime: TDateTime); virtual;
procedure SetResource(AResource: TcxSchedulerResourceViewInfo);
procedure ValidateDragKind; virtual;
property View: TcxSchedulerCustomResourceView read GetView;
property HitAtTimeZoneLabel: Boolean index htcTimeZoneLabel read GetBitState;
property TimeZone: Integer read FTimeZone;
public
function GetDragKind: TcxEventDragKind; override;
procedure SetDragKind(AValue: TcxEventDragKind);
property Button: TcxSchedulerMoreEventsButtonViewInfo read FButton;
property ContentCell: TcxSchedulerContentCellViewInfo read GetContentCell;
property EventCell: TcxSchedulerEventCellViewInfo read FEventCell;
property HeaderCell: TcxSchedulerHeaderCellViewInfo read GetHeaderCell;
property HitAtButton: Boolean index htcButton read GetBitState;
property HitAtContent: Boolean index htcContent read GetBitState;
property HitAtDayHeader: Boolean index htcDayHeader read GetBitState;
property HitAtGroupSeparator: Boolean index htcGroupSeparator read GetBitState;
property HitAtResourceHeader: Boolean index htcResourceHeader read GetBitState;
end;
{ TcxSchedulerCustomViewPainter }
TcxSchedulerCustomViewPainter = class(TcxSchedulerSubControlPainter)
private
function GetView: TcxSchedulerCustomResourceView;
protected
FPainter: IcxSchedulerCommonViewItemsPainter;
procedure DrawBackgroundCell(AItem: TcxSchedulerBackgroundCellViewInfo); virtual;
procedure DrawButtonCell(AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean); virtual;
procedure DrawContentCell(AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean); virtual;
procedure DrawEventCell(AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean); virtual;
procedure DrawGroupSeparatorCell(AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean); virtual;
procedure DrawHeaderCell(AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean); virtual;
procedure DrawResourceHeaderCell(AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean); virtual;
public
constructor Create(AOwner: TcxSchedulerSubControl); override;
procedure Paint; override;
property Painter: IcxSchedulerCommonViewItemsPainter read FPainter;
property View: TcxSchedulerCustomResourceView read GetView;
end;
{ TcxSchedulerEventPlace }
TcxSchedulerEventPlace = class
public
ColFinish: Integer;
ColStart: Integer;
Resource: TObject;
Data: TObject;
Event: TcxSchedulerEvent;
LineFinish: Integer;
LineStart: Integer;
procedure AlignPosition(APlace: TcxSchedulerEventPlace);
function IntersectHorz(APlace: TcxSchedulerEventPlace): Boolean;
function IntersectVert(APlace: TcxSchedulerEventPlace): Boolean;
procedure ResetPosition;
end;
{ TcxSchedulerEventLayoutBuilder }
TcxSchedulerEventLayoutBuilderGetEventPlaceProc = function(Sender: TcxSchedulerEventLayoutBuilder;
AEvent: TcxSchedulerControlEvent; out AStartCol, AFinishCol: Integer; out ALineCount: Integer): Boolean of object;
TcxSchedulerEventLayoutBuilder = class
private
FEventPlaces: TcxObjectList;
function GetEventPlace(AIndex: Integer): TcxSchedulerEventPlace;
function GetEventPlaceCount: Integer;
public
constructor Create; virtual;
destructor Destroy; override;
function AddEventPlace(AEvent: TcxSchedulerEvent;
AStartCol, AFinishCol: Integer; ALineCount: Integer = 1; AResource: TObject = nil): TcxSchedulerEventPlace;
procedure Clear;
procedure Calculate;
procedure CalculateEx(AEventsList: TcxSchedulerFilteredEventList;
APlaceInfoProc: TcxSchedulerEventLayoutBuilderGetEventPlaceProc);
property EventPlaceCount: Integer read GetEventPlaceCount;
property EventPlaces[Index: Integer]: TcxSchedulerEventPlace read GetEventPlace;
end;
function MakeTextOutcxFlags(AlignHorz: TAlignment;
AlignVert: TcxAlignmentVert; AMultiline: Boolean = False): Integer;
implementation
uses
cxEditTextUtils;
type
TcxCustomEditStyleAccess = class(TcxCustomEditStyle);
const
AlignmentsHorz: array[TAlignment] of Integer =
(cxAlignLeft, cxAlignRight, cxAlignHCenter);
AlignmentsVert: array[TcxAlignmentVert] of Integer =
(cxAlignTop, cxAlignBottom, cxAlignVCenter);
MultiLines: array[Boolean] of Integer = (0, cxWordBreak);
{$IFDEF USECXTEXTOUT}
cxTextOutFlags: array[Boolean] of Cardinal = (
CXTO_LEFT or CXTO_CENTER_VERTICALLY or CXTO_WORDBREAK,
CXTO_LEFT or CXTO_TOP or CXTO_WORDBREAK or CXTO_EDITCONTROL);
function MakeTextOutFlags(AlignHorz: TAlignment;
AlignVert: TcxAlignmentVert; AMultiline: Boolean = False): Integer;
const
Horz: array[TAlignment] of Integer =
(CXTO_LEFT, CXTO_RIGHT, CXTO_CENTER_HORIZONTALLY);
Vert: array[TcxAlignmentVert] of Integer =
(CXTO_TOP, CXTO_BOTTOM, CXTO_CENTER_VERTICALLY);
begin
Result := CXTO_PREVENT_LEFT_EXCEED or CXTO_PREVENT_TOP_EXCEED or
Horz[AlignHorz] or Vert[AlignVert] + CXTO_SINGLELINE;
if AMultiline then
begin
Result := CXTO_PREVENT_LEFT_EXCEED or CXTO_PREVENT_TOP_EXCEED or
Horz[AlignHorz] or Vert[AlignVert] or CXTO_WORDBREAK;
end;
end;
{$ELSE}
cxDrawTextFlags: array[Boolean] of Cardinal = (
cxAlignLeft or cxAlignVCenter or cxSingleLine,
cxAlignLeft or cxAlignTop or cxWordBreak or cxDontBreakChars);
{$ENDIF}
function MakeTextOutcxFlags(AlignHorz: TAlignment;
AlignVert: TcxAlignmentVert; AMultiline: Boolean = False): Integer;
begin
Result := AlignmentsHorz[AlignHorz] or cxDontBreakChars or
AlignmentsVert[AlignVert] or MultiLines[AMultiline];
end;
function MakeRect(ALeft, ATop: Integer; ASize: TSize): TRect;
begin
Result.Left := ALeft;
Result.Top := ATop;
Result.Right := ALeft + ASize.cx;
Result.Bottom := ATop + ASize.cy;
end;
function GetTrueMultilineTextHeight(ACanvas: TcxCanvas; const S: string; ABounds: TRect): Integer;
var
ARowCount: Integer;
ATextFlags: Cardinal;
ATextParams: TcxTextParams;
ATextRows: TcxTextRows;
begin
ABounds.Bottom := 30000;
ATextFlags := CXTO_CALCROWCOUNT or CXTO_LEFT or CXTO_TOP or CXTO_WORDBREAK or CXTO_EDITCONTROL;
ATextParams := cxCalcTextParams(ACanvas.Canvas, ATextFlags);
cxMakeTextRows(ACanvas.Canvas, PChar(S), ABounds, ATextParams, ATextRows, ARowCount);
Result := ATextParams.RowHeight * Max(ARowCount, 1);
ATextRows := nil;
end;
{ TcxSchedulerViewInfoCellList }
function TcxSchedulerViewInfoCellList.CalculateHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest): Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to Count - 1 do
if Items[I].GetHitTest(AHitTest, Result) and Result then Exit;
end;
procedure TcxSchedulerViewInfoCellList.Clear;
var
I: Integer;
begin
for I := Count - 1 downto 0 do
Items[I].Free;
inherited Clear;
end;
procedure TcxSchedulerViewInfoCellList.Draw(
ACanvas: TcxCanvas; ADrawItemProc: TcxSchedulerCustomDrawItemProc);
var
I: Integer;
ADone: Boolean;
AItem: TcxSchedulerCustomViewInfoItem;
ASavedFont: TFont;
begin
for I := 0 to Count - 1 do
begin
AItem := Items[I];
if AItem.FVisible then
begin
ASavedFont := AItem.FViewParams.Font;
AItem.BeforeCustomDraw(ACanvas);
ADone := False;
if AItem.FHasClipping then
begin
AItem.FCanvas := ACanvas;
AItem.ClippingCreate(AItem.FHasClipping);
ADrawItemProc(AItem, ADone);
AItem.ClippingRestore;
end
else
ADrawItemProc(AItem, ADone);
AItem.AfterCustomDraw(ACanvas);
if not ADone then AItem.Draw(ACanvas);
AItem.FViewParams.Font := ASavedFont;
end;
end;
// need Optimize if custom draw not supported do not need
// custom draw canvas preparation
// SelectClipRgn(ACanvas.Handle, 0);
// TODO: draw and custom draw events
end;
function TcxSchedulerViewInfoCellList.GetItem(
AIndex: Integer): TcxSchedulerCustomViewInfoItem;
begin
Result := List^[AIndex];
end;
{ TcxSchedulerCustomViewInfoItem }
constructor TcxSchedulerCustomViewInfoItem.Create(
APainter: TcxCustomLookAndFeelPainterClass;
const ABounds, AVisibleRect: TRect; const AViewParams: TcxViewParams);
begin
FPainter := APainter;
FDateTime := NullDate;
FViewParams := AViewParams;
CalculateCellBounds(ABounds, AVisibleRect);
end;
destructor TcxSchedulerCustomViewInfoItem.Destroy;
begin
FClipRgn.Free;
inherited Destroy;
end;
procedure TcxSchedulerCustomViewInfoItem.Draw(ACanvas: TcxCanvas);
var
ATransparent: Boolean;
APrevCanvas: TcxCanvas;
APrevParams: TcxViewParams;
begin
if not FVisible then Exit;
ATransparent := Transparent;
APrevCanvas := FCanvas;
ACanvas.GetParams(APrevParams);
FCanvas := ACanvas;
DoDraw;
ACanvas.SetParams(APrevParams);
FCanvas := APrevCanvas;
Transparent := ATransparent;
end;
procedure TcxSchedulerCustomViewInfoItem.CalculateCellBounds(
const ABounds, AVisibleRect: TRect);
begin
FBounds := ABounds;
FVisible := cxRectIntersect(FClipRect, ABounds, AVisibleRect);
FHasClipping := FVisible and not cxRectIsEqual(FClipRect, ABounds);
end;
procedure TcxSchedulerCustomViewInfoItem.ClippingCreate(AHasClipping: Boolean);
begin
Inc(FClipRef);
if not AHasClipping or (FClipRef > 1) then Exit;
if FClipRgn = nil then
FClipRgn := TcxRegion.Create(FClipRect);
FSavedClipRgn := Canvas.GetClipRegion;
Canvas.SetClipRegion(FClipRgn, roSet, False);
end;
procedure TcxSchedulerCustomViewInfoItem.ClippingRestore;
begin
Dec(FClipRef);
if (FClipRef = 0) and (FSavedClipRgn <> nil) then
begin
Canvas.SetClipRegion(FSavedClipRgn, roSet, True);
FSavedClipRgn := nil;
end;
end;
function TcxSchedulerCustomViewInfoItem.DrawBackground(
ACanvas: TcxCanvas; const ABounds: TRect): Boolean;
begin
Result := Transparent or Assigned(Bitmap) and not Bitmap.Empty;
if Result and not Transparent then
ACanvas.FillRect(ABounds, Bitmap);
end;
procedure TcxSchedulerCustomViewInfoItem.DrawFrame(
const ARect: TRect; ABorders: TcxBorders = [];
ABorderColor: TColor = clDefault; ALineWidth: Integer = 1);
begin
Canvas.FrameRect(ARect, ABorderColor, ALineWidth, ABorders);
end;
procedure TcxSchedulerCustomViewInfoItem.DrawRect(
const ARect: TRect; ABorders: TcxBorders = [];
ABorderColor: TColor = clDefault; ALineWidth: Integer = 1);
begin
if Transparent then
Canvas.FrameRect(ARect, ABorderColor, ALineWidth, ABorders)
else
Canvas.FillRect(ARect, FViewParams, ABorders, ABorderColor, ALineWidth);
end;
procedure TcxSchedulerCustomViewInfoItem.DrawText(
const ARect: TRect; const AText: string; AFlags: Integer; AFont: TFont = nil; AColor: TColor = clDefault);
begin
if AFont = nil then
Canvas.Font := FViewParams.Font
else
Canvas.Font := AFont;
if AColor <> clDefault then
Canvas.Font.Color := AColor;
Canvas.Brush.Style := bsClear;
Canvas.DrawTexT(AText, ARect, AFlags);
end;
function TcxSchedulerCustomViewInfoItem.GetFont: TFont;
begin
Result := FViewParams.Font;
end;
function TcxSchedulerCustomViewInfoItem.GetHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest; var ABreak: Boolean): Boolean;
begin
Result := FVisible and PtInRect(FClipRect, AHitTest.HitPoint);
ABreak := Result;
if Result then
InitHitTest(AHitTest);
end;
procedure TcxSchedulerCustomViewInfoItem.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
AHitTest.FHitObject := Self;
end;
procedure TcxSchedulerCustomViewInfoItem.RotateBitmap(
ABitmap: TBitmap; ARotationAngle: TcxRotationAngle; AFlipHorizontally: Boolean = False);
var
PDest, PDestStart: ^DWORD;
PSource, PSourceStart: ^DWord;
PBuffer: Pointer;
XSource, YSource: Integer;
LineCopyingDirection: Integer;
TempVar: Integer;
begin
if ABitmap.Empty then Exit;
case ARotationAngle of
ra0:
if AFlipHorizontally then
begin
with ABitmap do
begin
GetMem(PBuffer, Width * 4);
for YSource := 0 to Height - 1 do
begin
PSourceStart := ScanLine[YSource];
PSource := PSourceStart;
Inc(PSource, Width - 1);
PDest := PBuffer;
for XSource := 0 to Width - 1 do
begin
PDest^ := PSource^;
Inc(PDest);
Dec(PSource);
end;
Move(PBuffer^, PSourceStart^, Width * 4);
end;
end;
FreeMem(PBuffer);
end;
raPlus90, raMinus90:
with ABitmap do
begin
GetMem(PBuffer, Width * Height * 4);
LineCopyingDirection := 0;
PDestStart := PBuffer;
case ARotationAngle of
raPlus90:
begin
Inc(PDestStart, Height * (Width - 1));
LineCopyingDirection := 1;
end;
raMinus90:
begin
Inc(PDestStart, Height - 1);
LineCopyingDirection := -1;
end;
end;
for YSource := 0 to Height - 1 do
begin
PSource := ScanLine[YSource];
PDest := PDestStart;
if AFlipHorizontally then
begin
Inc(PSource, Width - 1);
for XSource := 0 to Width - 1 do
begin
PDest^ := PSource^;
Dec(PDest, Height * LineCopyingDirection);
Dec(PSource);
end
end
else
for XSource := 0 to Width - 1 do
begin
PDest^ := PSource^;
Dec(PDest, Height * LineCopyingDirection);
Inc(PSource);
end;
Inc(PDestStart, LineCopyingDirection);
end;
TempVar := Width;
Width := Height;
Height := TempVar;
if Width = Height then
begin
Width := Width + 1;
Width := Width - 1;
end;
PDest := PBuffer;
for YSource := 0 to Height - 1 do
begin
Move(PDest^, ScanLine[YSource]^, Width * 4);
Inc(PDest, Width);
end;
FreeMem(PBuffer);
end;
end;
end;
// custom draw support
procedure TcxSchedulerCustomViewInfoItem.AfterCustomDraw(ACanvas: TcxCanvas);
begin
ACanvas.GetParams(FViewParams);
end;
procedure TcxSchedulerCustomViewInfoItem.BeforeCustomDraw(ACanvas: TcxCanvas);
begin
ACanvas.SetParams(FViewParams);
end;
function TcxSchedulerCustomViewInfoItem.GetBitmap: TBitmap;
begin
Result := FViewParams.Bitmap;
end;
function TcxSchedulerCustomViewInfoItem.GetColor: TColor;
begin
Result := FViewParams.Color;
end;
function TcxSchedulerCustomViewInfoItem.GetDateTimeHelper: TcxSchedulerDateTimeHelperClass;
begin
Result := cxSchedulerUtils.DateTimeHelper;
end;
function TcxSchedulerCustomViewInfoItem.GetPainterHelper: TcxSchedulerPainterHelperClass;
begin
Result := TcxSchedulerHelpersFactory.PainterHelperClass;
end;
function TcxSchedulerCustomViewInfoItem.GetTextColor: TColor;
begin
Result := FViewParams.TextColor;
end;
procedure TcxSchedulerCustomViewInfoItem.SetBitmap(
AValue: TBitmap);
begin
FViewParams.Bitmap := AValue;
end;
procedure TcxSchedulerCustomViewInfoItem.SetColor(
AValue: TColor);
begin
FViewParams.Color := AValue;
end;
procedure TcxSchedulerCustomViewInfoItem.SetTextColor(
AValue: TColor);
begin
FViewParams.TextColor := AValue;
end;
{ TcxSchedulerBackgroundCellViewInfo }
procedure TcxSchedulerBackgroundCellViewInfo.DoDraw;
begin
DrawRect(Bounds, Borders, clBtnShadow);
end;
{ TcxSchedulerCustomResourceViewInfoItem }
procedure TcxSchedulerCustomResourceViewInfoItem.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
if IsResourceAssigned then
begin
AHitTest.SetResource(FResource);
AHitTest.SetBitState(htcResource, True);
end;
end;
{ TcxSchedulerHeaderCellViewInfo }
constructor TcxSchedulerHeaderCellViewInfo.Create(
APainter: TcxCustomLookAndFeelPainterClass;
const ABounds, AVisibleRect: TRect; const AViewParams: TcxViewParams);
begin
inherited Create(APainter, ABounds, AVisibleRect, AViewParams);
FImageIndex := -1;
FButtonState := cxbsDefault;
FAlignHorz := taCenter;
FAlignVert := vaCenter;
FBorders := cxBordersAll;
FTextRect := cxRectInflate(FBounds, -cxTextOffset, 0);
end;
destructor TcxSchedulerHeaderCellViewInfo.Destroy;
begin
FCachedBitmap.Free;
FRotateBitmap.Free;
inherited Destroy;
end;
procedure TcxSchedulerHeaderCellViewInfo.Calculate(const AText: string);
begin
FDisplayText := AText;
end;
procedure TcxSchedulerHeaderCellViewInfo.Draw(ACanvas: TcxCanvas);
var
ATransparent: Boolean;
ASavedCanvas: TCanvas;
begin
if not FVisible then Exit;
ValidateSelection;
FBackgroundDrawing := False;
ATransparent := Transparent;
if FCachedBitmap = nil then
begin
FCachedBitmap := cxCreateBitmap(cxRectSize(Bounds), pf32Bit);
if Transparent then
BitBlt(FCachedBitmap.Canvas.Handle, 0, 0, FCachedBitmap.Width,
FCachedBitmap.Height, ACanvas.Handle, Bounds.Left, Bounds.Top, srcCopy);
SetWindowOrgEx(FCachedBitmap.Canvas.Handle, FBounds.Left, FBounds.Top, nil);
ASavedCanvas := ACanvas.Canvas;
FCanvas := ACanvas;
FCanvas.Canvas := FCachedBitmap.Canvas;
CalculateImageLayout;
if RotateText or RotateHeader then
DrawVerticalHeader
else
DrawHorizontalHeader;
ACanvas.Canvas := ASavedCanvas;
SetWindowOrgEx(FCachedBitmap.Canvas.Handle, 0, 0, nil);
end;
ACanvas.Draw(FBounds.Left, FBounds.Top, FCachedBitmap);
FCanvas := nil;
Transparent := ATransparent;
end;
procedure TcxSchedulerHeaderCellViewInfo.CalculateImageLayout;
const
Alignments: array[TcxSchedulerHeaderImagePosition] of TAlignment =
(taLeftJustify, taCenter, taRightJustify, taCenter);
var
ATopLeft: TPoint;
ATextSize, AImageSize: TSize;
ABounds: TRect;
begin
FImageRectAssigned := FImageRectAssigned or not HasImage;
if FImageRectAssigned then
begin
FTextRect := cxRectInflate(PainterHelper.ExcludeBorders(Bounds, Borders), -cxTextOffset, 0);
if not HasImage and RotateHeader then
begin
if RotateText then
FTextRect := MakeRect(0, 0, cxSize(Height, Width))
else
FTextRect := MakeRect(0, 0, cxSize(Width, Height));
InflateRect(FTextRect, -(cxTextOffset + 1), -(cxTextOffset + 1));
end;
DisplayBounds := FTextRect;
Exit;
end;
FTextRect := cxTextRect(PainterHelper.ExcludeBorders(Bounds, Borders));
FImageRectAssigned := True;
FAlignHorz := Alignments[ImagePosition];
FAlignVert := vaTop;
MultiLine := AutoHeight;
// calculate text and image extents
AImageSize := cxSize(Images.Width, Images.Height);
if RotateHeader and RotateText then
begin
AImageSize := cxSize(Images.Height, Images.Width);
ABounds := MakeRect(0, 0, cxSize(Height - 2, Width - 2));
FTextRect := cxTextRect(ABounds);
end
else
begin
ABounds := Bounds;
if RotateHeader then
begin
OffsetRect(ABounds, -ABounds.Left, -ABounds.Top);
FTextRect := cxTextRect(ABounds);
end;
end;
DisplayBounds := cxRectInflate(ABounds, -1, -1);
if AutoHeight and (ImagePosition in [ipLeft, ipRight]) then
Dec(FTextRect.Right, AImageSize.cx + cxTextOffset * 2);
if Length(DisplayText) > 0 then
begin
// Canvas.Font.Assign(Font);
// Canvas.TextExtent(DisplayText, FTextRect, GetTextOutcxFlags);
FTextRect.Right := FTextRect.Left + cxRectWidth(Resource.FTextRect);
FTextRect.Bottom := FTextRect.Top + cxRectHeight(Resource.FTextRect);
end
else
FTextRect := cxNullRect;
ATextSize := cxRectSize(FTextRect);
ATopLeft := cxPointOffset(cxRectCenter(ABounds), 1, -1 + Byte(RotateHeader));
if ImagePosition in [ipLeft, ipRight] then
begin
Dec(ATopLeft.X, (AImageSize.cx + ATextSize.cx + cxTextOffset) div 2);
FTextRect := MakeRect(ATopLeft.X, ATopLeft.y - ATextSize.cy div 2, ATextSize);
FImageRect := MakeRect(ATopLeft.X, ATopLeft.y - AImageSize.cy div 2, AImageSize);
end
else
begin
Dec(ATopLeft.Y, (AImageSize.cy + ATextSize.cy + cxTextOffset) div 2);
FTextRect := MakeRect(ATopLeft.x - ATextSize.cx div 2, ATopLeft.y, ATextSize);
FImageRect := MakeRect(ATopLeft.x - AImageSize.cx div 2, ATopLeft.y, AImageSize);
end;
// calculate text bounds
if Length(DisplayText) > 0 then
begin
case ImagePosition of
ipLeft:
OffsetRect(FTextRect, AImageSize.cx + cxTextOffset, 0);
ipTop:
OffsetRect(FTextRect, 0, AImageSize.cy + cxTextOffset);
ipRight:
OffsetRect(FImageRect, ATextSize.cx + cxTextOffset, 0);
ipBottom:
OffsetRect(FImageRect, 0, ATextSize.cy + cxTextOffset);
end;
end;
end;
procedure TcxSchedulerHeaderCellViewInfo.CheckNeighbor(
APrevCell: TcxSchedulerHeaderCellViewInfo);
begin
if (APrevCell = nil) or (APrevCell.RotateHeader <> RotateHeader) then Exit;
if (RotateHeader and (APrevCell.Bounds.Bottom <> Bounds.Top)) or
(not RotateHeader and (APrevCell.Bounds.Right <> Bounds.Left)) then
Exclude(APrevCell.FBorders, bRight);
end;
function TcxSchedulerHeaderCellViewInfo.CheckSelection: Boolean;
begin
Result := False;
end;
procedure TcxSchedulerHeaderCellViewInfo.DoDraw;
begin
if Transparent and (DisplayText = '') then Exit;
Painter.DrawHeader(Canvas, Bounds, TextRect, Neighbors, Borders,
FButtonState, AlignHorz, AlignVert, MultiLine, ShowEndEllipsis, DisplayText,
Font, TextColor, Color, DrawBackground, not (nRight in Neighbors));
end;
procedure TcxSchedulerHeaderCellViewInfo.DrawCaption(ACanvas: TcxCanvas = nil);
var
ABitmap: TBitmap;
ARgn: TcxRegion;
begin
if ACanvas = nil then
ACanvas := Canvas;
ARgn := ACanvas.GetClipRegion;
try
ACanvas.Brush.Style := bsClear;
ACanvas.IntersectClipRect(DisplayBounds);
ACanvas.Font := Font;
ACanvas.Font.Color := TextColor;
ACanvas.DrawTexT(DisplayText, TextRect, GetTextOutcxFlags);
if FImageRectAssigned and HasImage then
begin
if not RotateText then
ACanvas.DrawImage(Images, FImageRect.Left, FImageRect.Top, ImageIndex)
else
begin //todo:
ABitmap := TBitmap.Create;
try
ABitmap.Width := Images.Width;
ABitmap.Height := Images.Height;
RotateBitmap(ABitmap, raMinus90);
BitBlt(ABitmap.Canvas.Handle, 0, 0, Images.Height, Images.Width, ACanvas.Handle,
FImageRect.Left, FImageRect.Top, srcCopy);
RotateBitmap(ABitmap, raPlus90);
Images.Draw(ABitmap.Canvas, 0, 0, ImageIndex{$IFDEF DELPHI6}, dsNormal, itImage {$ENDIF});
RotateBitmap(ABitmap, raMinus90);
ACanvas.Draw(FImageRect.Left, FImageRect.Top, ABitmap);
finally
ABitmap.Free;
end;
end;
end;
finally
ACanvas.SetClipRegion(ARgn, roSet);
end;
end;
procedure TcxSchedulerHeaderCellViewInfo.DrawHorizontalHeader;
var
AText: string;
begin
AText := DisplayText;
FDisplayText := '';
DoDraw;
if not FBackgroundDrawing and Selected then
cxAlphaBlend(FCachedBitmap, FSelectionRect, ColorToRgb(SelectionColor));
DisplayText := AText;
DrawCaption;
end;
function TcxSchedulerHeaderCellViewInfo.DrawRotateBackground(
ACanvas: TcxCanvas; const ABounds: TRect): Boolean;
begin
Result := FDrawRotatedBackground;
end;
procedure TcxSchedulerHeaderCellViewInfo.DrawVerticalHeader;
procedure CreateRotatedBitmap;
begin
with Bounds do
FRotateBitmap := cxCreateTrueColorBitmap(Right - Left, Bottom - Top);
FRotateBitmap.PixelFormat := pf32bit;
FRotateBitmap.Canvas.Lock;
if Transparent then
begin
BitBlt(FRotateBitmap.Canvas.Handle, 0, 0, FRotateBitmap.Width,
FRotateBitmap.Height, Canvas.Handle, Bounds.Left, Bounds.Top, srcCopy);
end;
end;
var
R: TRect;
ABitmapCanvas: TcxCanvas;
begin
if FRotateBitmap = nil then
begin
CreateRotatedBitmap;
ABitmapCanvas := TcxCanvas.Create(FRotateBitmap.Canvas);
try
ABitmapCanvas.WindowOrg := Bounds.TopLeft;
FDrawRotatedBackground := DrawBackground(ABitmapCanvas, Bounds);
RotateBitmap(FRotateBitmap, raPlus90, True);
R := cxRect(0, 0, FRotateBitmap.Width, FRotateBitmap.Height);
if not Transparent then
Painter.DrawHeader(ABitmapCanvas, R, cxRectInflate(R, -cxTextOffset, -cxTextOffset),
Neighbors, Borders, cxbsNormal, taCenter, vaCenter, False, False, '',
Font, TextColor, Color, DrawRotateBackground);
if RotateText then
begin
RotateBitmap(FRotateBitmap, ra0, True);
DrawCaption(ABitmapCanvas);
RotateBitmap(FRotateBitmap, raPlus90);
end
else
begin
RotateBitmap(FRotateBitmap, raPlus90, True);
R.BottomRight := cxPoint(R.Bottom, R.Right);
DrawCaption(ABitmapCanvas);
end;
finally
FRotateBitmap.Canvas.Unlock;
ABitmapCanvas.Free;
end;
end;
Canvas.Draw(Bounds.Left, Bounds.Top, FRotateBitmap);
end;
function TcxSchedulerHeaderCellViewInfo.GetTextOutcxFlags: Integer;
begin
Result := MakeTextOutcxFlags(AlignHorz, AlignVert, AutoHeight);
end;
function TcxSchedulerHeaderCellViewInfo.GetTextOutFlags: Integer;
const
Horz: array[TAlignment] of Integer =
(CXTO_LEFT, CXTO_RIGHT, CXTO_CENTER_HORIZONTALLY);
Vert: array[TcxAlignmentVert] of Integer =
(CXTO_TOP, CXTO_BOTTOM, CXTO_CENTER_VERTICALLY);
begin
Result := CXTO_PREVENT_LEFT_EXCEED or CXTO_PREVENT_TOP_EXCEED or
Horz[AlignHorz] or Vert[AlignVert] + CXTO_SINGLELINE;
if AutoHeight then
begin
Result := CXTO_PREVENT_LEFT_EXCEED or CXTO_PREVENT_TOP_EXCEED or
Horz[AlignHorz] or Vert[AlignVert] or CXTO_WORDBREAK;
end;
end;
function TcxSchedulerHeaderCellViewInfo.HasImage: Boolean;
begin
Result := ImageIndex >=0
end;
procedure TcxSchedulerHeaderCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
inherited InitHitTest(AHitTest);
if IsResourceAssigned then
AHitTest.SetBitState(htcResourceHeader, True);
if DateTime <> NullDate then
AHitTest.SetHitTime(htcDayHeader, DateTime);
end;
procedure TcxSchedulerHeaderCellViewInfo.TextOut(ACanvas: TcxCanvas;
const AText: string; R: TRect);
begin
if Length(AText) = 0 then Exit;
if not FImageRectAssigned then
R := cxRectInflate(R, -1, -(cxTextOffset + 1));
with ACanvas.Canvas do
begin
Font := FViewParams.Font;
Font.Color := FViewParams.TextColor;
cxTextOut(Handle, PChar(AText), R, GetTextOutFlags);
end;
end;
procedure TcxSchedulerHeaderCellViewInfo.ValidateSelection;
begin
if CheckSelection and (Date = DateOf(FDateTime)) then
FButtonState := cxbsHot;
if Selected then
begin
if Selected then
TextColor := FSelectionTextColor;
FSelectionRect := PainterHelper.ExcludeBorders(Bounds, Borders);
if FButtonState = cxbsHot then
begin
FSelectionRect.Left := Max(FSelectionRect.Left, FSelectionRect.Right -
PainterHelper.TextWidth(Font, DisplayText) - cxTextOffset * 2);
end;
end;
end;
function TcxSchedulerHeaderCellViewInfo.GetHeight: Integer;
begin
Result := Bounds.Bottom - Bounds.Top;
end;
function TcxSchedulerHeaderCellViewInfo.GetWidth: Integer;
begin
Result := Bounds.Right - Bounds.Left;
end;
{ TcxSchedulerDayHeaderCellViewInfo }
function TcxSchedulerDayHeaderCellViewInfo.ConvertDateToDisplayText(
AType: Integer = 0): Integer;
begin
Result := AType - 1;
repeat
Inc(Result);
if cxRectWidth(FTextRect) <= 0 then Exit;
FDisplayText := DateTimeHelper.DayToStr(FDateTime, Result, Compressed);
until (Result = DateTimeHelper.DayToStrFormatCount - 1) or
(cxTextWidth(Font, DisplayText) <= cxRectWidth(FTextRect) - 2{lcm!!!});
end;
function TcxSchedulerDayHeaderCellViewInfo.CheckSelection: Boolean;
begin
Result := True;
end;
procedure TcxSchedulerDayHeaderCellViewInfo.DoDraw;
begin
if Selected and not (FButtonState = cxbsHot) then
begin
Color := FSelectionColor;
TextColor := FSelectionTextColor;
end;
inherited DoDraw;
end;
function TcxSchedulerDayHeaderCellViewInfo.DrawBackground(
ACanvas: TcxCanvas; const ABounds: TRect): Boolean;
var
R: TRect;
begin
FBackgroundDrawing := True;
Result := inherited DrawBackground(ACanvas, ABounds);
if Result then Exit;
R := PainterHelper.ExcludeBorders(Bounds, Borders);
if FButtonState = cxbsHot then
PainterHelper.DrawGradientRect(Canvas, Color, R);
if Selected then
begin
Canvas.SetBrushColor(SelectionColor);
Canvas.FillRect(FSelectionRect);
end;
Result := (FButtonState = cxbsHot) or Selected;
end;
{ TcxSchedulerWeekDayHeaderCellViewInfo }
function TcxSchedulerWeekDayHeaderCellViewInfo.ConvertDateToDisplayText(
AType: Integer = 0): Integer;
begin
Result := AType - 1;
repeat
Inc(Result);
FDisplayText := GetDayText(Result);
until (Result = 3) or (cxTextWidth(Font, DisplayText) <= cxRectWidth(FTextRect));
if (DateOf(FDateTime) + 1) > 7 then
Result := 0;
end;
procedure TcxSchedulerWeekDayHeaderCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
inherited InitHitTest(AHitTest);
AHitTest.SetBitState(htcTime, False);
end;
function TcxSchedulerWeekDayHeaderCellViewInfo.GetDayText(
AType: Integer): string;
var
ADay: Integer;
begin
//DELPHI8! check Trunc()
ADay := Trunc(FDateTime) + 1;
if ADay > 7 then
begin
case AType of
0:
Result := LongDayNames[7]+ '/' + LongDayNames[1];
1:
Result := ShortDayNames[7]+ '/' + ShortDayNames[1];
else
Result := AnsiUpperCase(LongDayNames[7][1]+ '/' + LongDayNames[1][1]);
end;
end
else
case AType of
0:
Result := LongDayNames[ADay];
1:
Result := ShortDayNames[ADay];
else
Result := AnsiUpperCase(LongDayNames[ADay][1]);
end;
end;
{ TcxSchedulerContainerCellViewInfo }
procedure TcxSchedulerContainerCellViewInfo.DoDraw;
begin
DrawRect(Bounds, Borders, FDayBorderColor);
end;
procedure TcxSchedulerContainerCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
inherited InitHitTest(AHitTest);
AHitTest.FHitObject := Self;
AHitTest.SetHitTime(htcContainer, DateTime);
end;
{ TcxSchedulerTimeRulerCellViewInfo }
procedure TcxSchedulerTimeRulerCellViewInfo.Calculate(
const ALabel1, ALabel2: string; ATimeZone, AAdditionalTimeZone: Integer);
begin
Calculate(-1, 1, ATimeZone, AAdditionalTimeZone, nil);
FDisplayTexts[True] := ALabel1;
FDisplayTexts[False] := ALabel2;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.Calculate(AHour, ALineCount: Integer;
ATimeZone, AAdditionalTimeZone: Integer; ALargeFont: TFont);
begin
FHour := AHour;
FLineCount := ALineCount;
FAdditionalTimeZone := AAdditionalTimeZone;
FTimeZone := ATimeZone;
FLargeFont := ALargeFont;
if FVisible then
CalculateDisplayInfo;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.SetBottom(AValue: Integer);
begin
FClipRect.Bottom := AValue;
end;
class function TcxSchedulerTimeRulerCellViewInfo.CalculateWidth(
ATimeZoneCount, ALineCount: Integer; AFont1, AFont2: TFont): Integer;
begin
if ALineCount = 1 then
Result := TcxSchedulerPainterHelper.TextWidth(AFont1, ' 24:PM')
else
begin
Result := TcxSchedulerPainterHelper.TextWidth(AFont1, ' 24') +
cxTextWidth(AFont2, 'pm') + cxTextOffset;
end;
Inc(Result, cxTextOffset shl 2);
if ATimeZoneCount > 1 then
Result := Result shl 1;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.CalculateDisplayInfo;
begin
FBounds[True] := inherited Bounds;
FDateTime := Hour * HourToTime;
if Hour >= 0 then
FDisplayTexts[True] := GetTimeDisplayText(FDateTime);
FBounds[False] := inherited Bounds;
if HasAdditionalTimeZone then
begin
FBounds[True].Left := cxRectCenter(inherited Bounds).X;
FBounds[False].Right := FBounds[True].Left;
if Hour >= 0 then
FDisplayTexts[False] := GetTimeDisplayText(GetAdditionalTime);
end;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.DoDraw;
var
ACurrentTimeZone: Boolean;
const
ABorders: array[Boolean] of TcxBorders = ([bBottom], [bBottom, bRight]);
begin
ClippingCreate(FHasClipping);
for ACurrentTimeZone := not HasAdditionalTimeZone to True do
begin
if Hour >= 0 then
DrawTimeZone(Bounds[ACurrentTimeZone],
DisplayTexts[ACurrentTimeZone], ACurrentTimeZone)
else
DrawTimeZoneLabel(Bounds[ACurrentTimeZone],
DisplayTexts[ACurrentTimeZone], ABorders[ACurrentTimeZone]);
end;
ClippingRestore;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.DrawTimeZoneLabel(
const ABounds: TRect; const AText: string; ABorders: TcxBorders);
begin
DrawRect(ABounds, ABorders, clBtnShadow);
DrawText(cxTextRect(ABounds), AText, cxAlignBottom or cxAlignLeft, Font, TextColor);
end;
procedure TcxSchedulerTimeRulerCellViewInfo.DrawTimeZone(
const ABounds: TRect; const AText: string; AIsCurrent: Boolean);
var
J, LH: Integer;
S: string;
R, R1, TextR: TRect;
const
cxRightCenterAlign: Integer = cxAlignVCenter or cxAlignRight or cxDontClip;
cxRightTopAlign: Integer = cxAlignTop or cxAlignRight or cxDontClip;
begin
LH := cxRectHeight(inherited Bounds) div LineCount;
DrawRect(ABounds, [bRight], clBtnShadow);
R := cxRectSetHeight(ABounds, LH);
R.Left := (R.Left + R.Right) div 2 + cxTextOffset shl 1;
Dec(R.Right, 6);
for J := 0 to LineCount - 2 do
begin
Canvas.FrameRect(R, clBtnShadow, 1, [bBottom]);
OffsetRect(R, 0, LH);
end;
Canvas.Brush.Style := bsClear;
TextR := cxRectInflate(PainterHelper.ExcludeBorders(ABounds,
[bRight, bBottom]), -5, -cxTextOffset);
if AIsCurrent then
DrawCurrentTime(FDateTime, ABounds);
if LineCount > 1 then
begin
J := Length(AText);
DrawText(Rect(TextR.Left, TextR.Top, R.Left - cxTextOffset, TextR.Bottom),
Copy(AText, 1, J - 3), cxRightTopAlign, LargeFont, TextColor);
R1 := Rect(R.Left, TextR.Top, TextR.Right, TextR.Top + LH - 3);
DrawText(R1, Copy(AText, J - 1, 2), cxAlignCenter, Font, TextColor);
if ShowMinutes and AIsCurrent then
for J := 1 to LineCount - 1 do
begin
OffsetRect(R1, 0, LH);
S := IntToStr(MulDiv(60, J, LineCount));
if Length(S) < 2 then
S := '0' + S;
DrawText(R1, S, cxAlignCenter, Font, TextColor);
end;
end
else
DrawText(TextR, AText, cxRightCenterAlign, Font, TextColor);
R.Left := ABounds.Left + 5;
if (Hour <> 23) and not LastVisibleHour then
DrawFrame(R, [bBottom], clBtnShadow)
else
DrawFrame(ABounds, [bBottom], clBtnShadow);
end;
procedure TcxSchedulerTimeRulerCellViewInfo.DrawCurrentTime(
const AStart: TDateTime; ABounds: TRect);
var
Y: Integer;
ANow: TDateTime;
begin
ANow := TimeOf(Now) - TimeOf(AStart);
if (ANow < 0) or (ANow >= HourToTime) then Exit;
Y := Round(ABounds.Top + (ANow * cxRectHeight(ABounds)) / HourToTime);
Dec(Y, 3);
Dec(ABounds.Right);
if Y < ABounds.Top then
Y := ABounds.Top;
PainterHelper.DrawGradientRect(Canvas, Color, cxRectSetTop(ABounds, Y - 6, 6));
Canvas.Brush.Style := bsClear;
end;
function TcxSchedulerTimeRulerCellViewInfo.GetAdditionalTime: TDateTime;
begin
Result := DateTimeHelper.ConvertToAnotherTimeZone(
Hour * HourToTime + Date, TimeZone, AdditionalTimeZone);
end;
function TcxSchedulerTimeRulerCellViewInfo.GetTimeDisplayText(
const ATime: TDateTime): string;
var
APos: Integer;
begin
Result := DateTimeHelper.TimeToStr(ATime);
if LineCount > 1 then
begin
APos := Pos(TimeSeparator, Result);
if APos = 0 then
APos := Pos(' ', Result);
if APos = 0 then
APos := Length(Result) - 2;
Result := Copy(Result, 1, APos - 1) + ' ' + AnsiLowerCase(Copy(Result, APos + 1, 2));
end;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
var
LH: Integer;
ACurrentTimeZone: Boolean;
ATime, ATimePerLine: TDateTime;
begin
inherited InitHitTest(AHitTest);
if Hour >= 0 then
begin
LH := cxRectHeight(inherited Bounds) div FLineCount;
ATimePerLine := 60 / FLineCount * MinuteToTime;
ATime := (AHitTest.HitY - inherited Bounds.Top) div LH * ATimePerLine + FHour * HourToTime;
AHitTest.SetHitTime(htcTimeRuler, ATime);
end
else
AHitTest.SetBitState(htcTimeZoneLabel, True);
for ACurrentTimeZone := not HasAdditionalTimeZone to True do
if PtInRect(Bounds[ACurrentTimeZone], AHitTest.HitPoint) then
begin
if ACurrentTimeZone then
AHitTest.FTimeZone := TimeZone
else
AHitTest.FTimeZone := AdditionalTimeZone;
end;
end;
procedure TcxSchedulerTimeRulerCellViewInfo.AfterCustomDraw(ACanvas: TcxCanvas);
begin
FViewParams.TextColor := ACanvas.Font.Color;
FViewParams.Color := ACanvas.Brush.Color;
end;
function TcxSchedulerTimeRulerCellViewInfo.GetBoundsRect(
AType: Boolean): TRect;
begin
Result := FBounds[AType];
end;
function TcxSchedulerTimeRulerCellViewInfo.GetDisplayText(
AType: Boolean): string;
begin
Result := FDisplayTexts[AType];
end;
function TcxSchedulerTimeRulerCellViewInfo.GetHasAdditionalTimeZone: Boolean;
begin
Result := AdditionalTimeZone >= 0;
end;
{ TcxSchedulerContentCellViewInfo }
constructor TcxSchedulerContentCellViewInfo.Create(
APainter: TcxCustomLookAndFeelPainterClass;
const ABounds, AVisibleRect: TRect; const AViewParams: TcxViewParams);
begin
inherited Create(APainter, ABounds, AVisibleRect, AViewParams);
FTimeLineBorders := [bLeft, bRight];
BorderColor := clDefault;
end;
procedure TcxSchedulerContentCellViewInfo.SetTime(
const ATimeStart, ATimeFinish: TDateTime);
begin
FDateTime := ATimeStart;
FTimeFinish := ATimeFinish;
end;
procedure TcxSchedulerContentCellViewInfo.DoDraw;
var
R: TRect;
begin
if BorderColor = clDefault then
BorderColor := FDayBorderColor;
if FShowTimeLine then
begin
R := Bounds;
Inc(R.Left, cxTimeLineWidth);
DrawRect(R, Borders, BorderColor);
R := cxRectSetRight(R, R.Left, cxTimeLineWidth);
if FTimeEvent = nil then
Canvas.FillRect(R, FTimeLineParams, FTimeLineBorders, FTimeLineParams.TextColor)
else
FTimeEvent.DrawState(Canvas, R, FTimeLineBorders, FTimeLineParams.TextColor);
end
else
DrawRect(Bounds, Borders, BorderColor);
end;
procedure TcxSchedulerContentCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
inherited InitHitTest(AHitTest);
AHitTest.SetHitTime(htcContent, FDateTime);
AHitTest.FHitObject := Self;
end;
{ TcxSchedulerBackgroundSlotCellViewInfo }
procedure TcxSchedulerBackgroundSlotCellViewInfo.DoDraw;
begin
inherited DoDraw;
end;
{ TcxSchedulerMonthDayContentCellViewInfo }
destructor TcxSchedulerMonthDayContentCellViewInfo.Destroy;
begin
if FSmallFontCreated then
FreeAndNil(FSmallTextFont);
inherited Destroy;
end;
procedure TcxSchedulerMonthDayContentCellViewInfo.SetContentState(
AsDayOfMonth: Boolean; ASelected: Boolean;
ATextHeight: Integer; const ASelectionParams: TcxViewParams);
begin
FSelectionColor := ASelectionParams.Color;
FSelectionTextColor := ASelectionParams.TextColor;
FTextRect := PainterHelper.ExcludeBorders(Bounds, Borders);
if AsDayOfMonth then
FDisplayText := IntToStr(DayOf(TimeStart))
else
FDisplayText := GetLongDisplayText;
FSelected := ASelected;
FTextRect.Bottom := Min(FTextRect.Bottom, FTextRect.Top + ATextHeight);
if not SmallFont then
FTextRect.Left := Max(FTextRect.Left,
FTextRect.Right - PainterHelper.TextWidth(Font, DisplayText)) - cxTextOffset * 2
else
begin
if FSmallTextFont = nil then
begin
SmallTextFont := TFont.Create;
FSmallFontCreated := True;
FSmallTextFont.Assign(Font);
FSmallTextFont.Size := Round(Font.Size * 2 / 3);
end;
FTextRect.Left := Max(FTextRect.Left, FTextRect.Right -
PainterHelper.TextWidth(FSmallTextFont, DisplayText)) - cxTextOffset;
end;
end;
function TcxSchedulerMonthDayContentCellViewInfo.UpdateSelection(ASelected: Boolean): Boolean;
begin
Result := FSelected <> ASelected;
if Result then
FSelected := ASelected;
end;
procedure TcxSchedulerMonthDayContentCellViewInfo.DoDraw;
const
TextFlags = CXTO_PREVENT_LEFT_EXCEED or CXTO_PREVENT_TOP_EXCEED or
CXTO_CENTER_VERTICALLY or CXTO_RIGHT;
var
R: TRect;
AColor: Integer;
begin
inherited DoDraw;
if DisplayText <> '' then
begin
R := PainterHelper.ExcludeBorders(Bounds, Borders);
R.Bottom := FTextRect.Bottom;
if not Transparent and IsToday then
PainterHelper.DrawGradientRect(Canvas, Color, R);
if Selected then
begin
Inc(R.Top);
InflateRect(R, -1, 0);
Canvas.SetBrushColor(SelectionColor);
if not IsToday then
Canvas.FillRect(R)
else
begin
R := FTextRect;
R.Left := Max(Bounds.Left, (R.Left - cxTextOffset * 2));
Inc(R.Bottom);
InflateRect(R, -1, -1);
Canvas.FillRect(R);
end;
end;
if SmallFont then
Canvas.Font := SmallTextFont
else
Canvas.Font := Font;
if Selected then
AColor := SelectionTextColor
else
AColor := TextColor;
Canvas.Brush.Style := bsClear;
AColor := Windows.SetTextColor(Canvas.Handle, ColorToRgb(AColor));
cxTextOut(Canvas.Handle, PChar(DisplayText),
FTextRect, TextFlags, 0, 0, cxTextOffset + 1);
Windows.SetTextColor(Canvas.Handle, AColor);
end;
end;
function TcxSchedulerMonthDayContentCellViewInfo.GetLongDisplayText: string;
begin
Result := LongMonthNames[MonthOf(TimeStart)] + ', ' + IntToStr(DayOf(TimeStart));
if cxTextWidth(Font, Result) >= (cxRectWidth(FTextRect) div 2) then
Result := ShortMonthNames[MonthOf(TimeStart)] + ' ' + IntToStr(DayOf(TimeStart));
end;
function TcxSchedulerMonthDayContentCellViewInfo.GetIsToday: Boolean;
begin
Result := Date = TimeStart;
end;
procedure TcxSchedulerMonthDayContentCellViewInfo.SetSmallTextFont(AFont: TFont);
begin
if FSmallFontCreated then
FreeAndNil(FSmallFont);
FSmallTextFont := AFont;
end;
{ TcxSchedulerEventCellViewInfo }
constructor TcxSchedulerEventCellViewInfo.Create(
AViewData: TcxSchedulerEventViewData);
begin
inherited Create(AViewData.Painter, AViewData.Bounds,
AViewData.VisibleRect, AViewData.ViewParams);
ViewData := AViewData;
FSeparatorColor := clBtnShadow;
FCanvas := AViewData.Canvas;
FImages := TcxSchedulerEventImages.Create(AViewData.ImagesLayout);
Initialize;
end;
destructor TcxSchedulerEventCellViewInfo.Destroy;
begin
ViewData.Free;
FImages.Free;
FEditViewInfo.Free;
inherited Destroy;
end;
procedure TcxSchedulerEventCellViewInfo.Draw(
ACanvas: TcxCanvas; ABitmap: TBitmap);
begin
ViewData.Bitmap := ABitmap;
inherited Draw(ACanvas);
end;
procedure TcxSchedulerEventCellViewInfo.DrawState(ACanvas: TcxCanvas;
const ARect: TRect; ABorders: TcxBorders; ABorderColor: TColor);
begin
PainterHelper.DrawState(ACanvas, ARect, Event.State, ABorders, ABorderColor);
end;
function TcxSchedulerEventCellViewInfo.MeasureHeight(ACanvas: TcxCanvas): Integer;
var
L: TList;
begin
Canvas.Font := Font;
FIsHeaderEvent := GetIsHeaderEvent;
CalculateVisibility;
FCaptionRect := cxRectInflate(Bounds, -(cxTextOffset + 1), -(cxTextOffset + 1));
L := Images.CreateVisibleList;
try
case Images.Layout of
eilHorizontal:
Result := CalculateHorizontalImagesAutoHeight;
eilVertical:
Result := CalculateVerticalImagesAutoHeight;
else //eilAuto:;
Result := CalculateAutoLayoutImagesAutoHeight(L);
end;
finally
L.Free;
end;
Result := Max(ViewData.LineHeight, Result);
end;
procedure TcxSchedulerEventCellViewInfo.MoveTo(X, Y: Integer);
procedure ShiftRect(var R: TRect);
begin
if not cxRectIsEmpty(R) then OffsetRect(R, X, Y);
end;
var
I: Integer;
begin
ShiftRect(ViewData.Bounds);
CalculateCellBounds(ViewData.Bounds, ViewData.VisibleRect);
if not Visible or Hidden then Exit;
ShiftRect(FCaptionRect);
ShiftRect(FFinishRect);
ShiftRect(FMessageRect);
ShiftRect(FStartRect);
ShiftRect(FEventTimeRect);
ShiftRect(FTimeLineRect);
if FShowMessage then
CalculateEditViewInfo;
for I := 0 to Images.Count - 1 do
ShiftRect(Images[0].FBounds);
end;
procedure TcxSchedulerEventCellViewInfo.AssignEditStyle(
AEditStyle: TcxCustomEditStyle);
var
AStyle: TcxCustomEditStyleAccess;
begin
AStyle := TcxCustomEditStyleAccess(AEditStyle);
AStyle.FAssignedValues := AStyle.FAssignedValues -
[svFont] + [svColor, svButtonTransparency];
AStyle.StyleData.Font := Font;
AStyle.StyleData.Color := Color;
AStyle.StyleData.FontColor := TextColor;
AStyle.ButtonTransparency := ebtHideInactive;
AStyle.Changed;
end;
procedure TcxSchedulerEventCellViewInfo.BeforeCustomDraw(ACanvas: TcxCanvas);
begin
FViewParams := ViewData.ViewParams;
inherited BeforeCustomDraw(ACanvas);
end;
procedure TcxSchedulerEventCellViewInfo.Calculate;
begin
Canvas.Font := Font;
CalculateItemsLayout;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateBorders;
begin
end;
procedure TcxSchedulerEventCellViewInfo.CalculateCaptions;
begin
FStartText := DateTimeHelper.TimeToStrEx(EventStart);
FFinishText := DateTimeHelper.TimeToStrEx(EventFinish);
end;
procedure TcxSchedulerEventCellViewInfo.CalculateDetailInfo;
begin
FIsDetailInfo := ViewData.AutoHeight or (not IsHeaderEvent and
((TimeOf(ContentFinish) <> 0) or (TimeOf(ContentStart) <> 0)));
FIsDetailCaption := FIsDetailInfo and not IsHeaderEvent;
FShowMessage := IsDetailInfo and (Length(Message) > 0);
end;
procedure TcxSchedulerEventCellViewInfo.CalculateNeedHint;
var
R: TRect;
begin
if FHintNeededCalculated then Exit;
R := FCaptionRect;
{$IFDEF USECXTEXTOUT}
with TcxScreenCanvas.Create do
try
Font := Self.Font;
cxTextOut(Canvas, PChar(ViewData.Caption), R, CXTO_CALCRECT or cxTextOutFlags[IsDetailCaption]);
finally
Free;
end;
{$ELSE}
Canvas.TextExtent(ViewData.Caption, R, cxDrawTextFlags[IsDetailCaption]);
{$ENDIF}
FHintNeeded := (FCaptionRect.Right < R.Right) or (FCaptionRect.Bottom < R.Bottom);
FHintNeededCalculated := True;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateEditViewInfo;
var
AProperties: TcxCustomEditProperties;
AEditViewData: TcxCustomEditViewData;
begin
if not ViewData.AutoHeight then
begin
FMessageRect := GetMessageRect(CaptionRect, Images.VisibleImageCount > 0);
FCaptionRect.Bottom := Min(FMessageRect.Top, Bounds.Bottom - cxTextOffset);
end;
if cxRectIsEmpty(FMessageRect) then
begin
FShowMessage := False;
Exit;
end;
if FEditViewInfo = nil then
FEditViewInfo := TcxCustomEditViewInfo(ViewData.EditProperties.GetViewInfoClass.Create);
AProperties := ViewData.EditProperties;
AEditViewData := AProperties.CreateViewData(ViewData.EditStyle, True);
try
Include(AEditViewData.PaintOptions, epoAutoHeight);
AssignEditStyle(ViewData.EditStyle);
AEditViewData.ContentOffset := cxSimpleRect;
AEditViewData.EditValueToDrawValue(Canvas, Message, FEditViewInfo);
AEditViewData.CalculateEx(Canvas, FMessageRect,
cxInvalidPoint, cxmbNone, [], FEditViewInfo, False);
finally
AEditViewData.Free;
end;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateShowTimeAsClock;
begin
ViewData.ShowTimeAsClock := IsHeaderEvent or
(ViewData.ShowTimeAsClock and not IsDetailInfo);
end;
function TcxSchedulerEventCellViewInfo.CalculateAutoLayoutImagesAutoHeight(
AVisibleImages: TList): Integer;
function GetEventTextsHeight(const AWidth: Integer): Integer;
var
R: TRect;
begin
R := cxRect(0, 0, AWidth, MaxInt);
Result := GetCaptionAutoHeight(R) + 2 * cxTextOffset;
if ShowMessage then
begin
Inc(R.Right, 3);
Inc(Result, CalculateMessageHeight(R) + 1);
end;
end;
function GetColCountForRowCount(ARowCount: Integer): Integer;
begin
Result := Images.TotalVisibleImageCount div ARowCount;
if (Images.TotalVisibleImageCount mod ARowCount) > 0 then
Inc(Result);
Result := Max(1, Result);
end;
var
I, ANewColCount, ACaptionWidth, ASpaceWidth, AImagesHeight,
AImagesWidth, AImagesColCount, AImagesRowCount,
ATextsHeight: Integer;
begin
ASpaceWidth := cxRectWidth(Bounds) - 2 * cxTextOffset;
ACaptionWidth := Canvas.TextWidth(Caption);
if (Images.TotalVisibleImageCount < 2) or
(ASpaceWidth >= Images.TotalVisibleWidth + cxEventImagesGap + ACaptionWidth) then
begin
Result := CalculateHorizontalImagesAutoHeight;
Exit;
end;
AImagesWidth := 0;
AImagesRowCount := 1;
AImagesColCount := 0;
for I := 1 to Images.TotalVisibleImageCount do
begin
AImagesRowCount := I;
AImagesHeight := Min(Images.TotalVisibleImageCount, (AImagesRowCount + 1)) *
(Images.ItemHeight + cxEventImagesGap) + 4;
ANewColCount := GetColCountForRowCount(AImagesRowCount);
if ANewColCount <> AImagesColCount then
begin
AImagesColCount := ANewColCount;
AImagesWidth := AImagesColCount * (Images.ItemWidth + cxEventImagesGap) + 1;
if ASpaceWidth <= AImagesWidth then Continue;
ATextsHeight := GetEventTextsHeight(ASpaceWidth - AImagesWidth);
if ATextsHeight < AImagesHeight then Break;
end
else Continue;
end;
Result := AImagesRowCount * (Images.ItemHeight + cxEventImagesGap) + 1;
Images.CalculateForCols(AVisibleImages,
cxPointOffset(Bounds.TopLeft, cxEventImagesOffset + cxEventBorderWidth,
cxEventImagesOffset + cxEventBorderWidth), AImagesColCount);
Inc(FCaptionRect.Left, AImagesWidth);
CalculateMessageAutoLayout(Result);
end;
function TcxSchedulerEventCellViewInfo.CalculateHorizontalImagesAutoHeight: Integer;
var
ARightLimit, ACaptionWidth, ACaptionHeight, AMessageHeight, ASpaceWidth,
AMessageTop, AImagesWidth: Integer;
AImagesRect, R: TRect;
begin
Result := Images.ItemHeight + cxTextOffset;
ASpaceWidth := cxRectWidth(Bounds) - 2 * cxTextOffset;
ACaptionWidth := Canvas.TextWidth(Caption);
AImagesRect := cxRectInflate(Bounds, -cxTextOffset, -cxTextOffset);
if Images.ForceVisibleWidth + cxEventImagesGap >= ASpaceWidth then
begin
FCaptionRect := cxNullRect;
Images.CalculateSingleLineImages(AImagesRect);
AMessageTop := Bounds.Top + cxTextOffset + Result + cxEventImagesGap;
end
else
begin
ARightLimit := 0;
if not (Images.TotalVisibleWidth + cxEventImagesGap + ACaptionWidth <= ASpaceWidth) then
begin
R := FCaptionRect;
R.Left := Min(AImagesRect.Left + Images.TotalVisibleWidth, R.Right - 1);
Canvas.TextExtent(Caption, R, cxWordBreak or cxDontBreakChars);
if R.Right > FCaptionRect.Right then
begin
ACaptionWidth := cxRectWidth(R);
Dec(AImagesRect.Right, ACaptionWidth);
ARightLimit := Bounds.Right - cxTextOffset - cxRectWidth(R);
end;
end;
AImagesWidth := Images.CalculateSingleLineImages(AImagesRect, ARightLimit);
if AImagesWidth > 0 then Inc(AImagesWidth);
Inc(FCaptionRect.Left, AImagesWidth);
ACaptionHeight := GetCaptionAutoHeight(CaptionRect);
FCaptionRect.Bottom := FCaptionRect.Top + ACaptionHeight;
Result := Max(Result, ACaptionHeight + 2 * cxTextOffset);
AMessageTop := FCaptionRect.Top + Result;
end;
if FShowMessage then
begin
FMessageRect := cxRect(Bounds.Left + cxEventImagesGap, AMessageTop - 1, Bounds.Right - 1, 0);
AMessageHeight := CalculateMessageHeight(FMessageRect);
FMessageRect.Bottom := FMessageRect.Top + AMessageHeight;
Inc(Result, AMessageHeight + 1);
CalculateEditViewInfo;
end;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateMessageAutoLayout(var AHeight: Integer);
var
ACaptionHeight, AMessageHeight, AMessageTop: Integer;
begin
if not cxRectIsEmpty(CaptionRect) then
begin
ACaptionHeight := GetCaptionAutoHeight(CaptionRect);
FCaptionRect.Bottom := CaptionRect.Top + ACaptionHeight;
Inc(ACaptionHeight, 2 * cxTextOffset);
AHeight := Max(AHeight, ACaptionHeight);
if FShowMessage then
begin
AMessageTop := FCaptionRect.Top + ACaptionHeight - 1;
FMessageRect := cxRect(FCaptionRect.Left - 2, AMessageTop, Bounds.Right - 1, 0);
AMessageHeight := CalculateMessageHeight(FMessageRect);
FMessageRect.Bottom := FMessageRect.Top + AMessageHeight;
AHeight := Max(AHeight, ACaptionHeight + AMessageHeight);
CalculateEditViewInfo;
end;
end
else FShowMessage := False;
end;
function TcxSchedulerEventCellViewInfo.CalculateVerticalImagesAutoHeight: Integer;
var
AImagesRect: TRect;
begin
Result := Images.ItemHeight + cxTextOffset;
if Images.TotalVisibleHeight > 0 then
begin
AImagesRect := cxRectInflate(Bounds, -cxTextOffset, -cxTextOffset);
AImagesRect.Bottom := AImagesRect.Top + Images.TotalVisibleHeight;
if (cxRectWidth(AImagesRect) > Images.ItemWidth + cxEventImagesGap) or
(Images.ForceVisibleHeight > 0) then
begin
Inc(FCaptionRect.Left, Images.ItemWidth + cxTextOffset);
Result := Images.TotalVisibleHeight + cxEventImagesGap;
end;
Images.CalculateSingleColumnImages(AImagesRect);
end;
CalculateMessageAutoLayout(Result);
end;
procedure TcxSchedulerEventCellViewInfo.CalculateItemsLayout;
begin
if IsDetailInfo then
CalculateDetailViewEventLayout
else
CalculateHeaderEventLayout;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateDetailViewEventLayout;
var
AImagesWidth: Integer;
begin
FCaptionRect := cxRectInflate(Bounds, -cxTextOffset, -(cxTextOffset + 1));
AImagesWidth := Images.Calculate(GetImagesBounds);
Images.Offset(0, GetImagesVerticalOffset(Images.ItemHeight, False));
Inc(FCaptionRect.Left, AImagesWidth + cxEventImagesGap);
if FShowMessage then CalculateEditViewInfo;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateHeaderEventLayout;
var
ACaptionRect: TRect;
ALeft, AWidth, AImagesWidth, ACaptionWidth, AVertOffset: Integer;
ACanShowClock: Boolean;
R: TRect;
procedure CalculateCaption;
var
R: TRect;
begin
InflateRect(ACaptionRect, -cxTextOffset, 0);
R := cxRectSetLeft(cxRectInflate(Bounds, -1, -1), 0,
cxRectWidth(ACaptionRect) - (ACaptionWidth + cxTextOffset));
AImagesWidth := Images.CalculateSingleLineImages(R);
if AImagesWidth <> 0 then Inc(AImagesWidth, cxTextOffset);
AWidth := AImagesWidth + ACaptionWidth;
end;
begin
FCaptionRect := cxRectInflate(Bounds, -cxTextOffset, -1);
R := cxRect(0, 0, EventImages.Width, EventImages.Height);
AVertOffset := GetImagesVerticalOffset(R.Bottom, True);
ACaptionWidth := Canvas.TextWidth(ViewData.Caption);
ACaptionRect := FCaptionRect;
ACanShowClock := cxRectWidth(ACaptionRect) >= EventImages.Width + cxEventImagesGap;
if ShowStartTime and ACanShowClock then
begin
FStartRect := cxRectOffset(R, Bounds.Left + (cxEventBorderWidth + cxEventImagesOffset), AVertOffset);
ACaptionRect.Left := FStartRect.Right;
end;
if ShowFinishTime and ACanShowClock then
begin
FFinishRect := cxRectOffset(R, Bounds.Right - R.Right - (cxEventBorderWidth + cxEventImagesOffset), AVertOffset);
ACaptionRect.Right := FFinishRect.Left;
end;
CalculateCaption;
if (ShowStartTime or ShowFinishTime) and
(ACaptionWidth + Images.TotalVisibleWidth > cxRectWidth(ACaptionRect)) and
not GetForceShowClockInHeaderEvent then
begin
FStartRect := cxEmptyRect;
FFinishRect := cxEmptyRect;
ViewData.ShowStartTime := False;
ViewData.ShowFinishTime := False;
ACaptionRect := FCaptionRect;
CalculateCaption;
end;
with ACaptionRect do
ALeft := Max(Left + ((Right - Left - AWidth) div 2), ACaptionRect.Left);
Images.Offset(ALeft, GetImagesVerticalOffset(Images.ItemHeight, False));
ACaptionRect.Left := ALeft + AImagesWidth;
FCaptionRect := ACaptionRect;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateNonDetailEventLayout;
var
R: TRect;
ALeft, ACaptionWidth, AImagesWidth: Integer;
begin
FCaptionRect := cxRectInflate(Bounds, -cxTextOffset, -1);
ALeft := CaptionRect.Left;
ACaptionWidth := Canvas.TextWidth(ViewData.Caption);
R := CalculateNonDetailEventImages(ACaptionWidth, AImagesWidth);
if ShowFinishTime or ShowStartTime then
begin
if ShowTimeAsClock then
CalculateEventTimeAsClockLayout(R, ACaptionWidth, AImagesWidth, ALeft)
else
CalculateEventTimeAsTextLayout(R, ACaptionWidth, AImagesWidth, ALeft);
end;
AImagesWidth := Images.Offset(ALeft - FCaptionRect.Left,
GetImagesVerticalOffset(Images.ItemHeight, False));
if AImagesWidth > 0 then Inc(AImagesWidth);
Inc(ALeft, AImagesWidth + cxEventImagesOffset);
FCaptionRect.Left := ALeft;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateEventTimeAsClockLayout(
const ABounds: TRect; const ACaptionWidth, AImagesWidth: Integer; var ALeft: Integer);
var
R: TRect;
AVertOffset: Integer;
begin
R := cxRectBounds(0, 0, TcxSchedulerPainterHelper.IconsWidth,
TcxSchedulerPainterHelper.IconsHeight);
AVertOffset := GetImagesVerticalOffset(R.Bottom, True);
FStartRect := SetItemRect(ShowStartTime, R, AVertOffset, ALeft);
FFinishRect := SetItemRect(ShowFinishTime, R, AVertOffset, ALeft);
Inc(ALeft);
end;
procedure TcxSchedulerEventCellViewInfo.CalculateEventTimeAsTextLayout(
const ABounds: TRect; const ACaptionWidth, AImagesWidth: Integer; var ALeft: Integer);
var
ASpaceWidth, AWidth: Integer;
R: TRect;
begin
ASpaceWidth := cxRectWidth(ABounds) - AImagesWidth;
with Canvas.TextExtent('00:00') do
R := cxRectBounds(ABounds.Left, 0, CX, CY);
if not Is24HourTimeFormat then
R := cxRectSetWidth(R, Max(Canvas.TextWidth('00:00' + TimeAMString),
Canvas.TextWidth('00:00' + TimePMString)));
AWidth := cxRectWidth(R);
if ASpaceWidth >= AWidth then
begin
FStartRect := cxRect(ALeft, FCaptionRect.Top, ALeft + AWidth, FCaptionRect.Bottom);
Inc(AWidth, Canvas.TextWidth('0') div 2);
Inc(ALeft, AWidth);
Dec(ASpaceWidth, AWidth);
if ShowFinishTime and (ASpaceWidth >= AWidth) then
begin
FFinishRect := cxRectOffset(FStartRect, AWidth, 0);
Inc(ALeft, AWidth);
end;
end;
end;
function TcxSchedulerEventCellViewInfo.CalculateNonDetailEventImages(
const ACaptionWidth: Integer; out AImagesWidth: Integer): TRect;
begin
Result := GetImagesBounds;
AImagesWidth := CalculateSingleLineImages(Result);
end;
function TcxSchedulerEventCellViewInfo.CalculateSingleLineImages(
const ABounds: TRect; ARightLimit: Integer = 0): Integer;
begin
Result := Images.CalculateSingleLineImages(ABounds, ARightLimit);
end;
function TcxSchedulerEventCellViewInfo.SetItemRect(AShowItem: Boolean;
const ABounds: TRect; AVertOffset: Integer; var APos: Integer): TRect;
begin
Result := cxNullRect;
if AShowItem then
begin
if ((APos + cxRectWidth(ABounds)) <= cxRectCenter(FBounds).X) then
begin
Result := cxRectOffset(ABounds, APos, AVertOffset);
APos := Result.Right + cxTextOffset;
end;
end
end;
procedure TcxSchedulerEventCellViewInfo.CalculateEventTimeVisibility;
begin
if IsDetailInfo then
CalculateDetailEventTimeVisibility
else
CalculateNonDetailEventTimeVisibility;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateDetailEventTimeVisibility;
begin
ViewData.ShowFinishTime := (IsDetailCaption and ViewData.AlwaysShowTime) or
((ViewData.ContentFinish > EventFinish) and (ViewData.ContentStart <> EventFinish)) or
(ViewData.ContentStart < EventStart);
ViewData.ShowStartTime := ViewData.ShowFinishTime;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateNonDetailEventTimeVisibility;
begin
if Event.AllDayEvent then
begin
ViewData.ShowFinishTime := False;
ViewData.ShowStartTime := False;
end
else
begin
ViewData.ShowFinishTime := (ViewData.ContentFinish >= EventFinish) and
(ViewData.ShowFinishTime or (Event.Duration >= 1));
ViewData.ShowStartTime := (ContentStart <= EventStart);
end;
end;
procedure TcxSchedulerEventCellViewInfo.CalculateVisibility;
begin
if ViewData.ShowTimeLine then
begin
if Selected then
FVisible := cxRectIntersect(FClipRect, cxRectInflate(Bounds, 0, cxTimeLineWidth), ViewData.VisibleRect);
end
else
FVisible := FVisible and (FClipRect.Bottom = FBounds.Bottom);
CalculateDetailInfo;
CalculateShowTimeAsClock;
CalculateEventTimeVisibility;
CalculateBorders;
end;
function TcxSchedulerEventCellViewInfo.CanAutoHideStandardImages: Boolean;
begin
Result := False;
end;
procedure TcxSchedulerEventCellViewInfo.DoDraw;
begin
if FHidden then Exit;
ClippingCreate(True);
DrawContent;
ClippingRestore;
end;
procedure TcxSchedulerEventCellViewInfo.DrawCaption;
begin
if cxRectIsEmpty(FCaptionRect) or (ViewData.Caption = '') then Exit;
{$IFDEF USECXTEXTOUT}
cxTextOut(Canvas.Canvas, PChar(ViewData.Caption), FCaptionRect, cxTextOutFlags[IsDetailCaption]);
{$ELSE}
Canvas.Brush.Style := bsClear;
Canvas.DrawText(ViewData.Caption, FCaptionRect, cxDrawTextFlags[IsDetailCaption]);
Canvas.Brush.Style := bsSolid;
{$ENDIF}
end;
procedure TcxSchedulerEventCellViewInfo.DrawContent;
begin
DrawRect(FBounds, FBorders, ViewData.BorderColor);
if not Event.IsEditing then
DrawImages;
if IsNeedDrawTime then
DrawTime;
DrawCaption;
if FShowMessage then
begin
FEditViewInfo.Transparent := True;
FEditViewInfo.TextColor := TextColor;
FEditViewInfo.PaintEx(Canvas);
DrawMessageSeparator;
end;
end;
procedure TcxSchedulerEventCellViewInfo.DrawImages;
var
I: Integer;
ASaveRgn: TcxRegion;
begin
with Images do
begin
if Count = 0 then Exit;
ASaveRgn := Canvas.GetClipRegion;
Canvas.IntersectClipRect(cxRectInflate(Bounds, -1, -1));
for I := 0 to Count - 1 do
with Items[I] do
if Visible and not FHidden then
begin
Images.DrawingStyle := dsTransparent;
Canvas.DrawImage(Images, Bounds.Left, Bounds.Top, ImageIndex);
end;
Canvas.SetClipRegion(ASaveRgn, roSet);
end;
end;
procedure TcxSchedulerEventCellViewInfo.DrawMessageSeparator;
var
R: TRect;
begin
R := cxRectInflate(MessageRect, -(1 + Byte(not ShowTimeLine)), 1, -2, 0);
Canvas.FrameRect(R, SeparatorColor, 1, [bTop]);
end;
procedure TcxSchedulerEventCellViewInfo.DrawTime;
const
RightJustify = cxAlignRight or cxAlignVCenter or cxSingleLine;
begin
if ShowTimeAsClock then
begin
if ShowStartTime then
PainterHelper.DrawClock(Canvas, FStartRect, Event.Start, FViewParams);
if ShowFinishTime then
PainterHelper.DrawClock(Canvas, FFinishRect, Event.Finish, FViewParams);
end
else
begin
DrawText(FStartRect, FStartText, RightJustify);
DrawText(FFinishRect, FFinishText, RightJustify);
end;
end;
function TcxSchedulerEventCellViewInfo.GetCaptionAutoHeight(const R: TRect): Integer;
begin
if (Caption <> '') and not cxRectIsEmpty(CaptionRect) then
Result := GetTrueMultilineTextHeight(Canvas, ViewData.Caption, R)
else
Result := Canvas.FontHeight(Font);
end;
function TcxSchedulerEventCellViewInfo.GetEditingRect: TRect;
begin
cxRectIntersect(Result, PainterHelper.ExcludeBorders(Bounds, Borders), FClipRect);
with Result do
begin
if IsDetailCaption then
begin
Inc(Left, cxTextOffset - Byte(bLeft in Borders));
Dec(Right);
end
else
Inc(Left);
end;
end;
function TcxSchedulerEventCellViewInfo.GetForceShowClockInHeaderEvent: Boolean;
begin
Result := True;
end;
function TcxSchedulerEventCellViewInfo.GetHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest; var ABreak: Boolean): Boolean;
begin
Result := inherited GetHittest(AHitTest, ABreak);
Result := Result and not Hidden;
if Result and not Hidden and ShowTimeLine and Selected then
ABreak := not PtInRect(CaptionRect, AHitTest.HitPoint) and not
PtInRect(MessageRect, AHitTest.HitPoint)
else
ABreak := False;
end;
function TcxSchedulerEventCellViewInfo.GetImagesBounds: TRect;
begin
with Bounds do
Result := cxRect(Left + cxEventBorderWidth + cxEventImagesOffset - Byte(ViewData.ShowTimeLine),
Top + cxEventBorderWidth,
(Left + Right - cxTextOffset) div 2,
Bottom - (cxEventBorderWidth + cxEventImagesOffset));
end;
function TcxSchedulerEventCellViewInfo.GetImagesVerticalOffset(
AImageHeight: Integer; AIsAbsolute: Boolean): Integer;
begin
Result := cxEventImagesOffset;
if not FIsDetailCaption then
Result := Max(Result, (cxRectHeight(Bounds) - 2 * cxEventBorderWidth - AImageHeight) div 2);
if AIsAbsolute then
Inc(Result, Bounds.Top + cxEventBorderWidth);
end;
function TcxSchedulerEventCellViewInfo.GetMessageRect(const ACaptionRect: TRect;
AHasImages: Boolean): TRect;
var
ACaptionBottom: Integer;
R: TRect;
begin
if not cxRectIsEmpty(ACaptionRect) then
begin
R := GetCaptionBounds(ACaptionRect);
ACaptionBottom := R.Bottom + cxTextOffset; //bottom text offset
end
else
ACaptionBottom := Bounds.Top + cxTextOffset;
if AHasImages then
ACaptionBottom := Max(ACaptionBottom, Bounds.Top + Images.ItemHeight);
Inc(ACaptionBottom); //horz line
Result.Top := ACaptionBottom;
Result.Bottom := Bounds.Bottom;
Result.Right := Bounds.Right - 1;
if Images.Layout = eilHorizontal then
Result.Left := Bounds.Left + cxEventBorderWidth
else
Result.Left := R.Left - cxTextOffset;
end;
procedure TcxSchedulerEventCellViewInfo.Initialize;
begin
FBorders := cxBordersAll;
FEventStart := TruncTime(Event.Start);
FEventFinish := TruncTime(Event.Finish);
FIsHeaderEvent := GetIsHeaderEvent;
FStartRect := cxNullRect;
FFinishRect := cxNullRect;
FTimeLineRect := cxNullRect;
ViewData.ShowTimeLine := ViewData.ShowTimeLine and IsTimeLineVisible;
InitStandardEventImages;
CalculateVisibility;
CalculateCaptions;
end;
procedure TcxSchedulerEventCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
AHitTest.FEventCell := Self;
AHitTest.FEventBounds := FClipRect;
AHitTest.FDragKind := edkMoveEvent;
CalculateNeedHint;
AHitTest.FNeedShowHint := FHintNeeded;
end;
procedure TcxSchedulerEventCellViewInfo.InitHitTestForHorzEvent(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
if (bLeft in Borders) and ((AHitTest.HitX - Bounds.Left) <= cxHitDelta) then
AHitTest.FDragKind := edkResizeStart
else
if (bRight in Borders) and ((Bounds.Right - AHitTest.HitX) <= cxHitDelta) then
AHitTest.FDragKind := edkResizeEnd;
end;
procedure TcxSchedulerEventCellViewInfo.InitStandardEventImages;
var
AutoHide: Boolean;
begin
AutoHide := CanAutoHideStandardImages;
with Event do
begin
if Reminder and Storage.IsReminderAvailable and Storage.Reminders.Active then
Images.AddStandardImage(eitReminder, AutoHide);
case EventType of
etOccurrence: Images.AddStandardImage(eitRecurrence, AutoHide);
etCustom: Images.AddStandardImage(eitCustomOccurrence, AutoHide);
end;
end;
end;
function TcxSchedulerEventCellViewInfo.IsHorzSizing: Boolean;
begin
Result := True;
end;
function TcxSchedulerEventCellViewInfo.IsNeedDrawTime: Boolean;
begin
Result := ViewData.ShowFinishTime or ViewData.ShowStartTime;
end;
function TcxSchedulerEventCellViewInfo.IsTimeLineVisible: Boolean;
begin
Result := False;
end;
function TcxSchedulerEventCellViewInfo.TruncTime(
const ATime: TDateTime): TDateTime;
begin
Result := DateTimeHelper.RoundTime(ATime);
end;
function TcxSchedulerEventCellViewInfo.GetContentFinish: TDateTime;
begin
Result := ViewData.ContentFinish;
end;
function TcxSchedulerEventCellViewInfo.CalculateMessageHeight(const R: TRect): Integer;
function CreateEditViewData: TcxCustomEditViewData;
begin
with ViewData do
Result := EditProperties.CreateViewData(EditStyle, True);
end;
var
AEditViewData: TcxCustomEditViewData;
ASize: TcxEditSizeProperties;
begin
AEditViewData := CreateEditViewData;
try
AssignEditStyle(ViewData.EditStyle);
AEditViewData.ContentOffset := cxSimpleRect;
ASize.MaxLineCount := 0;
ASize.Height := -1;
ASize.Width := cxRectWidth(R);
Result := AEditViewData.GetEditSize(Canvas, Message, ASize).cy;
finally
AEditViewData.Free;
end;
end;
function TcxSchedulerEventCellViewInfo.GetBorderColor: TColor;
begin
Result := ViewData.BorderColor;
end;
function TcxSchedulerEventCellViewInfo.GetCaption: string;
begin
Result := ViewData.Caption;
end;
function TcxSchedulerEventCellViewInfo.GetCaptionBounds(const R: TRect): TRect;
{$IFDEF USECXTEXTOUT}
var
ARowCount: Integer;
ATextFlags: Cardinal;
ATextParams: TcxTextParams;
ATextRows: TcxTextRows;
{$ENDIF}
begin
Result := R;
{$IFDEF USECXTEXTOUT}
with TcxScreenCanvas.Create do
try
Font := Self.Font;
ATextFlags := CXTO_CALCROWCOUNT or cxTextOutFlags[True];
Result.Bottom := MaxInt;
ATextParams := cxCalcTextParams(Canvas, ATextFlags);
cxMakeTextRows(Canvas, PChar(ViewData.Caption), Result, ATextParams, ATextRows, ARowCount, 0);
Result.Bottom := Result.Top + ARowCount * TextHeight('Wg');
ATextRows := nil;
finally
Free;
end;
{$ELSE}
if Length(ViewData.Caption) > 0 then
Canvas.TextExtent(ViewData.Caption, Result, cxDrawTextFlags[IsDetailCaption])
else
Canvas.TextExtent('Wg', Result, cxDrawTextFlags[IsDetailCaption]);
{$ENDIF}
end;
function TcxSchedulerEventCellViewInfo.GetContentStart: TDateTime;
begin
Result := ViewData.ContentStart;
end;
function TcxSchedulerEventCellViewInfo.GetEvent: TcxSchedulerControlEvent;
begin
Result := ViewData.Event;
end;
function TcxSchedulerEventCellViewInfo.GetIsHeaderEvent: Boolean;
begin
Result := Event.AllDayEvent or ((Event.Finish - Event.Start) >= 1);
end;
function TcxSchedulerEventCellViewInfo.GetMessage: string;
begin
Result := Event.Message;
end;
function TcxSchedulerEventCellViewInfo.GetResourceInfo: TcxSchedulerResourceViewInfo;
begin
Result := ViewData.Resource;
end;
function TcxSchedulerEventCellViewInfo.GetResourceItem: TcxSchedulerStorageResourceItem;
begin
Result := nil;
if ResourceInfo <> nil then
Result := ResourceInfo.ResourceItem;
end;
function TcxSchedulerEventCellViewInfo.GetSelected: Boolean;
begin
Result := Event.Selected;
end;
function TcxSchedulerEventCellViewInfo.GetShowingState(
AIndex: Integer): Boolean;
begin
case AIndex of
0: Result := ViewData.ShowFinishTime;
1: Result := ViewData.ShowStartTime;
2: Result := ViewData.ShowTimeAsClock;
3: Result := ViewData.ShowTimeLine;
else
Result := False;
end;
end;
procedure TcxSchedulerEventCellViewInfo.SetBorderColor(AValue: TColor);
begin
ViewData.BorderColor := AValue;
end;
{ TcxSchedulerMoreEventsButtonViewInfo }
procedure TcxSchedulerMoreEventsButtonViewInfo.Click;
begin
if Assigned(FOnClick) then
FOnClick(Self);
end;
procedure TcxSchedulerMoreEventsButtonViewInfo.DoDraw;
begin
MoreEventButtonGlyphs.DrawingStyle := dsTransparent;
Canvas.DrawImage(MoreEventButtonGlyphs, Bounds.Left, Bounds.Top, Byte(not IsDown));
end;
procedure TcxSchedulerMoreEventsButtonViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
inherited InitHitTest(AHitTest);
AHitTest.SetBitState(htcButton, True);
AHitTest.FButton := Self;
if Int(DateTime) > 0 then
AHitTest.SetHitTime(htcTime, Int(DateTime));
end;
{ TcxSchedulerGroupSeparatorCellViewInfo }
destructor TcxSchedulerGroupSeparatorCellViewInfo.Destroy;
begin
FreeAndNil(FRotateBitmap);
inherited Destroy;
end;
procedure TcxSchedulerGroupSeparatorCellViewInfo.DoDraw;
procedure CreateRotatedBitmap;
begin
with Bounds do
FRotateBitmap := cxCreateTrueColorBitmap(Right - Left, Bottom - Top);
FRotateBitmap.PixelFormat := pf32bit;
FRotateBitmap.Canvas.Lock;
end;
var
ABitmapCanvas: TcxCanvas;
begin
if not Rotated then
Painter.DrawHeader(Canvas, Bounds, Bounds, [nRight, nLeft], cxBordersAll, cxbsNormal,
taLeftJustify, vaCenter, False, False, '', nil, clNone, Color, DrawBackground)
else
begin
if FRotateBitmap = nil then
begin
CreateRotatedBitmap;
ABitmapCanvas := TcxCanvas.Create(FRotateBitmap.Canvas);
try
ABitmapCanvas.WindowOrg := Bounds.TopLeft;
FDrawRotatedBackground := DrawBackground(ABitmapCanvas, Bounds);
RotateBitmap(FRotateBitmap, raPlus90, True);
Painter.DrawHeader(ABitmapCanvas, Rect(0, 0, FRotateBitmap.Width,
FRotateBitmap.Height), cxNullRect, [nRight, nLeft], cxBordersAll,
cxbsNormal, taCenter, vaCenter, False, False, '', nil, clNone, Color,
DrawRotateBackground);
RotateBitmap(FRotateBitmap, raPlus90, True);
finally
FRotateBitmap.Canvas.Unlock;
ABitmapCanvas.Free;
end;
end;
Canvas.Draw(Bounds.Left, Bounds.Top, FRotateBitmap);
end;
end;
procedure TcxSchedulerGroupSeparatorCellViewInfo.InitHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
AHitTest.SetBitState(htcGroupSeparator, True);
end;
function TcxSchedulerGroupSeparatorCellViewInfo.DrawRotateBackground(
ACanvas: TcxCanvas; const ABounds: TRect): Boolean;
begin
Result := FDrawRotatedBackground;
end;
{ TcxSchedulerResourceViewInfo }
constructor TcxSchedulerResourceViewInfo.Create(
AResource: TcxSchedulerStorageResourceItem);
begin
FResourceItem := AResource;
FColor := AResource.Color;
FResourceID := AResource.ResourceID;
FCaption := AResource.Resources.GetResourceName(FResourceItem);
FImages := AResource.Resources.Images;
FImageIndex := AResource.ActualImageIndex;
end;
{ TcxSchedulerCustomResourceView }
constructor TcxSchedulerCustomResourceView.Create(
AOwner: TcxCustomScheduler);
begin
inherited Create(AOwner);
FShowEndTime := True;
end;
procedure TcxSchedulerCustomResourceView.Assign(Source: TPersistent);
begin
if Source is TcxSchedulerCustomResourceView then
begin
ShowEndTime := TcxSchedulerCustomResourceView(Source).ShowEndTime;
ShowTimeAsClock := TcxSchedulerCustomResourceView(Source).ShowTimeAsClock;
FGroupingKind := TcxSchedulerCustomResourceView(Source).GroupingKind;
end;
inherited Assign(Source);
end;
procedure TcxSchedulerCustomResourceView.CalculateViewInfo;
begin
Adapter.Calculate;
end;
procedure TcxSchedulerCustomResourceView.CheckGroupingKind(
AStyle: TcxSchedulerGroupingKind; var ActuallyStyle: TcxSchedulerGroupingKind);
begin
ActuallyStyle := AStyle;
end;
function TcxSchedulerCustomResourceView.CreateController: TcxSchedulerSubControlController;
begin
Result := TcxSchedulerCustomResourceViewController.Create(Self);
end;
function TcxSchedulerCustomResourceView.CreateHitTest: TcxSchedulerSubControlHitTest;
begin
Result := TcxSchedulerCustomResourceViewHitTest.Create(Self);
end;
function TcxSchedulerCustomResourceView.CreateViewAdapter: TcxCustomResourceViewAdapter;
begin
Result := TcxCustomResourceViewAdapter.Create(Self);
end;
procedure TcxSchedulerCustomResourceView.CreateSubClasses;
begin
inherited CreateSubClasses;
FAdapter := CreateViewAdapter;
ViewInfo.FAdapter := FAdapter;
end;
procedure TcxSchedulerCustomResourceView.DestroySubClasses;
var
Adapter: TObject;
begin
Adapter := ViewInfo.FAdapter;
inherited DestroySubClasses;
Adapter.Free;
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawBackground(
AViewInfo: TcxSchedulerBackgroundCellViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawBackground) then
FOnCustomDrawBackground(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawButton(
AViewInfo: TcxSchedulerMoreEventsButtonViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawButton) then
FOnCustomDrawButton(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawContent(
AViewInfo: TcxSchedulerContentCellViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawContent) then
FOnCustomDrawContent(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawDayHeader(
AViewInfo: TcxSchedulerDayHeaderCellViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawDayHeader) then
FOnCustomDrawDayHeader(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawEvent(
AViewInfo: TcxSchedulerEventCellViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawEvent) then
FOnCustomDrawEvent(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawGroupSeparator(
AViewInfo: TcxSchedulerGroupSeparatorCellViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawGroupSeparator) then
FOnCustomDrawGroupSeparator(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoCustomDrawResourceHeader(
AViewInfo: TcxSchedulerHeaderCellViewInfo; var ADone: Boolean);
begin
if Assigned(FOnCustomDrawResourceHeader) then
FOnCustomDrawResourceHeader(Self, Canvas, AViewInfo, ADone);
end;
procedure TcxSchedulerCustomResourceView.DoLayoutChanged;
begin
inherited DoLayoutChanged;
end;
function TcxSchedulerCustomResourceView.DoShowPopupMenu(X, Y: Integer): Boolean;
begin
if HitTest.HitAtEvent then
Result := not Controller.IsEditing and Scheduler.EventPopupMenu.Popup(X, Y)
else
Result := Scheduler.ContentPopupMenu.Popup(X, Y)
end;
function TcxSchedulerCustomResourceView.FindEventViewInfo(AEvent: TcxSchedulerEvent;
const ADate: TDateTime; AResource: TcxSchedulerStorageResourceItem;
var AViewInfo: TcxSchedulerEventCellViewInfo): Boolean;
var
I: Integer;
begin
Result := False;
for I := 0 to ViewInfo.EventCells.Count - 1 do
begin
AViewInfo := TcxSchedulerEventCellViewInfo(ViewInfo.EventCells[I]);
if AViewInfo.Event = AEvent then
begin
Result := True;
with AViewInfo do
begin
if (AResource = nil) or (ResourceItem = AResource) then
if (ADate = NullDate) or ((DateOf(ContentStart) = ADate) or (IsHeaderEvent and
(ADate >= DateOf(ContentStart)) and (ADate < DateOf(ContentFinish)))) then Break;
end;
end;
end;
end;
function TcxSchedulerCustomResourceView.GetCommonViewItemsPainter: IcxSchedulerCommonViewItemsPainter;
begin
if not Supports(TObject(Scheduler), IcxSchedulerCommonViewItemsPainter, Result) then
Result := nil;
end;
function TcxSchedulerCustomResourceView.GetCompressWeekEnd: Boolean;
begin
Result := False;
end;
function TcxSchedulerCustomResourceView.GetEditRectForEvent(
AEvent: TcxSchedulerControlEvent; const ADate: TDateTime;
AResource: TcxSchedulerStorageResourceItem): TRect;
var
AViewInfo: TcxSchedulerEventCellViewInfo;
begin
if FindEventViewInfo(AEvent, ADate, AResource, AViewInfo) then
Result := AViewInfo.EditingRect
else
Result := inherited GetEditRectForEvent(AEvent, ADate, AResource);
end;
procedure TcxSchedulerCustomResourceView.InitScrollBarsParameters;
begin
ViewInfo.InitScrollBarsParameters;
end;
function TcxSchedulerCustomResourceView.GetEventVisibility(
AEvent: TcxSchedulerControlEvent): Boolean;
var
AViewInfo: TcxSchedulerEventCellViewInfo;
begin
Result := FindEventViewInfo(AEvent, NullDate, nil, AViewInfo)
end;
function TcxSchedulerCustomResourceView.GetGroupingKind: TcxSchedulerGroupingKind;
begin
Result := GroupingKind;
if Result = gkDefault then
Result := OptionsView.GroupingKind;
end;
function TcxSchedulerCustomResourceView.IsShowResources: Boolean;
var
AKind: TcxSchedulerGroupingKind;
begin
Result := inherited IsShowResources;
if Result then
begin
AKind := GroupingKind;
if AKind = gkDefault then
AKind := OptionsView.GroupingKind;
Result := AKind <> gkNone;
end;
end;
procedure TcxSchedulerCustomResourceView.Scroll(AScrollBarKind: TScrollBarKind;
AScrollCode: TScrollCode; var AScrollPos: Integer);
begin
if AScrollBarKind = sbHorizontal then
ViewInfo.ScrollHorizontal(AScrollCode, AScrollPos)
else
ViewInfo.ScrollVertical(AScrollCode, AScrollPos);
inherited Scroll(AScrollBarKind, AScrollCode, AScrollPos);
end;
function TcxSchedulerCustomResourceView.GetViewInfo: TcxSchedulerCustomResourceViewViewInfo;
begin
Result := TcxSchedulerCustomResourceViewViewInfo(inherited ViewInfo);
end;
procedure TcxSchedulerCustomResourceView.SetEventImagesLayout(
const AValue: TcxSchedulerEventImagesLayout);
begin
if FEventImagesLayout <> AValue then
begin
FEventImagesLayout := AValue;
LayoutChanged;
end;
end;
procedure TcxSchedulerCustomResourceView.SetGroupingKind(
AValue: TcxSchedulerGroupingKind);
begin
CheckGroupingKind(AValue, AValue);
if (FGroupingKind <> AValue) then
begin
FGroupingKind := AValue;
LayoutChanged;
end;
end;
procedure TcxSchedulerCustomResourceView.SetShowEndTime(
const AValue: Boolean);
begin
if FShowEndTime <> AValue then
begin
FShowEndTime := AValue;
LayoutChanged;
end;
end;
procedure TcxSchedulerCustomResourceView.SetShowTimeAsClock(
const AValue: Boolean);
begin
if FShowTimeAsClock <> AValue then
begin
FShowTimeAsClock := AValue;
LayoutChanged;
end;
end;
{ TcxCustomResourceViewAdapter }
constructor TcxCustomResourceViewAdapter.Create(
AView: TcxSchedulerCustomResourceView);
begin
FView := AView;
end;
procedure TcxCustomResourceViewAdapter.Calculate;
var
FPrevAdapter: TcxCustomResourceViewAdapter;
begin
FPrevAdapter := FView.ViewInfo.SetAdapter(Self);
FPrevAdapter.Store;
try
BeforeCalculatePage;
FView.ViewInfo.Calculate;
AfterCalculatePage;
finally
FView.ViewInfo.SetAdapter(FPrevAdapter);
if (FPrevAdapter <> Self) and FView.Active then
begin
FPrevAdapter.Restore;
FView.ViewInfo.Calculate;
end;
FView.ViewInfo.FStylesAdapter := nil;
end;
end;
procedure TcxCustomResourceViewAdapter.GetPageResources(
AResources: TcxObjectList);
var
ACount, I: Integer;
AResourceViewInfo: TcxSchedulerResourceViewInfo;
begin
if Resources = nil then Exit;
Scheduler.ValidateFirstVisibleResourceIndex;
ACount := Resources.VisibleResourceCount;
with Scheduler.OptionsView do
begin
if (ResourcesPerPage > 0) and (ACount > ResourcesPerPage) then
ACount := ResourcesPerPage;
end;
for I := 0 to ACount - 1 do
begin
AResourceViewInfo := TcxSchedulerResourceViewInfo.Create(
Resources.VisibleResources[Scheduler.FirstVisibleResourceIndex + I]);
AResources.Add(AResourceViewInfo);
end;
end;
procedure TcxCustomResourceViewAdapter.GetPageDays(
APageIndex: Integer; ADays: TcxSchedulerDateList);
begin
end;
procedure TcxCustomResourceViewAdapter.Invalidate;
begin
end;
function TcxCustomResourceViewAdapter.CanCalculate: Boolean;
begin
Result := View.Active;
end;
function TcxCustomResourceViewAdapter.GetCompressWeekends: Boolean;
begin
Result := View.GetCompressWeekEnd;
end;
function TcxCustomResourceViewAdapter.GetDontPrintWeekEnds: Boolean;
begin
Result := False;
end;
function TcxCustomResourceViewAdapter.GetHideSelection: Boolean;
begin
Result := View.OptionsView.HideSelection and not View.Scheduler.IsFocused;
end;
function TcxCustomResourceViewAdapter.GetPageBounds: TRect;
begin
Result := View.ClientRect;
end;
function TcxCustomResourceViewAdapter.GetPagesPerWeek: Byte;
begin
Result := 1;
end;
function TcxCustomResourceViewAdapter.GetPrimaryPage: Boolean;
begin
Result := True;
end;
function TcxCustomResourceViewAdapter.GetPrintExactlyOneMonth: Boolean;
begin
Result := False;
end;
function TcxCustomResourceViewAdapter.GetPrintRange(
Index: Integer): TDateTime;
begin
Result := NullDate;
end;
function TcxCustomResourceViewAdapter.GetStylesAdapter: IcxSchedulerStylesAdapter;
begin
Result := FView.Styles;
end;
function TcxCustomResourceViewAdapter.GetView: TcxSchedulerCustomResourceView;
begin
Result := FView;
end;
procedure TcxCustomResourceViewAdapter.AfterCalculatePage;
begin
end;
procedure TcxCustomResourceViewAdapter.BeforeCalculatePage;
begin
end;
procedure TcxCustomResourceViewAdapter.DoInitialize(
var ASelectedDays: TcxSchedulerDateList; var AEvents: TcxSchedulerCachedEventList);
begin
ASelectedDays := View.Scheduler.SelectedDays;
AEvents := ViewInfo.GetSchedulerEventsList;
end;
function TcxCustomResourceViewAdapter.GetPageHeaderText: string;
begin
Result := ViewInfo.GetPageHeaderText;
end;
procedure TcxCustomResourceViewAdapter.Store;
begin
end;
procedure TcxCustomResourceViewAdapter.Restore;
begin
end;
function TcxCustomResourceViewAdapter.GetCells: TcxObjectList;
begin
Result := ViewInfo.FCells;
end;
function TcxCustomResourceViewAdapter.GetContentLineHeight: Integer;
var
AEventHeight, AIconHeight: Integer;
AImages: TImageList;
begin
with View do
begin
AEventHeight := OptionsView.EventHeight;
AImages := Scheduler.EventImages;
end;
with ViewInfo do
begin
Result := GetFontHeight(StylesAdapter.GetEventParams(nil)) + 2 * cxTextOffset;
if AEventHeight = 0 then
begin
if AImages <> nil then
AIconHeight := Max(PainterHelper.IconsHeight, AImages.Height)
else
AIconHeight := PainterHelper.IconsHeight;
Result := Max(AIconHeight + cxTextOffset + 2 * cxEventImagesOffset, Result);
end
else
Result := Max(AEventHeight, Result);
end;
end;
function TcxCustomResourceViewAdapter.GetPainterHelper: TcxSchedulerPainterHelperClass;
begin
Result := TcxSchedulerHelpersFactory.PainterHelperClass;
end;
function TcxCustomResourceViewAdapter.GetResourceNavigator: TcxSchedulerResourceNavigator;
begin
Result := View.Scheduler.ResourceNavigator;
end;
function TcxCustomResourceViewAdapter.GetResources: TcxSchedulerStorageResourceItems;
begin
Result := View.Resources;
end;
function TcxCustomResourceViewAdapter.GetScheduler: TcxCustomScheduler;
begin
Result := View.Scheduler;
end;
function TcxCustomResourceViewAdapter.GetViewInfo: TcxSchedulerCustomResourceViewViewInfo;
begin
Result := View.ViewInfo;
end;
{ TcxSchedulerEventImageItem }
constructor TcxSchedulerEventImageItem.Create(Collection: TCollection);
begin
inherited Create(Collection);
FAutoHide := True;
FImageIndex := -1;
FVisible := True;
end;
function TcxSchedulerEventImageItem.GetHeight: Integer;
begin
Result := Images.Height;
end;
function TcxSchedulerEventImageItem.GetWidth: Integer;
begin
Result := Images.Width;
end;
{ TcxSchedulerEventImages }
constructor TcxSchedulerEventImages.Create(
ALayout: TcxSchedulerEventImagesLayout);
begin
inherited Create(TcxSchedulerEventImageItem);
FLayout := ALayout;
FItemHeight := EventImages.Height;
FItemWidth := EventImages.Width;
end;
function TcxSchedulerEventImages.Add(AImageIndex: Integer;
AutoHide: Boolean = True): TcxSchedulerEventImageItem;
begin
if (FImages = nil) or ((AImageIndex < 0) or (AImageIndex >= FImages.Count)) then
begin
Result := nil;
Exit;
end;
Result := TcxSchedulerEventImageItem(inherited Add);
Result.FImageIndex := AImageIndex;
Result.AutoHide := AutoHide;
Result.FImageType := eitCustom;
Result.FImages := FImages;
end;
function TcxSchedulerEventImages.AddStandardImage(
AImageType: TcxSchedulerEventImageType;
AutoHide: Boolean = True): TcxSchedulerEventImageItem;
const
Indexes: array[TcxSchedulerEventImageType] of TImageIndex = (4, 2, 3, -1);
begin
Result := TcxSchedulerEventImageItem(inherited Add);
Result.AutoHide := AutoHide;
Result.FImageType := AImageType;
Result.FImages := EventImages;
Result.FImageIndex := Indexes[AImageType];
end;
function TcxSchedulerEventImages.Calculate(const R: TRect): Integer;
begin
case FLayout of
eilAuto: Result := CalculateImages(R);
eilHorizontal: Result := CalculateSingleLineImages(R);
else
Result := CalculateSingleColumnImages(R);
end;
end;
procedure TcxSchedulerEventImages.CalculateForCols(AVisibleImages: TList;
const ATopLeft: TPoint; AColCount: Integer);
var
ARow, ACol, AIndex: Integer;
begin
AIndex := 0;
ACol := 0;
ARow := 0;
while AIndex < TotalVisibleImageCount do
begin
SetItemBounds(TcxSchedulerEventImageItem(AVisibleImages[AIndex]),
ATopLeft.X + ACol * (ItemWidth + cxEventImagesGap),
ATopLeft.Y + ARow * (ItemHeight + cxEventImagesGap));
if ACol = AColCount - 1 then
begin
ACol := 0;
Inc(ARow);
end
else Inc(ACol);
Inc(AIndex);
end;
end;
function TcxSchedulerEventImages.CalculateImages(const R: TRect): Integer;
var
I, AWidth, AHeight, ACount, ARows, AColIndex,
ARowIndex: Integer;
L: TList;
RS: TSize;
procedure CheckAutoHideItems;
var
I: Integer;
AItem: TcxSchedulerEventImageItem;
begin
if ACount >= L.Count then Exit;
for I := L.Count - 1 downto 0 do
begin
AItem := TcxSchedulerEventImageItem(L[I]);
if AItem.AutoHide then
begin
AItem.FHidden := True;
L.Delete(I);
if ACount >= L.Count then break;
end;
end;
end;
begin
AHeight := ItemHeight + cxEventImagesGap;
RS := cxRectSize(R);
ARows := Max(1, RS.cy div AHeight);
if ARows = 1 then
begin
Result := CalculateSingleLineImages(R);
Exit;
end;
Result := 0;
L := CreateVisibleList;
try
if L.Count = 0 then Exit;
AWidth := ItemWidth + cxEventImagesGap;
ACount := Max(1, RS.cx div AWidth) * ARows;
CheckAutoHideItems;
AColIndex := 0;
ARowIndex := 0;
for I := 0 to L.Count - 1 do
begin
SetItemBounds(TcxSchedulerEventImageItem(L[I]),
R.Left + AColIndex * AWidth,
R.Top + ARowIndex * AHeight);
Result := Max(Result, (AColIndex + 1) * AWidth);
Inc(ARowIndex);
if ARowIndex = ARows then
begin
Inc(AColIndex);
ARowIndex := 0;
end;
end;
FVisibleImageCount := L.Count;
finally
L.Free;
end;
end;
function TcxSchedulerEventImages.CalculateSingleLineImages(const R: TRect; ARightLimit: Integer = 0): Integer;
var
I, ALeft, AImageWidth, ATotalWidth, ARectWidth: Integer;
L: TList;
AItem: TcxSchedulerEventImageItem;
procedure CheckAutoHideItems;
var
I: Integer;
AItem: TcxSchedulerEventImageItem;
begin
if ARectWidth >= ATotalWidth then Exit;
if ARightLimit > 0 then
ARectWidth := Min(ARightLimit, Max(ARectWidth, ForceVisibleWidth));
for I := L.Count - 1 downto 0 do
begin
AItem := TcxSchedulerEventImageItem(L.List^[I]);
if AItem.AutoHide then
begin
AItem.FHidden := True;
Dec(ATotalWidth, AImageWidth);
L.Delete(I);
if ARectWidth >= ATotalWidth then break;
end;
end;
end;
begin
Result := 0;
L := CreateVisibleList;
try
if L.Count = 0 then Exit;
ATotalWidth := TotalVisibleWidth;
ARectWidth := R.Right - R.Left;
AImageWidth := ItemWidth + cxEventImagesGap;
CheckAutoHideItems;
ALeft := R.Left;
for I := 0 to L.Count - 1 do
begin
AItem := TcxSchedulerEventImageItem(L.List^[I]);
SetItemBounds(AItem, ALeft, R.Top);
Inc(ALeft, AImageWidth);
Inc(Result, AImageWidth);
end;
FVisibleImageCount := L.Count;
finally
L.Free;
end;
end;
function TcxSchedulerEventImages.CalculateSingleColumnImages(const R: TRect): Integer;
var
I, ATop, AWidth, AHeight, ATotalHeight: Integer;
RS: TSize;
L: TList;
procedure CheckAutoHideItems;
var
I: Integer;
AItem: TcxSchedulerEventImageItem;
begin
if RS.cy + cxEventImagesGap >= ATotalHeight then Exit;
for I := L.Count - 1 downto 0 do
begin
AItem := TcxSchedulerEventImageItem(L.List^[I]);
if AItem.AutoHide then
begin
AItem.FHidden := True;
Dec(ATotalHeight, AHeight);
L.Delete(I);
if RS.cy + cxEventImagesGap >= ATotalHeight then break;
end;
end;
end;
function CanAutoHideAllItems: Boolean;
var
I: Integer;
begin
Result := True;
for I := 0 to L.Count - 1 do
if not TcxSchedulerEventImageItem(L.List^[I]).AutoHide then
begin
Result := False;
break;
end;
end;
begin
Result := 0;
L := CreateVisibleList;
try
if L.Count = 0 then Exit;
ATotalHeight := TotalVisibleHeight;
RS := cxRectSize(R);
AWidth := ItemWidth + cxEventImagesGap;
if (RS.cx < AWidth) and CanAutoHideAllItems then Exit;
AHeight := ItemHeight + cxEventImagesGap;
CheckAutoHideItems;
if L.Count = 0 then Exit;
Result := AWidth;
ATop := R.Top;
for I := 0 to L.Count - 1 do
begin
SetItemBounds(TcxSchedulerEventImageItem(L.List^[I]), R.Left, ATop);
Inc(ATop, AHeight);
end;
FVisibleImageCount := L.Count;
finally
L.Free;
end;
end;
function TcxSchedulerEventImages.CreateVisibleList: TList;
var
I: Integer;
AItem: TcxSchedulerEventImageItem;
begin
FVisibleImageCount := 0;
FForceVisibleHeight := 0;
FForceVisibleWidth := 0;
FTotalVisibleImageCount := 0;
Result := TList.Create;
for I := 0 to Count - 1 do
begin
AItem := Items[I];
if AItem.Visible then
begin
Inc(FTotalVisibleImageCount);
if not AItem.AutoHide then
begin
Inc(FForceVisibleHeight, ItemHeight + cxEventImagesGap);
Inc(FForceVisibleWidth, ItemWidth + cxEventImagesGap);
end;
AItem.FHidden := False;
Result.Add(AItem);
end
else AItem.FHidden := True;
end;
FTotalVisibleWidth := (ItemWidth + cxEventImagesGap) * Result.Count;
FTotalVisibleHeight := (ItemHeight + cxEventImagesGap) * Result.Count;
end;
procedure TcxSchedulerEventImages.Init(AImages: TImageList);
begin
FVisibleImageCount := 0;
FImages := AImages;
if (FImages <> nil) then
begin
if FImages.Height > FItemHeight then FItemHeight := FImages.Height;
if FImages.Width > FItemWidth then FItemWidth := FImages.Width;
end;
end;
function TcxSchedulerEventImages.Offset(ADeltaX, ADeltaY: Integer): Integer;
var
I: Integer;
begin
Result := 0;
for I := 0 to Count - 1 do
with Items[I] do
begin
if not FHidden then
begin
FBounds := cxRectOffset(FBounds, ADeltaX, ADeltaY);
Inc(Result, ItemWidth + cxEventImagesGap);
end;
end;
end;
procedure TcxSchedulerEventImages.SetItemBounds(
AItem: TcxSchedulerEventImageItem; ALeft, ATop: Integer);
begin
Inc(ALeft, Max(0, (ItemWidth - AItem.Width) div 2));
Inc(ATop, Max(0, (ItemHeight - AItem.Height) div 2));
AItem.FBounds := cxRectBounds(ALeft, ATop, AItem.Width, AItem.Height);
end;
function TcxSchedulerEventImages.GetImageItem(
AIndex: Integer): TcxSchedulerEventImageItem;
begin
Result := TcxSchedulerEventImageItem(inherited Items[AIndex]);
end;
{ TcxSchedulerCustomResourceViewViewInfo }
constructor TcxSchedulerCustomResourceViewViewInfo.Create(
AOwner: TcxSchedulerSubControl);
begin
inherited Create(AOwner);
FCells := TcxObjectList.Create;
FResources := TcxObjectList.Create;
FGroupSeparatorCells := TcxSchedulerViewInfoCellList.Create;
FButtons := TcxSchedulerViewInfoCellList.Create;
FContentCells := TcxSchedulerViewInfoCellList.Create;
FEventCells := TcxSchedulerViewInfoCellList.Create;
FDayHeaderCells := TcxSchedulerViewInfoCellList.Create;
FResourceHeaderCells := TcxSchedulerViewInfoCellList.Create;
FHeaderContainerCells := TcxSchedulerViewInfoCellList.Create;
FCells.Add(FEventCells);
FCells.Add(FGroupSeparatorCells);
FCells.Add(FDayHeaderCells);
FCells.Add(FResourceHeaderCells);
FCells.Add(FContentCells);
FCells.Add(FHeaderContainerCells);
end;
destructor TcxSchedulerCustomResourceViewViewInfo.Destroy;
begin
FEventImages := nil;
FResources.Free;
FButtons.Free;
FCells.Free;
inherited Destroy;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.Calculate;
begin
ScreenCanvas := TcxScreenCanvas.Create;
try
Supports(TObject(View.Scheduler), IcxSchedulerEventImages, FEventImages);
FPrimaryPage := Adapter.GetPrimaryPage;
Adapter.DoInitialize(FSelectedDays, FEvents);
FHasVisibleBounds := GetHasVisibleBounds;
FPrintWeekEnds := not Adapter.DontPrintWeekEnd;
FPagesPerWeek := Adapter.PagesPerWeek;
FPageBounds := Adapter.GetPageBounds;
FCanSelected := not Adapter.GetHideSelection;
inherited Calculate;
finally
FreeAndNil(ScreenCanvas);
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.CalculateHitTest(
AHitTest: TcxSchedulerCustomResourceViewHitTest);
begin
FEventCells.CalculateHitTest(AHitTest);
if not FDayHeaderCells.CalculateHitTest(AHitTest) then
if not FResourceHeaderCells.CalculateHitTest(AHitTest) then
if not FHeaderContainerCells.CalculateHitTest(AHitTest) then
if not FButtons.CalculateHitTest(AHitTest) then
if not FContentCells.CalculateHitTest(AHitTest) then
FGroupSeparatorCells.CalculateHitTest(AHitTest);
if AHitTest.HitAtButton and AHitTest.HitAtEvent then
begin
AHitTest.FHitObject := nil;
AHitTest.FEventCell := nil;
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.InitScrollBarsParameters;
begin
CheckResourceNavigator;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.ScrollHorizontal(
AScrollCode: TScrollCode; var AScrollPos: Integer);
begin
end;
procedure TcxSchedulerCustomResourceViewViewInfo.ScrollVertical(
AScrollCode: TScrollCode; var AScrollPos: Integer);
begin
end;
procedure TcxSchedulerCustomResourceViewViewInfo.SetEventsVisibility(
AShowSources, AShowClones: Boolean; AForceRepaint: Boolean = False);
var
ARepaint: Boolean;
begin
ARepaint := AForceRepaint or (FHideSource <> not AShowSources) or
(FHideClones <> not AShowClones);
FHideSource := not AShowSources;
FHideClones := not AShowClones;
if ARepaint then View.Refresh;
end;
function TcxSchedulerCustomResourceViewViewInfo.AddButton(
ABounds: TRect; const ADateTime: TDateTime; AResourceIndex: Integer;
AIsDown: Boolean): TcxSchedulerMoreEventsButtonViewInfo;
begin
ABounds := cxRectInflate(ABounds, -cxTextOffset, -cxTextOffset);
ABounds.Left := ABounds.Right - PainterHelper.MoreButtonWidth;
if AIsDown then
ABounds.Top := ABounds.Bottom - PainterHelper.MoreButtonHeight
else
ABounds.Bottom := ABounds.Top + PainterHelper.MoreButtonHeight;
if DateOf(ADateTime) = 0 then
CreateCellInstance(TcxSchedulerMoreEventsButtonViewInfo, ABounds,
Styles.GetBackgroundParams, Result)
else
CreateCellInstance(TcxSchedulerMoreEventsButtonViewInfo, ABounds,
GetContentParams(ADateTime, nil), Result);
Result.FIsDown := AIsDown;
Result.FDateTime := ADateTime;
Result.FOnClick := OnMoreEventsButtonClick;
AssignResourceID(Result, AResourceIndex);
FButtons.Add(Result);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddBackgroundSlot(const ABounds: TRect;
ABorders: TcxBorders; const AText: string = ''): TcxSchedulerBackgroundSlotCellViewInfo;
begin
CreateCellInstance(TcxSchedulerBackgroundSlotCellViewInfo, ABounds,
Styles.GetBackgroundParams, Result);
Result.FBorders := ABorders;
AssignResourceID(Result, -1);
ContentCells.Add(Result);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddContentCell(const ARect: TRect;
const AStart, AFinish: TDateTime; AResourceIndex: Integer): TcxSchedulerContentCellViewInfo;
begin
CreateCellInstance(ContentCellClass, ARect,
GetContentParams(AStart, Resources[AResourceIndex]), Result);
Result.SetTime(AStart, AFinish);
AssignResourceID(Result, AResourceIndex);
ContentCells.Add(Result);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddDayHeader(
const ADate: TDateTime; const ABounds: TRect;
AResourceIndex: Integer): TcxSchedulerDayHeaderCellViewInfo;
begin
CreateCellInstance(TcxSchedulerDayHeaderCellViewInfo, ABounds,
StylesAdapter.GetDayHeaderParams(ADate), Result);
Result.DateTime := ADate;
AssignResourceID(Result, AResourceIndex);
FDayHeaderCells.Add(Result);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddDayHeader(
const ADate: TDateTime; ATop, ALeft, ARight: Integer;
AResourceIndex: Integer): TcxSchedulerDayHeaderCellViewInfo;
begin
Result := AddDayHeader(ADate,
cxRect(ALeft, ATop, ARight, ATop + FDayHeaderHeight), AResourceIndex);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddEventCell(
AViewData: TcxSchedulerEventViewData;
AImmediateCalculate: Boolean = True): TcxSchedulerEventCellViewInfo;
begin
Result := CreateEventCellViewInfo(AViewData);
if (FEventImages <> nil) and FEventImages.SupportEventImages then
begin
Result.Images.Init(FEventImages.GetImages);
FEventImages.DoInitEventImages(AViewData.Event, Result.Images);
end;
if AImmediateCalculate then Result.Calculate;
EventCells.Add(Result);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddGroupHorzSeparator(
APos: Integer): TcxSchedulerGroupSeparatorCellViewInfo;
begin
Result := AddGroupSeparator(cxRectSetTop(Bounds, APos, SeparatorWidth));
if Result <> nil then
Result.Rotated := True;
end;
function TcxSchedulerCustomResourceViewViewInfo.AddGroupSeparator(
const ABounds: TRect): TcxSchedulerGroupSeparatorCellViewInfo;
begin
Result := nil;
if not HasSeparator then Exit;
CreateCellInstance(TcxSchedulerGroupSeparatorCellViewInfo, ABounds,
FGroupSeparatorParams, Result);
GroupSeparatorCells.Add(Result);
end;
function TcxSchedulerCustomResourceViewViewInfo.AddGroupVertSeparator(
APos: Integer): TcxSchedulerGroupSeparatorCellViewInfo;
begin
Result := AddGroupSeparator(cxRectSetLeft(Bounds, APos, SeparatorWidth));
end;
function TcxSchedulerCustomResourceViewViewInfo.AddResourceHeader(
const AIndex: Integer; const ABounds: TRect): TcxSchedulerHeaderCellViewInfo;
begin
CreateCellInstance(TcxSchedulerHeaderCellViewInfo, ABounds,
StylesAdapter.GetResourceHeaderParams(GetResourceItemByIndex(AIndex)), Result);
if AIndex >= 0 then
begin
Result.FDisplayText := ResourceCaptions[AIndex];
AssignResourceID(Result, AIndex);
with Resources[AIndex] do
begin
Result.FAutoHeight := ResourceHeaders.MultilineCaptions;
Result.FImageIndex := ImageIndex;
Result.FImagePosition := ImagePosition;
Result.FImages := Images;
end;
end;
ResourceHeaderCells.Add(Result);
Result.FIsResourceHeader := True;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.AfterCalculate;
begin
inherited AfterCalculate;
if FHideClones then
HideCloneEventsOnDragDrop;
if FHideSource then
HideSourceEventsOnDragDrop;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.AssignResourceID(
ACell: TcxSchedulerCustomResourceViewInfoItem; AIndex: Integer);
begin
if AIndex >= 0 then
ACell.Resource := Resources[AIndex];
ACell.FIsResourceAssigned := AIndex >= 0;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.CalculateMetrics;
begin
FHideSelection := View.OptionsView.HideSelection and not View.Scheduler.IsFocused;
FGroupSeparatorParams := Styles.GetGroupSeparatorParams;
FTimeLineParams := GetTimeLineParams;
FSelectionParams := Styles.GetSelectionParams;
FContentLineHeight := Adapter.GetContentLineHeight;
FContentFontHeight := cxTextHeight(StylesAdapter.GetContentParams(Now, nil).Font) + cxTextOffset * 2;
FDayHeaderHeight :=
LookAndFeelPainter.HeaderHeight(GetFontHeight(StylesAdapter.GetDayHeaderStyle));
FResourceHeaderHeight :=
LookAndFeelPainter.HeaderHeight(GetFontHeight(StylesAdapter.GetResourceHeaderStyle));
FUseResourceImages := HasStorage and View.Scheduler.Storage.Resources.AreImagesUsed;
if HasStorage then
FResourceImages := View.Scheduler.Storage.Resources.Images
else
FResourceImages := nil;
if HasStorage then
begin
if ResourceHeaders.Height = 0 then
CalculateResourceHeadersAutoHeight(GetResourceHeaderWidth - cxTextOffset * 3)
else
FResourceHeaderHeight := ResourceHeaders.Height;
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.CalculateResourceHeadersAutoHeight(
AWidth: Integer);
function CalculateResourceHeight(AResource: TcxSchedulerStorageResourceItem;
AWidth: Integer): Integer;
var
R: TRect;
AFont: TFont;
AText: string;
AHasImage: Boolean;
begin
AFont := Styles.GetResourceHeaderParams(AResource).Font;
AHasImage := UseResourceImages and (AResource.ActualImageIndex >= 0);
if AHasImage and (ResourceHeaders.ImagePosition in [ipLeft, ipRight]) then
AWidth := Max(0, AWidth - (GetResourceImagesSize.cx + cxTextOffset * 2));
R := Rect(0, 0, Max(AWidth, 2), 0);
AText := AResource.Resources.GetResourceName(AResource);
ScreenCanvas.Font.Assign(AFont);
ScreenCanvas.TextExtent(AText, R,
MakeTextOutcxFlags(taLeftJustify, vaCenter, ResourceHeaders.MultilineCaptions));
Result := R.Bottom - R.Top + cxTextOffset * 3;
SetResourceTextRect(AResource, R);
if AHasImage then
begin
if (ResourceHeaders.ImagePosition in [ipTop, ipBottom]) then
Inc(Result, GetResourceImagesSize.cy + cxTextOffset * 4)
else
Result := Max(Result, GetResourceImagesSize.cy + cxTextOffset * 3);
end;
end;
var
I: Integer;
begin
AWidth := Max(0, AWidth);
for I := 0 to Adapter.Resources.VisibleResourceCount - 1 do
FResourceHeaderHeight := Max(FResourceHeaderHeight, CalculateResourceHeight(
Adapter.Resources.VisibleResources[I], AWidth));
end;
function TcxSchedulerCustomResourceViewViewInfo.CalculateResourceHeaderWidth: Integer;
var
I: Integer;
AWidth: Integer;
function CalculateWidth(AResource: TcxSchedulerStorageResourceItem): Integer;
var
R: TRect;
AText: string;
AHasImage: Boolean;
AViewParams: TcxViewParams;
begin
AViewParams := StylesAdapter.GetResourceHeaderParams(AResource);
Result := 0;
AHasImage := AResource.ActualImageIndex >= 0;
AText := AResource.Resources.GetResourceName(AResource);
if Length(AText) > 0 then
begin
R := Rect(0, 0, FResourceHeaderHeight, AWidth);
if AHasImage and (ResourceHeaders.ImagePosition in [ipTop, ipBottom]) then
Dec(R.Bottom, ResourceImages.Height + cxTextOffset * 3);
ScreenCanvas.Font.Assign(AViewParams.Font);
ScreenCanvas.TextExtent(AText, R, MakeTextOutcxFlags(taLeftJustify,
vaCenter, ResourceHeaders.MultilineCaptions));
Result := R.Right - R.Left + cxTextOffset * 3;
SetResourceTextRect(AResource, R);
if AHasImage and (ResourceHeaders.ImagePosition in [ipTop, ipBottom]) then
Result := Max(Result, ResourceImages.Width + cxTextOffset * 4);
end;
if AHasImage and (ResourceHeaders.ImagePosition in [ipLeft, ipRight]) then
Inc(Result, ResourceImages.Width + cxTextOffset * 4);
end;
begin
AWidth := GetResourceHeaderWidth - cxTextOffset * 3;
Result := FResourceHeaderHeight;
for I := 0 to Adapter.Resources.VisibleResourceCount - 1 do
Result := Max(Result, CalculateWidth(Adapter.Resources.VisibleResources[I]));
end;
procedure TcxSchedulerCustomResourceViewViewInfo.Clear;
begin
FResources.Clear;
GroupSeparatorCells.Clear;
Buttons.Clear;
ContentCells.Clear;
EventCells.Clear;
DayHeaderCells.Clear;
ResourceHeaderCells.Clear;
HeaderContainerCells.Clear;
end;
function TcxSchedulerCustomResourceViewViewInfo.ContentCellClass: TcxSchedulerContentCellViewInfoClass;
begin
Result := TcxSchedulerContentCellViewInfo
end;
procedure TcxSchedulerCustomResourceViewViewInfo.CreateCellInstance(
AClass: TcxSchedulerCustomViewInfoItemClass; const ABounds: TRect;
const AViewParams: TcxViewParams; var Instance);
begin
CreateCellInstance(AClass, ABounds, Bounds, AViewParams, Instance);
end;
procedure TcxSchedulerCustomResourceViewViewInfo.CreateCellInstance(
AClass: TcxSchedulerCustomViewInfoItemClass; const ABounds,
AVisibleBounds: TRect; const AViewParams: TcxViewParams; var Instance);
begin
Pointer(Instance) := AClass.Create(LookAndFeelPainter,
ABounds, AVisibleBounds, AViewParams);
TcxSchedulerCustomViewInfoItem(Instance).FDayBorderColor := FDayBorderColor;
end;
function TcxSchedulerCustomResourceViewViewInfo.CreateEventViewData(
AEvent: TcxSchedulerControlEvent; const ABounds: TRect;
const AStart, AFinish: TDateTime; AResource: TcxSchedulerResourceViewInfo): TcxSchedulerEventViewData;
var
ALocation: string;
begin
Result := TcxSchedulerEventViewData.Create;
Result.Bounds := ABounds;
Result.VisibleRect := Bounds;
Result.Canvas := View.Canvas;
Result.ContentStart := DateTimeHelper.RoundTime(AStart);
{$IFNDEF DEBUGPAINT}
Result.Bitmap := View.Bitmap;
{$ENDIF}
Result.BorderColor := View.OptionsView.EventBorderColor;
Result.ContentFinish := DateTimeHelper.RoundTime(AFinish);
Result.Event := AEvent;
Result.ShowTimeAsClock := View.ShowTimeAsClock;
Result.TimeLineParams := FTimeLineParams;
Result.ShowFinishTime := View.ShowEndTime;
Result.Painter := LookAndFeelPainter;
Result.ViewParams := StylesAdapter.GetEventParams(AEvent);
Result.EditProperties := View.GetEditProperties(AEvent);
Result.EditStyle := View.GetEditStyle(AEvent);
Result.Resource := AResource;
Result.Caption := DoGetEventDisplayText(AEvent);
Result.ImagesLayout := View.EventImagesLayout;
ALocation := Trim(AEvent.Location);
if ALocation <> '' then
Result.Caption := Result.Caption + ' (' + ALocation + ')';
Result.LineHeight := FContentLineHeight;
end;
function TcxSchedulerCustomResourceViewViewInfo.CreateEventCellViewInfo(
AViewData: TcxSchedulerEventViewData): TcxSchedulerEventCellViewInfo;
begin
Result := TcxSchedulerEventCellViewInfo.Create(AViewData);
end;
procedure TcxSchedulerCustomResourceViewViewInfo.DoCalculate;
begin
FDayBorderColor := View.OptionsView.DayBorderColor;
if FDayBorderColor = clDefault then
FDayBorderColor := clWindowText;
ExtractResources;
FGroupingKind := GetGroupingKind;
if FGroupingKind = gkNone then
FResources.Clear;
if SelectedDays.Count = 0 then
SelectedDays.Add(Date);
with View.Controller.Navigation do
Self.FSelResource := GetResourceViewInfoByItem(SelResource);
if (FSelResource = nil) and (ResourceCount > 0) then
FSelResource := Resources[0];
CalculateMetrics;
View.Controller.Navigation.CheckSelection;
with View.Controller.Navigation do
begin
Self.FSelStart := DateTimeHelper.RoundTime(Min(SelStart, SelFinish));
Self.FSelFinish := DateTimeHelper.RoundTime(Max(SelStart, SelFinish));
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.DoMoreEventsButtonClick(
Sender: TcxSchedulerMoreEventsButtonViewInfo);
begin
end;
procedure TcxSchedulerCustomResourceViewViewInfo.ExtractResources;
var
I: Integer;
begin
FResources.Clear;
Adapter.GetPageResources(FResources);
for I := 0 to FResources.Count - 1 do
Resources[I].FImagePosition := ResourceHeaders.ImagePosition;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetBounds: TRect;
begin
Result := FPageBounds;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetContentParams(
const ATime: TDateTime; AResource: TcxSchedulerResourceViewInfo): TcxViewParams;
begin
if AResource = nil then
Result := StylesAdapter.GetContentParams(ATime, nil)
else
Result := StylesAdapter.GetContentParams(ATime, AResource.ResourceItem)
end;
function TcxSchedulerCustomResourceViewViewInfo.GetDayHeaderHeight: Integer;
begin
Result := FDayHeaderHeight;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceHeaderWidth: Integer;
begin
Result := GetResourcesContentWidth;
if ResourceCount > 0 then
Result := Max(0, (Result - SeparatorWidth * GetSeparatorCount) div ResourceCount);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceImagesSize: TSize;
begin
if ResourceImages = nil then
Result := TSize(cxNullSize)
else
Result := cxSize(ResourceImages.Width, ResourceImages.Height);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourcesContentWidth: Integer;
begin
Result := FBounds.Bottom - FBounds.Top - FDayHeaderHeight;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetTimeLineParams: TcxViewParams;
begin
Result := StylesAdapter.GetContentParams(NullDate, nil)
end;
function TcxSchedulerCustomResourceViewViewInfo.GetSelectionParams(
const AParams: TcxViewParams): TcxViewParams;
begin
Result := AParams;
if View.Scheduler.Focused or not HideSelection then
begin
Result := FSelectionParams;
Result.Bitmap := nil;
end;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetSeparatorCount: Integer;
begin
Result := ResourceCount - 1;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetFontHeight(
AStyle: TcxStyle): Integer;
begin
if (AStyle = nil) or not (cxStyles.svFont in AStyle.AssignedValues) then
Result := PainterHelper.TextHeight(DefaultFont)
else
Result := PainterHelper.TextHeight(AStyle.Font);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetFontHeight(
const AParams: TcxViewParams): Integer;
begin
Result := PainterHelper.TextHeight(AParams.Font);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetPageHeaderText: string;
begin
Result := FormatDateTime(LongDateFormat, Days[0]);
if Days[0] <> Days[DayCount - 1] then
Result := Result + ' - ' + FormatDateTime(LongDateFormat, Days[DayCount - 1]);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceItemByIndex(
AIndex: Integer): TcxSchedulerStorageResourceItem;
begin
Result := nil;
if AIndex >= 0 then
Result := Resources[AIndex].ResourceItem;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceViewInfoByItem(
AItem: TcxSchedulerStorageResourceItem): TcxSchedulerResourceViewInfo;
var
I: Integer;
begin
Result := nil;
for I := 0 to ResourceCount - 1 do
if Resources[I].ResourceItem = AItem then
Result := Resources[I];
end;
function TcxSchedulerCustomResourceViewViewInfo.HasStorage: Boolean;
begin
Result := View.Scheduler.Storage <> nil;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.ProcessCheckBorders(
AList: TcxSchedulerViewInfoCellList; AHasCommonArea: Boolean;
ANeighbors: TcxNeighbors = []; AExcludeBorders: TcxBorders = [];
AAddBorders: TcxBorders = []);
var
I: Integer;
DrawCommonBorders: Boolean;
ACell, APrevCell: TcxSchedulerHeaderCellViewInfo;
begin
DrawCommonBorders :=
LookAndFeelPainter.HeaderBorders([nLeft..nBottom]) = cxBordersAll;
APrevCell := nil;
for I := 0 to AList.Count - 1 do
begin
ACell := TcxSchedulerHeaderCellViewInfo(AList[I]);
ACell.FNeighbors := [nLeft, nRight];
if (I = 0) and not ACell.RotateHeader then
begin
Exclude(ACell.FNeighbors, nLeft);
if AHasCommonArea then
Include(ACell.FNeighbors, nBottom);
end;
ACell.FNeighbors := ACell.FNeighbors + ANeighbors;
ACell.FBorders := LookAndFeelPainter.HeaderBorders(ACell.FNeighbors);
if not DrawCommonBorders then
begin
ACell.CheckNeighbor(APrevCell);
ACell.FBorders := ACell.FBorders - AExcludeBorders + AAddBorders;
end;
if I = (AList.Count - 1) then
begin
Exclude(ACell.FBorders, bRight);
Exclude(ACell.FNeighbors, nRight);
end;
APrevCell := ACell;
end;
end;
function TcxSchedulerCustomResourceViewViewInfo.SetAdapter(
Adapter: TcxCustomResourceViewAdapter): TcxCustomResourceViewAdapter;
begin
Result := FAdapter;
FAdapter := Adapter;
FStylesAdapter := FAdapter.GetStylesAdapter;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.SetResourceTextRect(
AResource: TcxSchedulerStorageResourceItem; const ARect: TRect);
var
I: Integer;
begin
for I := 0 to ResourceCount - 1 do
if Resources[I].ResourceItem = AResource then
begin
Resources[I].FTextRect := ARect;
Break;
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.ProcessDateToDisplayText(
ArrangeByType: Boolean = False);
var
I: Integer;
AType: Integer;
begin
AType := 0;
for I := 0 to FDayHeaderCells.Count - 1 do
AType := Max(TcxSchedulerDayHeaderCellViewInfo(
FDayHeaderCells[I]).ConvertDateToDisplayText, AType);
if ArrangeByType and (AType > 0) then
begin
for I := 0 to FDayHeaderCells.Count - 1 do
TcxSchedulerDayHeaderCellViewInfo(
FDayHeaderCells[I]).ConvertDateToDisplayText(AType);
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.HideCloneEventsOnDragDrop;
var
I: Integer;
AEventCell: TcxSchedulerEventCellViewInfo;
begin
for I := 0 to EventCells.Count - 1 do
begin
AEventCell := TcxSchedulerEventCellViewInfo(EventCells[I]);
if Events.Clones.IndexOf(AEventCell.Event) <> -1 then
AEventCell.Hidden := True;
end;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.HideSourceEventsOnDragDrop;
var
I, J: Integer;
AEventCell: TcxSchedulerEventCellViewInfo;
begin
for I := 0 to EventCells.Count - 1 do
begin
AEventCell := TcxSchedulerEventCellViewInfo(EventCells[I]);
for J := 0 to Events.Clones.Count - 1 do
if TcxSchedulerControlEvent(Events.Clones[J]).Source = AEventCell.Event then
begin
AEventCell.Hidden := True;
Break;
end;
end;
end;
function TcxSchedulerCustomResourceViewViewInfo.IsTimeSelected(
ATime: TDateTime; AResource: TObject): Boolean;
begin
ATime := DateTimeHelper.RoundTime(ATime);
Result := not HideSelection and ((AResource = FSelResource) and
(ATime >= SelStart) and (ATime <= SelFinish));
Result := Result and CanSelected;
end;
procedure TcxSchedulerCustomResourceViewViewInfo.MakeTimeVisible(
const ATime: TDateTime);
begin
end;
procedure TcxSchedulerCustomResourceViewViewInfo.OnMoreEventsButtonClick(
Sender: TcxSchedulerMoreEventsButtonViewInfo);
begin
if not DoSchedulerMoreEventsButtonClick then
DoMoreEventsButtonClick(Sender);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetClones: TcxSchedulerEventList;
begin
Result := View.EventList.Clones;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetDay(AIndex: Integer): TDateTime;
begin
Result := Integer(SelectedDays.List^[AIndex]);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetDayCount: Integer;
begin
Result := SelectedDays.Count;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetShowEventsWithoutResource: Boolean;
begin
Result := View.OptionsView.ShowEventsWithoutResource or (FGroupingKind = gkNone);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetGroupByDate: Boolean;
begin
Result := GroupingKind = gkByDate;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetGroupByResource: Boolean;
begin
Result := GroupingKind = gkByResource;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetGroupingKind: TcxSchedulerGroupingKind;
begin
Result := View.GroupingKind;
if Result = gkDefault then
Result := View.OptionsView.GroupingKind;
if ResourceCount = 0 then
Result := gkNone
else
if Result = gkDefault then
Result := gkByResource;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetHasSeparator: Boolean;
begin
Result := (SeparatorWidth > 0) and (GroupingKind <> gkNone);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetHasVisibleBounds: Boolean;
begin
Result := (PrintFrom <> NullDate) and (PrintTo <> NullDate)
end;
function TcxSchedulerCustomResourceViewViewInfo.GetHiddenSelection: Boolean;
begin
Result := View.Controller.IsEditing or (Events.Selection.Count > 0);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResource(
AIndex: Integer): TcxSchedulerResourceViewInfo;
begin
if AIndex < 0 then
Result := nil
else
Result := TcxSchedulerResourceViewInfo(FResources[AIndex]);
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceCaption(
AIndex: Integer): string;
begin
Result := Resources[AIndex].Caption;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceCount: Integer;
begin
Result := FResources.Count;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetResourceHeaders: TcxSchedulerResourceHeaders;
begin
Result := View.OptionsView.ResourceHeaders;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetPrintRange(
Index: Integer): TDateTime;
begin
Result := Adapter.GetPrintRange(Index)
end;
function TcxSchedulerCustomResourceViewViewInfo.GetSeparatorWidth: Integer;
begin
Result := View.OptionsView.GroupSeparatorWidth;
end;
function TcxSchedulerCustomResourceViewViewInfo.GetView: TcxSchedulerCustomResourceView;
begin
Result := TcxSchedulerCustomResourceView(Owner);
end;
{ TcxSchedulerCustomResourceViewNavigation }
procedure TcxSchedulerCustomResourceViewNavigation.ValidateSelection(
var ASelStart, ASelFinish: TDateTime;
var AResource: TcxSchedulerStorageResourceItem);
begin
AResource := ResourceItem;
end;
function TcxSchedulerCustomResourceViewNavigation.GetNextResource(
AGoToForward: Boolean): TcxSchedulerStorageResourceItem;
var
AIndex: Integer;
begin
Result := ResourceItem;
AIndex := ViewInfo.FResources.IndexOf(ResourceObject) + Byte(AGoToForward) * 2 - 1;
if (AIndex < 0) or (AIndex >= ViewInfo.FResources.Count) then Exit;
Result := ViewInfo.GetResourceItemByIndex(AIndex);
end;
function TcxSchedulerCustomResourceViewNavigation.GetResourceItem: TcxSchedulerStorageResourceItem;
begin
Result := nil;
if ResourceObject <> nil then
Result := ResourceObject.ResourceItem;
end;
function TcxSchedulerCustomResourceViewNavigation.GetResourceFromViewInfo(
AInfo: TcxSchedulerResourceViewInfo): TcxSchedulerStorageResourceItem;
begin
Result := nil;
if AInfo <> nil then
Result := AInfo.ResourceItem;
end;
function TcxSchedulerCustomResourceViewNavigation.RoundTime(
const ADateTime: TDateTime): TDateTime;
begin
Result := DateTimeHelper.RoundTime(ADateTime);
end;
function TcxSchedulerCustomResourceViewNavigation.GetIsFirstResource: Boolean;
begin
Result := ViewInfo.FResources.IndexOf(ResourceObject) <= 0;
end;
function TcxSchedulerCustomResourceViewNavigation.GetIsLastResource: Boolean;
begin
Result := ViewInfo.FResources.IndexOf(ResourceObject) =
(ViewInfo.FResources.Count - 1);
end;
function TcxSchedulerCustomResourceViewNavigation.GetGroupingKind: TcxSchedulerGroupingKind;
begin
Result := ViewInfo.FGroupingKind;
end;
function TcxSchedulerCustomResourceViewNavigation.GetResourceObject: TcxSchedulerResourceViewinfo;
begin
Result := ViewInfo.FSelResource;
end;
function TcxSchedulerCustomResourceViewNavigation.GetViewInfo: TcxSchedulerCustomResourceViewViewInfo;
begin
Result := TcxSchedulerCustomResourceView(View).ViewInfo;
end;
{ TcxSchedulerCustomResourceViewController }
function TcxSchedulerCustomResourceViewController.CreateNavigation: TcxSchedulerViewNavigation;
begin
Result := TcxSchedulerCustomResourceViewNavigation.Create(View);
end;
function TcxSchedulerCustomResourceViewController.GetCursor(X, Y: Integer): TCursor;
const
Cursors: array[Boolean] of TCursor = (crSchedulerVertResize, crSchedulerHorzResize);
begin
with HitTest do
case GetDragKind of
edkEventDragRect:
Result := crSchedulerSplitAll;
edkResizeStart, edkResizeEnd:
Result := Cursors[EventCell.IsHorzSizing];
else
Result := inherited GetCursor(X, Y);
end;
end;
procedure TcxSchedulerCustomResourceViewController.MouseDown(
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited MouseDown(Button, Shift, X, Y);
with HitTest do
if HitAtButton then Button.Click;
end;
function TcxSchedulerCustomResourceViewController.GetHitTest: TcxSchedulerCustomResourceViewHitTest;
begin
Result := TcxSchedulerCustomResourceViewHitTest(inherited HitTest);
end;
{ TcxSchedulerCustomResourceViewHitTest }
function TcxSchedulerCustomResourceViewHitTest.GetDragKind: TcxEventDragKind;
begin
ValidateDragKind;
Result := FDragKind;
end;
procedure TcxSchedulerCustomResourceViewHitTest.SetDragKind(
AValue: TcxEventDragKind);
begin
FDragKind := AValue;
ValidateDragKind;
end;
function TcxSchedulerCustomResourceViewHitTest.CanMoveEvent(
AEvent: TcxSchedulerControlEvent): Boolean;
var
AResource: TcxSchedulerStorageResourceItem;
begin
Result := Scheduler.EventOperations.Moving;
if Result then
begin
AResource := AEvent.GetResourceItem;
Result := (AResource = nil) or not AResource.ReadOnly;
end;
end;
function TcxSchedulerCustomResourceViewHitTest.CanResizeEvent(
AEvent: TcxSchedulerControlEvent): Boolean;
var
AResource: TcxSchedulerStorageResourceItem;
begin
Result := Scheduler.EventOperations.Sizing;
if Result then
begin
AResource := AEvent.GetResourceItem;
Result := (AResource = nil) or not AResource.ReadOnly;
end;
end;
procedure TcxSchedulerCustomResourceViewHitTest.Clear;
begin
FDragKind := edkNone;
FEventCell := nil;
FResource := nil;
FHitObject := nil;
inherited Clear;
end;
procedure TcxSchedulerCustomResourceViewHitTest.DoCalculate;
begin
inherited DoCalculate;
if HitAtControl then
View.ViewInfo.CalculateHitTest(Self);
end;
function TcxSchedulerCustomResourceViewHitTest.GetHitEvent: TcxSchedulerControlEvent;
begin
Result := inherited GetHitEvent;
if FEventCell <> nil then
Result := FEventCell.Event;
end;
procedure TcxSchedulerCustomResourceViewHitTest.SetHitTime(
AItemFlag: Integer; const ATime: TDateTime);
begin
SetBitState(AItemFlag, True);
SetBitState(htcTime, True);
FTime := ATime;
end;
procedure TcxSchedulerCustomResourceViewHitTest.SetResource(
AResource: TcxSchedulerResourceViewInfo);
begin
if AResource = nil then
FResource := nil
else
FResource := AResource.ResourceItem;
end;
procedure TcxSchedulerCustomResourceViewHitTest.ValidateDragKind;
begin
if (Event = nil) or ((FDragKind in [edkEventDragRect, edkMoveEvent]) and not CanMoveEvent(Event)) or
((FDragKind in [edkResizeStart, edkResizeEnd]) and not CanResizeEvent(Event)) then
FDragKind := edkNone;
end;
function TcxSchedulerCustomResourceViewHitTest.GetContentCell: TcxSchedulerContentCellViewInfo;
begin
if HitAtContent then
Result := TcxSchedulerContentCellViewInfo(FHitObject)
else
Result := nil;
end;
function TcxSchedulerCustomResourceViewHitTest.GetHeaderCell: TcxSchedulerHeaderCellViewInfo;
begin
if HitAtDayHeader or HitAtResourceHeader then
Result := TcxSchedulerHeaderCellViewInfo(FHitObject)
else
Result := nil;
end;
function TcxSchedulerCustomResourceViewHitTest.GetView: TcxSchedulerCustomResourceView;
begin
Result := TcxSchedulerCustomResourceView(inherited Owner);
end;
{ TcxSchedulerCustomViewPainter }
constructor TcxSchedulerCustomViewPainter.Create(
AOwner: TcxSchedulerSubControl);
begin
inherited Create(AOwner);
FPainter := View.GetCommonViewItemsPainter;
end;
procedure TcxSchedulerCustomViewPainter.Paint;
begin
end;
procedure TcxSchedulerCustomViewPainter.DrawBackgroundCell(
AItem: TcxSchedulerBackgroundCellViewInfo);
var
ADone: Boolean;
begin
if AItem = nil then Exit;
ADone := False;
AItem.BeforeCustomDraw(Canvas);
if Painter <> nil then
Painter.DoCustomDrawBackground(AItem, ADone);
if not ADone then
View.DoCustomDrawBackground(AItem, ADone);
AItem.AfterCustomDraw(Canvas);
if not ADone then
AItem.Draw(Canvas);
end;
procedure TcxSchedulerCustomViewPainter.DrawButtonCell(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean);
begin
if Painter <> nil then
Painter.DoCustomDrawButton(TcxSchedulerMoreEventsButtonViewInfo(AItem), ADone);
if not ADone then
View.DoCustomDrawButton(TcxSchedulerMoreEventsButtonViewInfo(AItem), ADone);
end;
procedure TcxSchedulerCustomViewPainter.DrawContentCell(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean);
begin
if Painter <> nil then
Painter.DoCustomDrawContent(TcxSchedulerContentCellViewInfo(AItem), ADone);
if not ADone then
View.DoCustomDrawContent(TcxSchedulerContentCellViewInfo(AItem), ADone);
end;
procedure TcxSchedulerCustomViewPainter.DrawEventCell(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean);
begin
with TcxSchedulerEventCellViewInfo(AItem) do
if Hidden or not Visible then Exit;
if Painter <> nil then
Painter.DoCustomDrawEvent(TcxSchedulerEventCellViewInfo(AItem), ADone);
if not ADone then
View.DoCustomDrawEvent(TcxSchedulerEventCellViewInfo(AItem), ADone);
end;
procedure TcxSchedulerCustomViewPainter.DrawHeaderCell(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean);
begin
if Painter <> nil then
Painter.DoCustomDrawDayHeader(TcxSchedulerDayHeaderCellViewInfo(AItem), ADone);
if not ADone then
View.DoCustomDrawDayHeader(TcxSchedulerDayHeaderCellViewInfo(AItem), ADone);
end;
procedure TcxSchedulerCustomViewPainter.DrawGroupSeparatorCell(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean);
begin
if Painter <> nil then
Painter.DoCustomDrawGroupSeparator(TcxSchedulerGroupSeparatorCellViewInfo(AItem), ADone);
if not ADone then
View.DoCustomDrawGroupSeparator(TcxSchedulerGroupSeparatorCellViewInfo(AItem), ADone);
end;
procedure TcxSchedulerCustomViewPainter.DrawResourceHeaderCell(
AItem: TcxSchedulerCustomViewInfoItem; var ADone: Boolean);
begin
if Painter <> nil then
Painter.DoCustomDrawResourceHeader(TcxSchedulerHeaderCellViewInfo(AItem), ADone);
if not ADone then
View.DoCustomDrawResourceHeader(TcxSchedulerHeaderCellViewInfo(AItem), ADone);
end;
function TcxSchedulerCustomViewPainter.GetView: TcxSchedulerCustomResourceView;
begin
Result := TcxSchedulerCustomResourceView(Owner);
end;
{ TcxSchedulerEventPlace }
procedure TcxSchedulerEventPlace.AlignPosition(APlace: TcxSchedulerEventPlace);
begin
LineFinish := APlace.LineFinish + 1 + (LineFinish - LineStart);
LineStart := APlace.LineFinish + 1;
end;
function TcxSchedulerEventPlace.IntersectHorz(APlace: TcxSchedulerEventPlace): Boolean;
begin
Result := (APlace.Resource = Resource) and (APlace.ColFinish >= ColStart) and
(APlace.ColStart <= ColFinish);
end;
function TcxSchedulerEventPlace.IntersectVert(APlace: TcxSchedulerEventPlace): Boolean;
begin
Result := (APlace.Resource = Resource) and (APlace.LineFinish >= LineStart) and
(APlace.LineStart <= LineFinish);
end;
procedure TcxSchedulerEventPlace.ResetPosition;
begin
LineFinish := LineFinish - LineStart;
LineStart := 0;
end;
function cxCompareEventPlaces(AEventPlace1, AEventPlace2: TcxSchedulerEventPlace): Integer;
var
AAllDay1, AAllDay2: Boolean;
AEvent1, AEvent2: TcxSchedulerEvent;
begin
Result := Integer(AEventPlace1.Resource) - Integer(AEventPlace1.Resource);
if Result <> 0 then Exit;
AEvent1 := AEventPlace1.Event;
AEvent2 := AEventPlace2.Event;
AAllDay1 := AEvent1.AllDayEvent or (AEvent1.Duration >= 1);
AAllDay2 := AEvent2.AllDayEvent or (AEvent2.Duration >= 1);
Result := Byte(AAllDay2) - Byte(AAllDay1);
if Result <> 0 then Exit;
if AEvent1.Start < AEvent2.Start then
Result := -1
else
if AEvent1.Start > AEvent2.Start then
Result := 1
else
if AEvent1.Finish > AEvent2.Finish then
Result := -1
else
if AEvent1.Finish < AEvent2.Finish then
Result := 1
else
if AEvent1.RecordIndex < AEvent2.RecordIndex then
Result := -1
else
if AEvent1.RecordIndex > AEvent2.RecordIndex then
Result := 1
else
Result := 0;
end;
{ TcxSchedulerEventLayoutBuilder }
constructor TcxSchedulerEventLayoutBuilder.Create;
begin
FEventPlaces := TcxObjectList.Create;
end;
destructor TcxSchedulerEventLayoutBuilder.Destroy;
begin
FreeAndNil(FEventPlaces);
inherited Destroy;
end;
function TcxSchedulerEventLayoutBuilder.AddEventPlace(AEvent: TcxSchedulerEvent;
AStartCol, AFinishCol: Integer; ALineCount: Integer = 1; AResource: TObject = nil): TcxSchedulerEventPlace;
begin
Result := TcxSchedulerEventPlace.Create;
Result.ColStart := AStartCol;
Result.ColFinish := AFinishCol;
Result.Event := AEvent;
Result.LineFinish := ALineCount - 1;
Result.Resource := AResource;
FEventPlaces.Add(Result);
end;
procedure TcxSchedulerEventLayoutBuilder.Clear;
begin
FEventPlaces.Clear;
end;
procedure TcxSchedulerEventLayoutBuilder.Calculate;
var
I, J, K: Integer;
ACurPlace: TcxSchedulerEventPlace;
begin
FEventPlaces.Sort(TListSortCompare(@cxCompareEventPlaces));
for I := 1 to EventPlaceCount - 1 do
begin
J := I;
K := I;
ACurPlace := EventPlaces[I];
repeat
Dec(J);
if ACurPlace.IntersectHorz(EventPlaces[J]) then K := J;
until J = 0;
ACurPlace.ResetPosition;
J := K;
while J < I do
begin
if ACurPlace.IntersectHorz(EventPlaces[J]) and ACurPlace.IntersectVert(EventPlaces[J]) then
begin
ACurPlace.AlignPosition(EventPlaces[J]);
J := K;
end
else
Inc(J);
end;
end;
end;
procedure TcxSchedulerEventLayoutBuilder.CalculateEx(AEventsList: TcxSchedulerFilteredEventList;
APlaceInfoProc: TcxSchedulerEventLayoutBuilderGetEventPlaceProc);
var
AEvent: TcxSchedulerControlEvent;
I, AStartCol, AFinishCol, ALineCount: Integer;
begin
Clear;
for I := 0 to AEventsList.Count - 1 do
begin
AEvent := AEventsList[I];
ALineCount := 1;
if APlaceInfoProc(Self, AEventsList[I], AStartCol, AFinishCol, ALineCount) then
AddEventPlace(AEvent, AStartCol, AFinishCol, ALineCount);
end;
Calculate;
end;
function TcxSchedulerEventLayoutBuilder.GetEventPlace(AIndex: Integer): TcxSchedulerEventPlace;
begin
Result := TcxSchedulerEventPlace(FEventPlaces.List^[AIndex]);
end;
function TcxSchedulerEventLayoutBuilder.GetEventPlaceCount: Integer;
begin
Result := FEventPlaces.Count;
end;
end.