2016-06-25 23:46:00 +00:00
|
|
|
{$I vp.inc}
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
unit VpDayViewPainter;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
SysUtils, LCLType, LCLIntf, Types,
|
2016-06-23 09:37:07 +00:00
|
|
|
Classes, Graphics, VpConst, VPBase, VpData, VpBasePainter, VpDayView;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
{ Defines matrix of event records for managing how events overlap with each other. }
|
|
|
|
TVpDvEventRec = packed record
|
|
|
|
Event: Pointer;
|
|
|
|
Level: Integer;
|
|
|
|
OLLevels: Integer; { Number of levels which overlap with the event represented by this record. }
|
|
|
|
WidthDivisor: Integer; { Maximum OLEvents of all of this event's overlapping neighbors. }
|
|
|
|
RealStartTime: TDateTime;
|
|
|
|
RealEndTime: TDateTime;
|
|
|
|
end;
|
|
|
|
|
|
|
|
TVpDvEventArray = array of TVpDvEventRec;
|
|
|
|
|
2016-06-23 09:37:07 +00:00
|
|
|
TVpDayViewPainter = class(TVpBasePainter)
|
2016-06-22 14:43:43 +00:00
|
|
|
private
|
|
|
|
FDayView: TVpDayView;
|
|
|
|
// local parameters of the old render procedure
|
|
|
|
ColHeadRect: TRect;
|
|
|
|
CellsRect: TRect;
|
|
|
|
RowHeadRect: TRect;
|
|
|
|
ADEventsRect: TRect;
|
|
|
|
Drawn: Boolean;
|
|
|
|
ScrollBarOffset: Integer;
|
|
|
|
EventCount: Integer;
|
|
|
|
DayWidth: Integer;
|
|
|
|
RealNumDays: Integer;
|
|
|
|
RealRowHeight: Integer;
|
|
|
|
RealColHeadHeight: Integer;
|
|
|
|
RealRowHeadWidth: Integer;
|
|
|
|
RealVisibleLines: Integer;
|
|
|
|
BevelShadow: TColor;
|
|
|
|
BevelHighlight: TColor;
|
|
|
|
BevelDarkShadow: TColor;
|
|
|
|
WindowColor: TColor;
|
|
|
|
HighlightText: TColor;
|
|
|
|
RealHeadAttrColor: TColor;
|
|
|
|
RealRowHeadAttrColor: TColor;
|
|
|
|
RealLineColor: TColor;
|
|
|
|
RealColor: TColor;
|
|
|
|
BevelFace: TColor;
|
|
|
|
HighlightBkg: TColor;
|
|
|
|
RealADEventBkgColor: TColor;
|
|
|
|
ADEventAttrBkgColor: TColor;
|
|
|
|
ADEventBorderColor: TColor;
|
|
|
|
// variables from local procedures for better access
|
|
|
|
dvBmpRecurring: TBitmap;
|
|
|
|
dvBmpCategory: TBitmap;
|
|
|
|
dvBmpAlarm: TBitmap;
|
|
|
|
dvBmpCustom: TBitmap;
|
|
|
|
RecurringW: Integer;
|
|
|
|
RecurringH: Integer;
|
|
|
|
CategoryW: Integer;
|
|
|
|
CategoryH: Integer;
|
|
|
|
AlarmW: Integer;
|
|
|
|
AlarmH: Integer;
|
|
|
|
CustomW: Integer;
|
|
|
|
CustomH: Integer;
|
2016-06-25 10:08:36 +00:00
|
|
|
EventArray: TVpDvEventArray;
|
|
|
|
VisibleRect: TRect;
|
|
|
|
LineDuration, PixelDuration: Double;
|
|
|
|
IconRect: TRect;
|
|
|
|
OldPen: TPen;
|
|
|
|
OldBrush: TBrush;
|
|
|
|
OldFont: TFont;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
protected
|
2016-06-27 23:00:17 +00:00
|
|
|
function BuildEventString(AEvent: TVpEvent; const AEventRect, AIconRect: TRect): String;
|
2016-06-26 13:52:59 +00:00
|
|
|
procedure CalcRowHeadRect(out ARect: TRect);
|
2016-07-04 19:21:55 +00:00
|
|
|
function CalcRowHeadWidth: Integer;
|
2016-06-27 23:00:17 +00:00
|
|
|
function CountOverlappingEvents(Event: TVpEvent; const EArray: TVpDvEventArray): Integer;
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure CreateBitmaps;
|
2016-06-26 08:14:09 +00:00
|
|
|
function DetermineIconRect(AEventRect: TRect): TRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
function GetMaxOLEvents(Event: TVpEvent; const EArray: TVpDvEventArray): Integer;
|
|
|
|
procedure DrawAllDayEvents;
|
|
|
|
procedure DrawCells(R: TRect; ColDate: TDateTime; Col: Integer);
|
|
|
|
procedure DrawColHeader(R: TRect; ARenderDate: TDateTime; Col: Integer);
|
2016-06-26 14:19:55 +00:00
|
|
|
procedure DrawEditFrame(R: TRect; AGutter, ALevel: Integer; AColor: TColor);
|
2016-06-30 18:45:39 +00:00
|
|
|
procedure DrawEvent(AEvent: TVpEvent; var AEventRec: TVpDvEventRec;
|
2016-06-25 10:08:36 +00:00
|
|
|
ARenderDate: TDateTime; Col: Integer);
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure DrawEvents(ARenderDate: TDateTime; Col: Integer);
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure DrawEventText(const AText: String; const AEventRect, AIconRect: TRect;
|
2016-06-26 11:37:20 +00:00
|
|
|
ALevel: Integer; AEventIsEditing: Boolean);
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure DrawIcons(AIconRect: TRect);
|
2016-06-26 13:52:59 +00:00
|
|
|
procedure DrawNavBtns;
|
|
|
|
procedure DrawNavBtnBackground;
|
2016-06-28 11:08:29 +00:00
|
|
|
procedure DrawRegularEvents;
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure DrawRowHeader(R: TRect);
|
2016-07-04 19:21:55 +00:00
|
|
|
procedure FixFontHeights;
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure FreeBitmaps;
|
|
|
|
procedure GetIcons(Event: TVpEvent);
|
2016-06-23 11:53:21 +00:00
|
|
|
procedure InitColors;
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure InitializeEventRectangles;
|
2016-06-26 11:37:20 +00:00
|
|
|
procedure PopulateEventArray(ARenderDate: TDateTime);
|
|
|
|
procedure PrepareEventRect(AWidthDivisor, ALevel: Integer;
|
2016-06-26 22:21:39 +00:00
|
|
|
var AEventRect: TRect);
|
2016-06-26 11:37:20 +00:00
|
|
|
procedure PrepareEventTimes(AEvent: TVpEvent; ARenderDate: TDateTime;
|
|
|
|
out AStartTime, AEndTime: TDateTime);
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure ScaleIcons(EventRect: TRect);
|
2016-06-23 11:53:21 +00:00
|
|
|
procedure SetMeasurements; override;
|
2016-06-26 16:27:01 +00:00
|
|
|
procedure VerifyMaxWidthDevisors;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create(ADayView: TVpDayview; ARenderCanvas: TCanvas);
|
|
|
|
procedure RenderToCanvas(ARenderIn: TRect; AAngle: TVpRotationAngle;
|
|
|
|
AScale: Extended; ARenderDate: TDateTime; AStartLine, AStopLine: Integer;
|
2016-06-23 09:37:07 +00:00
|
|
|
AUseGran: TVpGranularity; ADisplayOnly: Boolean); override;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2016-07-01 19:02:09 +00:00
|
|
|
StrUtils, Math, LazUtf8,
|
2016-06-22 14:43:43 +00:00
|
|
|
VpCanvasUtils, VpMisc;
|
|
|
|
|
2016-06-27 23:00:17 +00:00
|
|
|
const
|
|
|
|
ICON_MARGIN = 4;
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
type
|
|
|
|
TVpDayViewOpener = class(TVpDayView);
|
|
|
|
|
|
|
|
constructor TVpDayViewPainter.Create(ADayView: TVpDayView; ARenderCanvas: TCanvas);
|
|
|
|
begin
|
2016-06-23 09:37:07 +00:00
|
|
|
inherited Create(ARenderCanvas);
|
2016-06-22 14:43:43 +00:00
|
|
|
FDayView := ADayView;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
function TVpDayViewPainter.BuildEventString(AEvent: TVpEvent;
|
|
|
|
const AEventRect, AIconRect: TRect): String;
|
|
|
|
var
|
|
|
|
maxW: Integer;
|
|
|
|
timeFmt: String;
|
|
|
|
begin
|
|
|
|
if FDayView.ShowEventTimes then begin
|
|
|
|
timeFmt := IfThen(FDayView.TimeFormat = tf24Hour, 'h:nn', 'h:nnam/pm');
|
|
|
|
Result := Format('%s - %s: %s', [
|
|
|
|
FormatDateTime(timeFmt, AEvent.StartTime),
|
|
|
|
FormatDateTime(timeFmt, AEvent.EndTime),
|
|
|
|
AEvent.Description
|
|
|
|
]);
|
|
|
|
end else
|
|
|
|
Result := AEvent.Description;
|
|
|
|
|
|
|
|
if FDayView.WrapStyle = wsNone then begin
|
|
|
|
{ if the string is longer than the availble space then chop off the end
|
|
|
|
and place those little '...'s at the end }
|
|
|
|
maxW := AEventRect.Right - AIconRect.Right - Round(FDayView.GutterWidth * Scale) - TextMargin;
|
|
|
|
if RenderCanvas.TextWidth(Result) > maxW then
|
|
|
|
Result := GetDisplayString(RenderCanvas, Result, 0, maxW);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-28 11:08:29 +00:00
|
|
|
{ returns the number of events which overlap the specified event }
|
2016-06-22 14:43:43 +00:00
|
|
|
function TVpDayViewPainter.CountOverlappingEvents(Event: TVpEvent;
|
|
|
|
const EArray: TVpDvEventArray): Integer;
|
|
|
|
var
|
|
|
|
K, SelfLevel: Integer;
|
|
|
|
Tmp: TVpEvent;
|
|
|
|
Levels: array of Integer;
|
|
|
|
begin
|
|
|
|
{ initialize the levels array }
|
|
|
|
SetLength(Levels, MaxEventDepth);
|
|
|
|
for K := 0 to pred(MaxEventDepth) do
|
|
|
|
Levels[K] := 0;
|
|
|
|
result := 0;
|
|
|
|
{ First, simply count the number of overlapping events. }
|
|
|
|
K := 0;
|
|
|
|
SelfLevel := -1;
|
|
|
|
Tmp := TVpEvent(EArray[K].Event);
|
|
|
|
while Tmp <> nil do begin
|
|
|
|
if Tmp = Event then begin
|
|
|
|
SelfLevel := K;
|
|
|
|
Inc(K);
|
|
|
|
Tmp := TVpEvent(EArray[K].Event);
|
|
|
|
Continue;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ if the Tmp event's StartTime or EndTime falls within the range of }
|
|
|
|
{ Event... }
|
|
|
|
if TimeInRange(frac(Tmp.StartTime), frac(Event.StartTime), frac(Event.EndTime), false) or
|
|
|
|
TimeInRange(frac(Tmp.EndTime), frac(Event.StartTime), frac(Event.EndTime), false) or
|
|
|
|
{ or the Tmp event's StartTime is before or equal to the Event's }
|
|
|
|
{ start time AND its end time is after or equal to the Event's }
|
|
|
|
{ end time, then the events overlap and we will need to increment }
|
|
|
|
{ the value of K. }
|
|
|
|
((frac(Tmp.StartTime) <= frac(Event.StartTime)) and (frac(Tmp.EndTime) >= frac(Event.EndTime)))
|
|
|
|
then begin
|
|
|
|
{ Count this event at this level }
|
|
|
|
Inc(Levels[EArray[K].Level]);
|
|
|
|
Inc(result);
|
|
|
|
end;
|
|
|
|
|
|
|
|
Inc(K);
|
|
|
|
Tmp := TVpEvent(EArray[K].Event);
|
|
|
|
end;
|
|
|
|
{ Then adjust count for overlapping events which share a level. }
|
|
|
|
for K := 0 to pred(MaxEventDepth) do begin
|
|
|
|
if K = SelfLevel then Continue;
|
|
|
|
if Levels[K] = 0 then Continue;
|
|
|
|
result := result - (Levels[K] - 1);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.CreateBitmaps;
|
|
|
|
begin
|
|
|
|
dvBmpRecurring := TBitmap.Create;
|
|
|
|
dvBmpCategory := TBitmap.Create;
|
|
|
|
dvBmpAlarm := TBitmap.Create;
|
|
|
|
dvBmpCustom := TBitmap.Create;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 08:14:09 +00:00
|
|
|
function TVpDayViewPainter.DetermineIconRect(AEventRect: TRect): TRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
var
|
|
|
|
MaxHeight: Integer;
|
|
|
|
begin
|
|
|
|
Result.Left := AEventRect.Left;
|
|
|
|
Result.Top := AEventRect.Top;
|
|
|
|
Result.Bottom := AEventRect.Bottom;
|
2016-06-27 23:00:17 +00:00
|
|
|
Result.Right := AEventRect.Left + AlarmW + RecurringW + CategoryW + CustomW + ICON_MARGIN + 2;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
2016-06-27 23:00:17 +00:00
|
|
|
MaxHeight := AlarmH + ICON_MARGIN;
|
|
|
|
if RecurringH + ICON_MARGIN > MaxHeight then
|
2016-06-22 14:43:43 +00:00
|
|
|
MaxHeight := dvBmpRecurring.Height;
|
2016-06-27 23:00:17 +00:00
|
|
|
if CategoryH + ICON_MARGIN > MaxHeight then
|
2016-06-22 14:43:43 +00:00
|
|
|
MaxHeight := dvBmpCategory.Height;
|
2016-06-27 23:00:17 +00:00
|
|
|
if CustomH + ICON_MARGIN > MaxHeight then
|
2016-06-22 14:43:43 +00:00
|
|
|
MaxHeight := dvBmpCustom.Height;
|
|
|
|
if MaxHeight > AEventRect.Bottom - AEventRect.Top then
|
|
|
|
MaxHeight := AEventRect.Bottom - AEventRect.Top;
|
|
|
|
|
|
|
|
Result.Bottom := AEventRect.Top + MaxHeight;
|
|
|
|
if Result.Right > AEventRect.Right then
|
|
|
|
Result.Right := AEventRect.Right;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ returns the maximum OLEvents value from all overlapping neighbors }
|
|
|
|
function TVpDayViewPainter.GetMaxOLEvents(Event: TVpEvent; const EArray: TVpDvEventArray): Integer;
|
|
|
|
var
|
|
|
|
K: Integer;
|
|
|
|
Tmp: TVpEvent;
|
|
|
|
begin
|
|
|
|
result := 1;
|
|
|
|
K := 0;
|
|
|
|
Tmp := TVpEvent(EArray[K].Event);
|
|
|
|
while Tmp <> nil do begin
|
|
|
|
{ if the Tmp event's StartTime or EndTime falls within the range of Event. }
|
|
|
|
if TimeInRange(frac(Tmp.StartTime), frac(Event.StartTime), frac(Event.EndTime), false) or
|
|
|
|
TimeInRange(frac(Tmp.EndTime), frac(Event.StartTime), frac(Event.EndTime), false) or
|
|
|
|
{ or the Tmp event's StartTime is before or equal to the Event's }
|
|
|
|
{ start time AND its end time is after or equal to the Event's }
|
|
|
|
{ end time, then the events overlap and we will need to check the }
|
|
|
|
{ value of OLLevels. If it is bigger than result, then modify }
|
|
|
|
{ Result accordingly. }
|
|
|
|
((frac(Tmp.StartTime) <= frac(Event.StartTime)) and (frac(Tmp.EndTime) >= frac(Event.EndTime)))
|
|
|
|
then begin
|
|
|
|
if EArray[K].OLLevels > result then
|
|
|
|
Result := EArray[K].OLLevels;
|
|
|
|
end;
|
|
|
|
|
|
|
|
Inc(K);
|
|
|
|
Tmp := TVpEvent(EArray[K].Event);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
{ Draws the all-day events at the top of the DayView in a special manner }
|
|
|
|
procedure TVpDayViewPainter.DrawAllDayEvents;
|
|
|
|
var
|
|
|
|
ADEventsList: TList;
|
|
|
|
TempList: TList;
|
|
|
|
I, J, K: Integer;
|
|
|
|
Event: TVpEvent;
|
|
|
|
ADEventRect: TRect;
|
|
|
|
StartsBeforeRange : Boolean;
|
|
|
|
MaxADEvents: Integer;
|
|
|
|
Skip: Boolean;
|
|
|
|
ADTextHeight: Integer;
|
|
|
|
EventStr: string;
|
|
|
|
I2: Integer;
|
|
|
|
DI: Integer;
|
|
|
|
AllDayWidth: Integer;
|
|
|
|
OldTop: LongInt;
|
|
|
|
begin
|
|
|
|
if (FDayView.DataStore = nil) or (FDayView.DataStore.Resource = nil) then
|
|
|
|
Exit;
|
|
|
|
|
|
|
|
{ Collect all of the events for this range and determine the maximum }
|
|
|
|
{ number of all day events for the range of days covered by the control. }
|
|
|
|
MaxADEvents := 0;
|
|
|
|
|
|
|
|
AllDayWidth := RealWidth - RealRowHeadWidth - 1 - ScrollBarOffset;
|
|
|
|
DayWidth := AllDayWidth div FDayView.NumDays;
|
|
|
|
|
|
|
|
ADEventsList := TList.Create;
|
|
|
|
try
|
|
|
|
TempList := TList.Create;
|
|
|
|
try
|
|
|
|
for I := 0 to pred(RealNumDays) do begin
|
|
|
|
{ skip weekends }
|
|
|
|
if ((DayOfWeek (RenderDate + i) = 1) or (DayOfWeek (RenderDate + i) = 7)) and
|
|
|
|
(not FDayView.IncludeWeekends)
|
|
|
|
then
|
|
|
|
Continue;
|
|
|
|
|
|
|
|
{ get the all day events for the day specified by RenderDate + I }
|
|
|
|
FDayView.DataStore.Resource.Schedule.AllDayEventsByDate(RenderDate + I, TempList);
|
|
|
|
|
|
|
|
{ Iterate through these events and place them in ADEventsList }
|
|
|
|
Skip := false;
|
|
|
|
for J := 0 to pred(TempList.Count) do begin
|
|
|
|
if AdEventsList.Count > 0 then begin
|
|
|
|
for K := 0 to pred(AdEventsList.Count) do begin
|
|
|
|
if TVpEvent(AdEventsList[K]) = TVpEvent(TempList[J]) then begin
|
|
|
|
Skip := true;
|
|
|
|
Break;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
if not Skip then
|
|
|
|
AdEventsList.Add(TempList[J]);
|
|
|
|
end else
|
|
|
|
AdEventsList.Add(TempList[J]);
|
|
|
|
end;
|
|
|
|
|
|
|
|
if TempList.Count > MaxADEvents then
|
|
|
|
MaxADEvents := TempList.Count;
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
TempList.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if MaxADEvents > 0 then begin
|
|
|
|
RenderCanvas.Brush.Color := RealADEventBkgColor;
|
|
|
|
RenderCanvas.Font.Assign(FDayView.AllDayEventAttributes.Font);
|
|
|
|
|
|
|
|
{ Measure the AllDayEvent TextHeight }
|
|
|
|
ADTextHeight := RenderCanvas.TextHeight(VpProductName) + TextMargin;
|
|
|
|
|
|
|
|
{ set the top of the event's rect }
|
|
|
|
OldTop := ADEventsRect.Top;
|
|
|
|
AdEventRect.Top := OldTop + TextMargin + I * ADTextHeight;
|
|
|
|
|
|
|
|
{ Build the AllDayEvent rect based on the value of MaxADEvents }
|
|
|
|
ADEventsRect.Bottom := AdEventsRect.Top + MaxADEvents * ADTextHeight + TextMargin * 2;
|
|
|
|
|
|
|
|
{ Clear the AllDayEvents area }
|
|
|
|
TpsFillRect(RenderCanvas, Angle, RenderIn, ADEventsRect);
|
|
|
|
|
|
|
|
for I := 0 to pred(RealNumDays) do begin
|
|
|
|
{ Set attributes }
|
|
|
|
StartsBeforeRange := false;
|
|
|
|
DI := 0;
|
|
|
|
{ Cycle through the all day events and draw them appropriately }
|
|
|
|
for I2 := 0 to pred(ADEventsList.Count) do begin
|
|
|
|
Event := ADEventsList[I2];
|
|
|
|
if (trunc(Event.StartTime)<=(trunc(RenderDate)+I)) and
|
|
|
|
(trunc(Event.EndTime)>=(trunc(RenderDate)+I))
|
|
|
|
then begin
|
|
|
|
{ set the top of the event's rect }
|
|
|
|
AdEventRect.Top := OldTop + TextMargin + DI * ADTextHeight;
|
|
|
|
inc(DI);
|
|
|
|
|
|
|
|
{ see if the event began before the start of the range }
|
|
|
|
if (Event.StartTime < trunc(RenderDate)) then
|
|
|
|
StartsBeforeRange := true;
|
|
|
|
|
|
|
|
AdEventRect.Bottom := ADEventRect.Top + ADTextHeight;
|
|
|
|
AdEventRect.Left := AdEventsRect.Left + DayWidth*I + TextMargin div 2;
|
|
|
|
AdEventRect.Right := AdEventRect.Left+DayWidth;
|
|
|
|
|
|
|
|
if StartsBeforeRange then
|
|
|
|
EventStr := '>> '
|
|
|
|
else
|
|
|
|
EventStr := '';
|
|
|
|
|
|
|
|
EventStr := EventStr + Event.Description;
|
|
|
|
|
|
|
|
RenderCanvas.Brush.Color := ADEventAttrBkgColor;
|
|
|
|
RenderCanvas.Pen.Color := ADEventBorderColor;
|
|
|
|
TPSRectangle(RenderCanvas, Angle, RenderIn,
|
|
|
|
ADEventRect.Left + TextMargin,
|
|
|
|
ADEventRect.Top + TextMargin div 2,
|
|
|
|
ADEventRect.Right - TextMargin,
|
|
|
|
ADEventRect.Top + ADTextHeight + TextMargin div 2
|
|
|
|
);
|
|
|
|
TPSTextOut(RenderCanvas,Angle, RenderIn,
|
|
|
|
AdEventRect.Left + TextMargin * 2 + TextMargin div 2,
|
|
|
|
AdEventRect.Top + TextMargin div 2,
|
|
|
|
EventStr
|
|
|
|
);
|
|
|
|
|
2016-06-23 09:37:07 +00:00
|
|
|
TVpDayViewOpener(FDayView).dvEventArray[EventCount].Rec := Rect(
|
2016-06-22 14:43:43 +00:00
|
|
|
ADEventRect.Left,
|
|
|
|
ADEventRect.Top - 2,
|
|
|
|
ADEventRect.Right - TextMargin,
|
|
|
|
ADEventRect.Bottom
|
|
|
|
);
|
2016-06-23 09:37:07 +00:00
|
|
|
TVpDayViewOpener(FDayView).dvEventArray[EventCount].Event := Event;
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
Inc(EventCount);
|
|
|
|
end;
|
|
|
|
end; { for I2 := 0 to pred(ADEventsList.Count) do ... }
|
|
|
|
end;
|
|
|
|
end; { if MaxADEvents > 0 }
|
|
|
|
|
|
|
|
finally
|
|
|
|
ADEventsList.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.DrawCells(R: TRect; ColDate: TDateTime; Col: Integer);
|
|
|
|
var
|
|
|
|
I: Integer;
|
|
|
|
LineRect: TRect;
|
|
|
|
SavedFont: TFont;
|
|
|
|
GutterRect: TRect;
|
2016-07-03 09:36:40 +00:00
|
|
|
tmpRect: TRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
LineStartTime: Double;
|
|
|
|
begin
|
|
|
|
if StartLine < 0 then
|
|
|
|
StartLine := FDayView.TopLine;
|
|
|
|
|
2016-07-01 10:04:08 +00:00
|
|
|
dec(R.Top);
|
2016-07-01 15:19:38 +00:00
|
|
|
inc(R.Bottom);
|
2016-07-01 10:04:08 +00:00
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
{ Set GutterRect size }
|
|
|
|
GutterRect.Left := R.Left;
|
|
|
|
GutterRect.Top := R.Top;
|
|
|
|
GutterRect.Bottom := R.Bottom;
|
|
|
|
GutterRect.Right := GutterRect.Left + Round(FDayView.GutterWidth * Scale);
|
|
|
|
R.Left := R.Left + Round(FDayView.GutterWidth * Scale) + 1;
|
|
|
|
|
|
|
|
{ paint gutter area }
|
|
|
|
RenderCanvas.Brush.Color := RealColor;
|
2016-07-03 09:36:40 +00:00
|
|
|
tmpRect := GutterRect;
|
|
|
|
if FDayView.DrawingStyle = dsNoBorder then
|
|
|
|
inc(tmpRect.Bottom);
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, tmpRect);
|
2016-07-01 15:19:38 +00:00
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
{ draw the line down the right side of the gutter }
|
|
|
|
RenderCanvas.Pen.Color := BevelShadow;
|
|
|
|
RenderCanvas.Pen.Style := psSolid;
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, GutterRect.Right, GutterRect.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, GutterRect.Right, GutterRect.Bottom);
|
|
|
|
|
2016-07-03 09:36:40 +00:00
|
|
|
for I := 0 to FDayView.LineCount do begin // don't subtract 1 because of partially filled last line
|
2016-06-23 09:37:07 +00:00
|
|
|
with TVpDayViewOpener(FDayView) do begin
|
|
|
|
dvLineMatrix[Col, I].Rec.Left := -1;
|
|
|
|
dvLineMatrix[Col, I].Rec.Top := -1;
|
|
|
|
dvLineMatrix[Col, I].Rec.Right := -1;
|
|
|
|
dvLineMatrix[Col, I].Rec.Bottom := -1;
|
|
|
|
end;
|
2016-06-22 14:43:43 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
SavedFont := TFont.Create;
|
|
|
|
SavedFont.Assign(RenderCanvas.Font);
|
|
|
|
try
|
|
|
|
RenderCanvas.Font.Assign(FDayView.Font);
|
|
|
|
RenderCanvas.Brush.Color := RealColor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
|
|
|
|
|
|
|
LineRect := Rect(R.left, R.top, R.Right, R.Top + RealRowHeight);
|
|
|
|
RenderCanvas.Pen.Style := psSolid;
|
|
|
|
RenderCanvas.Pen.Color := FDayView.LineColor;
|
|
|
|
|
|
|
|
{ Paint the client area }
|
2016-07-02 15:44:34 +00:00
|
|
|
for I := 0 to RealVisibleLines + 1 do begin // +1 to show the partial line at the bottom
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
if (I > pred(FDayView.LineCount)) then
|
|
|
|
Break;
|
|
|
|
|
|
|
|
if FDayView.TopLine + i >= FDayView.LineCount then
|
|
|
|
Break;
|
|
|
|
|
|
|
|
RenderCanvas.Brush.Color := RealColor;
|
|
|
|
RenderCanvas.Font.Assign(SavedFont);
|
2016-07-01 15:19:38 +00:00
|
|
|
LineRect.Top := Round(R.Top + i * RealRowHeight);
|
|
|
|
LineRect.Bottom := Round(LineRect.Top + RealRowHeight);
|
2016-06-22 14:43:43 +00:00
|
|
|
if I + StartLine < FDayView.LineCount then
|
2016-06-23 09:37:07 +00:00
|
|
|
TVpDayViewOpener(FDayView).dvLineMatrix[Col, I + StartLine].Rec := LineRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
{ color-code cells }
|
|
|
|
|
|
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
// !!!! This causes problems at design time - implement a better !!!!
|
|
|
|
// !!!! Fix - check the value after the component is streamed in !!!!
|
|
|
|
// !!!! May be a good use for ... loaded or in my message !!!!
|
|
|
|
// !!!! Handler (the message handler would be better !!!!
|
|
|
|
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
// if ActiveRow = -1 then
|
|
|
|
// ActiveRow := TopLine;
|
|
|
|
|
2016-07-01 15:19:38 +00:00
|
|
|
if i = 0 then
|
|
|
|
dec(LineRect.Top);
|
2016-06-22 14:43:43 +00:00
|
|
|
if not DisplayOnly then begin
|
|
|
|
if FDayView.Focused and (FDayView.ActiveCol = col) and
|
|
|
|
(FDayView.ActiveRow = StartLine + I)
|
|
|
|
then begin
|
|
|
|
{ Paint background hilight color }
|
|
|
|
RenderCanvas.Brush.Color := HighlightBkg;
|
|
|
|
RenderCanvas.Font.Color := HighlightText;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, LineRect);
|
|
|
|
end else begin
|
|
|
|
{ paint the active, inactive, weekend, and holiday colors }
|
|
|
|
|
|
|
|
{ HOLIDAY COLORS ARE NOT IMPLEMENTED YET }
|
|
|
|
|
|
|
|
{ if ColDate is a weekend, then paint all rows the weekend }
|
|
|
|
{ color. }
|
|
|
|
if (DayOfWeek(ColDate) = 1) or (DayOfWeek(ColDate) = 7) then begin
|
|
|
|
{ this is a weekend }
|
|
|
|
RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Weekend;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, LineRect);
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
{ ColDate is a weekday, so check to see if the active }
|
|
|
|
{ range is set. If it isn't then paint all rows the color }
|
|
|
|
{ corresponding to Weekday. If it is, then paint inactive }
|
|
|
|
{ rows the color corresponding to inactive and the active }
|
|
|
|
{ rows the color corresponding to Active Rows. }
|
|
|
|
if FDayView.TimeSlotColors.ActiveRange.RangeBegin = FDayView.TimeSlotColors.ActiveRange.RangeEnd then
|
|
|
|
begin
|
|
|
|
{ there is no active range, so all time slots are to be }
|
|
|
|
{ painted the color of Weekday }
|
|
|
|
RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Weekday;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, LineRect);
|
|
|
|
end
|
|
|
|
else begin
|
|
|
|
{ there is an active range defined, so we need to see if }
|
|
|
|
{ the current line falls in the active range or not, and }
|
|
|
|
{ paint it accordingly }
|
2016-06-23 09:37:07 +00:00
|
|
|
LineStartTime := TVpDayViewOpener(FDayView).dvLineMatrix[Col, StartLine + I].Time;
|
2016-06-22 14:43:43 +00:00
|
|
|
if TimeInRange(LineStartTime,
|
|
|
|
FDayView.TimeSlotColors.ActiveRange.StartTime,
|
|
|
|
FDayView.TimeSlotColors.ActiveRange.EndTime - (1/MinutesInDay), true)
|
|
|
|
then begin
|
|
|
|
RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Active;
|
|
|
|
TPSFillRect (RenderCanvas, Angle, RenderIn, LineRect);
|
|
|
|
end else begin
|
|
|
|
RenderCanvas.Brush.Color := FDayView.TimeSlotColors.Inactive;
|
|
|
|
TPSFillRect (RenderCanvas, Angle, RenderIn, LineRect);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ Draw the lines }
|
|
|
|
if I + StartLine <= FDayView.LineCount then begin
|
|
|
|
RenderCanvas.Pen.Color := FDayView.LineColor;
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, LineRect.Left, LineRect.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, LineRect.Right - 1, LineRect.Top);
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, LineRect.Left, LineRect.Bottom);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, LineRect.Right - 1, LineRect.Bottom);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ Draw a line down the right side of the column to close the }
|
|
|
|
{ cells right sides }
|
|
|
|
RenderCanvas.Pen.Color := BevelShadow;
|
|
|
|
RenderCanvas.Pen.Style := psSolid;
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Bottom);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Top - 1);
|
|
|
|
|
|
|
|
finally
|
2016-06-30 18:45:39 +00:00
|
|
|
RenderCanvas.Font.Assign(SavedFont);
|
2016-06-22 14:43:43 +00:00
|
|
|
SavedFont.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.DrawColHeader(R: TRect; ARenderDate: TDateTime;
|
|
|
|
Col: Integer);
|
|
|
|
var
|
|
|
|
SaveFont: TFont;
|
|
|
|
DateStr, ResStr: string;
|
|
|
|
DateStrLen, ResStrLen: integer;
|
|
|
|
StrHt: Integer;
|
|
|
|
TextRect: TRect;
|
|
|
|
X, Y: Integer;
|
2016-07-01 10:04:08 +00:00
|
|
|
tmpRect: TRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
begin
|
|
|
|
SaveFont := TFont.Create;
|
|
|
|
try
|
|
|
|
SaveFont.Assign(RenderCanvas.Font);
|
2016-07-01 10:04:08 +00:00
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
{ Draw Column Header }
|
|
|
|
RenderCanvas.Font.Assign(FDayView.HeadAttributes.Font);
|
|
|
|
RenderCanvas.Brush.Color := RealHeadAttrColor;
|
|
|
|
RenderCanvas.Pen.Style := psClear;
|
2016-07-01 10:04:08 +00:00
|
|
|
tmpRect := R;
|
|
|
|
InflateRect(tmpRect, 1, 1);
|
|
|
|
inc(tmpRect.Left);
|
2016-07-03 09:36:40 +00:00
|
|
|
if FDayView.DrawingStyle = dsNoBorder then
|
|
|
|
InflateRect(tmpRect, 1, 1);
|
2016-07-01 10:04:08 +00:00
|
|
|
TPSRectangle(RenderCanvas, Angle, RenderIn, tmpRect);
|
2016-06-22 14:43:43 +00:00
|
|
|
RenderCanvas.Pen.Style := psSolid;
|
|
|
|
|
|
|
|
{ Size text rect }
|
|
|
|
TextRect.TopLeft := R.TopLeft;
|
|
|
|
TextRect.BottomRight := R.BottomRight;
|
|
|
|
TextRect.Right := TextRect.Right - 3;
|
|
|
|
TextRect.Left := TextRect.Left + 2;
|
|
|
|
|
|
|
|
{ Fix Date String }
|
|
|
|
DateStr := FormatDateTime(FDayView.DateLabelFormat, ARenderDate);
|
|
|
|
DateStrLen := RenderCanvas.TextWidth(DateStr);
|
|
|
|
StrHt := RenderCanvas.TextHeight(DateStr);
|
|
|
|
if DateStrLen > TextRect.Right - TextRect.Left then begin
|
|
|
|
DateStr := GetDisplayString(RenderCanvas, DateStr, 0, TextRect.Right - TextRect.Left);
|
|
|
|
DateStrLen := RenderCanvas.TextWidth(DateStr);
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (FDayView.DataStore <> nil) and (FDayView.DataStore.Resource <> nil)
|
|
|
|
and FDayView.ShowResourceName
|
|
|
|
then begin
|
|
|
|
{ fix Res String }
|
|
|
|
ResStr := FDayView.DataStore.Resource.Description;
|
|
|
|
ResStrLen := RenderCanvas.TextWidth(ResStr);
|
|
|
|
if ResStrLen > TextRect.Right - TextRect.Left then begin
|
|
|
|
ResStr := GetDisplayString(RenderCanvas, ResStr, 0, TextRect.Right - TextRect.Left);
|
|
|
|
ResStrLen := RenderCanvas.TextWidth(ResStr);
|
|
|
|
end;
|
|
|
|
{ center and write the resource name in the first column }
|
|
|
|
if (Col = 0) then begin
|
|
|
|
X := TextRect.Left + (TextRect.Right - TextRect.Left) div 2 - ResStrLen div 2;
|
|
|
|
Y := TextRect.Top + TextMargin;
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, X, Y, FDayView.DataStore.Resource.Description);
|
|
|
|
end;
|
2016-07-01 10:04:08 +00:00
|
|
|
{ center the date string }
|
2016-06-22 14:43:43 +00:00
|
|
|
X := TextRect.Left + (TextRect.Right - TextRect.Left) div 2 - DateStrLen div 2;
|
|
|
|
Y := TextRect.Top + (TextMargin * 2) + StrHt;
|
|
|
|
end else begin
|
2016-07-01 10:04:08 +00:00
|
|
|
{ center the date string }
|
2016-06-22 14:43:43 +00:00
|
|
|
Y := TextRect.Top + TextMargin;
|
|
|
|
X := TextRect.Left + (TextRect.Right - TextRect.Left) div 2 - DateStrLen div 2;
|
|
|
|
end;
|
2016-07-01 10:04:08 +00:00
|
|
|
{ Write the date string }
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, X, Y, DateStr);
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
{Draw Column Head Borders }
|
|
|
|
if FDayView.DrawingStyle = dsFlat then begin
|
2016-07-01 10:04:08 +00:00
|
|
|
// bottom
|
2016-06-22 14:43:43 +00:00
|
|
|
RenderCanvas.Pen.Color := BevelShadow;
|
2016-07-01 15:19:38 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom - 1);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Left - 2, R.Bottom - 1);
|
2016-07-01 10:04:08 +00:00
|
|
|
// right side
|
2016-07-01 15:19:38 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom - 1);
|
2016-07-01 10:04:08 +00:00
|
|
|
RenderCanvas.Pen.Color := RealHeadAttrColor;
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom - 4);
|
|
|
|
RenderCanvas.Pen.Color := BevelShadow;
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top + 2);
|
|
|
|
RenderCanvas.Pen.Color := RealHeadAttrColor;
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top);
|
2016-06-22 14:43:43 +00:00
|
|
|
end
|
|
|
|
else
|
|
|
|
if FDayView.DrawingStyle = ds3d then begin
|
2016-07-01 15:19:38 +00:00
|
|
|
dec(R.Bottom);
|
2016-07-02 13:07:46 +00:00
|
|
|
if Col = FDayView.NumDays - 1 then
|
|
|
|
dec(R.Right, 4);
|
2016-07-01 10:04:08 +00:00
|
|
|
R := TPSRotateRectangle(Angle, RenderIn, R);
|
|
|
|
DrawBevelRect(RenderCanvas, R, BevelHighlight, BevelDarkShadow);
|
2016-06-22 14:43:43 +00:00
|
|
|
end;
|
|
|
|
RenderCanvas.Font.Assign(SaveFont);
|
|
|
|
finally
|
|
|
|
SaveFont.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-24 19:37:53 +00:00
|
|
|
{ paint extra borders around the editor }
|
2016-06-26 14:19:55 +00:00
|
|
|
procedure TVpDayViewPainter.DrawEditFrame(R: TRect; AGutter, ALevel: Integer;
|
2016-06-24 19:37:53 +00:00
|
|
|
AColor: TColor);
|
|
|
|
begin
|
|
|
|
RenderCanvas.Pen.Color := clWindowFrame;
|
|
|
|
RenderCanvas.Brush.Color := AColor;
|
2016-06-26 14:19:55 +00:00
|
|
|
if ALevel = 0 then
|
|
|
|
with R do begin
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Left, Top-AGutter, Right, Top));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Left-AGutter, Top, Left, Bottom));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Left, Bottom, Right, Bottom + AGutter));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Right, Top, Right+AGutter, Bottom));
|
|
|
|
end
|
|
|
|
else
|
|
|
|
with R do begin
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Left+AGutter, Top-AGutter, Right, Top));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Left, Top, Left, Bottom));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Left+AGutter, Bottom, Right, Bottom + AGutter));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, Rect(Right, Top, Right+AGutter, Bottom));
|
|
|
|
end;
|
2016-06-24 19:37:53 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-30 18:45:39 +00:00
|
|
|
procedure TVpDayViewPainter.DrawEvent(AEvent: TVpEvent; var AEventRec: TVpDvEventRec;
|
2016-06-25 10:08:36 +00:00
|
|
|
ARenderDate: TDateTime; Col: Integer);
|
2016-06-22 14:43:43 +00:00
|
|
|
var
|
2016-06-25 10:08:36 +00:00
|
|
|
EventCategory: TVpCategoryInfo;
|
|
|
|
EventIsEditing: Boolean;
|
|
|
|
EventSTime, EventETime: Double;
|
|
|
|
EventDuration: Double;
|
|
|
|
EventSLine, EventELine, EventLineCount: Integer;
|
|
|
|
EventRect, GutterRect: TRect;
|
|
|
|
StartPixelOffset, EndPixelOffset: Integer;
|
|
|
|
StartOffset, EndOffset: Double;
|
|
|
|
EventString: String;
|
|
|
|
tmpRect: TRect;
|
|
|
|
begin
|
|
|
|
{ Initialize, collect useful information needed later }
|
|
|
|
EventCategory := FDayView.Datastore.CategoryColorMap.GetCategory(AEvent.Category);
|
|
|
|
|
|
|
|
with TVpDayViewOpener(FDayView) do
|
|
|
|
if (dvInplaceEditor <> nil) and dvInplaceEditor.Visible then
|
2016-06-26 08:14:09 +00:00
|
|
|
EventIsEditing := (ActiveEvent = AEvent)
|
|
|
|
else
|
|
|
|
EventIsEditing := false;
|
2016-06-25 10:08:36 +00:00
|
|
|
|
|
|
|
{ remove the date portion from the start and end times }
|
2016-06-26 11:37:20 +00:00
|
|
|
PrepareEventTimes(AEvent, ARenderDate, EventSTime, EventETime);
|
2016-06-30 18:45:39 +00:00
|
|
|
AEventRec.RealStartTime := EventSTime;
|
|
|
|
AEventRec.RealEndTime := EventETime;
|
2016-06-25 10:08:36 +00:00
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
{ Find the lines on which this event starts and ends }
|
2016-06-25 10:08:36 +00:00
|
|
|
EventSLine := GetStartLine(EventSTime, FDayView.Granularity);
|
2016-06-26 11:37:20 +00:00
|
|
|
EventELine := GetEndLine(EventETime, FDayView.Granularity);
|
2016-06-25 10:08:36 +00:00
|
|
|
|
|
|
|
{ If the event doesn't occupy area that is currently visible, then skip it. }
|
2016-07-02 15:44:34 +00:00
|
|
|
if (EventELine < StartLine) or (EventSLine > StartLine + RealVisibleLines + 1) then
|
2016-06-25 10:08:36 +00:00
|
|
|
Exit;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
{ Calculate the number of lines this event will cover }
|
|
|
|
EventLineCount := EventELine - EventSLine + 1;
|
|
|
|
EventDuration := EventETime - EventSTime;
|
|
|
|
|
2016-06-25 10:08:36 +00:00
|
|
|
{ Build the rectangle in which the event will be painted. }
|
|
|
|
EventRect := TVpDayViewOpener(FDayView).dvLineMatrix[Col, EventSLine].Rec;
|
|
|
|
EventRect.Bottom := TVpDayViewOpener(FDayView).dvLineMatrix[Col, EventELine].Rec.Bottom;
|
2016-06-26 22:21:39 +00:00
|
|
|
PrepareEventRect(AEventRec.WidthDivisor, AEventRec.Level, EventRect);
|
2016-06-25 10:08:36 +00:00
|
|
|
|
|
|
|
{ Draw the event rectangle }
|
|
|
|
if Assigned(FDayView.DataStore) then begin
|
|
|
|
if EventIsEditing then
|
|
|
|
RenderCanvas.Brush.Color := WindowColor
|
|
|
|
else
|
|
|
|
RenderCanvas.Brush.Color := EventCategory.BackgroundColor
|
|
|
|
end else
|
|
|
|
RenderCanvas.Brush.Color := WindowColor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, EventRect);
|
|
|
|
|
2016-07-03 09:36:40 +00:00
|
|
|
{ Paint the little area to the left of the text the color corresponding to
|
2016-06-25 10:08:36 +00:00
|
|
|
the event's category. These colors are used even when printing }
|
|
|
|
if Assigned(FDayView.DataStore) then
|
|
|
|
RenderCanvas.Brush.Color := EventCategory.Color;
|
|
|
|
|
|
|
|
{ find the pixel offset to use for determining where to start and }
|
|
|
|
{ stop drawing colored area according to the start time and end time of the event. }
|
|
|
|
StartPixelOffset := 0;
|
|
|
|
EndPixelOffset := 0;
|
|
|
|
if (PixelDuration > 0) and (EventDuration < GetLineDuration(FDayView.Granularity) * EventLineCount)
|
|
|
|
then begin
|
|
|
|
if (EventSLine >= StartLine) and (EventSTime > TVpDayViewOpener(FDayView).dvLineMatrix[0, EventSLine].Time)
|
|
|
|
then begin
|
|
|
|
{ Get the start offset in TDateTime format }
|
|
|
|
StartOffset := EventSTime - TVpDayViewOpener(FDayView).dvLineMatrix[0, EventSLine].Time;
|
|
|
|
{ determine how many pixels to scooch down before painting the event's color code. }
|
|
|
|
StartPixelOffset := trunc(StartOffset / PixelDuration);
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (EventELine <= StartLine + RealVisibleLines) and
|
|
|
|
(EventETime < TVpDayViewOpener(FDayView).dvLineMatrix[0, EventELine + 1].Time)
|
|
|
|
then begin
|
|
|
|
{ Get the end offset in TDateTime format }
|
2016-07-02 15:44:34 +00:00
|
|
|
EndOffset := TVpDayViewOpener(FDayView).dvLineMatrix[0, EventELine + 1].Time - EventETime;
|
2016-06-25 10:08:36 +00:00
|
|
|
{ determine how many pixels to scooch down before painting the event's color code. }
|
2016-07-03 09:36:40 +00:00
|
|
|
EndPixelOffset := trunc(EndOffset / PixelDuration);;
|
2016-06-25 10:08:36 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 22:21:39 +00:00
|
|
|
{ Paint the gutter inside the EventRect of all events }
|
2016-06-25 10:08:36 +00:00
|
|
|
if (AEventRec.Level = 0) then
|
|
|
|
GutterRect.Left := EventRect.Left - Trunc(FDayView.GutterWidth * Scale)
|
|
|
|
else
|
|
|
|
GutterRect.Left := EventRect.Left;
|
|
|
|
GutterRect.Right := GutterRect.Left + Round(FDayView.GutterWidth * Scale);
|
|
|
|
GutterRect.Top := EventRect.Top + StartPixelOffset;
|
2016-07-03 09:36:40 +00:00
|
|
|
GutterRect.Bottom := EventRect.Bottom - EndPixelOffset + 1;
|
2016-06-25 10:08:36 +00:00
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, GutterRect);
|
|
|
|
|
|
|
|
RenderCanvas.Brush.Color := WindowColor;
|
|
|
|
|
|
|
|
IconRect.Left := EventRect.Left;
|
|
|
|
IconRect.Top := EventRect.Top;
|
|
|
|
IconRect.Right := EventRect.Left;
|
|
|
|
IconRect.Bottom := EventRect.Top;
|
|
|
|
if not DisplayOnly then begin
|
|
|
|
GetIcons(AEvent);
|
|
|
|
if AEventRec.Level = 0 then begin
|
|
|
|
ScaleIcons(EventRect);
|
2016-06-26 08:14:09 +00:00
|
|
|
IconRect := DetermineIconRect(EventRect);
|
2016-06-25 10:08:36 +00:00
|
|
|
end else begin
|
|
|
|
tmpRect := EventRect;
|
|
|
|
inc(tmpRect.Left, FDayView.GutterWidth);
|
|
|
|
ScaleIcons(tmpRect);
|
2016-06-26 08:14:09 +00:00
|
|
|
IconRect := DetermineIconRect(tmpRect);
|
2016-06-25 10:08:36 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
OldPen.Assign(RenderCanvas.Pen); // wp: Original code had "Canvas" here which does not look correct
|
2016-06-25 10:08:36 +00:00
|
|
|
OldBrush.Assign(RenderCanvas.Brush);
|
|
|
|
OldFont.Assign(RenderCanvas.Font);
|
2016-06-26 11:37:20 +00:00
|
|
|
|
|
|
|
if Assigned(FDayView.OnBeforeDrawEvent) then begin
|
|
|
|
tmpRect := EventRect;
|
|
|
|
if (AEventRec.Level <> 0) then
|
|
|
|
inc(tmpRect.Left, FDayView.GutterWidth);
|
|
|
|
FDayView.OnBeforeDrawEvent(Self, AEvent, FDayView.ActiveEvent = AEvent, RenderCanvas, tmpRect, IconRect);
|
|
|
|
end;
|
2016-06-25 10:08:36 +00:00
|
|
|
|
|
|
|
if not DisplayOnly then
|
|
|
|
DrawIcons(IconRect);
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
{ build the event string }
|
|
|
|
EventString := BuildEventString(AEvent, EventRect, IconRect);
|
2016-06-25 10:08:36 +00:00
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
{ draw the event string }
|
2016-06-26 20:44:06 +00:00
|
|
|
DrawEventText(EventString, EventRect, IconRect, AEventRec.Level, EventIsEditing);
|
2016-06-25 10:08:36 +00:00
|
|
|
|
|
|
|
{ paint the borders around the event text area }
|
|
|
|
TPSPolyline(RenderCanvas, Angle, RenderIn, [
|
|
|
|
Point(EventRect.Left, EventRect.Top),
|
|
|
|
Point(EventRect.Right, EventRect.Top),
|
|
|
|
Point(EventRect.Right, EventRect.Bottom),
|
|
|
|
Point(EventRect.Left, EventRect.Bottom),
|
|
|
|
Point(EventRect.Left, EventRect.Top)
|
|
|
|
]);
|
|
|
|
|
|
|
|
{ don't paint gutter area on level 0 items }
|
|
|
|
if AEventRec.Level > 0 then begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, EventRect.Left + Round(FDayView.GutterWidth * Scale), EventRect.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, EventRect.Left + Round(FDayView.GutterWidth * Scale), EventRect.Bottom);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
if Assigned(FDayView.OnAfterDrawEvent) then begin
|
|
|
|
tmpRect := EventRect;
|
|
|
|
if (AEventRec.Level <> 0) then
|
|
|
|
inc(tmpRect.Left, FDayView.GutterWidth);
|
|
|
|
FDayView.OnAfterDrawEvent(Self, AEvent, FDayView.ActiveEvent = AEvent, RenderCanvas, tmpRect, IconRect);
|
|
|
|
end;
|
2016-06-25 10:08:36 +00:00
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
RenderCanvas.Brush.Assign(OldBrush); // wp: Original code had "Canvas" here which does not look correct.
|
2016-06-25 10:08:36 +00:00
|
|
|
RenderCanvas.Pen.Assign(OldPen);
|
|
|
|
RenderCanvas.Font.Assign(OldFont);
|
|
|
|
|
|
|
|
tmpRect := EventRect;
|
|
|
|
inc(tmpRect.Bottom);
|
|
|
|
TVpDayViewOpener(FDayView).dvEventArray[EventCount].Rec := tmpRect;
|
|
|
|
TVpDayViewOpener(FDayView).dvEventArray[EventCount].IconRect := IconRect;
|
|
|
|
TVpDayViewOpener(FDayView).dvEventArray[EventCount].Event := AEvent;
|
|
|
|
|
|
|
|
Inc(EventCount);
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.DrawEvents(ARenderDate: TDateTime; Col: Integer);
|
2016-06-22 14:43:43 +00:00
|
|
|
var
|
2016-06-25 10:08:36 +00:00
|
|
|
I,J: Integer;
|
|
|
|
Event: TVpEvent;
|
|
|
|
SaveFont: TFont;
|
|
|
|
SaveColor: TColor;
|
2016-06-24 21:41:24 +00:00
|
|
|
OKToDrawEditFrame: Boolean;
|
2016-06-26 14:19:55 +00:00
|
|
|
tmpRect: TRect;
|
|
|
|
level: Integer;
|
2016-06-22 14:43:43 +00:00
|
|
|
begin
|
|
|
|
if (FDayView.DataStore = nil) or (FDayView.DataStore.Resource = nil) or
|
2016-06-30 18:45:39 +00:00
|
|
|
(not FDayView.DataStore.Connected)
|
|
|
|
then
|
2016-06-22 14:43:43 +00:00
|
|
|
Exit;
|
|
|
|
|
|
|
|
{ Save the canvas color and font }
|
|
|
|
SaveColor := RenderCanvas.Brush.Color;
|
|
|
|
SaveFont := TFont.Create;
|
|
|
|
SaveFont.Assign(RenderCanvas.Font);
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
{Get all of the events for this day}
|
|
|
|
PopulateEventArray(ARenderDate);
|
2016-06-22 14:43:43 +00:00
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
// Count the number of events which all share some of the same time
|
2016-06-22 14:43:43 +00:00
|
|
|
for I := 0 to pred(MaxVisibleEvents) do begin
|
|
|
|
if EventArray[I].Event = nil then
|
|
|
|
Break;
|
|
|
|
EventArray[I].OLLevels := 1 + { it is necessary to count this event too }
|
|
|
|
CountOverlappingEvents(TVpEvent(EventArray[I].Event), EventArray);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
// Calculate the largest width divisor of all overlapping events, for each event.
|
2016-06-22 14:43:43 +00:00
|
|
|
for I := 0 to pred(MaxVisibleEvents) do begin
|
|
|
|
if EventArray[I].Event = nil then
|
|
|
|
Break;
|
|
|
|
EventArray[I].WidthDivisor := GetMaxOLEvents(TVpEvent(EventArray[I].Event), EventArray);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
// Make one last pass, to make sure that we have set up the width divisors properly
|
2016-06-26 16:27:01 +00:00
|
|
|
VerifyMaxWidthDevisors;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
// Time to paint 'em. Let's see if we calculated their placements correctly
|
2016-06-22 14:43:43 +00:00
|
|
|
IconRect := Rect(0, 0, 0, 0);
|
|
|
|
CreateBitmaps;
|
|
|
|
OldFont := TFont.Create;
|
|
|
|
OldPen := TPen.Create;
|
|
|
|
OldBrush := TBrush.Create;
|
|
|
|
try
|
|
|
|
{ get a rectangle of the visible area }
|
2016-06-23 09:37:07 +00:00
|
|
|
VisibleRect := TVpDayViewOpener(FDayView).dvLineMatrix[Col, StartLine].Rec;
|
2016-06-22 14:43:43 +00:00
|
|
|
VisibleRect.Bottom := FDayView.ClientRect.Bottom;
|
|
|
|
|
|
|
|
LineDuration := GetLineDuration(FDayView.Granularity);
|
|
|
|
{ Determine how much time is represented by one pixel. It is the }
|
|
|
|
{ amount of time represented by one line, divided by the height of }
|
|
|
|
{ a line in pixels. }
|
2016-06-23 09:37:07 +00:00
|
|
|
with TVpDayViewOpener(FDayView) do
|
2016-06-24 21:41:24 +00:00
|
|
|
if HeightOf(dvLineMatrix[Col, StartLine].Rec) > 0 then
|
|
|
|
PixelDuration := LineDuration / HeightOf(dvLineMatrix[Col, StartLine].Rec)
|
2016-06-23 09:37:07 +00:00
|
|
|
else
|
|
|
|
PixelDuration := 0;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
{ Iterate through events and paint them }
|
2016-06-26 14:19:55 +00:00
|
|
|
level := -1;
|
2016-06-22 14:43:43 +00:00
|
|
|
for I := 0 to pred(MaxVisibleEvents) do begin
|
|
|
|
{ get the next event }
|
|
|
|
Event := TVpEvent(EventArray[I].Event);
|
|
|
|
|
|
|
|
{ if we have hit the end of the events, then bail out }
|
|
|
|
if Event = nil then
|
|
|
|
Break;
|
2016-06-24 21:41:24 +00:00
|
|
|
|
2016-06-25 10:08:36 +00:00
|
|
|
DrawEvent(Event, EventArray[i], ARenderDate, Col);
|
2016-06-26 14:19:55 +00:00
|
|
|
if Event = FDayView.ActiveEvent then level := i;
|
2016-06-22 14:43:43 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-24 19:37:53 +00:00
|
|
|
{ paint extra borders around the editor }
|
2016-06-22 14:43:43 +00:00
|
|
|
OKToDrawEditFrame := True;
|
|
|
|
if Assigned(FDayView.ActiveEvent) then
|
2016-06-28 19:28:31 +00:00
|
|
|
OKToDrawEditFrame := not FDayView.ActiveEvent.AllDayEvent;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
2016-06-26 14:19:55 +00:00
|
|
|
with TVpDayViewOpener(FDayView) do
|
|
|
|
if (dvInPlaceEditor <> nil) and dvInplaceEditor.Visible and OKToDrawEditFrame then
|
|
|
|
begin
|
|
|
|
tmpRect := dvActiveEventRec;
|
|
|
|
DrawEditFrame(tmpRect, GutterWidth, level,
|
|
|
|
Datastore.CategoryColorMap.GetColor(ActiveEvent.Category));
|
|
|
|
end;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
finally
|
2016-06-24 19:37:53 +00:00
|
|
|
{ Clean Up }
|
2016-06-22 14:43:43 +00:00
|
|
|
try
|
|
|
|
SetLength(EventArray, 0);
|
|
|
|
FreeBitmaps;
|
|
|
|
finally
|
|
|
|
{ restore canvas color and font }
|
|
|
|
RenderCanvas.Brush.Color := SaveColor;
|
|
|
|
RenderCanvas.Font.Assign(SaveFont);
|
|
|
|
SaveFont.Free;
|
|
|
|
OldFont.Free;
|
|
|
|
OldPen.Free;
|
|
|
|
OldBrush.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.DrawIcons(AIconRect: TRect);
|
|
|
|
var
|
|
|
|
DrawPos: Integer;
|
|
|
|
|
|
|
|
procedure DrawIcon(bmp: TBitmap; w, h: Integer; IncDrawPos: Boolean = false);
|
2016-06-24 21:41:24 +00:00
|
|
|
var
|
|
|
|
R: TRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
begin
|
|
|
|
if (bmp.Width <> 0) and (bmp.Height <> 0) then
|
|
|
|
begin
|
2016-06-24 21:41:24 +00:00
|
|
|
bmp.Transparent := True;
|
|
|
|
R := Rect(0, 0, w, h);
|
2016-06-27 23:00:17 +00:00
|
|
|
OffsetRect(R, AIconRect.Left + ICON_MARGIN, AIconRect.Top + ICON_MARGIN);
|
2016-06-24 21:41:24 +00:00
|
|
|
RenderCanvas.StretchDraw(R, bmp);
|
|
|
|
{
|
2016-06-23 09:37:07 +00:00
|
|
|
RenderCanvas.CopyRect( // wp: was FDayview.Canvas -- does not look correct...
|
2016-06-24 21:41:24 +00:00
|
|
|
Rect(AIconRect.Left + 1, AIconRect.Top + 1, AIconRect.Left + w + 1, AIconRect.Top + h + 1),
|
2016-06-22 14:43:43 +00:00
|
|
|
bmp.Canvas,
|
|
|
|
Rect(0, 0, bmp.Width, bmp.Height)
|
|
|
|
);
|
2016-06-24 21:41:24 +00:00
|
|
|
}
|
2016-06-22 14:43:43 +00:00
|
|
|
if IncDrawPos then
|
2016-06-27 23:00:17 +00:00
|
|
|
inc(DrawPos, w + ICON_MARGIN);
|
2016-06-22 14:43:43 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
DrawPos := 1;
|
|
|
|
DrawIcon(dvBmpCustom, CustomW, CustomH);
|
|
|
|
DrawIcon(dvBmpCategory, CategoryW, CategoryH);
|
|
|
|
DrawIcon(dvBmpAlarm, AlarmW, AlarmH);
|
|
|
|
DrawIcon(dvBmpRecurring, RecurringW, RecurringH, false);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 20:44:06 +00:00
|
|
|
procedure TVpDayViewPainter.DrawEventText(const AText: String;
|
2016-06-26 11:37:20 +00:00
|
|
|
const AEventRect, AIconRect: TRect; ALevel: Integer; AEventIsEditing: Boolean);
|
|
|
|
var
|
|
|
|
WorkRegion1: HRGN;
|
|
|
|
WorkRegion2: HRGN;
|
|
|
|
TextRegion: HRGN;
|
|
|
|
CW: Integer;
|
|
|
|
begin
|
2016-06-26 22:21:39 +00:00
|
|
|
{
|
|
|
|
if AEventIsEditing then
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
if (FDayView.WrapStyle <> wsNone) then begin
|
2016-06-26 11:37:20 +00:00
|
|
|
if (AEventRect.Bottom <> AIconRect.Bottom) and (AEventRect.Left <> AIconRect.Right)
|
|
|
|
then begin
|
|
|
|
if FDayView.WrapStyle = wsIconFlow then
|
|
|
|
begin
|
|
|
|
WorkRegion1 := CreateRectRgn(AIconRect.Right, AEventRect.Top, AEventRect.Right, AIconRect.Bottom);
|
|
|
|
WorkRegion2 := CreateRectRgn(AEventRect.Left + FDayView.GutterWidth, AIconRect.Bottom, AEventRect.Right, AEventRect.Bottom);
|
|
|
|
TextRegion := CreateRectRgn(AIconRect.Right, AEventRect.Top, AEventRect.Right, AIconRect.Bottom);
|
|
|
|
CombineRgn(TextRegion, WorkRegion1, WorkRegion2, RGN_OR);
|
|
|
|
end else
|
|
|
|
TextRegion := CreateRectRgn(AIconRect.Right, AEventRect.Top, AEventRect.Right, AEventRect.Bottom);
|
|
|
|
end else
|
|
|
|
TextRegion := CreateRectRgn(AIconRect.Right + FDayView.GutterWidth, AEventRect.Top, AEventRect.Right, AEventRect.Bottom);
|
|
|
|
|
|
|
|
try
|
|
|
|
CW := RenderTextToRegion(RenderCanvas, Angle, RenderIn, TextRegion, AText);
|
|
|
|
{ write the event string to the proper spot in the EventRect }
|
|
|
|
if CW < Length(AText) then begin
|
|
|
|
RenderCanvas.Brush.Color := FDayView.DotDotDotColor;
|
|
|
|
{ draw dot dot dot }
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn,
|
|
|
|
Rect(AEventRect.Right - 20, AEventRect.Bottom - 7, AEventRect.Right - 17, AEventRect.Bottom - 4)
|
|
|
|
);
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn,
|
|
|
|
Rect(AEventRect.Right - 13, AEventRect.Bottom - 7, AEventRect.Right - 10, AEventRect.Bottom - 4));
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn,
|
|
|
|
Rect(AEventRect.Right - 6, AEventRect.Bottom - 7, AEventRect.Right - 3, AEventRect.Bottom - 4));
|
|
|
|
end;
|
|
|
|
finally
|
|
|
|
if ((AEventRect.Bottom > AIconRect.Bottom) and (AEventRect.Left > AIconRect.Right)) or
|
|
|
|
(FDayView.WrapStyle = wsIconFlow)
|
|
|
|
then begin
|
|
|
|
DeleteObject(WorkRegion1);
|
|
|
|
DeleteObject(WorkRegion2);
|
|
|
|
DeleteObject(TextRegion);
|
|
|
|
end else begin
|
|
|
|
DeleteObject(TextRegion);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end
|
2016-06-26 22:21:39 +00:00
|
|
|
else begin
|
|
|
|
if ALevel = 0 then
|
2016-06-28 19:50:19 +00:00
|
|
|
{ don't draw the gutter in the EventRect for level 0 events. }
|
2016-06-26 22:21:39 +00:00
|
|
|
TPSTextOut(RenderCanvas, // wp: both cases are the same ?!
|
|
|
|
Angle,
|
|
|
|
RenderIn,
|
|
|
|
AIconRect.Right + FDayView.GutterWidth + TextMargin,
|
|
|
|
AEventRect.Top + TextMargin,
|
|
|
|
AText
|
|
|
|
)
|
2016-06-26 11:37:20 +00:00
|
|
|
else
|
2016-06-26 22:21:39 +00:00
|
|
|
TPSTextOut(RenderCanvas,
|
|
|
|
Angle,
|
|
|
|
RenderIn,
|
|
|
|
AIconRect.Right + FDayView.GutterWidth + TextMargin,
|
|
|
|
AEventRect.Top + TextMargin,
|
|
|
|
AText
|
|
|
|
);
|
2016-06-26 11:37:20 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
procedure TVpDayViewPainter.DrawNavBtns;
|
2016-07-01 15:19:38 +00:00
|
|
|
var
|
|
|
|
w: Integer;
|
2016-06-26 13:52:59 +00:00
|
|
|
begin
|
|
|
|
{ size and place the Today button first. }
|
|
|
|
with TVpDayViewOpener(FDayView) do begin
|
2016-07-01 15:19:38 +00:00
|
|
|
{ Calculate width of buttons }
|
2016-06-26 13:52:59 +00:00
|
|
|
dvTodayBtn.Height := trunc(RealColHeadHeight div 2);
|
2016-07-01 15:19:38 +00:00
|
|
|
dvTodayBtn.Width := RealRowHeadWidth;
|
|
|
|
dvWeekDownBtn.Width := RealRowHeadWidth div 4 + 2;
|
|
|
|
dvWeekUpBtn.Width := dvWeekDownBtn.Width;
|
|
|
|
dvDaydownBtn.Width := dvWeekdownBtn.Width - 4;
|
|
|
|
dvDayUpBtn.Width := dvDayDownBtn.Width;
|
|
|
|
|
|
|
|
w := dvWeekDownBtn.Width + dvWeekUpBtn.Width + dvDaydownBtn.Width + dvDayUpBtn.Width;
|
2016-07-02 23:14:26 +00:00
|
|
|
if DrawingStyle = ds3d then begin
|
2016-07-01 15:19:38 +00:00
|
|
|
dvTodayBtn.Left := 2 + (RealRowHeadWidth - w) div 2;
|
2016-06-26 13:52:59 +00:00
|
|
|
dvTodayBtn.Top := 2;
|
2016-07-02 23:14:26 +00:00
|
|
|
end else
|
|
|
|
begin
|
|
|
|
dvTodayBtn.Left := 1 + (RealRowHeadWidth - w) div 2;
|
|
|
|
dvTodayBtn.Top := 1;
|
2016-06-26 13:52:59 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
{ size and place the WeekDown button }
|
|
|
|
dvWeekDownBtn.Height := dvTodayBtn.Height;
|
|
|
|
dvWeekDownBtn.Left := dvTodayBtn.Left;
|
|
|
|
dvWeekDownBtn.Top := dvTodayBtn.Top + dvTodayBtn.Height;
|
|
|
|
|
|
|
|
{ size and place the DayDown button }
|
|
|
|
dvDayDownBtn.Height := dvTodayBtn.Height;
|
|
|
|
dvDayDownBtn.Left := dvWeekDownBtn.Left + dvWeekDownBtn.Width;
|
2016-07-01 15:19:38 +00:00
|
|
|
dvDayDownBtn.Top := dvWeekDownBtn.Top;
|
2016-06-26 13:52:59 +00:00
|
|
|
|
|
|
|
{ size and place the DayUp button }
|
|
|
|
dvDayUpBtn.Height := dvTodayBtn.Height;
|
|
|
|
dvDayUpBtn.Left := dvDayDownBtn.Left + dvDayDownBtn.Width;
|
2016-07-01 15:19:38 +00:00
|
|
|
dvDayUpBtn.Top := dvWeekDownBtn.Top;
|
2016-06-26 13:52:59 +00:00
|
|
|
|
|
|
|
{ size and place the WeekUp button }
|
|
|
|
dvWeekUpBtn.Height := dvTodayBtn.Height;
|
|
|
|
dvWeekUpBtn.Left := dvDayUpBtn.Left + dvDayUpBtn.Width;
|
2016-07-01 15:19:38 +00:00
|
|
|
dvWeekUpBtn.Top := dvWeekDownBtn.Top;
|
2016-06-26 13:52:59 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.DrawNavBtnBackground;
|
|
|
|
var
|
|
|
|
R: TRect;
|
|
|
|
begin
|
2016-07-03 09:36:40 +00:00
|
|
|
RenderCanvas.Brush.Color := RealHeadAttrColor;
|
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
R := Rect(
|
|
|
|
RealLeft + 1,
|
|
|
|
RealTop,
|
|
|
|
RealLeft + 3 + RealRowHeadWidth,
|
2016-07-01 15:19:38 +00:00
|
|
|
RealTop + RealColHeadHeight // + 1
|
2016-06-26 13:52:59 +00:00
|
|
|
);
|
2016-07-03 09:36:40 +00:00
|
|
|
if FDayView.DrawingStyle = dsNoBorder then begin
|
|
|
|
InflateRect(R, 1, 1);
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
|
|
|
exit;
|
|
|
|
end;
|
2016-06-26 13:52:59 +00:00
|
|
|
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
|
|
|
|
2016-07-01 10:04:08 +00:00
|
|
|
if FDayView.DrawingStyle = ds3d then begin
|
2016-07-01 15:19:38 +00:00
|
|
|
R := Rect(R.Left + 1, R.Top + 2, R.Right - 2, R.Bottom - 1);
|
2016-06-26 13:52:59 +00:00
|
|
|
DrawBevelRect(
|
|
|
|
RenderCanvas,
|
2016-07-01 10:04:08 +00:00
|
|
|
TPSRotateRectangle(Angle, RenderIn, R),
|
2016-06-26 13:52:59 +00:00
|
|
|
BevelHighlight,
|
|
|
|
BevelShadow
|
|
|
|
)
|
2016-07-01 10:04:08 +00:00
|
|
|
end else
|
2016-07-03 08:39:53 +00:00
|
|
|
if FDayView.DrawingStyle = dsFlat then begin
|
2016-06-26 13:52:59 +00:00
|
|
|
RenderCanvas.Pen.Color := BevelShadow;
|
2016-07-01 15:19:38 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right - 6, R.Bottom- 1);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Left + 3, R.Bottom - 1);
|
2016-07-01 10:04:08 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right - 2, R.Top + 6);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 2, R.Bottom - 5);
|
|
|
|
{
|
2016-06-26 13:52:59 +00:00
|
|
|
RenderCanvas.Pen.Color := BevelHighlight;
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Left, R.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 2, R.Top);
|
2016-07-01 10:04:08 +00:00
|
|
|
}
|
2016-06-26 13:52:59 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-28 11:08:29 +00:00
|
|
|
procedure TVpDayViewPainter.DrawRegularEvents;
|
|
|
|
var
|
|
|
|
i: Integer;
|
|
|
|
RPos: Integer;
|
|
|
|
AllDayWidth: Integer;
|
|
|
|
ExtraSpace: Integer;
|
|
|
|
DrawMe: Boolean;
|
|
|
|
RealDay: Integer;
|
|
|
|
begin
|
|
|
|
if RealNumDays = 0 then begin
|
|
|
|
while (DayOfWeek(RenderDate) = 1) or (DayOfWeek(RenderDate) = 7) do
|
|
|
|
RenderDate := RenderDate + 1;
|
|
|
|
RealNumDays := FDayView.NumDays;
|
|
|
|
end;
|
|
|
|
AllDayWidth := RealWidth - RealRowHeadWidth - 1 - ScrollBarOffset;
|
|
|
|
|
|
|
|
DayWidth := AllDayWidth div FDayView.NumDays;
|
|
|
|
ExtraSpace := AllDayWidth mod FDayView.NumDays;
|
|
|
|
|
|
|
|
RPos := RowHeadRect.Right;
|
|
|
|
|
|
|
|
RealDay := 0;
|
|
|
|
for i := 0 to RealNumDays - 1 do begin
|
|
|
|
DrawMe := True;
|
|
|
|
if not FDayView.IncludeWeekends then begin
|
|
|
|
if (DayOfWeek(RenderDate + i) = 1) or (DayOfWeek(RenderDate + i) = 7) then
|
|
|
|
DrawMe := False
|
|
|
|
end;
|
|
|
|
if DrawMe then begin
|
2016-07-01 10:04:08 +00:00
|
|
|
{ Calculate Column Header rectangle }
|
2016-06-28 11:08:29 +00:00
|
|
|
ColHeadRect := Rect(RPos, RealTop + 2, RPos + DayWidth - 1, RealTop + RealColHeadHeight);
|
|
|
|
if (i = RealNumDays - 1) and (ExtraSpace > 0) then
|
|
|
|
ColHeadRect.Right := ColHeadRect.Right + ExtraSpace;
|
|
|
|
|
|
|
|
{ Calculate the column rect for this day }
|
|
|
|
RenderCanvas.Font.Assign(FDayView.Font);
|
|
|
|
CellsRect := Rect(RPos, ADEventsRect.Bottom + 1, RPos + DayWidth, RealBottom - 2);
|
|
|
|
if (i = RealNumDays - 1) and (ExtraSpace > 0) then
|
|
|
|
CellsRect.Right := CellsRect.Right + ExtraSpace;
|
|
|
|
|
|
|
|
{ set the ColRectArray }
|
|
|
|
TVpDayViewOpener(FDayView).dvColRectArray[RealDay].Rec := CellsRect;
|
|
|
|
TVpDayViewOpener(FDayView).dvColRectArray[RealDay].Date := RenderDate + i;
|
|
|
|
|
|
|
|
{ Draw the cells }
|
|
|
|
if Assigned(FDayView.OwnerDrawCells) then begin
|
|
|
|
FDayView.OwnerDrawCells(self, RenderCanvas, CellsRect, RealRowHeight, Drawn);
|
|
|
|
if not Drawn then
|
|
|
|
DrawCells(CellsRect, RenderDate + i, RealDay);
|
|
|
|
end else
|
|
|
|
DrawCells(CellsRect, RenderDate + i, RealDay);
|
|
|
|
|
|
|
|
{ Draw the regular events }
|
|
|
|
DrawEvents(RenderDate + i, RealDay);
|
|
|
|
|
2016-07-01 10:04:08 +00:00
|
|
|
{ Draw the column header }
|
|
|
|
if Assigned(FDayView.OwnerDrawColHeader) then begin
|
|
|
|
Drawn := false;
|
|
|
|
FDayView.OwnerDrawColHeader(self, RenderCanvas, ColHeadRect, Drawn);
|
|
|
|
if not Drawn then
|
|
|
|
DrawColHeader(ColHeadRect, RenderDate + i, RealDay);
|
|
|
|
end else
|
|
|
|
DrawColHeader(ColHeadRect, RenderDate + i, RealDay);
|
|
|
|
|
2016-06-28 11:08:29 +00:00
|
|
|
Inc(RPos, DayWidth);
|
|
|
|
Inc(RealDay);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure TVpDayViewPainter.DrawRowHeader(R: TRect);
|
2016-07-03 09:36:40 +00:00
|
|
|
const
|
|
|
|
MINUTES_BORDER = 7;
|
|
|
|
MINUTES_HOUR_DISTANCE = 4;
|
2016-06-22 14:43:43 +00:00
|
|
|
var
|
2016-07-03 09:36:40 +00:00
|
|
|
I, MinutesLen: Integer;
|
2016-06-22 14:43:43 +00:00
|
|
|
LineRect: TRect;
|
|
|
|
LastHour, Hour: Integer;
|
|
|
|
MinuteStr, HourStr: string;
|
|
|
|
SaveFont: TFont;
|
2016-07-03 09:36:40 +00:00
|
|
|
x: Integer;
|
2016-06-22 14:43:43 +00:00
|
|
|
begin
|
|
|
|
if StartLine < 0 then
|
|
|
|
StartLine := FDayView.TopLine;
|
|
|
|
|
|
|
|
SaveFont := TFont.Create;
|
|
|
|
try
|
2016-07-03 09:36:40 +00:00
|
|
|
{ Draw row header background }
|
|
|
|
if FDayView.DrawingStyle = dsNoBorder then
|
|
|
|
InflateRect(R, 1,1);
|
2016-06-22 14:43:43 +00:00
|
|
|
RenderCanvas.Pen.Style := psClear;
|
|
|
|
RenderCanvas.Brush.Color := RealRowHeadAttrColor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
|
|
|
RenderCanvas.Pen.Style := psSolid;
|
2016-07-03 09:36:40 +00:00
|
|
|
if FDayView.DrawingStyle = dsNoBorder then
|
|
|
|
InflateRect(R, -1,-1);
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
RenderCanvas.Font.Assign(FDayView.RowHeadAttributes.MinuteFont);
|
|
|
|
RealVisibleLines := TVpDayViewOpener(FDayView).dvCalcVisibleLines(
|
2016-07-03 09:36:40 +00:00
|
|
|
HeightOf(R),
|
2016-06-22 14:43:43 +00:00
|
|
|
RealColHeadHeight,
|
|
|
|
RealRowHeight,
|
|
|
|
Scale,
|
|
|
|
StartLine,
|
|
|
|
StopLine
|
|
|
|
);
|
2016-07-03 09:36:40 +00:00
|
|
|
MinutesLen := RenderCanvas.TextWidth('00') + MINUTES_BORDER + MINUTES_HOUR_DISTANCE div 2;
|
2016-06-26 13:52:59 +00:00
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
RenderCanvas.Pen.Style := psSolid;
|
|
|
|
RenderCanvas.Pen.Color := RealLineColor;
|
|
|
|
LineRect := Rect(R.Left, R.Top, R.Right, R.Top + RealRowHeight);
|
2016-06-23 09:37:07 +00:00
|
|
|
Hour := Ord(TVpDayViewOpener(FDayView).dvLineMatrix[0, StartLine].Hour);
|
2016-06-22 14:43:43 +00:00
|
|
|
|
2016-07-02 15:44:34 +00:00
|
|
|
i := High(TVpDayviewOpener(FDayview).dvLinematrix[0]);
|
|
|
|
|
|
|
|
for I := 0 to RealVisibleLines + 1 do begin // ok: + 1 needed to see the partial line at the bottom
|
2016-06-26 13:52:59 +00:00
|
|
|
{ prevent any extraneous drawing below the last hour }
|
2016-07-02 15:44:34 +00:00
|
|
|
if (I + FDayView.TopLine > FDayView.LineCount) or (Hour > 23) then
|
2016-06-22 14:43:43 +00:00
|
|
|
Break;
|
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
case FDayView.TimeFormat of
|
|
|
|
tf24Hour: MinuteStr := '00';
|
|
|
|
tf12Hour: MinuteStr := IfThen(Hour < 12, 'am', 'pm');
|
|
|
|
end;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
{ Position the rect }
|
|
|
|
LineRect.Top := R.Top + i * RealRowHeight;
|
|
|
|
LineRect.Bottom := LineRect.Top + RealRowHeight;
|
|
|
|
|
|
|
|
if (Hour > 12) and (FDayView.TimeFormat = tf12Hour) then
|
|
|
|
HourStr := IntToStr(Hour - 12)
|
|
|
|
else begin
|
|
|
|
HourStr := IntToStr(Hour);
|
|
|
|
if (FDayView.TimeFormat = tf12Hour) and (HourStr = '0') then
|
|
|
|
HourStr := '12';
|
|
|
|
end;
|
|
|
|
|
|
|
|
if UseGran = gr60Min then begin
|
|
|
|
{ Paint time }
|
|
|
|
RenderCanvas.Font.Assign(FDayView.RowHeadAttributes.MinuteFont);
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn,
|
2016-07-03 09:36:40 +00:00
|
|
|
LineRect.Right - RenderCanvas.TextWidth(HourStr + ':' + MinuteStr) - MINUTES_BORDER,
|
2016-06-22 14:43:43 +00:00
|
|
|
LineRect.Top + TextMargin,
|
|
|
|
HourStr + ':' + MinuteStr
|
|
|
|
);
|
|
|
|
LastHour := Hour;
|
|
|
|
Inc(Hour);
|
|
|
|
end else begin
|
|
|
|
{ Paint Minute Text}
|
2016-06-23 09:37:07 +00:00
|
|
|
if TVpDayViewOpener(FDayView).dvLineMatrix[0, StartLine + i].Minute = 0 then begin
|
2016-06-22 14:43:43 +00:00
|
|
|
RenderCanvas.Font.Assign(FDayView.RowHeadAttributes.MinuteFont);
|
2016-07-03 09:36:40 +00:00
|
|
|
x := LineRect.Right - RenderCanvas.TextWidth(MinuteStr) - MINUTES_BORDER;
|
2016-06-22 14:43:43 +00:00
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn,
|
2016-07-03 09:36:40 +00:00
|
|
|
x,
|
2016-06-22 14:43:43 +00:00
|
|
|
LineRect.Top + TextMargin,
|
|
|
|
MinuteStr
|
|
|
|
);
|
|
|
|
{ Paint Hour Text }
|
|
|
|
RenderCanvas.Font.Assign(FDayView.RowHeadAttributes.HourFont);
|
2016-07-03 09:36:40 +00:00
|
|
|
dec(x, RenderCanvas.TextWidth(HourStr) + MINUTES_HOUR_DISTANCE);
|
2016-06-22 14:43:43 +00:00
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn,
|
2016-07-03 09:36:40 +00:00
|
|
|
x,
|
2016-06-22 14:43:43 +00:00
|
|
|
LineRect.Top + TextMargin - 2,
|
|
|
|
HourStr
|
|
|
|
);
|
|
|
|
end;
|
2016-07-02 15:44:34 +00:00
|
|
|
if StartLine + i + 1 >= High(TVpDayViewOpener(FDayView).dvLineMatrix[0]) then
|
|
|
|
// ">=" avoids seeing a parasitic hour in the last line
|
|
|
|
Hour := 24
|
|
|
|
else begin
|
|
|
|
LastHour := Hour;
|
|
|
|
Hour := Ord(TVpDayViewOpener(FDayView).dvLineMatrix[0, StartLine + i + 1].Hour);
|
|
|
|
end;
|
2016-06-22 14:43:43 +00:00
|
|
|
end;
|
|
|
|
|
2016-07-03 09:36:40 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, LineRect.Right - 6, LineRect.Bottom);
|
2016-06-22 14:43:43 +00:00
|
|
|
if LastHour <> Hour then
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, LineRect.Left + 6, LineRect.Bottom)
|
|
|
|
else
|
2016-07-03 09:36:40 +00:00
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, LineRect.Right - MinutesLen, LineRect.Bottom);
|
2016-06-22 14:43:43 +00:00
|
|
|
end; {for}
|
|
|
|
|
|
|
|
{ Draw Row Header Borders }
|
|
|
|
if FDayView.DrawingStyle = dsFlat then begin
|
2016-07-01 10:04:08 +00:00
|
|
|
RenderCanvas.Pen.Color := BevelShadow;
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Top);
|
2016-07-01 15:19:38 +00:00
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right - 1, R.Bottom - 1);
|
2016-07-01 10:04:08 +00:00
|
|
|
{
|
|
|
|
DrawBevelRect(RenderCanvas, TPSRotateRectangle(Angle, RenderIn,
|
2016-06-22 14:43:43 +00:00
|
|
|
Rect(R.Left - 1, R.Top, R.Right - 1, R.Bottom - 2)),
|
2016-07-01 10:04:08 +00:00
|
|
|
clRed, //BevelHighlight,
|
|
|
|
clBlue //BevelShadow
|
2016-06-22 14:43:43 +00:00
|
|
|
);
|
2016-07-01 10:04:08 +00:00
|
|
|
}
|
2016-06-22 14:43:43 +00:00
|
|
|
end
|
2016-07-01 10:04:08 +00:00
|
|
|
else
|
|
|
|
if FDayView.DrawingStyle = ds3d then begin
|
2016-06-22 14:43:43 +00:00
|
|
|
DrawBevelRect(RenderCanvas,
|
2016-07-01 15:19:38 +00:00
|
|
|
TPSRotateRectangle(Angle, RenderIn, Rect(R.Left + 1, R.Top, R.Right - 1, R.Bottom - 1)),
|
2016-06-22 14:43:43 +00:00
|
|
|
BevelHighlight,
|
|
|
|
BevelDarkShadow
|
|
|
|
);
|
|
|
|
end;
|
|
|
|
|
|
|
|
RenderCanvas.Font.Assign(SaveFont);
|
|
|
|
|
|
|
|
finally
|
|
|
|
SaveFont.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
procedure TVpDayViewPainter.CalcRowHeadRect(out ARect: TRect);
|
|
|
|
begin
|
|
|
|
ARect := Rect(
|
2016-07-02 15:44:34 +00:00
|
|
|
RealLeft,
|
|
|
|
ADEventsRect.Bottom,
|
2016-06-26 13:52:59 +00:00
|
|
|
RealLeft + 2 + RealRowHeadWidth,
|
2016-07-02 15:44:34 +00:00
|
|
|
RealBottom
|
2016-06-26 13:52:59 +00:00
|
|
|
);
|
2016-07-03 08:39:53 +00:00
|
|
|
if FDayView.DrawingStyle <> ds3d then
|
2016-06-26 13:52:59 +00:00
|
|
|
inc(ARect.Left);
|
|
|
|
end;
|
|
|
|
|
2016-07-04 19:21:55 +00:00
|
|
|
function TVpDayViewPainter.CalcRowHeadWidth: integer;
|
|
|
|
var
|
|
|
|
w: Integer;
|
|
|
|
begin
|
|
|
|
RenderCanvas.Font.Assign(FDayView.RowHeadAttributes.HourFont);
|
|
|
|
w := RenderCanvas.TextWidth('33');
|
|
|
|
Result := w * 2 + 10;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.FixFontHeights;
|
|
|
|
begin
|
|
|
|
with FDayView do begin
|
|
|
|
AllDayEventAttributes.Font.Height := GetRealFontHeight(AllDayEventAttributes.Font);
|
|
|
|
Font.Height := GetRealFontHeight(Font);
|
|
|
|
HeadAttributes.Font.Height := GetRealFontHeight(HeadAttributes.Font);
|
|
|
|
RowHeadAttributes.HourFont.Height := GetRealFontHeight(RowHeadAttributes.HourFont);
|
|
|
|
RowHeadAttributes.MinuteFont.Height := GetRealFontHeight(RowHeadAttributes.MinuteFont);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure TVpDayViewPainter.FreeBitmaps;
|
|
|
|
begin
|
|
|
|
dvBmpRecurring.Free;
|
|
|
|
dvBmpCategory.Free;
|
|
|
|
dvBmpAlarm.Free;
|
|
|
|
dvBmpCustom.Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.GetIcons(Event: TVpEvent);
|
|
|
|
var
|
|
|
|
ShowAlarm: Boolean;
|
|
|
|
ShowRecurring: Boolean;
|
|
|
|
ShowCategory: Boolean;
|
|
|
|
ShowCustom: Boolean;
|
|
|
|
Icons: TVpDVIcons;
|
|
|
|
cat: TVpCategoryInfo;
|
|
|
|
w, h: Integer;
|
2016-07-02 15:44:34 +00:00
|
|
|
R: TRect;
|
2016-06-22 14:43:43 +00:00
|
|
|
begin
|
|
|
|
ShowAlarm := False;
|
|
|
|
ShowRecurring := False;
|
|
|
|
ShowCategory := False;
|
|
|
|
ShowCustom := False;
|
|
|
|
|
2016-06-24 21:41:24 +00:00
|
|
|
// FDayView.IconAttributes.AlarmBitmap.SaveToFile('d:\test.bmp');
|
|
|
|
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
if Event.AlarmSet then begin
|
|
|
|
dvBmpAlarm.Assign(FDayView.IconAttributes.AlarmBitmap);
|
|
|
|
ShowAlarm := (dvBmpAlarm.Width <> 0) and (dvBmpAlarm.Height <> 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
if Event.RepeatCode <> rtNone then begin
|
2016-06-24 21:41:24 +00:00
|
|
|
dvBmpRecurring.Assign(FDayView.IconAttributes.RecurringBitmap);
|
2016-06-22 14:43:43 +00:00
|
|
|
ShowRecurring := (dvBmpRecurring.Width <> 0) and (dvBmpRecurring.Height <> 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
if Assigned(FDayView.DataStore) then begin
|
|
|
|
if Event.Category < 10 then begin
|
|
|
|
cat := FDayView.Datastore.CategoryColorMap.GetCategory(Event.Category);
|
|
|
|
w := cat.Bitmap.Width;
|
|
|
|
h := cat.Bitmap.Height;
|
|
|
|
dvBmpCategory.Width := w;
|
|
|
|
dvBmpCategory.Height := h;
|
2016-07-02 15:44:34 +00:00
|
|
|
R := Rect(0, 0, w, h);
|
|
|
|
dvBmpCategory.Canvas.CopyRect(R, cat.Bitmap.canvas, R);
|
2016-06-22 14:43:43 +00:00
|
|
|
end else
|
|
|
|
begin
|
|
|
|
dvBmpCategory.Width := 0;
|
|
|
|
dvBmpCategory.Height := 0;
|
|
|
|
end;
|
|
|
|
ShowCategory := (dvBmpCategory.Width <> 0) and (dvBmpCategory.Height <> 0);
|
|
|
|
end;
|
|
|
|
|
|
|
|
dvBmpCustom.Width := 0;
|
|
|
|
dvBmpCustom.Height := 0;
|
|
|
|
|
|
|
|
if not FDayView.IconAttributes.ShowAlarmBitmap then
|
|
|
|
ShowAlarm := False;
|
|
|
|
if not FDayView.IconAttributes.ShowCategoryBitmap then
|
|
|
|
ShowCategory := False;
|
|
|
|
if not FDayView.IconAttributes.ShowRecurringBitmap then
|
|
|
|
ShowRecurring := False;
|
|
|
|
|
|
|
|
if Assigned(FDayView.OnDrawIcons) then begin
|
|
|
|
Icons[itAlarm].Show := ShowAlarm;
|
|
|
|
Icons[itAlarm].Bitmap := dvBmpAlarm;
|
|
|
|
Icons[itRecurring].Show := ShowRecurring;
|
|
|
|
Icons[itRecurring].Bitmap := dvBmpRecurring;
|
|
|
|
Icons[itCategory].Show := ShowCategory;
|
|
|
|
Icons[itCategory].Bitmap := dvBmpCategory;
|
|
|
|
Icons[itCustom].Show := ShowCustom;
|
|
|
|
Icons[itCustom].Bitmap := dvBmpCustom;
|
|
|
|
|
|
|
|
FDayView.OnDrawIcons (Self, Event, Icons);
|
|
|
|
|
|
|
|
ShowAlarm := Icons[itAlarm].Show;
|
|
|
|
ShowRecurring := Icons[itRecurring].Show;
|
|
|
|
ShowCategory := Icons[itCategory].Show;
|
|
|
|
ShowCustom := Icons[itCustom].Show;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if not ShowAlarm then begin
|
|
|
|
dvBmpAlarm.Width := 0;
|
|
|
|
dvBmpAlarm.Height := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if not ShowRecurring then begin
|
|
|
|
dvBmpRecurring.Width := 0;
|
|
|
|
dvBmpRecurring.Height := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if not ShowCategory then begin
|
|
|
|
dvBmpCategory.Width := 0;
|
|
|
|
dvBmpCategory.Height := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if not ShowCustom then begin
|
|
|
|
dvBmpCustom.Width := 0;
|
|
|
|
dvBmpCustom.Height := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
AlarmW := dvBmpAlarm.Width;
|
|
|
|
RecurringW := dvBmpRecurring.Width;
|
|
|
|
CategoryW := dvBmpCategory.Width;
|
|
|
|
CustomW := dvBmpCustom.Width;
|
|
|
|
AlarmH := dvBmpAlarm.Height;
|
|
|
|
RecurringH := dvBmpRecurring.Height;
|
|
|
|
CategoryH := dvBmpCategory.Height;
|
|
|
|
CustomH := dvBmpCustom.Height;
|
|
|
|
end;
|
|
|
|
|
2016-06-23 11:53:21 +00:00
|
|
|
procedure TVpDayViewPainter.InitColors;
|
2016-06-22 14:43:43 +00:00
|
|
|
begin
|
|
|
|
if DisplayOnly then begin
|
|
|
|
BevelShadow := clBlack;
|
|
|
|
BevelHighlight := clBlack;
|
|
|
|
BevelDarkShadow := clBlack;
|
|
|
|
BevelFace := clBlack;
|
|
|
|
WindowColor := clWhite;
|
|
|
|
HighlightText := clBlack;
|
|
|
|
RealHeadAttrColor := clSilver;
|
|
|
|
RealRowHeadAttrColor := clSilver;
|
|
|
|
RealLineColor := clBlack;
|
|
|
|
RealColor := clWhite;
|
|
|
|
HighlightBkg := clWhite;
|
|
|
|
RealADEventBkgColor := clWhite;
|
|
|
|
ADEventAttrBkgColor := clWhite;
|
|
|
|
ADEventBorderColor := clBlack;
|
|
|
|
end else begin
|
|
|
|
BevelShadow := clBtnShadow;
|
|
|
|
BevelHighlight := clBtnHighlight;
|
|
|
|
BevelDarkShadow := cl3DDkShadow;
|
|
|
|
BevelFace := clBtnFace;
|
|
|
|
WindowColor := clWindow;
|
|
|
|
HighlightText := clHighlightText;
|
|
|
|
HighlightBkg := clHighlight;
|
|
|
|
RealHeadAttrColor := FDayView.HeadAttributes.Color;
|
|
|
|
RealRowHeadAttrColor := FDayView.RowHeadAttributes.Color;
|
|
|
|
RealLineColor := FDayView.LineColor;
|
|
|
|
RealColor := FDayView.Color;
|
|
|
|
RealADEventBkgColor := FDayView.AllDayEventAttributes.BackgroundColor;
|
|
|
|
ADEventAttrBkgColor := FDayView.AllDayEventAttributes.EventBackgroundColor;
|
|
|
|
ADEventBorderColor := FDayView.AllDayEventAttributes.EventBorderColor;
|
|
|
|
end;
|
2016-06-23 11:53:21 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.InitializeEventRectangles;
|
|
|
|
var
|
|
|
|
I : Integer;
|
|
|
|
begin
|
|
|
|
EventCount := 0;
|
|
|
|
with TVpDayViewOpener(FDayView) do
|
|
|
|
for I := 0 to pred(Length(dvEventArray)) do begin
|
|
|
|
dvEventArray[I].Rec.Left := -1;
|
|
|
|
dvEventArray[I].Rec.Top := -1;
|
|
|
|
dvEventArray[I].Rec.Right := -1;
|
|
|
|
dvEventArray[I].Rec.Bottom := -1;
|
|
|
|
dvEventArray[I].Event := nil;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.RenderToCanvas(ARenderIn: TRect;
|
|
|
|
AAngle: TVpRotationAngle; AScale: Extended; ARenderDate: TDateTime;
|
|
|
|
AStartLine, AStopLine: Integer; AUseGran: TVpGranularity; ADisplayOnly: Boolean);
|
2016-07-04 15:53:06 +00:00
|
|
|
{wp: DisplayOnly is poorly-named. It is false during screen output in the form,
|
|
|
|
it is true during printing and in print preview }
|
2016-06-26 13:52:59 +00:00
|
|
|
var
|
|
|
|
tmpRect: TRect;
|
2016-06-23 11:53:21 +00:00
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
|
2016-07-04 09:55:08 +00:00
|
|
|
// Make sure to use only the date part
|
|
|
|
ARenderDate := trunc(ARenderDate);
|
|
|
|
|
2016-06-23 11:53:21 +00:00
|
|
|
InitColors;
|
|
|
|
SavePenBrush;
|
|
|
|
InitPenBrush;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
SetMeasurements;
|
|
|
|
|
2016-07-01 13:21:43 +00:00
|
|
|
{
|
2016-06-22 14:43:43 +00:00
|
|
|
if DisplayOnly then
|
|
|
|
ScrollBarOffset := 2
|
|
|
|
else
|
|
|
|
ScrollBarOffset := 14;
|
|
|
|
|
2016-07-01 13:21:43 +00:00
|
|
|
}
|
|
|
|
|
2016-07-04 15:53:06 +00:00
|
|
|
ScrollbarOffset := 0;
|
|
|
|
with TVpDayViewOpener(FDayView) do
|
|
|
|
if ADisplayOnly then begin
|
|
|
|
// use printer settings
|
|
|
|
SetTimeIntervals(ControlLink.Printer.Granularity);
|
|
|
|
TopLine := StartLine;
|
|
|
|
StartLine := TopLine;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
// use screen settings
|
|
|
|
SetTimeIntervals(Granularity);
|
|
|
|
if StartLine < 0 then
|
|
|
|
StartLine := FDayView.TopLine;
|
|
|
|
if VisibleLines < LineCount then
|
|
|
|
ScrollbarOffset := 14;
|
|
|
|
end;
|
2016-07-01 13:21:43 +00:00
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
Rgn := CreateRectRgn(RenderIn.Left, RenderIn.Top, RenderIn.Right, RenderIn.Bottom);
|
|
|
|
try
|
|
|
|
SelectClipRgn(RenderCanvas.Handle, Rgn);
|
|
|
|
|
2016-07-03 09:36:40 +00:00
|
|
|
// Fix zero font heights for printer
|
2016-07-04 19:21:55 +00:00
|
|
|
FixFontHeights;
|
2016-07-02 22:46:05 +00:00
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
{ Calculate Row Header }
|
|
|
|
RealRowHeight := TVpDayViewOpener(FDayView).dvCalcRowHeight(Scale, UseGran);
|
|
|
|
RealColHeadHeight := TVpDayViewOpener(FDayView).dvCalcColHeadHeight(Scale);
|
2016-07-04 19:21:55 +00:00
|
|
|
RealRowHeadWidth := CalcRowHeadWidth;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
{ initialize the All Day Events area... }
|
|
|
|
ADEventsRect.Left := RealLeft + 3 + RealRowHeadWidth;
|
|
|
|
ADEventsRect.Top := RealTop + RealColHeadHeight;
|
|
|
|
ADEventsRect.Right := FDayView.ClientRect.Right;
|
|
|
|
ADEventsRect.Bottom := AdEventsRect.Top;
|
|
|
|
|
|
|
|
{ Calculate the RealNumDays (The number of days the control covers) }
|
|
|
|
RealNumDays := TVpDayViewOpener(FDayView).GetRealNumDays(RenderDate);
|
|
|
|
|
|
|
|
InitializeEventRectangles;
|
|
|
|
|
2016-07-02 15:44:34 +00:00
|
|
|
{ Draw the all-day events }
|
2016-06-22 14:43:43 +00:00
|
|
|
DrawAllDayEvents;
|
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
{ Draw the area in the top left corner, where the nav buttons go. }
|
|
|
|
DrawNavBtnBackground;
|
|
|
|
|
|
|
|
{ Draw row headers }
|
|
|
|
CalcRowHeadRect(RowHeadRect);
|
2016-06-22 14:43:43 +00:00
|
|
|
if Assigned(FDayView.OwnerDrawRowHeader) then begin
|
|
|
|
Drawn := false;
|
|
|
|
FDayView.OwnerDrawRowHeader(self, RenderCanvas, RowHeadRect, RealRowHeight, Drawn);
|
|
|
|
if not Drawn then
|
|
|
|
DrawRowHeader(RowHeadRect);
|
|
|
|
end else
|
|
|
|
DrawRowHeader(RowHeadRect);
|
|
|
|
|
|
|
|
{ Draw the regular events }
|
2016-06-28 11:08:29 +00:00
|
|
|
DrawRegularEvents;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
{ Draw borders }
|
|
|
|
tmpRect := Rect(RealLeft, RealTop, RealRight-1, RealBottom-1);
|
2016-06-22 14:43:43 +00:00
|
|
|
if FDayView.DrawingStyle = dsFlat then begin
|
2016-07-03 08:39:53 +00:00
|
|
|
{ Draw a simple border }
|
2016-07-01 10:04:08 +00:00
|
|
|
DrawBevelRect(RenderCanvas, TPSRotateRectangle(Angle, RenderIn, tmpRect), BevelShadow, BevelShadow);
|
2016-06-22 14:43:43 +00:00
|
|
|
end else
|
|
|
|
if FDayView.DrawingStyle = ds3d then begin
|
|
|
|
{ Draw a 3d bevel }
|
2016-06-26 13:52:59 +00:00
|
|
|
DrawBevelRect(RenderCanvas, TPSRotateRectangle(Angle, RenderIn, tmpRect), BevelShadow, BevelHighlight);
|
|
|
|
InflateRect(tmpRect, -1, -1);
|
|
|
|
DrawBevelRect(RenderCanvas, TPSRotateRectangle(Angle, RenderIn, tmpRect), BevelDarkShadow, BevelFace);
|
2016-06-22 14:43:43 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 13:52:59 +00:00
|
|
|
{ Place navigation buttons }
|
|
|
|
DrawNavBtns;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
{ Reinstate RenderCanvas settings }
|
2016-06-23 11:53:21 +00:00
|
|
|
RestorePenBrush;
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
finally
|
|
|
|
SelectClipRgn(RenderCanvas.Handle, 0);
|
|
|
|
DeleteObject(Rgn);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
procedure TVpDayViewPainter.PopulateEventArray(ARenderDate: TDateTime);
|
|
|
|
var
|
|
|
|
EventList: TList;
|
|
|
|
event: TVpEvent;
|
|
|
|
level: Integer;
|
|
|
|
I, J: Integer;
|
|
|
|
thisTime: TTime;
|
|
|
|
begin
|
|
|
|
{ Set the event array's max size }
|
|
|
|
SetLength(EventArray, MaxVisibleEvents); // EventArray is global within painter
|
|
|
|
|
|
|
|
{ Initialize the new matrix }
|
|
|
|
for I := 0 to pred(MaxVisibleEvents) do begin
|
|
|
|
EventArray[I].Event := nil;
|
|
|
|
EventArray[I].Level := 0;
|
|
|
|
EventArray[I].OLLevels := 0;
|
|
|
|
EventArray[I].WidthDivisor := 0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
EventList := TList.Create;
|
|
|
|
try
|
|
|
|
{Get all of the events for this day}
|
|
|
|
FDayView.DataStore.Resource.Schedule.EventsByDate(ARenderDate, EventList);
|
|
|
|
|
|
|
|
{ Discard AllDayEvents, because they are drawn separately. }
|
|
|
|
for I := pred(EventList.Count) downto 0 do begin
|
|
|
|
event := EventList[I];
|
|
|
|
if event.AllDayEvent then
|
|
|
|
EventList.Delete(I);
|
|
|
|
end;
|
|
|
|
|
2016-06-30 18:45:39 +00:00
|
|
|
{ Now sort times in ascending order. This must be done because the event
|
|
|
|
list can contain recurring events which have the wrong date part }
|
2016-06-30 21:29:02 +00:00
|
|
|
EventList.Sort(@CompareEventsByTimeOnly);
|
2016-06-30 18:45:39 +00:00
|
|
|
|
2016-06-26 11:37:20 +00:00
|
|
|
{ Arrange this day's events in the event matrix }
|
|
|
|
level := 0;
|
|
|
|
I := 0;
|
|
|
|
while EventList.Count > 0 do begin
|
2016-06-30 18:45:39 +00:00
|
|
|
{ Iterate through the (corrected) events, and place them all at the proper place
|
|
|
|
in the EventMatrix, according to their start and end times }
|
2016-06-26 11:37:20 +00:00
|
|
|
J := 0;
|
|
|
|
ThisTime := 0.0;
|
|
|
|
while (J < EventList.Count) and (J < MaxVisibleEvents) do begin
|
|
|
|
event := EventList[J];
|
|
|
|
if frac(event.StartTime) >= thisTime then begin
|
|
|
|
thisTime := frac(event.EndTime);
|
|
|
|
{ Handle end times of midnight }
|
|
|
|
if thisTime = 0 then
|
|
|
|
thisTime := EncodeTime(23, 59, 59, 0);
|
|
|
|
EventList.Delete(J);
|
|
|
|
EventArray[I].Event := event;
|
|
|
|
EventArray[I].Level := level;
|
|
|
|
Inc(I);
|
|
|
|
Continue;
|
|
|
|
end
|
|
|
|
else
|
|
|
|
Inc(J);
|
|
|
|
end;
|
|
|
|
Inc(level);
|
|
|
|
end;
|
|
|
|
|
|
|
|
finally
|
|
|
|
EventList.Free;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.PrepareEventRect(AWidthDivisor, ALevel: Integer;
|
2016-06-26 22:21:39 +00:00
|
|
|
var AEventRect: TRect);
|
|
|
|
var
|
|
|
|
eventWidth: Integer;
|
2016-06-26 11:37:20 +00:00
|
|
|
begin
|
|
|
|
if AEventRect.Left < VisibleRect.Left then
|
|
|
|
AEventRect.Left := VisibleRect.Left;
|
|
|
|
|
|
|
|
if AEventRect.Top < VisibleRect.Top then
|
|
|
|
AEventRect.Top := VisibleRect.Top;
|
|
|
|
|
2016-07-02 15:44:34 +00:00
|
|
|
if AEventRect.Bottom = -1 then
|
|
|
|
AEventRect.Bottom := AEventRect.Top + RealRowHeight
|
|
|
|
else
|
|
|
|
if (AEventRect.Bottom < VisibleRect.Top) then
|
2016-06-26 11:37:20 +00:00
|
|
|
AEventRect.Bottom := VisibleRect.Bottom;
|
2016-07-02 15:44:34 +00:00
|
|
|
|
2016-06-26 22:21:39 +00:00
|
|
|
eventWidth := WidthOf(VisibleRect) div AWidthDivisor;
|
2016-06-26 11:37:20 +00:00
|
|
|
|
|
|
|
{ Slide the rect over to correspond with the level }
|
|
|
|
if ALevel > 0 then
|
2016-06-26 22:21:39 +00:00
|
|
|
AEventRect.Left := AEventRect.Left + eventWidth * ALevel
|
2016-06-26 11:37:20 +00:00
|
|
|
{ added because level 0 events were one pixel too far to the right }
|
|
|
|
else
|
|
|
|
AEventRect.Left := AEventRect.Left - 1;
|
2016-07-02 15:44:34 +00:00
|
|
|
AEventRect.Right := AEventRect.Left + eventWidth + 1;
|
2016-06-26 11:37:20 +00:00
|
|
|
end;
|
|
|
|
|
2016-06-26 16:27:01 +00:00
|
|
|
{ remove the date portion from the start and end times }
|
2016-06-26 11:37:20 +00:00
|
|
|
procedure TVpDayViewPainter.PrepareEventTimes(AEvent: TVpEvent;
|
|
|
|
ARenderDate: TDateTime; out AStartTime, AEndTime: TDateTime);
|
|
|
|
begin
|
|
|
|
(* -- original
|
|
|
|
{ remove the date portion from the start and end times }
|
|
|
|
EventSTime := Event.StartTime;
|
|
|
|
EventETime := Event.EndTime;
|
|
|
|
if trunc(EventSTime) < trunc(ARenderDate) then //First Event
|
|
|
|
EventSTime := 0+trunc(ARenderDate);
|
|
|
|
if trunc(EventETime) > trunc(ARenderDate) then //First Event
|
|
|
|
EventETime := 0.999+trunc(ARenderDate);
|
|
|
|
EventSTime := EventSTime - ARenderDate;
|
|
|
|
EventETime := EventETime - ARenderDate;
|
|
|
|
{ Find the line on which this event starts }
|
|
|
|
EventSLine := GetStartLine(EventSTime, Granularity);
|
|
|
|
{ Handle End Times of Midnight }
|
|
|
|
if EventETime = 0 then
|
|
|
|
EventETime := EncodeTime (23, 59, 59, 0);
|
|
|
|
*)
|
|
|
|
|
|
|
|
AStartTime := AEvent.StartTime;
|
|
|
|
AEndTime := AEvent.EndTime;
|
|
|
|
|
|
|
|
if (AStartTime < trunc(ARenderDate)) and (AEvent.RepeatCode = rtNone) then // First Event
|
|
|
|
AStartTime := trunc(ARenderDate)
|
|
|
|
else if (AEvent.RepeatCode <> rtNone) then
|
|
|
|
AStartTime := frac(AStartTime) + trunc(ARenderDate);
|
|
|
|
|
|
|
|
if (trunc(AEndTime) > trunc(ARenderDate)) and (AEvent.RepeatCode = rtNone) then // First Event
|
|
|
|
// wp: wouldn't this be better?
|
|
|
|
// AEndtime := trunc(ARenderDate) + 1 - 1.0 / (24 * 60 * 60) // 1 sec before midnight
|
|
|
|
AEndTime := 0.999 + trunc(ARenderDate)
|
|
|
|
else if (AEvent.RepeatCode <> rtNone) then
|
|
|
|
AEndTime := frac(AEndTime) + trunc(ARenderDate);
|
|
|
|
|
|
|
|
AStartTime := AStartTime - trunc(ARenderDate);
|
|
|
|
AEndTime := AEndTime - trunc(ARenderDate);
|
|
|
|
|
|
|
|
{ Handle End Times of Midnight }
|
|
|
|
if AEndTime = 0 then
|
|
|
|
AEndTime := EncodeTime(23, 59, 59, 0); // wp: Is the date part correct here?
|
|
|
|
end;
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
procedure TVpDayViewPainter.ScaleIcons(EventRect: TRect);
|
|
|
|
var
|
|
|
|
h: Integer;
|
|
|
|
begin
|
|
|
|
h := EventRect.Bottom - EventRect.Top - 2;
|
|
|
|
|
|
|
|
if (dvBmpAlarm.Height > h) and (dvBmpAlarm.Height * dvBmpAlarm.Width <> 0)
|
|
|
|
then begin
|
|
|
|
AlarmW := Trunc((h / dvBmpAlarm.Height) * dvBmpAlarm.Width);
|
|
|
|
AlarmH := h;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (dvBmpRecurring.Height > h) and (dvBmpRecurring.Height * dvBmpRecurring.Width <> 0)
|
|
|
|
then begin
|
|
|
|
RecurringW := Trunc((h / dvBmpRecurring.Height) * dvBmpRecurring.Width);
|
|
|
|
RecurringH := h;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (dvBmpCategory.Height > h) and (dvBmpCategory.Height * dvBmpCategory.Width <> 0)
|
|
|
|
then begin
|
|
|
|
CategoryW := Trunc((h / dvBmpCategory.Height) * dvBmpCategory.Width);
|
|
|
|
CategoryH := h;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if (dvBmpCustom.Height > h) and (dvBmpCustom.Height * dvBmpCustom.Width <> 0)
|
|
|
|
then begin
|
|
|
|
CustomW := Trunc((h / dvBmpCustom.Height) * dvBmpCustom.Width);
|
|
|
|
CustomH := h;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpDayViewPainter.SetMeasurements;
|
|
|
|
begin
|
2016-06-23 11:53:21 +00:00
|
|
|
inherited;
|
2016-06-22 14:43:43 +00:00
|
|
|
TVpDayViewOpener(FDayView).dvCalcColHeadHeight(Scale);
|
|
|
|
end;
|
|
|
|
|
2016-06-26 16:27:01 +00:00
|
|
|
procedure TVpDayViewPainter.VerifyMaxWidthDevisors;
|
|
|
|
var
|
|
|
|
I, K: Integer;
|
|
|
|
Event1, Event2: TVpEvent;
|
|
|
|
tStart1, tEnd1, tStart2, tEnd2: TTime;
|
|
|
|
begin
|
|
|
|
for I := 0 to pred(MaxVisibleEvents) do begin
|
|
|
|
{ if we hit a null event, then we're through }
|
|
|
|
if EventArray[I].Event = nil then
|
|
|
|
Break;
|
|
|
|
|
|
|
|
{ otherwise keep going }
|
|
|
|
Event1 := EventArray[I].Event;
|
|
|
|
|
|
|
|
{ get start and end times without the date part }
|
|
|
|
tStart1 := frac(Event1.StartTime);
|
|
|
|
tEnd1 := frac(Event1.EndTime);
|
|
|
|
|
|
|
|
{ initialize the WidthDivisor for this record }
|
|
|
|
EventArray[I].WidthDivisor := 1;
|
|
|
|
|
|
|
|
{ Now iterate through all events and get the maximum OLEvents value of all
|
|
|
|
the overlapping events }
|
|
|
|
for K := 0 to pred(MaxVisibleEvents) do begin
|
|
|
|
{ if we hit a null event, then we're through }
|
|
|
|
if EventArray[K].Event = nil then
|
|
|
|
Break;
|
|
|
|
|
|
|
|
Event2 := EventArray[K].Event;
|
|
|
|
tStart2 := frac(Event2.StartTime);
|
|
|
|
tEnd2 := frac(Event2.EndTime);
|
|
|
|
|
|
|
|
{ if the Tmp event overlaps with Event, then check its WidthDivisor }
|
|
|
|
if TimeInRange(tStart2, tStart1, tEnd1, false) or
|
|
|
|
TimeInRange(tEnd2, tStart1, tEnd1, false) or
|
|
|
|
((tStart2 <= tStart1) and (tEnd2 >= tEnd1))
|
|
|
|
then begin
|
|
|
|
if EventArray[I].WidthDivisor < EventArray[K].WidthDivisor then
|
|
|
|
EventArray[I].WidthDivisor := EventArray[K].WidthDivisor;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ -- original
|
|
|
|
if (TimeInRange(Event2.StartTime, Event1.StartTime, Event1.EndTime, false)
|
|
|
|
or TimeInRange(Event2.EndTime, Event1.StartTime, Event1.EndTime, false))
|
|
|
|
or ((Event2.StartTime <= Event1.StartTime)
|
|
|
|
and (Event2.EndTime >= Event1.EndTime))
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
if TimeInRange(frac(Event2.StartTime), frac(Event1.StartTime), frac(Event1.EndTime), false) or
|
|
|
|
TimeInRange(frac(Event2.EndTime), frac(Event1.StartTime), frac(Event1.EndTime), false) or
|
|
|
|
((frac(Event2.StartTime) <= frac(Event1.StartTime)) and (frac(Event2.EndTime) >= frac(Event1.EndTime)))
|
|
|
|
then begin
|
|
|
|
if EventArray[I].WidthDivisor < EventArray[K].WidthDivisor then
|
|
|
|
EventArray[I].WidthDivisor := EventArray[K].WidthDivisor;
|
|
|
|
end;
|
|
|
|
}
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2016-06-22 14:43:43 +00:00
|
|
|
|
|
|
|
end.
|