diff --git a/components/tvplanit/source/vpganttview.pas b/components/tvplanit/source/vpganttview.pas index 029e5b76b..040bac762 100644 --- a/components/tvplanit/source/vpganttview.pas +++ b/components/tvplanit/source/vpganttview.pas @@ -167,6 +167,10 @@ type StartLine, StopLine: Integer; UseGran: TVpGranularity; DisplayOnly: Boolean); override; + // Methods to be called by painter + function CalcVisibleCols(AWidth: Integer): Integer; + function CalcVisibleRows(AHeight: Integer): Integer; + property Date: TDateTime read FDate write SetDate; property StartDate: TDateTime read FStartDate write FStartDate; property EndDate: TDateTime read FEndDate write FEndDate; @@ -211,7 +215,7 @@ type implementation uses - DateUtils, + DateUtils, Math, VpGanttViewPainter; const @@ -370,6 +374,28 @@ begin FRowHeight := GetCanvasTextHeight(Canvas, FRowHeaderAttributes.EventFont) + 2 * FTextMargin; end; +function TVpGanttView.CalcVisibleCols(AWidth: Integer): Integer; +var + d, m: Integer; // "d" = result of div, "m" = result of mod +begin + DivMod(AWidth - FixedColWidth, ColWidth, d, m); + if m <> 0 then + d := d-1; + if d < 1 then d := 1; + Result := d; +end; + +function TVpGanttView.CalcVisibleRows(AHeight: Integer): Integer; +var + d, m: Integer; // "d" = result of div, "m" = result of mod +begin + DivMod(AHeight - TotalColHeaderHeight, FRowHeight, d, m); + if m <> 0 then + d := d-1; + if d < 1 then d := 1; + Result := d; +end; + procedure TVpGanttView.CreateParams(var AParams: TCreateParams); begin inherited CreateParams(AParams); @@ -833,8 +859,8 @@ end; procedure TVpGanttView.SetLeftCol(AValue: Integer); begin if AValue <> FLeftCol then begin - if AValue + FVisibleCols > FColCount then begin - FLeftCol := FColCount - FVisibleCols - 1; + if AValue + FVisibleCols >= FColCount then begin + FLeftCol := FColCount - FVisibleCols; if FLeftCol < 0 then FLeftCol := 0; // Prevent the control from hanging at the right @@ -895,8 +921,8 @@ end; procedure TVpGanttView.SetTopRow(AValue: Integer); begin if AValue <> FTopRow then begin - if AValue + FVisibleRows > RowCount then begin - FTopRow := FRowCount - FVisibleRows - 1; + if AValue + FVisibleRows >= RowCount then begin + FTopRow := FRowCount - FVisibleRows; if FTopRow < 0 then FTopRow := 0; // Prevent the control from hanging at the bottom @@ -907,8 +933,6 @@ begin FTopRow := 0 else FTopRow:= AValue; - - WriteLn('TopRow = ', TopRow); Invalidate; SetVScrollPos; end; @@ -952,7 +976,7 @@ begin SB_LINERIGHT : ScrollHorizontal(1); SB_PAGELEFT : ScrollHorizontal(-FVisibleCols); SB_PAGERIGHT : ScrollHorizontal(FVisibleCols); - SB_THUMBPOSITION, SB_THUMBTRACK : FLeftCol := Msg.Pos; + SB_THUMBPOSITION, SB_THUMBTRACK : SetLeftCol(Msg.Pos); end; end; @@ -969,7 +993,7 @@ begin SB_LINEDOWN : ScrollVertical(1); SB_PAGEUP : ScrollVertical(-FVisibleRows); SB_PAGEDOWN : ScrollVertical(FVisibleRows); - SB_THUMBPOSITION, SB_THUMBTRACK : FTopRow := Msg.Pos; + SB_THUMBPOSITION, SB_THUMBTRACK : SetTopRow(Msg.Pos); end; end; diff --git a/components/tvplanit/source/vpganttviewpainter.pas b/components/tvplanit/source/vpganttviewpainter.pas index ee7b8378d..75f560393 100644 --- a/components/tvplanit/source/vpganttviewpainter.pas +++ b/components/tvplanit/source/vpganttviewpainter.pas @@ -475,146 +475,11 @@ begin end; procedure TVpGanttViewPainter.SetMeasurements; -var - firstEvent: TVpEvent; - firstDay, lastDay: TDateTime; - firstMonth, lastMonth: TDateTime; - eventCount, numDays, numMonths: Integer; - x1, x2, y1, y2: Integer; - i: Integer; - dt, t1, t2: TDateTime; - totalWidth: double; - event: TVpEvent; begin inherited; - FGanttView.Init; - (* - // Determine range of dates as well as the rectangles containing the day, - // column and event headers and the event data. - if (FGanttView.Datastore = nil) or (FGanttView.Datastore.Resource = nil) or - (FGanttView.Datastore.Resource.Schedule.EventCount = 0) then - begin - eventCount := 0; - FGanttView.StartDate := NO_DATE; - FGanttView.EndDate := NO_DATE; - SetLength(TVpGanttViewOpener(FGanttView).FEventRecords, 0); - SetLength(TVpGanttViewOpener(FGanttView).FDayRecords, 0); - SetLength(TVpGanttViewOpener(FGanttView).FMonthRecords, 0); - FGanttView.VisibleRows := 0; - FGanttView.VisibleCols := 0; - end else - begin - eventCount := FGanttView.Datastore.Resource.Schedule.EventCount; - firstEvent := FGanttView.DataStore.Resource.Schedule.GetEvent(0); - - // Find date range needed for the GanttView - firstDay := trunc(firstEvent.StartTime); - lastDay := trunc(firstEvent.EndTime); - if frac(lastDay) = 0.0 then lastDay := lastDay + 1; - for i := 1 to FGanttView.Datastore.Resource.Schedule.EventCount-1 do - begin - event := FGanttView.Datastore.Resource.Schedule.GetEvent(i); - if event.AllDayEvent then begin - t1 := trunc(event.StartTime); - t2 := trunc(event.EndTime); - end else - begin - t1 := event.StartTime; - t2 := event.EndTime; - end; - if t1 < firstDay then - firstDay := trunc(t1); - if t2 > lastDay then - lastDay := trunc(t2); - end; - lastDay := lastDay + 1; - - FGanttView.StartDate := firstDay; - FGanttView.EndDate := lastDay; - - // Prepare the event, day and month records for painting the cells - numdays := DaysBetween(FGanttView.StartDate, FGanttView.EndDate); - totalWidth := numdays * FGanttView.ColWidth; - - // Populate event records - SetLength(TVpGanttViewOpener(FGanttView).FEventRecords, eventCount); - y1 := 0; // this dimension is scrollable - for i := 0 to eventCount-1 do - begin - event := FGanttView.DataStore.Resource.Schedule.GetEvent(i); - if event.AllDayEvent then - begin - t1 := trunc(event.StartTime); - t2 := trunc(event.EndTime); - if frac(t2) = 0 then t2 := t2 + 1; - end else - begin - t1 := event.StartTime; - t2 := event.EndTime; - end; - x1 := round((t1 - FGanttView.StartDate) / numDays * totalWidth); - x2 := round((t2 - FGanttView.StartDate) / numDays * totalWidth); - y2 := y1 + FGanttView.RowHeight; - with TVpGanttViewOpener(FGanttView) do - begin - FEventRecords[i].Event := event; - FEventRecords[i].Caption := event.Description; - FEventRecords[i].HeadRect := Rect(RealLeft, y1, RealLeft + FixedColWidth, y2); - FEventRecords[i].EventRect := Rect(x1, y1, x2, y2); - end; - y1 := y2; - end; - - // Populate day records - SetLength(TVpGanttViewOpener(FGanttView).FDayRecords, numDays); - x1 := 0; // Scrollable dimension - y1 := RealTop + FGanttView.MonthColHeaderHeight; - y2 := RealTop + FGanttView.TotalColHeaderHeight; - dt := trunc(FGanttView.StartDate); - for i := 0 to numDays-1 do - begin - x2 := x1 + FGanttView.ColWidth; - with TVpGanttViewOpener(FGanttView) do - begin - FDayRecords[i].Date := dt; - FDayRecords[i].Rect := Rect(x1, y1, x2, y2); - end; - dt := IncDay(dt, 1); - x1 := x2; - end; - - // Populate month records - firstMonth := FGanttView.StartDate; - lastMonth := FGanttView.EndDate; - numMonths := CountMonths(firstMonth, lastMonth); - SetLength(TVpGanttViewOpener(FGanttView).FMonthRecords, numMonths); - dt := firstMonth; - x1 := 0; // Scrollable dimension; - y1 := RealTop; - y2 := RealTop + FGanttView.TotalColHeaderHeight; - for i := 0 to numMonths - 1do - begin - numDays := DaysInMonth(dt); - if i = 0 then - // partial first month - numDays := numDays - DayOf(dt) + 1 - else - if i = numMonths-1 then - numDays := DayOf(lastMonth) - 1; - x2 := x1 + numDays * FGanttView.ColWidth; - with TVpGanttViewOpener(FGanttView) do - begin - FMonthRecords[i].Date := dt; - FMonthRecords[i].Rect := Rect(x1, y1, x2, y2); - end; - dt := IncMonth(dt, 1); - x1 := x2; - end; - *) - - FGanttView.VisibleCols := (RealRight - RealLeft - FGanttView.FixedColWidth) div FGanttView.ColWidth; - FGanttView.VisibleRows := (RealBottom - RealTop - FGanttView.TotalColHeaderHeight) div FGanttView.RowHeight; + FGanttView.VisibleCols := FGanttView.CalcVisibleCols(RealRight - RealLeft); + FGanttView.VisibleRows := FGanttView.CalcVisibleRows(RealBottom - RealTop); end; end.