You've already forked lazarus-ccr
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:
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user