2022-08-23 22:38:13 +00:00
|
|
|
unit VpGanttViewPainter;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
|
|
|
Classes, SysUtils, Graphics, LCLType, LCLIntf, Types,
|
|
|
|
VpBase, VpBasePainter, VpGanttView;
|
|
|
|
|
|
|
|
type
|
|
|
|
TVpGanttViewPainter = class(TVpBasePainter)
|
|
|
|
private
|
|
|
|
FGanttView: TVpGanttView;
|
|
|
|
|
2023-10-08 22:41:21 +00:00
|
|
|
FHourFont: TFont;
|
2022-08-28 18:17:04 +00:00
|
|
|
FDayFont: TFont;
|
|
|
|
FMonthFont: TFont;
|
2022-09-21 22:50:43 +00:00
|
|
|
FWeekFont: TFont;
|
2022-08-28 18:17:04 +00:00
|
|
|
FEventFont: TFont;
|
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
FScaledColWidth: Integer;
|
|
|
|
FScaledFixedColWidth: Integer;
|
|
|
|
FScaledTextMargin: Integer;
|
|
|
|
FScaledTotalColHeaderHeight: Integer;
|
|
|
|
FScaledRowHeight: Integer;
|
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
BevelHighlight: TColor;
|
|
|
|
BevelShadow: TColor;
|
|
|
|
BevelDarkShadow: TColor;
|
|
|
|
BevelFace: TColor;
|
|
|
|
RealColHeadAttrColor: TColor;
|
|
|
|
RealColor: TColor;
|
|
|
|
RealLineColor: TColor;
|
|
|
|
RealRowHeadAttrColor: TColor;
|
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
function ScaleRect(ARect: TRect): TRect;
|
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
protected
|
|
|
|
procedure Clear;
|
2022-08-29 21:25:03 +00:00
|
|
|
procedure DrawActiveDate;
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure DrawBorders;
|
|
|
|
procedure DrawColHeader;
|
2022-09-21 22:50:43 +00:00
|
|
|
procedure DrawDayColHeaders;
|
2022-08-26 22:35:42 +00:00
|
|
|
procedure DrawEvents;
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure DrawGrid;
|
2023-10-08 22:41:21 +00:00
|
|
|
procedure DrawHourColHeaders;
|
2022-09-21 22:50:43 +00:00
|
|
|
procedure DrawMonthColHeaders;
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure DrawRowHeader;
|
2022-09-01 09:42:04 +00:00
|
|
|
procedure DrawSpecialDays;
|
2022-09-21 22:50:43 +00:00
|
|
|
procedure DrawWeekColHeaders;
|
|
|
|
procedure FixFontHeights;
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure InitColors;
|
|
|
|
procedure SetMeasurements; override;
|
|
|
|
|
|
|
|
public
|
|
|
|
constructor Create(AGanttView: TVpGanttView; ARenderCanvas: TCanvas);
|
|
|
|
procedure RenderToCanvas(ARenderIn: TRect; AAngle: TVpRotationAngle;
|
|
|
|
AScale: Extended; ARenderDate: TDateTime; AStartLine, AStopLine: Integer;
|
|
|
|
AUseGran: TVpGranularity; ADisplayOnly: Boolean); override;
|
|
|
|
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2022-08-26 22:35:42 +00:00
|
|
|
DateUtils,
|
2022-09-21 22:50:43 +00:00
|
|
|
VpSR, VpConst, VpMisc, VpCanvasUtils, VpData;
|
2022-08-26 22:35:42 +00:00
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
constructor TVpGanttViewPainter.Create(AGanttView: TVpGanttView;
|
|
|
|
ARenderCanvas: TCanvas);
|
|
|
|
begin
|
|
|
|
inherited Create(ARenderCanvas);
|
|
|
|
FGanttView := AGanttView;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.Clear;
|
|
|
|
begin
|
|
|
|
RenderCanvas.Brush.Color := RealColor;
|
|
|
|
RenderCanvas.FillRect(RenderIn);
|
|
|
|
end;
|
|
|
|
|
2022-08-29 21:25:03 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawActiveDate;
|
2022-08-29 15:09:38 +00:00
|
|
|
var
|
|
|
|
R: TRect;
|
|
|
|
dayRec: TVpGanttDayRec;
|
2022-10-12 16:40:15 +00:00
|
|
|
eventRec: PVpGanttEventRec;
|
2022-08-29 15:09:38 +00:00
|
|
|
dx, dy: Integer;
|
|
|
|
bs: TBrushStyle;
|
|
|
|
pw: Integer;
|
2023-10-08 22:41:21 +00:00
|
|
|
c: Integer;
|
2022-08-29 15:09:38 +00:00
|
|
|
begin
|
|
|
|
with FGanttView do
|
|
|
|
begin
|
|
|
|
if (ActiveRow < 0) or (ActiveRow >= RowCount) then
|
|
|
|
exit;
|
|
|
|
if (ActiveCol < 0) or (ActiveCol >= ColCount) then
|
|
|
|
exit;
|
|
|
|
|
2023-10-08 22:41:21 +00:00
|
|
|
c := ActiveCol;
|
|
|
|
if HourMode then
|
|
|
|
c := c div HoursPerDay;
|
|
|
|
dayRec := DayRecords[c];
|
2022-08-29 15:09:38 +00:00
|
|
|
eventRec := EventRecords[ActiveRow];
|
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
dx := LeftCol * FScaledColWidth;
|
|
|
|
dy := TopRow * FScaledRowHeight;
|
2022-08-29 15:09:38 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
R := Rect(
|
2022-10-12 16:40:15 +00:00
|
|
|
dayRec.Rect.Left, eventRec^.EventRect.Top, dayRec.Rect.Right, eventRec^.EventRect.Bottom
|
2022-08-29 15:09:38 +00:00
|
|
|
);
|
|
|
|
OffsetRect(R, -dx, -dy);
|
|
|
|
|
2023-10-09 15:47:05 +00:00
|
|
|
if R.Right < FScaledFixedColWidth then
|
|
|
|
exit;
|
2022-09-07 22:20:13 +00:00
|
|
|
if R.Top < FScaledTotalColHeaderHeight then
|
2022-08-29 21:25:03 +00:00
|
|
|
exit;
|
|
|
|
|
2023-10-09 15:47:05 +00:00
|
|
|
if R.Left < FScaledFixedColWidth then
|
|
|
|
R.Left := FScaledFixedColWidth;
|
|
|
|
|
2022-08-29 15:09:38 +00:00
|
|
|
pw := RenderCanvas.Pen.Width;
|
|
|
|
bs := RenderCanvas.Brush.Style;
|
|
|
|
RenderCanvas.Pen.Width := 3;
|
2022-08-29 21:25:03 +00:00
|
|
|
if FGanttView.Focused then
|
|
|
|
RenderCanvas.Pen.Color := clBlack
|
|
|
|
else
|
|
|
|
RenderCanvas.Pen.Color := clGray;
|
2022-08-29 15:09:38 +00:00
|
|
|
RenderCanvas.Brush.Style := bsClear;
|
|
|
|
TPSRectangle(RenderCanvas, Angle, RenderIn, R);
|
|
|
|
RenderCanvas.Pen.Width := pw;
|
|
|
|
RenderCanvas.Brush.Style := bs;
|
|
|
|
end;
|
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawBorders;
|
|
|
|
var
|
|
|
|
R: TRect;
|
|
|
|
begin
|
|
|
|
R := Rect(RealLeft, RealTop, RealRight - 1, RealBottom - 1);
|
2022-09-04 17:59:54 +00:00
|
|
|
R := TPSRotateRectangle(Angle, RenderIn, R);
|
2022-08-23 22:38:13 +00:00
|
|
|
case FGanttView.DrawingStyle of
|
2022-08-26 22:35:42 +00:00
|
|
|
dsNoBorder:
|
2022-09-04 17:59:54 +00:00
|
|
|
; // no border
|
2022-08-23 22:38:13 +00:00
|
|
|
dsFlat: // Draw a simple rectangular border
|
2022-09-04 17:59:54 +00:00
|
|
|
DrawBevelRect(RenderCanvas, R, BevelShadow, BevelShadow);
|
|
|
|
ds3D: // Draw a 3d bevel (recessed)
|
|
|
|
DrawBevelRect(RenderCanvas, R, BevelShadow, BevelHighlight);
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.DrawColHeader;
|
|
|
|
var
|
2022-08-26 22:35:42 +00:00
|
|
|
R, R1: TRect;
|
2022-08-23 22:38:13 +00:00
|
|
|
begin
|
|
|
|
RenderCanvas.Brush.Color := RealColHeadAttrColor;
|
2022-08-26 22:35:42 +00:00
|
|
|
RenderCanvas.Pen.Color := RealLineColor;
|
2022-08-23 22:38:13 +00:00
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
R := Rect(RealLeft, RealTop, RealRight, RealTop + FScaledTotalColHeaderHeight);
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
|
|
|
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
R1 := R;
|
|
|
|
InflateRect(R1, -1, -1);
|
2022-09-07 22:20:13 +00:00
|
|
|
R1.Right := RealLeft + FScaledFixedColWidth - 1;
|
2022-08-23 22:38:13 +00:00
|
|
|
DrawBevelRect(
|
|
|
|
RenderCanvas,
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSRotateRectangle(Angle, RenderIn, R1),
|
2022-08-23 22:38:13 +00:00
|
|
|
BevelHighlight,
|
2022-08-26 22:35:42 +00:00
|
|
|
BevelShadow
|
2022-08-23 22:38:13 +00:00
|
|
|
);
|
2022-09-07 22:20:13 +00:00
|
|
|
R1.Left := RealLeft + FScaledFixedColWidth;
|
|
|
|
R1.Right := RealRight - 2;
|
2022-08-23 22:38:13 +00:00
|
|
|
DrawBevelRect(
|
|
|
|
RenderCanvas,
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSRotateRectangle(Angle, RenderIn, R1),
|
2022-08-23 22:38:13 +00:00
|
|
|
BevelHighlight,
|
2022-08-26 22:35:42 +00:00
|
|
|
BevelShadow
|
2022-08-23 22:38:13 +00:00
|
|
|
);
|
2022-08-26 22:35:42 +00:00
|
|
|
end else
|
|
|
|
begin
|
2022-09-07 22:20:13 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, RealLeft + FScaledFixedColWidth, R.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, RealLeft + FScaledFixedColWidth, R.Bottom);
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, RealLeft, R.Bottom);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, RealRight, R.Bottom);
|
|
|
|
end;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Draw the month column headers
|
|
|
|
DrawMonthColHeaders;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Draw the week column headers
|
|
|
|
DrawWeekColHeaders;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Draw the day column headers
|
|
|
|
DrawDayColHeaders;
|
2023-10-08 22:41:21 +00:00
|
|
|
|
|
|
|
// Draw the hour column headers
|
|
|
|
DrawHourColHeaders;
|
2022-09-21 22:50:43 +00:00
|
|
|
end;
|
2022-08-26 22:35:42 +00:00
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawDayColHeaders;
|
|
|
|
var
|
|
|
|
dayRec: TVpGanttDayRec;
|
|
|
|
dx: Integer;
|
|
|
|
strH, strLen: Integer;
|
2023-10-08 22:41:21 +00:00
|
|
|
fmt, str: String;
|
2022-09-21 22:50:43 +00:00
|
|
|
i, n: Integer;
|
2023-10-08 22:41:21 +00:00
|
|
|
yLineBottom: Integer;
|
2022-09-21 22:50:43 +00:00
|
|
|
R, R1: TRect;
|
|
|
|
P: TPoint;
|
|
|
|
begin
|
2022-09-23 20:07:48 +00:00
|
|
|
if not (gchDay in FGanttView.ColHeaderAttributes.Visible) then
|
|
|
|
exit;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Offset due to scrolling
|
|
|
|
dx := FGanttView.LeftCol * FScaledColWidth;
|
2022-08-26 22:35:42 +00:00
|
|
|
|
2022-08-28 18:17:04 +00:00
|
|
|
// Draw day captions (always centered) and dividing lines (always at right side).
|
|
|
|
RenderCanvas.Font.Assign(FDayFont);
|
2022-08-26 22:35:42 +00:00
|
|
|
strH := RenderCanvas.TextHeight('Tg');
|
2022-08-28 18:17:04 +00:00
|
|
|
n := FGanttView.NumDays;
|
|
|
|
for i := 0 to n - 1 do
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-08-28 18:17:04 +00:00
|
|
|
dayRec := FGanttView.DayRecords[i];
|
2022-09-07 22:20:13 +00:00
|
|
|
R := ScaleRect(dayRec.Rect);
|
2022-08-28 18:17:04 +00:00
|
|
|
OffsetRect(R, -dx, 0);
|
2022-09-07 22:20:13 +00:00
|
|
|
if R.Left < RealLeft + FScaledFixedColWidth then
|
2022-08-27 10:31:14 +00:00
|
|
|
Continue;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
2022-09-01 09:42:04 +00:00
|
|
|
// In sdmHeader SpecialDayMode we must repaint the background of the
|
|
|
|
// day cells in the color of the special day (weekend/holiday)
|
|
|
|
if (FGanttView.SpecialDayMode = sdmHeader) then
|
|
|
|
begin
|
|
|
|
R1 := R;
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
inc(R1.Left, 2);
|
|
|
|
dec(R1.Bottom);
|
|
|
|
end else
|
|
|
|
inc(R1.Left);
|
|
|
|
if (gvoWeekends in FGanttView.Options) and IsWeekend(dayRec.Date) then
|
|
|
|
begin;
|
|
|
|
RenderCanvas.Brush.Color := FGanttView.Weekendcolor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R1);
|
|
|
|
end else
|
|
|
|
if (gvoHolidays in FGanttView.Options) and FGanttView.IsHoliday(dayRec.Date, str) then
|
|
|
|
begin
|
|
|
|
RenderCanvas.Brush.Color := FGanttView.HolidayColor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R1);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-28 18:17:04 +00:00
|
|
|
// No dividing line at last day of month because it already has been
|
|
|
|
// drawn as the month divider.
|
2023-10-08 22:41:21 +00:00
|
|
|
if FGanttView.HourMode then
|
|
|
|
yLineBottom := FScaledTotalColHeaderHeight
|
|
|
|
else
|
|
|
|
yLineBottom := R.Bottom;
|
2022-09-23 20:07:48 +00:00
|
|
|
if (DayOf(dayRec.Date) <> DaysInMonth(dayRec.Date)) or
|
|
|
|
([gchWeek, gchDay] * FGanttView.ColHeaderAttributes.Visible = [gchWeek, gchDay]) then
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
DrawBevelLine(
|
|
|
|
RenderCanvas,
|
|
|
|
TPSRotatePoint(Angle, RenderIn, Point(R.Right, R.Top)),
|
2023-10-08 22:41:21 +00:00
|
|
|
TPSRotatePoint(Angle, RenderIn, Point(R.Right, yLineBottom)),
|
2022-08-26 22:35:42 +00:00
|
|
|
BevelShadow,
|
|
|
|
BevelHighlight
|
|
|
|
)
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top);
|
2023-10-08 22:41:21 +00:00
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, yLineBottom);
|
2022-08-26 22:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
|
|
|
// Paint day name
|
2023-10-08 22:41:21 +00:00
|
|
|
if FGanttView.HourMode then
|
|
|
|
fmt := FGanttView.Dayformat_HourMode
|
|
|
|
else
|
|
|
|
fmt := FGanttView.DayFormat;
|
|
|
|
str := FormatDateTime(fmt, dayRec.Date);
|
2022-08-26 22:35:42 +00:00
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
P := Point((R.Left + R.Right - strLen) div 2, (R.Top + R.Bottom - strH) div 2);
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, P.X, P.Y, str);
|
2022-08-30 21:39:47 +00:00
|
|
|
|
|
|
|
// To do: replace above code for multi-line text, ie.
|
|
|
|
// strLen := GetCanvasTextWidth(RenderCanvas, FDayFont, str);
|
|
|
|
// TPSTextRect(RencerCanvas, Angle, RenderIn, R, P.X, P.Y, str);
|
|
|
|
// BUT: TPSTextRect does not yet exist...
|
2022-08-26 22:35:42 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.DrawEvents;
|
|
|
|
var
|
|
|
|
i: Integer;
|
2022-10-12 16:40:15 +00:00
|
|
|
eventRec: PVpGanttEventRec;
|
2022-08-26 22:35:42 +00:00
|
|
|
event: TVpEvent;
|
|
|
|
cat: TVpCategoryInfo;
|
|
|
|
R: TRect;
|
2022-08-27 10:31:14 +00:00
|
|
|
dx, dy: Integer;
|
2022-08-29 15:09:38 +00:00
|
|
|
top_margin, bottom_margin: Integer;
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-09-07 22:20:13 +00:00
|
|
|
dx := FGanttView.LeftCol * FScaledColWidth;
|
|
|
|
dy := FGanttView.TopRow * FScaledRowHeight;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
if DisplayOnly then
|
|
|
|
begin
|
|
|
|
top_margin := round(2*scale);
|
|
|
|
bottom_margin := top_margin;
|
|
|
|
end else
|
2022-08-29 15:09:38 +00:00
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
top_margin := 1;
|
|
|
|
bottom_margin := 2;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
top_margin := 2;
|
|
|
|
bottom_margin := 1;
|
|
|
|
end;
|
2022-09-07 22:20:13 +00:00
|
|
|
|
2022-08-28 18:17:04 +00:00
|
|
|
RenderCanvas.Font.Assign(FEventFont);
|
|
|
|
for i := 0 to FGanttView.NumEvents-1 do
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-08-28 18:17:04 +00:00
|
|
|
eventRec := FGanttView.EventRecords[i];
|
2022-10-12 16:40:15 +00:00
|
|
|
event := eventRec^.Event;
|
|
|
|
if eventRec^.EndTime < FGanttView.FirstDate then
|
2022-09-14 21:24:33 +00:00
|
|
|
Continue;
|
2022-10-12 16:40:15 +00:00
|
|
|
if eventRec^.StartTime > FGanttView.LastDate + 1then
|
2022-09-14 21:24:33 +00:00
|
|
|
exit;
|
2022-10-12 16:40:15 +00:00
|
|
|
R := ScaleRect(eventRec^.EventRect);
|
2022-08-28 18:17:04 +00:00
|
|
|
OffsetRect(R, -dx, -dy);
|
2022-08-29 15:09:38 +00:00
|
|
|
inc(R.Top, top_margin);
|
|
|
|
dec(R.Bottom, bottom_margin);
|
2022-09-07 22:20:13 +00:00
|
|
|
if R.Top < FScaledTotalColHeaderHeight then
|
2022-08-28 18:17:04 +00:00
|
|
|
Continue;
|
2022-09-07 22:20:13 +00:00
|
|
|
if R.Right < FScaledFixedColWidth then
|
2022-08-28 18:17:04 +00:00
|
|
|
Continue;
|
2022-09-07 22:20:13 +00:00
|
|
|
if R.Left < FScaledFixedColWidth then
|
|
|
|
R.Left := FScaledFixedColWidth;
|
2022-08-26 22:35:42 +00:00
|
|
|
cat := FGanttView.DataStore.CategoryColorMap.GetCategory(event.Category);
|
|
|
|
RenderCanvas.Pen.Color := cat.Color;
|
2022-09-07 22:20:13 +00:00
|
|
|
RenderCanvas.Pen.Width := round(Scale);
|
2022-08-26 22:35:42 +00:00
|
|
|
RenderCanvas.Brush.Color := cat.BackgroundColor;
|
2023-10-08 22:41:21 +00:00
|
|
|
//RenderCanvas.Brush.Style := bsSolid;
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSRectangle(RenderCanvas, Angle, RenderIn, R);
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.DrawGrid;
|
|
|
|
var
|
2022-08-26 22:35:42 +00:00
|
|
|
x1, x2, y0, y1, y2: Integer;
|
2022-08-28 18:17:04 +00:00
|
|
|
dx, dy: Integer;
|
|
|
|
i, n, numEvents: Integer;
|
2022-10-12 16:40:15 +00:00
|
|
|
eventRec: PVpGanttEventRec;
|
2023-10-09 15:47:05 +00:00
|
|
|
// dayRec: TVpGanttDayRec;
|
2022-08-26 22:35:42 +00:00
|
|
|
monthRec: TVpGanttMonthRec;
|
2022-09-07 22:20:13 +00:00
|
|
|
R: TRect;
|
2022-08-23 22:38:13 +00:00
|
|
|
begin
|
|
|
|
RenderCanvas.Pen.Color := RealLineColor;
|
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
dx := FGanttView.LeftCol * FScaledColWidth;
|
|
|
|
dy := FGanttView.TopRow * FScaledRowHeight;
|
2022-08-29 18:34:35 +00:00
|
|
|
|
2022-08-30 21:00:26 +00:00
|
|
|
// Horizontal line terminating the col header block
|
2022-09-07 22:20:13 +00:00
|
|
|
x1 := RealLeft + FScaledFixedColWidth;
|
2022-08-28 18:17:04 +00:00
|
|
|
n := FGanttView.NumMonths;
|
|
|
|
if n > 0 then
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-08-28 18:17:04 +00:00
|
|
|
monthRec := FGanttView.MonthRecords[n-1];
|
2022-09-07 22:20:13 +00:00
|
|
|
R := ScaleRect(monthRec.Rect);
|
|
|
|
x2 := R.Right - dx;
|
2022-08-26 22:35:42 +00:00
|
|
|
end else
|
|
|
|
x2 := RealRight;
|
2022-09-07 22:20:13 +00:00
|
|
|
y0 := RealTop + FScaledTotalColHeaderHeight;
|
2022-08-26 22:35:42 +00:00
|
|
|
if FGanttView.DrawingStyle = ds3D then dec(y0);
|
2022-09-07 22:20:13 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, x1, y0);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, x2, y0);
|
2022-08-26 22:35:42 +00:00
|
|
|
|
2022-08-30 21:00:26 +00:00
|
|
|
// Horizontal lines
|
|
|
|
if (gvoHorizGrid in FGanttView.Options) then
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-08-30 21:00:26 +00:00
|
|
|
y0 := -dy;
|
|
|
|
if FGanttView.DrawingStyle = ds3D then dec(y0);
|
|
|
|
numEvents := FGanttView.NumEvents;
|
|
|
|
for i := 0 to numEvents - 1 do
|
|
|
|
begin
|
|
|
|
eventRec := FGanttView.EventRecords[i];
|
2022-10-12 16:40:15 +00:00
|
|
|
R := ScaleRect(eventRec^.EventRect);
|
2022-09-07 22:20:13 +00:00
|
|
|
y1 := y0 + R.Bottom;
|
|
|
|
if y1 >= FScaledTotalColHeaderHeight then
|
|
|
|
begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, x1, y1);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, x2, y1);
|
|
|
|
end;
|
2022-08-30 21:00:26 +00:00
|
|
|
end;
|
2022-08-26 22:35:42 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
// Vertical lines
|
2023-10-09 15:47:05 +00:00
|
|
|
RenderCanvas.Brush.Style := bsClear;
|
2022-08-30 21:00:26 +00:00
|
|
|
if (gvoVertGrid in FGanttView.Options) then
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-09-07 22:20:13 +00:00
|
|
|
y1 := RealTop + FScaledTotalColHeaderHeight;
|
2022-08-30 21:00:26 +00:00
|
|
|
if numEvents > 0 then
|
|
|
|
begin
|
|
|
|
eventRec := FGanttView.EventRecords[numEvents-1];
|
2022-10-12 16:40:15 +00:00
|
|
|
R := ScaleRect(eventRec^.EventRect);
|
2022-09-07 22:20:13 +00:00
|
|
|
y2 := R.Bottom - dy;
|
2023-10-09 15:47:05 +00:00
|
|
|
n := FGanttView.ColCount;
|
2022-09-14 21:24:33 +00:00
|
|
|
for i := 0 to n-1 do
|
2022-09-07 22:20:13 +00:00
|
|
|
begin
|
2023-10-09 15:47:05 +00:00
|
|
|
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);
|
2022-09-14 21:24:33 +00:00
|
|
|
x1 := R.Right - dx;
|
|
|
|
if x1 >= FScaledFixedColWidth then
|
|
|
|
begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, x1, y1);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, x1, y2)
|
|
|
|
end;
|
2022-09-07 22:20:13 +00:00
|
|
|
end;
|
2022-08-30 21:00:26 +00:00
|
|
|
end;
|
2022-08-26 22:35:42 +00:00
|
|
|
end;
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
|
2023-10-08 22:41:21 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawHourColHeaders;
|
|
|
|
var
|
|
|
|
hourRec: TVpGanttHourRec;
|
|
|
|
dx: Integer;
|
|
|
|
strH, strLen: Integer;
|
|
|
|
str: String;
|
|
|
|
i, n: Integer;
|
|
|
|
R, R1: TRect;
|
|
|
|
P: TPoint;
|
|
|
|
begin
|
|
|
|
if not (gchHour in FGanttView.ColHeaderAttributes.Visible) then
|
|
|
|
exit;
|
|
|
|
|
|
|
|
// Offset due to scrolling
|
|
|
|
dx := FGanttView.LeftCol * FScaledColWidth;
|
|
|
|
|
|
|
|
// Draw hour captions (always centered) and dividing lines (always at right side).
|
|
|
|
RenderCanvas.Font.Assign(FHourFont);
|
|
|
|
strH := RenderCanvas.TextHeight('Tg');
|
|
|
|
n := FGanttView.NumHours;
|
|
|
|
for i := 0 to n - 1 do
|
|
|
|
begin
|
|
|
|
hourRec := FGanttView.HourRecords[i];
|
|
|
|
R := ScaleRect(hourRec.Rect);
|
|
|
|
OffsetRect(R, -dx, 0);
|
|
|
|
if R.Left < RealLeft + FScaledFixedColWidth then
|
|
|
|
Continue;
|
|
|
|
|
|
|
|
// In sdmHeader SpecialDayMode we must repaint the background of the
|
|
|
|
// day cells in the color of the special day (weekend/holiday)
|
|
|
|
if (FGanttView.SpecialDayMode = sdmHeader) then
|
|
|
|
begin
|
|
|
|
R1 := R;
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
inc(R1.Left, 2);
|
|
|
|
dec(R1.Bottom);
|
|
|
|
end else
|
|
|
|
inc(R1.Left);
|
|
|
|
if (gvoWeekends in FGanttView.Options) and IsWeekend(hourRec.Date) then
|
|
|
|
begin;
|
|
|
|
RenderCanvas.Brush.Color := FGanttView.Weekendcolor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R1);
|
|
|
|
end else
|
|
|
|
if (gvoHolidays in FGanttView.Options) and FGanttView.IsHoliday(hourRec.Date, str) then
|
|
|
|
begin
|
|
|
|
RenderCanvas.Brush.Color := FGanttView.HolidayColor;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R1);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// No dividing line at last hour of day because it already has been
|
|
|
|
// drawn as the day divider.
|
|
|
|
if hourRec.Hour <> 23 then
|
|
|
|
begin
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
DrawBevelLine(
|
|
|
|
RenderCanvas,
|
|
|
|
TPSRotatePoint(Angle, RenderIn, Point(R.Right, R.Top)),
|
|
|
|
TPSRotatePoint(Angle, RenderIn, Point(R.Right, R.Bottom)),
|
|
|
|
BevelShadow,
|
|
|
|
BevelHighlight
|
|
|
|
)
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Paint hour value
|
|
|
|
str := IntToStr(hourRec.Hour);
|
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
P := Point((R.Left + R.Right - strLen) div 2, (R.Top + R.Bottom - strH) div 2);
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, P.X, P.Y, str);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawMonthColHeaders;
|
|
|
|
var
|
|
|
|
dx: Integer;
|
|
|
|
i, n: Integer;
|
|
|
|
monthRec: TVpGanttMonthRec;
|
|
|
|
R, R1: TRect;
|
|
|
|
P: TPoint;
|
|
|
|
str: String;
|
|
|
|
strLen: Integer;
|
|
|
|
begin
|
2022-09-23 20:07:48 +00:00
|
|
|
if not (gchMonth in FGanttView.ColHeaderAttributes.Visible) then
|
|
|
|
exit;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Offset due to scrolling
|
|
|
|
dx := FGanttView.LeftCol * FScaledColWidth;
|
|
|
|
|
|
|
|
// Draw month rectangles and month captions
|
|
|
|
RenderCanvas.Font.Assign(FMonthFont);
|
|
|
|
n := FGanttView.NumMonths;
|
|
|
|
for i := 0 to n-1 do
|
|
|
|
begin
|
|
|
|
monthRec := FGanttView.MonthRecords[i];
|
|
|
|
R := monthRec.Rect;
|
|
|
|
R := ScaleRect(R);
|
|
|
|
OffsetRect(R, -dx , 0);
|
|
|
|
|
2022-09-24 10:50:26 +00:00
|
|
|
if R.Right <= RealLeft + FScaledFixedColWidth then
|
|
|
|
continue;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Clip at fixed col edge
|
|
|
|
if R.Left < RealLeft + FScaledFixedColWidth then
|
|
|
|
R.Left := RealLeft + FScaledFixedColWidth;
|
|
|
|
|
|
|
|
// Draw month box
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
R1 := R;
|
2022-09-24 10:50:26 +00:00
|
|
|
// if i > 0 then
|
2022-09-21 22:50:43 +00:00
|
|
|
inc(R1.Left);
|
|
|
|
dec(R1.Bottom);
|
|
|
|
DrawBevelRect(
|
|
|
|
RenderCanvas,
|
|
|
|
TPSRotateRectangle(Angle, RenderIn, R1),
|
|
|
|
BevelHighlight,
|
|
|
|
BevelShadow
|
|
|
|
)
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom);
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Paint month name. Use short format if space is too small for long format.
|
|
|
|
str := FormatDateTime(FGanttView.MonthFormat, monthRec.Date);
|
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
if strLen > R.Width - 2 * FScaledTextMargin then
|
|
|
|
begin
|
|
|
|
str := FormatDateTime(FGanttView.MonthFormat_short, monthRec.Date);
|
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
end;
|
|
|
|
if strLen > R.Width - 2 * FScaledTextMargin then
|
|
|
|
str := '';
|
|
|
|
if str <> '' then
|
|
|
|
begin
|
|
|
|
P := Point((R.Left + R.Right - strLen) div 2, R.Top + FScaledTextMargin);
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, P.X, P.Y, str);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawRowHeader;
|
|
|
|
var
|
2022-08-26 22:35:42 +00:00
|
|
|
R: TRect;
|
|
|
|
P: TPoint;
|
|
|
|
strH: Integer;
|
|
|
|
str: String;
|
|
|
|
i: Integer;
|
2022-08-27 10:31:14 +00:00
|
|
|
dy: Integer;
|
2022-10-12 16:40:15 +00:00
|
|
|
eventRec: PVpGanttEventRec;
|
2022-08-23 22:38:13 +00:00
|
|
|
begin
|
|
|
|
RenderCanvas.Brush.Color := RealRowHeadAttrColor;
|
|
|
|
|
|
|
|
if FGanttView.DrawingStyle = ds3d then begin
|
2022-08-26 22:35:42 +00:00
|
|
|
R.Left := RealLeft + 1;
|
2022-08-28 18:17:04 +00:00
|
|
|
R.Top := RealTop;
|
2022-09-07 22:20:13 +00:00
|
|
|
R.Right := RealLeft + FScaledFixedColWidth - 1;
|
2022-08-26 22:35:42 +00:00
|
|
|
R.Bottom := RealBottom - 1;
|
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
2022-08-23 22:38:13 +00:00
|
|
|
DrawBevelRect(
|
|
|
|
RenderCanvas,
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSRotateRectangle(Angle, RenderIn, R),
|
2022-08-23 22:38:13 +00:00
|
|
|
BevelHighlight,
|
2022-08-26 22:35:42 +00:00
|
|
|
BevelShadow
|
2022-08-23 22:38:13 +00:00
|
|
|
);
|
|
|
|
end else begin
|
2022-09-07 22:20:13 +00:00
|
|
|
R := Rect(RealLeft, RealTop + 1, RealLeft + FScaledFixedColWidth, RealBottom);
|
2022-08-26 22:35:42 +00:00
|
|
|
TPSFillRect(RenderCanvas, Angle, RenderIn, R);
|
2022-08-23 22:38:13 +00:00
|
|
|
RenderCanvas.Pen.Color := RealLineColor;
|
2022-09-07 22:20:13 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom);
|
2022-08-26 22:35:42 +00:00
|
|
|
end;
|
|
|
|
|
2022-08-28 18:17:04 +00:00
|
|
|
RenderCanvas.Font.Assign(FEventFont);
|
2022-08-26 22:35:42 +00:00
|
|
|
strH := RenderCanvas.TextHeight('Tg');
|
|
|
|
RenderCanvas.Pen.Color := RealLineColor;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
|
|
|
// Offset due to scrolling
|
2022-09-07 22:20:13 +00:00
|
|
|
dy := FGanttView.TopRow * FScaledRowHeight;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
|
|
|
for i := 0 to FGanttView.NumEvents-1 do
|
2022-08-26 22:35:42 +00:00
|
|
|
begin
|
2022-08-28 18:17:04 +00:00
|
|
|
eventRec := FGanttView.EventRecords[i];
|
2022-10-12 16:40:15 +00:00
|
|
|
R := ScaleRect(eventRec^.HeadRect);
|
2022-08-28 18:17:04 +00:00
|
|
|
OffsetRect(R, 0, -dy);
|
2022-09-07 22:20:13 +00:00
|
|
|
if R.Top < FScaledTotalColHeaderHeight then
|
2022-08-27 10:31:14 +00:00
|
|
|
Continue;
|
2022-08-26 22:35:42 +00:00
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
R.BottomRight := R.BottomRight - Point(1, 1);
|
|
|
|
DrawBevelRect(
|
|
|
|
RenderCanvas,
|
|
|
|
TPSRotateRectangle(Angle, RenderIn, R),
|
|
|
|
BevelHighlight,
|
|
|
|
BevelShadow
|
|
|
|
);
|
|
|
|
end else
|
2022-09-03 17:58:24 +00:00
|
|
|
begin
|
2022-09-07 22:20:13 +00:00
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Left, R.Bottom);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom);
|
2022-09-03 17:58:24 +00:00
|
|
|
end;
|
2022-08-26 22:35:42 +00:00
|
|
|
|
2022-10-12 12:36:21 +00:00
|
|
|
// Paint event description as header.
|
|
|
|
// Use clipping in case the text is too long
|
|
|
|
RenderCanvas.Clipping := true;
|
|
|
|
try
|
|
|
|
RenderCanvas.ClipRect := R;
|
|
|
|
inc(R.Left, FScaledTextMargin + 2);
|
|
|
|
P := Point(R.Left, (R.Top + R.Bottom - strH) div 2);
|
2022-10-12 16:40:15 +00:00
|
|
|
str := eventRec^.Caption;
|
2022-10-12 12:36:21 +00:00
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, P.X, P.Y, str);
|
|
|
|
finally
|
|
|
|
RenderCanvas.Clipping := false;
|
|
|
|
end;
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-09-01 09:42:04 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawSpecialDays;
|
|
|
|
var
|
|
|
|
i, nDays, nEvents: Integer;
|
|
|
|
x1, y1, x2, y2: Integer;
|
|
|
|
dx, dy: Integer;
|
|
|
|
clr: TColor;
|
|
|
|
dayRec: TVpGanttDayRec;
|
|
|
|
holiday: String;
|
2022-09-07 22:20:13 +00:00
|
|
|
R: TRect;
|
2022-09-01 09:42:04 +00:00
|
|
|
begin
|
|
|
|
with FGanttView do
|
|
|
|
begin
|
2022-09-14 21:24:33 +00:00
|
|
|
if (RealStartDate = NO_DATE) or (SpecialDayMode <> sdmColumn) then
|
2022-09-01 09:42:04 +00:00
|
|
|
exit;
|
|
|
|
|
|
|
|
nEvents := NumEvents;
|
|
|
|
nDays := NumDays;
|
2022-09-07 22:20:13 +00:00
|
|
|
dx := LeftCol * FScaledColWidth;
|
|
|
|
dy := TopRow * FScaledRowHeight;
|
2022-09-01 09:42:04 +00:00
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
y1 := RealTop + FScaledTotalColHeaderHeight;
|
2022-09-14 21:24:33 +00:00
|
|
|
if nEvents > 0 then
|
|
|
|
begin
|
2022-10-12 16:40:15 +00:00
|
|
|
R := ScaleRect(EventRecords[nEvents-1]^.HeadRect);
|
2022-09-14 21:24:33 +00:00
|
|
|
y2 := R.Bottom - dy;
|
|
|
|
end else
|
|
|
|
y2 := y1;
|
2022-09-01 09:42:04 +00:00
|
|
|
|
|
|
|
RenderCanvas.Brush.style := bsSolid;
|
|
|
|
for i := 0 to nDays-1 do
|
|
|
|
begin
|
|
|
|
dayRec := DayRecords[i];
|
|
|
|
clr := clNone;
|
|
|
|
if (gvoWeekends in Options) and IsWeekend(dayRec.Date) then
|
|
|
|
clr := WeekendColor
|
|
|
|
else
|
|
|
|
if (gvoHolidays in Options) and IsHoliday(dayRec.Date, holiday) then
|
|
|
|
clr := HolidayColor;
|
|
|
|
if clr <> clNone then
|
|
|
|
begin
|
|
|
|
RenderCanvas.Brush.Color := clr;
|
2022-09-07 22:20:13 +00:00
|
|
|
R := ScaleRect(dayRec.Rect);
|
|
|
|
x1 := R.Left - dx;
|
|
|
|
x2 := R.Right - dx;
|
2022-09-11 17:38:30 +00:00
|
|
|
if x2 < FScaledFixedColWidth then
|
|
|
|
Continue;
|
|
|
|
if x1 < FScaledFixedColWidth then
|
|
|
|
x1 := FScaledFixedColWidth;
|
2022-09-08 21:00:40 +00:00
|
|
|
TPSFilLRect(RenderCanvas, Angle, RenderIn, Rect(x1, y1, x2, y2));
|
2022-09-01 09:42:04 +00:00
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
procedure TVpGanttViewPainter.DrawWeekColHeaders;
|
|
|
|
var
|
|
|
|
dx: Integer;
|
|
|
|
i, n: Integer;
|
|
|
|
weekRec: TVpGanttWeekRec;
|
|
|
|
weekNo, yearNo: Integer;
|
|
|
|
R, R1: TRect;
|
|
|
|
P: TPoint;
|
|
|
|
str: String;
|
|
|
|
strLen: Integer;
|
|
|
|
begin
|
2022-09-23 20:07:48 +00:00
|
|
|
if not (gchWeek in FGanttView.ColHeaderAttributes.Visible) then
|
|
|
|
exit;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Offset due to scrolling
|
|
|
|
dx := FGanttView.LeftCol * FScaledColWidth;
|
|
|
|
|
|
|
|
// Draw week rectangles and week numbers as captions
|
|
|
|
RenderCanvas.Font.Assign(FWeekFont);
|
|
|
|
n := FGanttView.NumWeeks;
|
|
|
|
for i := 0 to n-1 do
|
|
|
|
begin
|
|
|
|
weekRec := FGanttView.WeekRecords[i];
|
|
|
|
R := weekRec.Rect;
|
|
|
|
R := ScaleRect(R);
|
|
|
|
OffsetRect(R, -dx , 0);
|
|
|
|
|
2022-09-24 10:50:26 +00:00
|
|
|
if R.Right <= RealLeft + FScaledFixedColWidth then
|
|
|
|
Continue;
|
|
|
|
|
2022-09-21 22:50:43 +00:00
|
|
|
// Clip at fixed col edge
|
|
|
|
if R.Left < RealLeft + FScaledFixedColWidth then
|
|
|
|
R.Left := RealLeft + FScaledFixedColWidth;
|
|
|
|
|
|
|
|
// Draw week box
|
|
|
|
if FGanttView.DrawingStyle = ds3D then
|
|
|
|
begin
|
|
|
|
R1 := R;
|
2022-09-24 10:50:26 +00:00
|
|
|
// if i > 0 then
|
2022-09-21 22:50:43 +00:00
|
|
|
inc(R1.Left);
|
|
|
|
dec(R1.Bottom);
|
|
|
|
DrawBevelLine(
|
|
|
|
RenderCanvas,
|
|
|
|
TPSRotatePoint(Angle, RenderIn, Point(R.Right, R.Top)),
|
|
|
|
TPSRotatePoint(Angle, RenderIn, Point(R.Right, R.Bottom)),
|
|
|
|
BevelShadow,
|
|
|
|
BevelHighlight
|
|
|
|
)
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
TPSMoveTo(RenderCanvas, Angle, RenderIn, R.Right, R.Top);
|
|
|
|
TPSLineTo(RenderCanvas, Angle, RenderIn, R.Right, R.Bottom);
|
|
|
|
end;
|
|
|
|
|
|
|
|
// Paint ISO week number.
|
|
|
|
weekNo := WeekOfTheYear(weekRec.Date);
|
|
|
|
yearNo := YearOf(weekRec.Date);
|
|
|
|
str := Format('%s %d (%d)', [RSCalendarWeekAbbr, weekNo, yearNo]);
|
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
if strLen > R.Width - 2 * FScaledTextMargin then
|
|
|
|
begin
|
|
|
|
str := Format('%s %d', [RSCalendarWeekAbbr, weekNo]);
|
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
end;
|
|
|
|
if strLen > R.Width - 2 * FScaledTextMargin then
|
|
|
|
begin
|
|
|
|
str := IntToStr(weekNo);
|
|
|
|
strLen := RenderCanvas.TextWidth(str);
|
|
|
|
end;
|
|
|
|
if strLen > R.Width - 2 * FScaledTextMargin then
|
|
|
|
str := '';
|
|
|
|
if str <> '' then
|
|
|
|
begin
|
|
|
|
P := Point((R.Left + R.Right - strLen) div 2, R.Top + FScaledTextMargin);
|
|
|
|
TPSTextOut(RenderCanvas, Angle, RenderIn, P.X, P.Y, str);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
procedure TVpGanttViewPainter.FixFontHeights;
|
|
|
|
begin
|
|
|
|
with FGanttView do begin
|
|
|
|
ColHeaderAttributes.DayFont.Height := GetRealFontHeight(ColHeaderAttributes.DayFont);
|
2022-09-21 22:50:43 +00:00
|
|
|
ColHeaderAttributes.WeekFont.Height := GetRealFontHeight(ColHeaderAttributes.WeekFont);
|
2022-08-23 22:38:13 +00:00
|
|
|
ColHeaderAttributes.MonthFont.Height := GetRealFontHeight(ColHeaderAttributes.MonthFont);
|
|
|
|
RowHeaderAttributes.EventFont.Height := GetRealFontHeight(RowHeaderAttributes.EventFont);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.InitColors;
|
|
|
|
begin
|
|
|
|
if DisplayOnly then begin
|
|
|
|
BevelShadow := clBlack;
|
|
|
|
BevelDarkShadow := clBlack;
|
|
|
|
BevelFace := clBlack;
|
|
|
|
RealColHeadAttrColor := clSilver;
|
|
|
|
RealRowHeadAttrColor := clSilver;
|
|
|
|
RealColor := clWhite;
|
|
|
|
RealLineColor := clSilver;
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
BevelHighlight := clBtnHighlight;
|
|
|
|
BevelShadow := clBtnShadow;
|
|
|
|
BevelDarkShadow := cl3DDkShadow;
|
|
|
|
BevelFace := clBtnFace;
|
|
|
|
RealColHeadAttrColor := ColorToRGB(FGanttView.ColHeaderAttributes.Color);
|
|
|
|
RealRowHeadAttrColor := ColorToRGB(FGanttView.RowHeaderAttributes.Color);
|
|
|
|
RealColor := ColorToRGB(FGanttView.Color);
|
|
|
|
RealLineColor := ColorToRGB(FGanttView.LineColor);
|
|
|
|
end;
|
2022-08-28 18:17:04 +00:00
|
|
|
|
2023-10-08 22:41:21 +00:00
|
|
|
FHourFont := FGanttView.ColHeaderAttributes.HourFont;
|
2022-08-28 18:17:04 +00:00
|
|
|
FDayFont := FGanttView.ColHeaderAttributes.DayFont;
|
|
|
|
FMonthFont := FGanttView.ColHeaderAttributes.MonthFont;
|
2022-09-21 22:50:43 +00:00
|
|
|
FWeekFont := FGanttView.ColHeaderAttributes.WeekFont;
|
2022-08-28 18:17:04 +00:00
|
|
|
FEventFont := FGanttView.RowHeaderAttributes.EventFont;
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.RenderToCanvas(ARenderIn: TRect;
|
|
|
|
AAngle: TVpRotationAngle; AScale: Extended; ARenderDate: TDateTime;
|
|
|
|
AStartLine, AStopLine: Integer; AUseGran: TVpGranularity;
|
|
|
|
ADisplayOnly: Boolean);
|
|
|
|
begin
|
|
|
|
inherited;
|
|
|
|
|
|
|
|
InitColors;
|
|
|
|
SavePenBrush;
|
|
|
|
InitPenBrush;
|
|
|
|
if ADisplayOnly then
|
|
|
|
FixFontHeights;
|
|
|
|
|
|
|
|
Rgn := CreateRectRgn(RenderIn.Left, RenderIn.Top, RenderIn.Right, RenderIn.Bottom);
|
|
|
|
try
|
|
|
|
SelectClipRgn(RenderCanvas.Handle, Rgn);
|
|
|
|
|
|
|
|
{ Clear client area }
|
|
|
|
Clear;
|
|
|
|
|
|
|
|
{ Measure the row heights }
|
|
|
|
SetMeasurements;
|
|
|
|
|
|
|
|
{ Draw headers }
|
|
|
|
DrawRowHeader;
|
2022-08-28 18:17:04 +00:00
|
|
|
DrawColHeader;
|
2022-08-23 22:38:13 +00:00
|
|
|
|
2022-09-01 09:42:04 +00:00
|
|
|
{ Draw weekends and holidays }
|
|
|
|
DrawSpecialDays;
|
2022-08-29 22:00:20 +00:00
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
{ Draw grid }
|
|
|
|
DrawGrid;
|
|
|
|
|
2022-08-26 22:35:42 +00:00
|
|
|
{ draw events }
|
|
|
|
DrawEvents;
|
2022-08-23 22:38:13 +00:00
|
|
|
|
2022-08-29 15:09:38 +00:00
|
|
|
{ Draw active day rectangle }
|
2022-08-30 21:00:26 +00:00
|
|
|
if (gvoActiveDate in FGanttView.Options) then
|
2022-08-29 21:25:03 +00:00
|
|
|
DrawActiveDate;
|
2022-08-29 15:09:38 +00:00
|
|
|
|
2022-08-23 22:38:13 +00:00
|
|
|
{ Draw the borders }
|
|
|
|
DrawBorders;
|
|
|
|
|
|
|
|
finally
|
|
|
|
SelectClipRgn(RenderCanvas.Handle, 0);
|
|
|
|
DeleteObject(Rgn);
|
|
|
|
end;
|
|
|
|
|
|
|
|
{ Restore canvas settings}
|
|
|
|
RestorePenBrush;
|
2022-09-07 22:20:13 +00:00
|
|
|
end;
|
2022-08-23 22:38:13 +00:00
|
|
|
|
2022-09-07 22:20:13 +00:00
|
|
|
function TVpGanttViewPainter.ScaleRect(ARect: TRect): TRect;
|
|
|
|
begin
|
|
|
|
Result.Left := RealLeft + round(ARect.Left * Scale);
|
|
|
|
Result.Top := RealTop + round(ARect.Top * Scale);
|
|
|
|
Result.Right := RealLeft + round(ARect.Right * Scale);
|
|
|
|
Result.Bottom := RealTop + round(ARect.Bottom * Scale);
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TVpGanttViewPainter.SetMeasurements;
|
|
|
|
begin
|
|
|
|
inherited;
|
2022-09-07 22:20:13 +00:00
|
|
|
|
2022-08-28 18:17:04 +00:00
|
|
|
FGanttView.Init;
|
2022-09-07 22:20:13 +00:00
|
|
|
|
|
|
|
FScaledFixedColWidth := round(FGanttView.FixedColWidth * Scale);
|
|
|
|
FScaledColWidth := round(FGanttView.ColWidth * Scale);
|
|
|
|
FScaledTextMargin := round(FGanttView.TextMargin * Scale);
|
|
|
|
FScaledTotalColHeaderHeight := round(FGanttView.TotalColHeaderHeight * Scale);
|
|
|
|
FScaledRowHeight := round(FGanttView.RowHeight * Scale);
|
|
|
|
|
|
|
|
FGanttView.VisibleCols := FGanttView.CalcVisibleCols(RealRight - RealLeft, FScaledFixedColWidth, FScaledColWidth);
|
|
|
|
FGanttView.VisibleRows := FGanttView.CalcVisibleRows(RealBottom - RealTop, FScaledTotalColHeaderHeight, FScaledRowHeight);
|
2022-08-23 22:38:13 +00:00
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|