From 897e036a0c41742fe64ff028211dfa4bff2e67c7 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Mon, 9 Oct 2023 15:47:05 +0000 Subject: [PATCH] tvplanit: Fix painting of GanttView events in hour mode. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8940 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/tvplanit/source/vpganttview.pas | 47 +++++++++++++++++-- .../tvplanit/source/vpganttviewpainter.pas | 23 +++++++-- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/components/tvplanit/source/vpganttview.pas b/components/tvplanit/source/vpganttview.pas index 99de29612..c761c190b 100644 --- a/components/tvplanit/source/vpganttview.pas +++ b/components/tvplanit/source/vpganttview.pas @@ -483,6 +483,8 @@ begin end; function TVpGanttEventList.AddSingleEvent(AEvent: TVpEvent): PVpGanttEventRec; +const + EPS = 1e-9; var eventRec: PVpGanttEventRec; dt1, dt2: TDateTime; @@ -491,7 +493,7 @@ begin if AEvent.AllDayEvent then begin dt1 := DatePart(AEvent.StartTime); - dt2 := DatePart(AEvent.EndTime) + 1; + dt2 := DatePart(AEvent.EndTime) + 1 - EPS; end else begin dt1 := AEvent.StartTime; @@ -786,10 +788,21 @@ begin end; procedure TVpGanttColHeaderAttributes.SetVisible(AValue: TVpGanttColHeaderKinds); +var + HourModeChanged: Boolean; + d: TDateTime; begin if FVisible <> AValue then begin + HourModeChanged := (gchHour in FVisible) <> (gchHour in AValue); FVisible := AValue; + if HourModeChanged then + begin + d := FGanttView.ActiveDate; + FGanttView.Init; + FGanttView.FActiveDate := 0; // Enforce execution of SetActiveDate + FGanttView.SetActiveDate(d); + end; UpdateGanttView; end; end; @@ -806,7 +819,7 @@ end; {******************************************************************************} -{ TVpGanttView } +{ TVpGanttView } {******************************************************************************} constructor TVpGanttView.Create(AOwner: TComponent); begin @@ -1781,7 +1794,9 @@ var i: Integer; xh1, xh2, y1, xe1, xe2, y2: Integer; t1, t2: TDateTime; - totalWidth: Integer; + startHr, endHr: TDateTime; + dayWidth, totalWidth: Integer; + dayFactor, hourFactor: Double; begin if (Datastore = nil) or (DataStore.Resource = nil) then exit; @@ -1817,6 +1832,11 @@ begin xh2 := FixedColWidth; y1 := FTotalColHeaderHeight; totalWidth := CalcDaysWidth(GetNumDays); + dayWidth := CalcDaysWidth(1); + startHr := ord(FStartHour) / 24; + endHr := (ord(FEndHour) + 1) / 24; // extend to the end of the endhour box + dayFactor := totalWidth / GetNumDays; + hourFactor := dayWidth / HoursPerDay * 24; for i := 0 to FEventRecords.Count-1 do begin eventRec := FEventRecords[i]; @@ -1825,8 +1845,25 @@ begin // Store event rectangle coordinates in the EventRec y2 := y1 + FRowHeight; - xe1 := round((t1 - FRealStartDate) / numDays * totalWidth) + FixedColWidth; - xe2 := round((t2 - FRealStartDate) / numDays * totalWidth) + FixedColWidth; + if HourMode then + begin + // Visible beginning of day at which the event starts + xe1 := round((DatePart(t1) - FRealStartDate) * dayFactor) + FixedColWidth; + // Add time part if event starts after FStartHour + if TimePart(t1) >= startHr then + xe1 := xe1 + round((TimePart(t1) - startHr) * hourFactor); + // Visible beginning of day at which the event ends + xe2 := round((DatePart(t2) - FRealStartDate) * dayFactor) + FixedColWidth; + // Add time part of event end, clipped at end of EndHour. + if TimePart(t2) <= endHr then + xe2 := xe2 + round((TimePart(t2) - startHr) * hourFactor) + else + xe2 := xe2 + round((endHr - startHr) * hourFactor); + end else + begin + xe1 := round((t1 - FRealStartDate) / numDays * totalWidth) + FixedColWidth; + xe2 := round((t2 - FRealStartDate) / numDays * totalWidth) + FixedColWidth; + end; if xe1 = xe2 then xe2 := xe1 + 1; eventRec^.HeadRect := Rect(xh1, y1, xh2, y2); diff --git a/components/tvplanit/source/vpganttviewpainter.pas b/components/tvplanit/source/vpganttviewpainter.pas index 5e32680fe..a326fd154 100644 --- a/components/tvplanit/source/vpganttviewpainter.pas +++ b/components/tvplanit/source/vpganttviewpainter.pas @@ -113,9 +113,14 @@ begin ); OffsetRect(R, -dx, -dy); + if R.Right < FScaledFixedColWidth then + exit; if R.Top < FScaledTotalColHeaderHeight then exit; + if R.Left < FScaledFixedColWidth then + R.Left := FScaledFixedColWidth; + pw := RenderCanvas.Pen.Width; bs := RenderCanvas.Brush.Style; RenderCanvas.Pen.Width := 3; @@ -350,7 +355,7 @@ var dx, dy: Integer; i, n, numEvents: Integer; eventRec: PVpGanttEventRec; - dayRec: TVpGanttDayRec; +// dayRec: TVpGanttDayRec; monthRec: TVpGanttMonthRec; R: TRect; begin @@ -394,6 +399,7 @@ begin end; // Vertical lines + RenderCanvas.Brush.Style := bsClear; if (gvoVertGrid in FGanttView.Options) then begin y1 := RealTop + FScaledTotalColHeaderHeight; @@ -402,11 +408,20 @@ begin eventRec := FGanttView.EventRecords[numEvents-1]; R := ScaleRect(eventRec^.EventRect); y2 := R.Bottom - dy; - n := FGanttView.NumDays; + n := FGanttView.ColCount; for i := 0 to n-1 do begin - dayRec := FGanttView.DayRecords[i]; - R := ScaleRect(dayRec.Rect); + RenderCanvas.Pen.Style := psSolid; + if FGanttView.HourMode then + begin + R := ScaleRect(FGanttView.HourRecords[i].Rect); + if (i+1) mod FGanttView.HoursPerDay <> 0 then + RenderCanvas.Pen.Style := psDot; + end + else + R := ScaleRect(FGanttView.DayRecords[i].Rect); +// dayRec := FGanttView.DayRecords[i]; +// R := ScaleRect(dayRec.Rect); x1 := R.Right - dx; if x1 >= FScaledFixedColWidth then begin