tvplanit: Fix scrolling by mousewheel and scrollbar in TVpGanttView.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8422 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-08-28 20:32:17 +00:00
parent 31a3ed6a14
commit 76e00658a3
2 changed files with 35 additions and 146 deletions

View File

@ -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;

View File

@ -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.