tvplanit: Extract event drawing code from TVpDayViewPainter.DrawEvents. Some more refactoring.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4834 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-06-25 10:08:36 +00:00
parent 448f4b8027
commit e704901b0e

View File

@ -69,6 +69,13 @@ type
AlarmH: Integer;
CustomW: Integer;
CustomH: Integer;
EventArray: TVpDvEventArray;
VisibleRect: TRect;
LineDuration, PixelDuration: Double;
IconRect: TRect;
OldPen: TPen;
OldBrush: TBrush;
OldFont: TFont;
protected
function CountOverlappingEvents(Event: TVpEvent; const EArray: TVpDvEventArray): Integer;
@ -80,6 +87,8 @@ type
procedure DrawCells(R: TRect; ColDate: TDateTime; Col: Integer);
procedure DrawColHeader(R: TRect; ARenderDate: TDateTime; Col: Integer);
procedure DrawEditFrame(R: TRect; AGutter: Integer; AColor: TColor);
procedure DrawEvent(AEvent: TVpEvent; AEventRec: TVpDvEventRec;
ARenderDate: TDateTime; Col: Integer);
procedure DrawEvents(ARenderDate: TDateTime; Col: Integer);
procedure DrawIcons(AIconRect: TRect);
procedure DrawRowHeader(R: TRect);
@ -102,6 +111,7 @@ type
implementation
uses
StrUtils,
VpCanvasUtils, VpMisc;
type
@ -695,22 +705,318 @@ begin
end;
end;
procedure TVpDayViewPainter.DrawEvents(ARenderDate: TDateTime; Col: Integer);
procedure TVpDayViewPainter.DrawEvent(AEvent: TVpEvent; AEventRec: TVpDvEventRec;
ARenderDate: TDateTime; Col: Integer);
var
I,J, StartPixelOffset, EndPixelOffset: Integer;
Level, EventWidth, EventSLine, EventELine: Integer;
EventLineCount: Integer;
EventSTime, EventETime, ThisTime: Double;
EventDuration, LineDuration, PixelDuration: Double;
StartOffset, EndOffset, STime, ETime: Double;
EventRect, VisibleRect, GutterRect: TRect;
EventString, Format: string;
Event: TVpEvent;
SaveFont: TFont;
SaveColor: TColor;
EventArray: TVpDvEventArray;
EventList: TList;
IconRect: TRect;
EventCategory: TVpCategoryInfo;
EventIsEditing: Boolean;
EventSTime, EventETime: Double;
EventDuration: Double;
EventSLine, EventELine, EventLineCount: Integer;
EventWidth: Integer;
EventRect, GutterRect: TRect;
StartPixelOffset, EndPixelOffset: Integer;
StartOffset, EndOffset: Double;
timeFmt: String;
EventString: String;
TextRegion : HRGN;
WorkRegion1: HRGN;
WorkRegion2: HRGN;
tmpRect: TRect;
CW: Integer;
w: Integer;
begin
{ Initialize, collect useful information needed later }
EventCategory := FDayView.Datastore.CategoryColorMap.GetCategory(AEvent.Category);
EventIsEditing := false;
with TVpDayViewOpener(FDayView) do
if (dvInplaceEditor <> nil) and dvInplaceEditor.Visible then
EventIsEditing := (ActiveEvent = AEvent);
timeFmt := IfThen(FDayView.TimeFormat = tf24Hour, 'h:nn', 'h:nnam/pm');
(* -- 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);
*)
{ remove the date portion from the start and end times }
EventSTime := AEvent.StartTime;
EventETime := AEvent.EndTime;
if (EventSTime < trunc(ARenderDate)) and (AEvent.RepeatCode = rtNone) then // First Event
EventSTime := trunc(ARenderDate)
else if (AEvent.RepeatCode <> rtNone) then
EventSTime := frac(EventSTime) + trunc(ARenderDate);
if (trunc(EventETime) > trunc(ARenderDate)) and (AEvent.RepeatCode = rtNone) then // First Event
EventETime := 0.999 + trunc(ARenderDate)
else if (AEvent.RepeatCode <> rtNone) then
EventETime := frac(EventETime) + trunc(ARenderDate);
EventSTime := EventSTime - trunc(ARenderDate);
EventETime := EventETime - trunc(ARenderDate);
{ Handle End Times of Midnight }
if EventETime = 0 then
EventETime := EncodeTime(23, 59, 59, 0);
{ Find the line on which this event starts }
EventSLine := GetStartLine(EventSTime, FDayView.Granularity);
{ Calculate the number of lines this event will cover }
EventELine := GetEndLine(EventETime {Event.EndTime}, FDayView.Granularity);
EventLineCount := EventELine - EventSLine + 1;
EventDuration := EventETime - EventSTime;
{ If the event doesn't occupy area that is currently visible, then skip it. }
if (EventELine < StartLine) or (EventSLine > StartLine + RealVisibleLines) then
Exit;
{ Build the rectangle in which the event will be painted. }
EventRect := TVpDayViewOpener(FDayView).dvLineMatrix[Col, EventSLine].Rec;
if EventRect.Left < VisibleRect.Left then
EventRect.Left := VisibleRect.Left;
if EventRect.Top < VisibleRect.Top then
EventRect.Top := VisibleRect.Top;
EventRect.Bottom := TVpDayViewOpener(FDayView).dvLineMatrix[Col, EventELine].Rec.Bottom;
if EventRect.Bottom < VisibleRect.Top then
EventRect.Bottom := VisibleRect.Bottom;
EventWidth := WidthOf(VisibleRect) div AEventRec.WidthDivisor;
{ Slide the rect over to correspond with the level }
if AEventRec.Level > 0 then
EventRect.Left := EventRect.Left + EventWidth * AEventRec.Level
{ added because level 0 events were one pixel too far to the right }
else
EventRect.Left := EventRect.Left - 1;
EventRect.Right := EventRect.Left + EventWidth - FDayView.GutterWidth;
{ Draw the event rectangle }
{ paint Event text area clWindow }
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);
{ paint the little area to the left of the text the color corresponding to
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 }
EndOffset := TVpDayViewOpener(FDayView).dvLineMatrix[0, EventELine + 1].Time - EventETime;
{ determine how many pixels to scooch down before painting the event's color code. }
EndPixelOffset := trunc(EndOffset / PixelDuration);
end;
end;
{ Paint the gutter inside the EventRect all events }
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;
GutterRect.Bottom := EventRect.Bottom - EndPixelOffset;
TPSFillRect(RenderCanvas, Angle, RenderIn, GutterRect);
RenderCanvas.Brush.Color := WindowColor;
{ build the event string }
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);
IconRect := DetermineIconRect(EventRect, AEvent);
end else begin
tmpRect := EventRect;
inc(tmpRect.Left, FDayView.GutterWidth);
ScaleIcons(tmpRect);
IconRect := DetermineIconRect(tmpRect, AEvent);
end;
end;
{ wp: Using Canvas here does not look correct...
OldPen.Assign(Canvas.Pen);
OldBrush.Assign(Canvas.Brush);
OldFont.Assign(Canvas.Font);
}
OldPen.Assign(RenderCanvas.Pen);
OldBrush.Assign(RenderCanvas.Brush);
OldFont.Assign(RenderCanvas.Font);
if Assigned(FDayView.OnBeforeDrawEvent) and (AEventRec.Level = 0) then
FDayView.OnBeforeDrawEvent(Self, AEvent, FDayView.ActiveEvent = AEvent, RenderCanvas, EventRect, IconRect)
else if Assigned(FDayView.OnBeforeDrawEvent) then
FDayView.OnBeforeDrawEvent(Self, AEvent, FDayView.ActiveEvent = AEvent, RenderCanvas,
Rect(EventRect.Left + FDayView.GutterWidth, EventRect.Top, EventRect.Right, EventRect.Bottom),
IconRect
);
if not DisplayOnly then
DrawIcons(IconRect);
if FDayView.ShowEventTimes then
EventString := Format('%s - %s: %s', [
FormatDateTime(timeFmt, AEvent.StartTime),
FormatDateTime(timeFmt, AEvent.EndTime),
AEvent.Description
])
else
EventString := AEvent.Description;
if FDayView.WrapStyle = wsNone then begin
{ if the string is longer than the availble space then chop }
{ off the and and place those little '...'s at the end }
w := EventRect.Right - IconRect.Right - Round(FDayView.GutterWidth * Scale) - TextMargin;
if RenderCanvas.TextWidth(EventString) > w then
EventString := GetDisplayString(RenderCanvas, EventString, 0, w);
end;
if (FDayView.WrapStyle <> wsNone) and (not EventIsEditing) then begin
if (EventRect.Bottom <> IconRect.Bottom) and (EventRect.Left <> IconRect.Right)
then begin
if FDayView.WrapStyle = wsIconFlow then
begin
WorkRegion1 := CreateRectRgn(IconRect.Right, EventRect.Top, EventRect.Right, IconRect.Bottom);
WorkRegion2 := CreateRectRgn(EventRect.Left + FDayView.GutterWidth, IconRect.Bottom, EventRect.Right, EventRect.Bottom);
TextRegion := CreateRectRgn(IconRect.Right, EventRect.Top, EventRect.Right, IconRect.Bottom);
CombineRgn(TextRegion, WorkRegion1, WorkRegion2, RGN_OR);
end else
TextRegion := CreateRectRgn(IconRect.Right, EventRect.Top, EventRect.Right, EventRect.Bottom);
end else
TextRegion := CreateRectRgn(IconRect.Right + FDayView.GutterWidth, EventRect.Top, EventRect.Right, EventRect.Bottom);
try
CW := RenderTextToRegion(RenderCanvas, Angle, RenderIn, TextRegion, EventString);
{ write the event string to the proper spot in the EventRect }
if CW < Length(EventString) then begin
RenderCanvas.Brush.Color := FDayView.DotDotDotColor;
{ draw dot dot dot }
TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(EventRect.Right - 20, EventRect.Bottom - 7, EventRect.Right - 17, EventRect.Bottom - 4)
);
TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(EventRect.Right - 13, EventRect.Bottom - 7, EventRect.Right - 10, EventRect.Bottom - 4));
TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(EventRect.Right - 6, EventRect.Bottom - 7, EventRect.Right - 3, EventRect.Bottom - 4));
end;
finally
if ((EventRect.Bottom > IconRect.Bottom) and (EventRect.Left > IconRect.Right)) or
(FDayView.WrapStyle = wsIconFlow)
then begin
DeleteObject(WorkRegion1);
DeleteObject(WorkRegion2);
DeleteObject(TextRegion);
end else begin
DeleteObject(TextRegion);
end;
end;
end
else
if (not EventIsEditing) then begin
if AEventRec.Level = 0 then
{ don't draw the gutter in the EventRest for level 0 events. }
TPSTextOut(RenderCanvas, // wp: both cases are the same ?!
Angle,
RenderIn,
IconRect.Right + FDayView.GutterWidth + TextMargin,
EventRect.Top + TextMargin,
EventString
)
else
TPSTextOut(RenderCanvas,
Angle,
RenderIn,
IconRect.Right + FDayView.GutterWidth + TextMargin,
EventRect.Top + TextMargin,
EventString
);
end;
{ 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;
if Assigned(FDayView.OnAfterDrawEvent) and (AEventRec.Level = 0) then
FDayView.OnAfterDrawEvent(Self, AEvent, FDayView.ActiveEvent = AEvent, RenderCanvas, EventRect, IconRect)
else
if Assigned(FDayView.OnAfterDrawEvent) then
FDayView.OnAfterDrawEvent(Self, AEvent, FDayView.ActiveEvent = AEvent, RenderCanvas,
Rect(EventRect.Left + FDayView.GutterWidth, EventRect.Top, EventRect.Right, EventRect.Bottom),
IconRect
);
{ Canvas does not look correct here...
Canvas.Brush.Assign(OldBrush);
Canvas.Pen.Assign(OldPen);
Canvas.Font.Assign(OldFont); }
RenderCanvas.Brush.Assign(OldBrush);
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);
procedure VerifyMaxWidthDivisors;
var
@ -756,16 +1062,15 @@ var
end;
var
I,J: Integer;
Level: Integer;
STime, ETime: Double;
Event: TVpEvent;
SaveFont: TFont;
SaveColor: TColor;
EventList: TList;
OKToDrawEditFrame: Boolean;
TextRegion : HRGN;
WorkRegion1: HRGN;
WorkRegion2: HRGN;
CW: Integer;
EventIsEditing: Boolean;
EventCategory: TVpCategoryInfo;
OldPen: TPen;
OldBrush: TBrush;
OldFont: TFont;
ThisTime: Double;
begin
if (FDayView.DataStore = nil) or (FDayView.DataStore.Resource = nil) or
(not FDayView.DataStore.Connected) then
@ -776,12 +1081,6 @@ begin
SaveFont := TFont.Create;
SaveFont.Assign(RenderCanvas.Font);
{ Initialize some stuff }
if FDayView.TimeFormat = tf24Hour then
Format := 'h:nn'
else
Format := 'h:nnam/pm';
{ set the event array's size }
SetLength(EventArray, MaxVisibleEvents);
@ -888,314 +1187,7 @@ begin
if Event = nil then
Break;
{ Collect useful information needed later }
EventCategory := FDayView.Datastore.CategoryColorMap.GetCategory(Event.Category);
EventIsEditing := false;
if (TVpDayViewOpener(FDayView).dvInPlaceEditor <> nil) and
TVpDayViewOpener(FDayView).dvInplaceEditor.Visible and
(FDayView.ActiveEvent = Event)
then
EventIsEditing := true;
(* -- 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);
*)
{ remove the date portion from the start and end times }
EventSTime := Event.StartTime;
EventETime := Event.EndTime;
if (EventSTime < trunc(ARenderDate)) and (Event.RepeatCode = rtNone) then // First Event
EventSTime := trunc(ARenderDate)
else if (Event.RepeatCode <> rtNone) then
EventSTime := frac(EventSTime) + trunc(ARenderDate);
if (trunc(EventETime) > trunc(ARenderDate)) and (Event.RepeatCode = rtNone) then // First Event
EventETime := 0.999 + trunc(ARenderDate)
else if (Event.RepeatCode <> rtNone) then
EventETime := frac(EventETime) + trunc(ARenderDate);
EventSTime := EventSTime - trunc(ARenderDate);
EventETime := EventETime - trunc(ARenderDate);
{ Find the line on which this event starts }
EventSLine := GetStartLine(EventSTime, FDayView.Granularity);
{ Handle End Times of Midnight }
if EventETime = 0 then
EventETime := EncodeTime(23, 59, 59, 0);
{ calculate the number of lines this event will cover }
EventELine := GetEndLine(EventETime {Event.EndTime}, FDayView.Granularity);
EventLineCount := EventELine - EventSLine + 1;
EventDuration := EventETime - EventSTime;
{ if the event doesn't occupy area that is currently visible, then skip it. }
if (EventELine < StartLine) or (EventSLine > StartLine + RealVisibleLines) then
Continue;
{ Build the rectangle in which the event will be painted. }
EventRect := TVpDayViewOpener(FDayView).dvLineMatrix[Col, EventSLine].Rec;
if EventRect.Left < VisibleRect.Left then
EventRect.Left := VisibleRect.Left;
if EventRect.Top < VisibleRect.Top then
EventRect.Top := VisibleRect.Top;
EventRect.Bottom := TVpDayViewOpener(FDayView).dvLineMatrix[Col, EventELine].Rec.Bottom;
if EventRect.Bottom < VisibleRect.Top then
EventRect.Bottom := VisibleRect.Bottom;
EventWidth := WidthOf(VisibleRect) div EventArray[I].WidthDivisor;
{ Slide the rect over to correspond with the level }
if EventArray[I].Level > 0 then
EventRect.Left := EventRect.Left + EventWidth * EventArray[I].Level
{ added because level 0 events were one pixel too far to the right }
else
EventRect.Left := EventRect.Left - 1;
EventRect.Right := EventRect.Left + EventWidth - FDayView.GutterWidth;
{ Draw the event rectangle }
{ paint Event text area clWindow }
if Assigned(FDayView.DataStore) then begin
if EventIsEditing then
RenderCanvas.Brush.Color := clWindow
else
RenderCanvas.Brush.Color := EventCategory.BackgroundColor
end else
RenderCanvas.Brush.Color := WindowColor;
TPSFillRect(RenderCanvas, Angle, RenderIn, EventRect);
{ paint the little area to the left of the text the color }
{ corresponding to the event's category }
{ These colors are used even when printing }
if Assigned(FDayView.DataStore) then
RenderCanvas.Brush.Color := EventCategory.Color; //FDayView.DataStore.CategoryColorMap.GetColor(Event.Category);
{ 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 }
EndOffset := TVpDayViewOpener(FDayView).dvLineMatrix[0, EventELine + 1].Time - EventETime;
{ determine how many pixels to scooch down before painting the }
{ event's color code. }
EndPixelOffset := trunc(EndOffset / PixelDuration);
end;
end;
{ Paint the gutter inside the EventRect all events }
if (EventArray[I].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;
GutterRect.Bottom := EventRect.Bottom - EndPixelOffset;
TPSFillRect(RenderCanvas, Angle, RenderIn, GutterRect);
RenderCanvas.Brush.Color := WindowColor;
{ if (TVpDayViewOpener(FDayView).dvInPlaceEditor <> nil) and
TVpDayViewOpener(FDayView).dvInplaceEditor.Visible then
begin
if FDayView.ActiveEvent = Event then
EventIsEditing := True
else
EventIsEditing := False;
end else
EventIsEditing := False;
}
{ build the event string }
IconRect.Left := EventRect.Left;
IconRect.Top := EventRect.Top;
IconRect.Right := EventRect.Left;
IconRect.Bottom := EventRect.Top;
if not DisplayOnly then begin
GetIcons(Event);
if EventArray[I].Level = 0 then begin
ScaleIcons(EventRect);
IconRect := DetermineIconRect(EventRect, Event);
end else begin
ScaleIcons(Rect(
EventRect.Left + FDayView.GutterWidth,
EventRect.Top,
EventRect.Right,
EventRect.Bottom
));
IconRect := DetermineIconRect(Rect(
EventRect.Left + FDayView.GutterWidth,
EventRect.Top,
EventRect.Right,
EventRect.Bottom
),
Event
);
end;
end;
{ wp: Using Canvas here does not look correct...
OldPen.Assign(Canvas.Pen);
OldBrush.Assign(Canvas.Brush);
OldFont.Assign(Canvas.Font);
}
OldPen.Assign(RenderCanvas.Pen);
OldBrush.Assign(RenderCanvas.Brush);
OldFont.Assign(RenderCanvas.Font);
if Assigned(FDayView.OnBeforeDrawEvent) and (EventArray[I].Level = 0) then
FDayView.OnBeforeDrawEvent(Self, Event, FDayView.ActiveEvent = Event, RenderCanvas, EventRect, IconRect)
else if Assigned(FDayView.OnBeforeDrawEvent) then
FDayView.OnBeforeDrawEvent(Self, Event, FDayView.ActiveEvent = Event, RenderCanvas,
Rect(EventRect.Left + FDayView.GutterWidth, EventRect.Top, EventRect.Right, EventRect.Bottom),
IconRect
);
if not DisplayOnly then
DrawIcons(IconRect);
if FDayView.ShowEventTimes then
EventString := FormatDateTime(Format, Event.StartTime) + '-' +
FormatDateTime(Format, Event.EndTime) + ' ' + Event.Description
else
EventString := Event.Description;
if FDayView.WrapStyle = wsNone then begin
{ if the string is longer than the availble space then chop }
{ off the and and place those little '...'s at the end }
if RenderCanvas.TextWidth(EventString) > EventRect.Right - IconRect.Right - Round(FDayView.GutterWidth * Scale) - TextMargin
then
EventString := GetDisplayString(
RenderCanvas,
EventString,
0,
EventRect.Right - IconRect.Right - Round(FDayView.GutterWidth * Scale) - TextMargin
);
end;
if (FDayView.WrapStyle <> wsNone) and (not EventIsEditing) then begin
if (EventRect.Bottom <> IconRect.Bottom) and (EventRect.Left <> IconRect.Right)
then begin
if FDayView.WrapStyle = wsIconFlow then
begin
WorkRegion1 := CreateRectRgn(IconRect.Right, EventRect.Top, EventRect.Right, IconRect.Bottom);
WorkRegion2 := CreateRectRgn(EventRect.Left + FDayView.GutterWidth, IconRect.Bottom, EventRect.Right, EventRect.Bottom);
TextRegion := CreateRectRgn(IconRect.Right, EventRect.Top, EventRect.Right, IconRect.Bottom);
CombineRgn(TextRegion, WorkRegion1, WorkRegion2, RGN_OR);
end else
TextRegion := CreateRectRgn(IconRect.Right, EventRect.Top, EventRect.Right, EventRect.Bottom);
end else
TextRegion := CreateRectRgn(IconRect.Right + FDayView.GutterWidth, EventRect.Top, EventRect.Right, EventRect.Bottom);
try
CW := RenderTextToRegion(RenderCanvas, Angle, RenderIn, TextRegion, EventString);
{ write the event string to the proper spot in the EventRect }
if CW < Length (EventString) then begin
RenderCanvas.Brush.Color := FDayView.DotDotDotColor;
{ draw dot dot dot }
TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(EventRect.Right - 20, EventRect.Bottom - 7, EventRect.Right - 17, EventRect.Bottom - 4)
);
TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(EventRect.Right - 13, EventRect.Bottom - 7, EventRect.Right - 10, EventRect.Bottom - 4));
TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(EventRect.Right - 6, EventRect.Bottom - 7, EventRect.Right - 3, EventRect.Bottom - 4));
end;
finally
if ((EventRect.Bottom > IconRect.Bottom) and (EventRect.Left > IconRect.Right)) or
(FDayView.WrapStyle = wsIconFlow)
then begin
DeleteObject(WorkRegion1);
DeleteObject(WorkRegion2);
DeleteObject(TextRegion);
end else begin
DeleteObject(TextRegion);
end;
end;
end
else
if (not EventIsEditing) then begin
if EventArray[I].Level = 0 then
{ don't draw the gutter in the EventRest for level 0 events. }
TPSTextOut(RenderCanvas,
Angle,
RenderIn,
IconRect.Right + FDayView.GutterWidth + TextMargin,
EventRect.Top + TextMargin,
EventString
)
else
TPSTextOut(RenderCanvas,
Angle,
RenderIn,
IconRect.Right + FDayView.GutterWidth + TextMargin,
EventRect.Top + TextMargin,
EventString
);
end;
{ 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 EventArray[I].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;
if Assigned(FDayView.OnAfterDrawEvent) and (EventArray[I].Level = 0) then
FDayView.OnAfterDrawEvent(Self, Event, FDayView.ActiveEvent = Event, RenderCanvas, EventRect, IconRect)
else
if Assigned(FDayView.OnAfterDrawEvent) then
FDayView.OnAfterDrawEvent(Self, Event, FDayView.ActiveEvent = Event, RenderCanvas,
Rect(EventRect.Left + FDayView.GutterWidth, EventRect.Top, EventRect.Right, EventRect.Bottom),
IconRect
);
{ Canvas does not look correct here...
Canvas.Brush.Assign(OldBrush);
Canvas.Pen.Assign(OldPen);
Canvas.Font.Assign(OldFont); }
RenderCanvas.Brush.Assign(OldBrush);
RenderCanvas.Pen.Assign(OldPen);
RenderCanvas.Font.Assign(OldFont);
TVpDayViewOpener(FDayView).dvEventArray[EventCount].Rec := Rect(
EventRect.Left, EventRect.Top, EventRect.Right, EventRect.Bottom + 1
);
TVpDayViewOpener(FDayView).dvEventArray[EventCount].IconRect := IconRect;
TVpDayViewOpener(FDayView).dvEventArray[EventCount].Event := Event;
Inc(EventCount);
DrawEvent(Event, EventArray[i], ARenderDate, Col);
end;
{ paint extra borders around the editor }