tvplanit: Refactor TVpWeekViewDrawer.DrawDays - extract separate method DrawDay. Some cosmetic changes.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4822 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-06-24 14:16:51 +00:00
parent 693008d145
commit d80869e322
3 changed files with 238 additions and 196 deletions

View File

@ -128,6 +128,8 @@ function GetLineDuration(Granularity: TVpGranularity): Double;
function GetLabelWidth(ALabel: TLabel): Integer; function GetLabelWidth(ALabel: TLabel): Integer;
function SameDate(dt1, dt2: TDateTime): Boolean; function SameDate(dt1, dt2: TDateTime): Boolean;
function GetWeekOfYear(ADate: TDateTime): byte;
implementation implementation
@ -612,4 +614,16 @@ begin
Result := trunc(dt1) = trunc(dt2); Result := trunc(dt1) = trunc(dt2);
end; end;
function GetWeekOfYear(ADate: TDateTime): byte;
// was in TvWeekView
var
yr, dummy: word;
First: TDateTime;
begin
DecodeDate(ADate + (8 - DayOfWeek(ADate)) mod 7 - 3, yr, dummy,dummy);
First := EncodeDate(yr, 1, 1);
Result := (trunc(ADate - First - 3 + (DayOfWeek(First) + 1) mod 7) div 7) + 1;
end;
end. end.

View File

@ -798,17 +798,18 @@ begin
{ edit this event } { edit this event }
wvSpawnEventEditDialog(False); wvSpawnEventEditDialog(False);
end end
else if (DataStore.Resource <> nil) then begin else
if (DataStore.Resource <> nil) then begin
{ otherwise, we must want to create a new event } { otherwise, we must want to create a new event }
StartTime := trunc(Date) + 1 / 2; { default to 12:00 noon } StartTime := trunc(Date) + 0.5; { default to 12:00 noon }
EndTime := StartTime + (30 / MinutesInDay); { StartTime + 30 minutes } EndTime := StartTime + 30 / MinutesInDay; { StartTime + 30 minutes }
ActiveEvent := DataStore.Resource.Schedule.AddEvent( ActiveEvent := DataStore.Resource.Schedule.AddEvent(
DataStore.GetNextID('Events'), DataStore.GetNextID('Events'),
StartTime, StartTime,
EndTime EndTime
); );
{ edit this new event } { edit this new event }
wvSpawnEventEditDialog(True); wvSpawnEventEditDialog(True); // true = new event
end; end;
end; end;
end; end;

View File

@ -38,6 +38,7 @@ type
procedure Clear; procedure Clear;
function DrawAllDayEvents(ADate: TDateTime; DayRect: TRect; var EAIndex: Integer): Boolean; function DrawAllDayEvents(ADate: TDateTime; DayRect: TRect; var EAIndex: Integer): Boolean;
procedure DrawBorders; procedure DrawBorders;
procedure DrawDay(AIndex: Integer; var DayRect: TRect; var EAIndex: Integer);
procedure DrawDays; procedure DrawDays;
procedure DrawHeader; procedure DrawHeader;
procedure InitColors; procedure InitColors;
@ -244,88 +245,65 @@ begin
end; end;
end; end;
procedure TVpWeekViewPainter.DrawDays; procedure TVpWeekViewPainter.DrawDay(AIndex: Integer; var DayRect: TRect;
var EAIndex: Integer);
var var
DayRect: TRect;
TextRect: TRect; TextRect: TRect;
I, J, SL: Integer; DayStr: String;
EAIndex: Integer; SL: Integer;
DayStr: string; tmpRect: TRect;
J: Integer;
EventList: TList; EventList: TList;
TodayStartTime: Double; TodayStartTime: Double;
TodayEndTime: Double; TodayEndTime: Double;
begin begin
RenderCanvas.Pen.Color := RealLineColor;
RenderCanvas.Pen.Style := psSolid;
{ initialize WeekdayArray }
with TVpWeekViewOpener(FWeekView) do
for I := 0 to pred(Length(wvWeekdayArray)) do begin
wvWeekdayArray[I].Rec.TopLeft := Point(-1, -1);
wvWeekdayArray[I].Rec.BottomRight := Point(-1, -1);
wvWeekdayArray[I].Day := 0;
end;
{ initialize Event Array }
EAIndex := 0;
with TVpWeekViewOpener(FWeekView) do
for I := 0 to pred(Length(wvEventArray)) do begin
wvEventArray[I].Rec.TopLeft := Point(-1, -1);
wvEventArray[I].Rec.BottomRight := Point(-1, -1);
wvEventArray[I].Event := nil;
end;
RenderCanvas.Pen.Color := RealLineColor;
{ build the first dayrect }
DayRectHeight := (RealBottom - RealTop - TVpWeekViewOpener(FWeekView).wvHeaderHeight) div 3;
if FWeekView.DrawingStyle = ds3D then
DayRect.TopLeft := Point(RealLeft + 1, RealTop + TVpWeekViewOpener(FWeekView).wvHeaderHeight + 3)
else
DayRect.TopLeft := Point(RealLeft + 1, RealTop + TVpWeekViewOpener(FWeekView).wvHeaderHeight + 2);
DayRect.BottomRight := Point(
RealLeft + (RealRight - RealLeft) div 2 + 1,
RealTop + TVpWeekViewOpener(FWeekView).wvHeaderHeight + DayRectHeight
);
{ draw the day frames }
for I := 0 to 6 do begin
{ draw day head} { draw day head}
RenderCanvas.Font.Assign(FWeekView.DayHeadAttributes.Font); RenderCanvas.Font.Assign(FWeekView.DayHeadAttributes.Font);
RenderCanvas.Brush.Color := RealDayHeadAttrColor; RenderCanvas.Brush.Color := RealDayHeadAttrColor;
TextRect := Rect(DayRect.Left, DayRect.Top, DayRect.Right, DayRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight); TextRect := DayRect;
TextRect.Bottom := DayRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight;
TPSFillRect(RenderCanvas, Angle, RenderIn, TextRect); TPSFillRect(RenderCanvas, Angle, RenderIn, TextRect);
if FWeekView.DayHeadAttributes.Bordered then if FWeekView.DayHeadAttributes.Bordered then
TPSRectangle(RenderCanvas, Angle, RenderIn, TextRect); TPSRectangle(RenderCanvas, Angle, RenderIn, TextRect);
{ Fix Header String } { Fix Header String }
{$IF FPC_FULLVERSION >= 30000} DayStr := FormatDateTime(FWeekView.DayHeadAttributes.DateFormat, StartDate + AIndex);
DayStr := FormatDateTime(FWeekView.DayHeadAttributes.DateFormat, StartDate + I); {$IFDEF LCL}
{$ELSE} {$IF FPC_FULLVERSION < 30000}DayStr := SysToUTF8(DayStr); {$ENDIF}
DayStr := SysToUTF8(FormatDateTime(FDayHeadAttributes.DateFormat, StartDate + I));
{$ENDIF} {$ENDIF}
SL := RenderCanvas.TextWidth(DayStr); SL := RenderCanvas.TextWidth(DayStr);
if SL > TextRect.Right - TextRect.Left then if SL > WidthOf(TextRect) then
DayStr := GetDisplayString(RenderCanvas, DayStr, 0, TextRect.Right - TextRect.Left - TextMargin); DayStr := GetDisplayString(RenderCanvas, DayStr, 0, WidthOf(TextRect) - TextMargin);
SL := RenderCanvas.TextWidth(DayStr); SL := RenderCanvas.TextWidth(DayStr);
TextRect.Left := TextRect.Right - SL - TextMargin; TextRect.Left := TextRect.Right - SL - TextMargin;
TPSTextOut(RenderCanvas, Angle, RenderIn, TPSTextOut(
TextRect.Left, TextRect.Top + TextMargin - 1, DayStr RenderCanvas,
Angle,
RenderIn,
TextRect.Left,
TextRect.Top + TextMargin - 1,
DayStr
); );
if (FWeekView.DataStore <> nil) and (FWeekView.DataStore.Resource <> nil) and if (FWeekView.DataStore <> nil) and (FWeekView.DataStore.Resource <> nil) and
(FWeekView.DataStore.Resource.Schedule.EventCountByDay(StartDate + I) > 0) and (FWeekView.DataStore.Resource.Schedule.EventCountByDay(StartDate + AIndex) > 0) and
(DayRect.Bottom - DayRect.Top >= TextMargin * 2 + TVpWeekViewOpener(FWeekView).wvDayHeadHeight) (HeightOf(DayRect) >= TextMargin * 2 + TVpWeekViewOpener(FWeekView).wvDayHeadHeight)
then begin then begin
{ events exist for this day } { events exist for this day }
EventList := TList.Create; EventList := TList.Create;
try try
{ populate the eventlist with events for this day } { populate the eventlist with events for this day }
FWeekView.DataStore.Resource.Schedule.EventsByDate(StartDate + I, EventList); FWeekView.DataStore.Resource.Schedule.EventsByDate(StartDate + AIndex, EventList);
{ initialize TextRect for this day } { initialize TextRect for this day }
TextRect.TopLeft := Point(DayRect.Left, DayRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight); TextRect := DayRect;
TextRect.BottomRight := Point(DayRect.Right, TextRect.Top + TVpWeekViewOpener(FWeekView).wvRowHeight); TextRect.Top := DayRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight;
TextRect.Bottom := TextRect.Top + TVpWeekViewOpener(FWeekView).wvRowHeight;
{ Handle All Day Events } { Handle All Day Events }
if DrawAllDayEvents (StartDate + I, Rect(TextRect.Left, TextRect.Top, TextRect.Right, DayRect.Bottom), EAIndex) tmpRect := TextRect;
then begin tmpRect.Bottom := DayRect.Bottom;
if DrawAllDayEvents(StartDate + AIndex, tmpRect, EAIndex) then
begin
TextRect.Bottom := TextRect.Bottom + ADEventsRect.Bottom - TextRect.Top; TextRect.Bottom := TextRect.Bottom + ADEventsRect.Bottom - TextRect.Top;
TextRect.Top := ADEventsRect.Bottom; TextRect.Top := ADEventsRect.Bottom;
end; end;
@ -343,6 +321,14 @@ begin
if TextRect.Bottom - TextMargin > DayRect.Bottom then begin if TextRect.Bottom - TextMargin > DayRect.Bottom then begin
RenderCanvas.Brush.Color := DotDotDotColor; RenderCanvas.Brush.Color := DotDotDotColor;
{ draw dot dot dot } { draw dot dot dot }
tmpRect := Rect(DayRect.Right, DayRect.Bottom, DayRect.Right + 3, DayRect.Bottom + 3);
OffsetRect(tmpRect, -20, -7);
TPSFillRect(RenderCanvas, Angle, RenderIn, tmpRect);
OffsetRect(tmpRect, 7, 0);
TPSFillRect(RenderCanvas, Angle, RenderIn, tmpRect);
OffsetRect(tmpRect, 7, 0);
TPSFillRect(RenderCanvas, Angle, RenderIn, tmpRect);
{
TPSFillRect(RenderCanvas, Angle, RenderIn, TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(DayRect.Right - 20, DayRect.Bottom - 7, DayRect.Right - 17, DayRect.Bottom - 4) Rect(DayRect.Right - 20, DayRect.Bottom - 7, DayRect.Right - 17, DayRect.Bottom - 4)
); );
@ -351,7 +337,7 @@ begin
); );
TPSFillRect(RenderCanvas, Angle, RenderIn, TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(DayRect.Right - 6, DayRect.Bottom - 7, DayRect.Right - 3, DayRect.Bottom - 4) Rect(DayRect.Right - 6, DayRect.Bottom - 7, DayRect.Right - 3, DayRect.Bottom - 4)
); );}
break; break;
end; end;
@ -359,42 +345,41 @@ begin
DayStr := ''; DayStr := '';
TodayStartTime := TVpEvent(EventList.List^[j]).StartTime; TodayStartTime := TVpEvent(EventList.List^[j]).StartTime;
TodayEndTime := TVpEvent(EventList.List^[j]).EndTime; TodayEndTime := TVpEvent(EventList.List^[j]).EndTime;
if trunc(TodayStartTime) < trunc(StartDate + I) then //First Event if trunc(TodayStartTime) < trunc(StartDate + AIndex) then //First Event
TodayStartTime := 0; TodayStartTime := 0;
if trunc(TodayEndTime) > trunc(StartDate + I) then //Last Event if trunc(TodayEndTime) > trunc(StartDate + AIndex) then //Last Event
TodayEndTime := 0.9999; TodayEndTime := 0.9999;
if FWeekView.ShowEventTime then if FWeekView.ShowEventTime then
begin begin
if FWeekView.TimeFormat = tf24Hour then if FWeekView.TimeFormat = tf24Hour then // wp: why different times for 24 and 12 hours ?
DayStr := FormatDateTime('hh:nn', TodayStartTime) + ' - ' + DayStr := FormatDateTime('hh:nn', TodayStartTime) + ' - ' +
FormatDateTime('hh:nn', TodayEndTime) + ': ' FormatDateTime('hh:nn', TodayEndTime) + ': '
else else
DayStr := FormatDateTime('hh:nn AM/PM',TVpEvent(EventList.List^[j]).StartTime) + ' - ' + DayStr := FormatDateTime('hh:nn AM/PM', TVpEvent(EventList.List^[J]).StartTime) + ' - ' +
FormatDateTime('hh:nn AM/PM',TVpEvent(EventList.List^[j]).EndTime) + ': '; FormatDateTime('hh:nn AM/PM', TVpEvent(EventList.List^[J]).EndTime) + ': ';
end; end;
if DayStr = '' then if DayStr = '' then
DayStr := TVpEvent(EventList.List^[j]).Description DayStr := TVpEvent(EventList.List^[J]).Description
else else
DayStr := DayStr + ' ' DayStr := DayStr + ' ' + TVpEvent(EventList.List^[J]).Description;
+ TVpEvent(EventList.List^[j]).Description;
{ set the event font } { set the event font }
RenderCanvas.Font.Assign(FWeekView.EventFont); RenderCanvas.Font.Assign(FWeekView.EventFont);
RenderCanvas.Brush.Color := RealColor; RenderCanvas.Brush.Color := RealColor;
StrLn := RenderCanvas.TextWidth(DayStr); StrLn := RenderCanvas.TextWidth(DayStr);
if (StrLn > TextRect.Right - TextRect.Left - TextMargin) then if (StrLn > WidthOf(TextRect) - TextMargin) then
DayStr := GetDisplayString(RenderCanvas, DayStr, 0, TextRect.Right - TextRect.Left - (TextMargin * 2)); DayStr := GetDisplayString(RenderCanvas, DayStr, 0, WidthOf(TextRect) - TextMargin * 2);
{ write the event text } { write the event text }
TPSTextOut(RenderCanvas, Angle, RenderIn, TPSTextOut(RenderCanvas, Angle, RenderIn,
TextRect.Left + TextMargin, TextRect.Top + (TextMargin div 2), TextRect.Left + TextMargin, TextRect.Top + TextMargin div 2,
DayStr DayStr
); );
{ update the EventArray } { update the EventArray }
TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Rec := TextRect; TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Rec := TextRect;
TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Event := TVpEvent(EventList.List^[j]); TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Event := TVpEvent(EventList.List^[J]);
Inc(EAIndex); Inc(EAIndex);
TextRect.Top := TextRect.Bottom; TextRect.Top := TextRect.Bottom;
@ -407,20 +392,30 @@ begin
{ Draw focus rect if this is the current day } { Draw focus rect if this is the current day }
if (not DisplayOnly) and (StartDate + I = Trunc(FWeekView.Date)) and FWeekView.Focused if (not DisplayOnly) and (StartDate + AIndex = Trunc(FWeekView.Date)) and FWeekView.Focused
then then begin
tmpRect := DayRect;
InflateRect(tmpRect, -2, -2);
tmpRect.Top := tmpRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight;
TPSDrawFocusRect(RenderCanvas, Angle, RenderIn, tmpRect);
{
TPSDrawFocusRect(RenderCanvas, Angle, RenderIn, Rect( TPSDrawFocusRect(RenderCanvas, Angle, RenderIn, Rect(
DayRect.Left + 2, DayRect.Left + 2,
DayRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight + 2, DayRect.Top + TVpWeekViewOpener(FWeekView).wvDayHeadHeight + 2,
DayRect.Right - 2, DayRect.Right - 2,
DayRect.Bottom - 2 DayRect.Bottom - 2
)); ));
}
end;
{ update WeekdayArray } { update WeekdayArray }
TVpWeekViewOpener(FWeekView).wvWeekdayArray[I].Rec := DayRect; with TVpWeekViewOpener(FWeekView).wvWeekdayArray[AIndex] do begin
TVpWeekViewOpener(FWeekView).wvWeekdayArray[I].Day := StartDate + I; Rec := DayRect;
Day := StartDate + AIndex;
end;
{ adjust the DayRect for the next day } { adjust the DayRect for the next day }
if (I = 2) then begin if (AIndex = 2) then begin
{ move the dayrect to the top of the next column } { move the dayrect to the top of the next column }
if FWeekView.DrawingStyle = ds3D then begin if FWeekView.DrawingStyle = ds3D then begin
DayRect.TopLeft := Point( DayRect.TopLeft := Point(
@ -443,8 +438,8 @@ begin
); );
end; end;
end end
else
else if (I = 4 {Friday}) then begin if (AIndex = 4 {Friday}) then begin
{ shrink DayRect for weekend days } { shrink DayRect for weekend days }
DayRectHeight := DayRectHeight div 2; DayRectHeight := DayRectHeight div 2;
DayRect.Top := DayRect.Bottom; DayRect.Top := DayRect.Bottom;
@ -454,9 +449,57 @@ begin
DayRect.Top := DayRect.Bottom; DayRect.Top := DayRect.Bottom;
DayRect.Bottom := DayRect.Top + DayRectHeight; DayRect.Bottom := DayRect.Top + DayRectHeight;
end; end;
end; end;
procedure TVpWeekViewPainter.DrawDays;
var
DayRect: TRect;
EAIndex: Integer;
I: Integer;
{
TextRect: TRect;
I, J, SL: Integer;
DayStr: string;
EventList: TList;
TodayStartTime: Double;
TodayEndTime: Double;
}
begin
{ initialize WeekdayArray }
with TVpWeekViewOpener(FWeekView) do
for I := 0 to pred(Length(wvWeekdayArray)) do begin
wvWeekdayArray[I].Rec.TopLeft := Point(-1, -1);
wvWeekdayArray[I].Rec.BottomRight := Point(-1, -1);
wvWeekdayArray[I].Day := 0;
end;
{ initialize Event Array }
EAIndex := 0;
with TVpWeekViewOpener(FWeekView) do
for I := 0 to pred(Length(wvEventArray)) do begin
wvEventArray[I].Rec.TopLeft := Point(-1, -1);
wvEventArray[I].Rec.BottomRight := Point(-1, -1);
wvEventArray[I].Event := nil;
end;
RenderCanvas.Pen.Color := RealLineColor;
RenderCanvas.Pen.Style := psSolid;
{ build the first dayrect }
DayRectHeight := (RealBottom - RealTop - TVpWeekViewOpener(FWeekView).wvHeaderHeight) div 3;
if FWeekView.DrawingStyle = ds3D then
DayRect.TopLeft := Point(RealLeft + 1, RealTop + TVpWeekViewOpener(FWeekView).wvHeaderHeight + 3)
else
DayRect.TopLeft := Point(RealLeft + 1, RealTop + TVpWeekViewOpener(FWeekView).wvHeaderHeight + 2);
DayRect.BottomRight := Point(
RealLeft + (RealRight - RealLeft) div 2 + 1,
RealTop + TVpWeekViewOpener(FWeekView).wvHeaderHeight + DayRectHeight
);
{ draw the day frames }
for I := 0 to 6 do
DrawDay(I, DayRect, EAIndex);
{ Draw the center vertical line } { Draw the center vertical line }
RenderCanvas.Pen.Color := RealLineColor; RenderCanvas.Pen.Color := RealLineColor;
TPSMoveTo(RenderCanvas, Angle, RenderIn, TPSMoveTo(RenderCanvas, Angle, RenderIn,
@ -465,11 +508,6 @@ begin
TPSLineTo(RenderCanvas, Angle, RenderIn, TPSLineTo(RenderCanvas, Angle, RenderIn,
RealLeft + (RealRight - RealLeft) div 2, RealBottom - 1 RealLeft + (RealRight - RealLeft) div 2, RealBottom - 1
); );
if (FWeekView.DataStore = nil) or (FWeekView.DataStore.Resource = nil) or
(FWeekView.DataStore.Resource.Tasks.Count = 0)
then
Exit;
end; end;
procedure TVpWeekViewPainter.DrawHeader; procedure TVpWeekViewPainter.DrawHeader;
@ -477,17 +515,6 @@ var
HeadTextRect: TRect; HeadTextRect: TRect;
HeadStr: string; HeadStr: string;
HeadStrLen : Integer; HeadStrLen : Integer;
function GetWeekOfYear(Datum: TDateTime): byte;
var
AYear, dummy:word;
First: TDateTime;
begin
DecodeDate(Datum+((8-DayOfWeek(Datum)) mod 7) - 3, AYear, dummy,dummy);
First := EncodeDate(AYear, 1, 1);
Result := (trunc(Datum-First-3+(DayOfWeek(First)+1) mod 7) div 7) + 1;
end;
begin begin
RenderCanvas.Brush.Color := RealHeadAttrColor; RenderCanvas.Brush.Color := RealHeadAttrColor;
RenderCanvas.Font.Assign(TFont(FWeekView.HeadAttributes.Font)); RenderCanvas.Font.Assign(TFont(FWeekView.HeadAttributes.Font));