tvplanit: Fix all-day events in WeekView

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4916 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-07-05 08:42:08 +00:00
parent 7e44228076
commit 5370e6afa1
2 changed files with 110 additions and 93 deletions

View File

@ -392,7 +392,7 @@ begin
{ Create internal classes and stuff } { Create internal classes and stuff }
FDayHeadAttributes := TVpDayHeadAttr.Create(self); FDayHeadAttributes := TVpDayHeadAttr.Create(self);
FHeadAttr := TVpWvHeadAttributes.Create(self); FHeadAttr := TVpWvHeadAttributes.Create(self);
FAllDayEventAttr := TVpAllDayEventAttributes.Create (self); FAllDayEventAttr := TVpAllDayEventAttributes.Create(self);
FEventFont := TFont.Create; FEventFont := TFont.Create;
FEventFont.Assign(Font); FEventFont.Assign(Font);
@ -578,17 +578,19 @@ end;
procedure TVpWeekView.DeleteActiveEvent(Verify: Boolean); procedure TVpWeekView.DeleteActiveEvent(Verify: Boolean);
var var
Str: string;
DoIt: Boolean; DoIt: Boolean;
begin begin
if ReadOnly then
exit;
wvClickTimer.Enabled := false;
EndEdit(nil);
DoIt := not Verify; DoIt := not Verify;
EndEdit(nil);
if ActiveEvent <> nil then begin if ActiveEvent <> nil then begin
Str := '"' + ActiveEvent.Description + '"';
if Verify then if Verify then
DoIt := (MessageDlg(RSDelete + ' ' + Str + ' ' + RSFromSchedule + #13#10#10 + RSPermanent, DoIt := (MessageDlg(RSConfirmDeleteEvent + #13#10#10 + RSPermanent,
mtConfirmation, [mbYes, mbNo], 0) = mrYes); mtConfirmation, [mbYes, mbNo], 0) = mrYes);
if DoIt then begin if DoIt then begin
@ -745,6 +747,8 @@ procedure TVpWeekView.WMLButtonDown(var Msg: TWMLButtonDown);
{$ELSE} {$ELSE}
procedure TVpWeekView.WMLButtonDown(var Msg: TLMLButtonDown); procedure TVpWeekView.WMLButtonDown(var Msg: TLMLButtonDown);
{$ENDIF} {$ENDIF}
var
P: TPoint;
begin begin
inherited; inherited;
@ -753,16 +757,17 @@ begin
if (wvInPlaceEditor <> nil) and wvInPlaceEditor.Visible then if (wvInPlaceEditor <> nil) and wvInPlaceEditor.Visible then
EndEdit(Self); EndEdit(Self);
P := Point(Msg.XPos, Msg.YPos);
if (Msg.YPos > wvHeaderHeight) then if (Msg.YPos > wvHeaderHeight) then
begin begin
{ If an active event was clicked, then enable the click timer. If the }
{ item is double clicked before the click timer fires, then the edit }
{ dialog will appear, otherwise the in-place editor will appear. }
if EventAtCoord(Point(Msg.XPos, Msg.YPos)) then
wvClickTimer.Enabled := true;
{ The mouse click landed inside the client area } { The mouse click landed inside the client area }
wvSetDateByCoord(Point(Msg.XPos, Msg.YPos)); wvSetDateByCoord(P);
{ If an active event was clicked, then enable the click timer. If the
item is double clicked before the click timer fires, then the edit
dialog will appear, otherwise the in-place editor will appear. }
if EventAtCoord(P) then
wvClickTimer.Enabled := true;
end; end;
end; end;
{=====} {=====}
@ -1127,44 +1132,34 @@ var
begin begin
result := false; result := false;
for I := 0 to pred(Length(wvEventArray)) do begin for I := 0 to pred(Length(wvEventArray)) do begin
if wvEventArray[I].Event = nil then begin
{ we've hit the end of visible events without finding a match }
ActiveEvent := nil; ActiveEvent := nil;
wvActiveEventRec.Top := 0; wvActiveEventRec.Top := 0;
wvActiveEventRec.Bottom := 0; wvActiveEventRec.Bottom := 0;
wvActiveEventRec.Right := 0; wvActiveEventRec.Right := 0;
wvActiveEventRec.Left := 0; wvActiveEventRec.Left := 0;
result := false;
Exit;
end;
// We've hit the end of visible events without finding a match
if wvEventArray[I].Event = nil then
Exit;
// Point falls inside this event's rectangle
if PointInRect(Pt, wvEventArray[I].Rec) then if PointInRect(Pt, wvEventArray[I].Rec) then
begin begin
{ point falls inside this event's rectangle }
wvHotPoint := Pt; wvHotPoint := Pt;
ActiveEvent := TVpEvent(wvEventArray[I].Event); ActiveEvent := TVpEvent(wvEventArray[I].Event);
wvActiveEventRec := wvEventArray[I].Rec; wvActiveEventRec := wvEventArray[I].Rec;
result := true; result := true;
Exit; Exit;
end
else begin
{ point is not within the boundaries of this event's rectangle. }
ActiveEvent := nil;
wvActiveEventRec.Top := 0;
wvActiveEventRec.Bottom := 0;
wvActiveEventRec.Right := 0;
wvActiveEventRec.Left := 0;
result := false;
end; end;
end; end;
end; end;
{=====} {=====}
{ This is the timer event which spawns an in-place editor.
If the event is double-clicked before this timer fires, then the event is
edited in a dialog based editor. }
procedure TVpWeekView.wvEditInPlace(Sender: TObject); procedure TVpWeekView.wvEditInPlace(Sender: TObject);
begin begin
{ this is the timer event which spawns an in-place editor }
{ if the event is doublecliked before this timer fires, then the }
{ event is edited in a dialog based editor. }
wvClickTimer.Enabled := false; wvClickTimer.Enabled := false;
EditEvent; EditEvent;
end; end;
@ -1190,6 +1185,14 @@ begin
wvInPlaceEditor.Parent := self; wvInPlaceEditor.Parent := self;
wvInPlaceEditor.OnExit := EndEdit; wvInPlaceEditor.OnExit := EndEdit;
end; end;
if ActiveEvent.AllDayEvent then
wvInPlaceEditor.SetBounds(
wvActiveEventRec.Left + TextMargin,
wvActiveEventRec.Top,
wvActiveEventRec.Right - TextMargin * 3,
wvActiveEventRec.Bottom - TextMargin * 2
)
else
wvInPlaceEditor.SetBounds( wvInPlaceEditor.SetBounds(
wvActiveEventRec.Left + TextMargin, wvActiveEventRec.Left + TextMargin,
wvActiveEventRec.Top, wvActiveEventRec.Top,

View File

@ -41,6 +41,7 @@ type
procedure DrawDays; procedure DrawDays;
procedure DrawEvent(AEvent: TVpEvent; DayRect, TextRect: TRect; ADayIndex: Integer); procedure DrawEvent(AEvent: TVpEvent; DayRect, TextRect: TRect; ADayIndex: Integer);
procedure DrawHeader; procedure DrawHeader;
procedure FixFontHeights;
procedure InitColors; procedure InitColors;
procedure SetMeasurements; override; procedure SetMeasurements; override;
@ -55,7 +56,10 @@ type
implementation implementation
uses uses
StrUtils, Math, LazUtf8, StrUtils, Math,
{$IFDEF LCL}
LazUtf8, DateUtils,
{$ENDIF}
VpCanvasUtils, VpMisc, VpSR; VpCanvasUtils, VpMisc, VpSR;
type type
@ -81,14 +85,16 @@ var
TempList: TList; TempList: TList;
I, J, K: Integer; I, J, K: Integer;
Event: TVpEvent; Event: TVpEvent;
ADEventRect: TRect; ADEvRect: TRect;
StartsBeforeRange: Boolean; StartsBeforeRange: Boolean;
MaxADEvents: Integer; NumADEvents: Integer;
Skip: Boolean; Skip: Boolean;
ADTextHeight: Integer; ADTextHeight: Integer;
EventStr: string; EventStr: string;
txtDist: Integer;
begin begin
Result := False; Result := False;
{ initialize the All Day Events area... } { initialize the All Day Events area... }
ADEventsRect := DayRect; ADEventsRect := DayRect;
@ -97,7 +103,7 @@ begin
{ Collect all of the events for this range and determine the maximum } { 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. } { number of all day events for the range of days covered by the control. }
MaxADEvents := 0; NumADEvents := 0;
ADEventsList := TList.Create; ADEventsList := TList.Create;
try try
@ -122,91 +128,95 @@ begin
AdEventsList.Add(TempList[J]); AdEventsList.Add(TempList[J]);
end; end;
if TempList.Count > MaxADEvents then if TempList.Count > NumADEvents then
MaxADEvents := TempList.Count; NumADEvents := TempList.Count;
finally finally
TempList.Free; TempList.Free;
end; end;
if MaxADEvents > 0 then begin if NumADEvents > 0 then begin
{ Set attributes } { Set attributes }
RenderCanvas.Brush.Color := ADBackgroundColor; RenderCanvas.Brush.Color := ADBackgroundColor;
RenderCanvas.Font.Assign(FWeekView.AllDayEventAttributes.Font);
{ Measure the AllDayEvent TextHeight } { Measure the AllDayEvent TextHeight }
ADTextHeight := RenderCanvas.TextHeight(VpProductName) + TextMargin + TextMargin div 2; txtDist := TextMargin div 2;
RenderCanvas.Font.Assign(FWeekView.AllDayEventAttributes.Font);
ADTextHeight := RenderCanvas.TextHeight(VpProductName) + TextMargin + txtDist;
{ Build the AllDayEvent rect based on the value of MaxADEvents } { Build the AllDayEvent rect based on the value of NumADEvents }
if AdEventsRect.Top + (MaxADEvents * ADTextHeight) + TextMargin * 2 > DayRect.Bottom if AdEventsRect.Top + (NumADEvents * ADTextHeight) + TextMargin * 2 > DayRect.Bottom
then then
ADeventsrect.Bottom := DayRect.Bottom ADEventsRect.Bottom := DayRect.Bottom
else else
ADEventsRect.Bottom := AdEventsRect.Top + (MaxADEvents * ADTextHeight) + TextMargin * 2; ADEventsRect.Bottom := AdEventsRect.Top + NumADEvents * ADTextHeight + TextMargin * 2;
{ Clear the AllDayEvents area } // Clear the AllDayEvents area
TpsFillRect(RenderCanvas, Angle, RenderIn, ADEventsRect); TpsFillRect(RenderCanvas, Angle, RenderIn, ADEventsRect);
StartsBeforeRange := false; StartsBeforeRange := false;
{ Cycle through the all day events and draw them appropriately }
// Cycle through the all day events and draw them appropriately
for I := 0 to pred(ADEventsList.Count) do begin for I := 0 to pred(ADEventsList.Count) do begin
Event := ADEventsList[I]; Event := ADEventsList[I];
{ set the top of the event's rect } // Draw ". . ."
AdEventRect.Top := ADEventsRect.Top + TextMargin + I * ADTextHeight; if ADEventsRect.Top + ((I + 1) * ADTextHeight) > DayRect.Bottom then
begin
DrawDotDotDot(DayRect, DotDotDotColor);
if ADEventsRect.Top + TextMargin + ((I + 1) * ADTextHeight) - TextMargin > DayRect.Bottom {
then begin
RenderCanvas.Brush.Color := DotDotDotColor; RenderCanvas.Brush.Color := DotDotDotColor;
{ draw dot dot dot }
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));
TPSFillRect(RenderCanvas, Angle, RenderIn, TPSFillRect(RenderCanvas, Angle, RenderIn,
Rect(DayRect.Right - 13, DayRect.Bottom - 7, DayRect.Right - 10, DayRect.Bottom - 4)); Rect(DayRect.Right - 13, DayRect.Bottom - 7, DayRect.Right - 10, DayRect.Bottom - 4));
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;
{ see if the event began before the start of the range } // See if the event began before the start of the range
if (Event.StartTime < trunc(RenderDate)) then if (Event.StartTime < DayOf(RenderDate)) then
StartsBeforeRange := true; StartsBeforeRange := true;
AdEventRect.Bottom := ADEventRect.Top + ADTextHeight; // Set the event's rect
AdEventRect.Left := AdEventsRect.Left + (TextMargin div 2); ADEvRect.Top := ADEventsRect.Top + TextMargin + I * ADTextHeight;
AdEventRect.Right := DayRect.Right; ADEvRect.Bottom := ADEvRect.Top + ADTextHeight;
ADEvRect.Left := AdEventsRect.Left + txtDist;
if (StartsBeforeRange) then ADEvRect.Right := DayRect.Right;
EventStr := '>> '
else
EventStr := '';
EventStr := EventStr + Event.Description;
// Paint the background of the event rect
RenderCanvas.Brush.Color := ADEventBackgroundColor; RenderCanvas.Brush.Color := ADEventBackgroundColor;
RenderCanvas.Pen.Color := ADEventBorderColor; RenderCanvas.Pen.Color := ADEventBorderColor;
TPSRectangle(RenderCanvas, Angle, RenderIn, TPSRectangle(RenderCanvas, Angle, RenderIn,
ADEventRect.Left + TextMargin, ADEvRect.Left + TextMargin,
ADEventRect.Top + TextMargin div 2, ADEvRect.Top + txtDist,
ADEventRect.Right - TextMargin, ADEvRect.Right - TextMargin,
ADEventRect.Top + ADTextHeight + TextMargin div 2 ADEvRect.Top + ADTextHeight + txtDist
); );
// Paint the event string
EventStr := IfThen(StartsBeforeRange, '>> ', '') + Event.Description;
EventStr := GetDisplayString(RenderCanvas, EventStr, 0, WidthOf(ADEvRect) - 3*TextMargin);
TPSTextOut(RenderCanvas,Angle, RenderIn, TPSTextOut(RenderCanvas,Angle, RenderIn,
AdEventRect.Left + TextMargin * 2 + TextMargin div 2, ADEvRect.Left + TextMargin * 2 + txtDist,
AdEventRect.Top + TextMargin, ADEvRect.Top + TextMargin,
EventStr EventStr
); );
Result := True; Result := True;
TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Rec := Rect( TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Rec := Rect(
ADEventRect.Left + TextMargin, ADEvRect.Left + TextMargin,
ADEventRect.Top + TextMargin, ADEvRect.Top + TextMargin,
ADEventRect.Right - TextMargin, ADEvRect.Right - TextMargin,
ADEventRect.Bottom ADEvRect.Bottom
); );
TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Event := Event; TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex].Event := Event;
Inc(EAIndex); Inc(EAIndex);
end; { for I := 0 to pred(ADEventsList.Count) do ... } end; { for I := 0 to pred(ADEventsList.Count) do ... }
end; { if MaxADEvents > 0 } end; { if NumADEvents > 0 }
finally finally
ADEventsList.Free; ADEventsList.Free;
@ -592,6 +602,17 @@ begin
); );
end; end;
procedure TVpWeekViewPainter.FixFontHeights;
begin
with FWeekView do begin
AllDayEventAttributes.Font.Height := GetRealFontHeight(AllDayEventAttributes.Font);
DayHeadAttributes.Font.Height := GetRealFontHeight(DayHeadAttributes.Font);
EventFont.Height := GetRealFontHeight(EventFont);
Font.Height := GetRealFontHeight(Font);
HeadAttributes.Font.Height := GetRealFontHeight(HeadAttributes.Font);
end;
end;
procedure TVpWeekViewPainter.InitColors; procedure TVpWeekViewPainter.InitColors;
begin begin
if DisplayOnly then begin if DisplayOnly then begin
@ -631,14 +652,7 @@ begin
InitColors; InitColors;
SavePenBrush; SavePenBrush;
InitPenBrush; InitPenBrush;
FixFontHeights;
with FWeekView do begin
AllDayEventAttributes.Font.Height := GetRealFontHeight(AllDayEventAttributes.Font);
DayHeadAttributes.Font.Height := GetRealFontHeight(DayHeadAttributes.Font);
EventFont.Height := GetRealFontHeight(EventFont);
Font.Height := GetRealFontHeight(Font);
HeadAttributes.Font.Height := GetRealFontHeight(HeadAttributes.Font);
end;
Rgn := CreateRectRgn(RenderIn.Left, RenderIn.Top, RenderIn.Right, RenderIn.Bottom); Rgn := CreateRectRgn(RenderIn.Left, RenderIn.Top, RenderIn.Right, RenderIn.Bottom);
try try