tvplanit: Add ISO week numbers to GanttView column headers

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8499 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-09-21 22:50:43 +00:00
parent e05d47afc0
commit b6753c216d
7 changed files with 349 additions and 67 deletions

View File

@ -306,3 +306,4 @@ msgstr "Erledigte Aufgaben verbergen"
#: tmainform.titlelbl.caption #: tmainform.titlelbl.caption
msgid "TitleLbl" msgid "TitleLbl"
msgstr "" msgstr ""

View File

@ -303,3 +303,4 @@ msgstr "Hide completed tasks"
#: tmainform.titlelbl.caption #: tmainform.titlelbl.caption
msgid "TitleLbl" msgid "TitleLbl"
msgstr "TitleLbl" msgstr "TitleLbl"

View File

@ -1095,7 +1095,7 @@ msgstr "Druckformat-Designer"
msgid "Print order" msgid "Print order"
msgstr "" msgstr ""
"Druck-\n" "Druck-\n"
"Reihenfolge" "Reihenfolge\n"
#: vpsr.rsprintprvcancel #: vpsr.rsprintprvcancel
msgctxt "vpsr.rsprintprvcancel" msgctxt "vpsr.rsprintprvcancel"
@ -1813,3 +1813,4 @@ msgstr "Unbekannte Achsen-Spezifikation: %s"
#: vpsr.sxmldecnotatbeg #: vpsr.sxmldecnotatbeg
msgid "The XML declaration must appear before the first element" msgid "The XML declaration must appear before the first element"
msgstr "Die XML-Deklaration muss vor dem ersten Element erscheinen" msgstr "Die XML-Deklaration muss vor dem ersten Element erscheinen"

View File

@ -1792,3 +1792,4 @@ msgstr "Unknown axis specifier: %s"
#: vpsr.sxmldecnotatbeg #: vpsr.sxmldecnotatbeg
msgid "The XML declaration must appear before the first element" msgid "The XML declaration must appear before the first element"
msgstr "The XML declaration must appear before the first element" msgstr "The XML declaration must appear before the first element"

View File

@ -37,6 +37,12 @@ type
Rect: TRect; Rect: TRect;
end; end;
TVpGanttWeekRec = record
WeekNo: Integer;
Date: TDateTime;
Rect: TRect;
end;
TVpGanttMonthRec = record TVpGanttMonthRec = record
Date: TDateTime; Date: TDateTime;
Rect: TRect; Rect: TRect;
@ -67,18 +73,27 @@ type
property EventFont: TVpFont read FEventFont write SetEventFont; property EventFont: TVpFont read FEventFont write SetEventFont;
end; end;
TVpGanttColHeaderKind = (gchMonth, gchWeek, gchDay);
TVpGanttColHeaderKinds = set of TVpGanttColHeaderKind;
TVpGanttColHeaderAttributes = class(TVpGanttHeaderAttributes) TVpGanttColHeaderAttributes = class(TVpGanttHeaderAttributes)
private private
FDayFont: TVpFont; FDayFont: TVpFont;
FMonthFont: TVpFont; FMonthFont: TVpFont;
FWeekFont: TVpFont;
FVisible: TVpGanttColHeaderKinds;
procedure SetDayFont(AValue: TVpFont); procedure SetDayFont(AValue: TVpFont);
procedure SetMonthFont(AValue: TVpFont); procedure SetMonthFont(AValue: TVpFont);
procedure SetVisible(AValue: TVpGanttColHeaderKinds);
procedure SetWeekFont(AValue: TVpFont);
public public
constructor Create(AOwner: TVpGanttView); override; constructor Create(AOwner: TVpGanttView); override;
destructor Destroy; override; destructor Destroy; override;
published published
property DayFont: TVpFont read FDayFont write SetDayFont; property DayFont: TVpFont read FDayFont write SetDayFont;
property MonthFont: TVpFont read FMonthFont write SetMonthFont; property MonthFont: TVpFont read FMonthFont write SetMonthFont;
property Visible: TVpGanttColHeaderKinds read FVisible write SetVisible default [gchMonth, gchDay];
property WeekFont: TVpFont read FWeekFont write SetWeekFont;
end; end;
TVpGanttView = class(TVpLinkableControl) TVpGanttView = class(TVpLinkableControl)
@ -112,6 +127,7 @@ type
FFixedColWidth: Integer; FFixedColWidth: Integer;
FRowHeight: Integer; FRowHeight: Integer;
FMonthColHeaderHeight: Integer; FMonthColHeaderHeight: Integer;
FWeekColHeaderHeight: Integer;
FDayColHeaderHeight: Integer; FDayColHeaderHeight: Integer;
FTotalColHeaderHeight: Integer; FTotalColHeaderHeight: Integer;
FTextMargin: Integer; FTextMargin: Integer;
@ -149,6 +165,8 @@ type
function GetNumDays: Integer; function GetNumDays: Integer;
function GetNumEvents: Integer; function GetNumEvents: Integer;
function GetNumMonths: Integer; function GetNumMonths: Integer;
function GetNumWeeks: Integer;
function GetWeekRec(AIndex: Integer): TVpGanttWeekRec;
function IsStoredColWidth: Boolean; function IsStoredColWidth: Boolean;
function IsStoredDateFormat(AIndex: Integer): Boolean; function IsStoredDateFormat(AIndex: Integer): Boolean;
procedure SetActiveCol(AValue: Integer); procedure SetActiveCol(AValue: Integer);
@ -175,6 +193,7 @@ type
// Needed by the painter // Needed by the painter
FEventRecords: array of TVpGanttEventRec; FEventRecords: array of TVpGanttEventRec;
FDayRecords: array of TVpGanttDayRec; FDayRecords: array of TVpGanttDayRec;
FWeekRecords: array of TVpGanttWeekRec;
FMonthRecords: array of TVpGanttMonthRec; FMonthRecords: array of TVpGanttMonthRec;
{ internal methods } { internal methods }
@ -195,6 +214,7 @@ type
procedure PopulateDayRecords; procedure PopulateDayRecords;
procedure PopulateEventRecords; procedure PopulateEventRecords;
procedure PopulateMonthRecords; procedure PopulateMonthRecords;
procedure PopulateWeekRecords;
procedure ScrollDateIntoView(ADate: TDateTime); procedure ScrollDateIntoView(ADate: TDateTime);
procedure ScrollHorizontal(ANumCols: Integer); procedure ScrollHorizontal(ANumCols: Integer);
procedure ScrollRowIntoView(ARow: Integer); procedure ScrollRowIntoView(ARow: Integer);
@ -296,10 +316,12 @@ type
property DayRecords[AIndex: Integer]: TVpGanttDayRec read GetDayRec; property DayRecords[AIndex: Integer]: TVpGanttDayRec read GetDayRec;
property EventRecords[AIndex: Integer]: TVpGanttEventRec read GetEventRec; property EventRecords[AIndex: Integer]: TVpGanttEventRec read GetEventRec;
property MonthRecords[AIndex: Integer]: TVpGanttMonthRec read GetMonthRec; property MonthRecords[AIndex: Integer]: TVpGanttMonthRec read GetMonthRec;
property WeekRecords[AIndex: Integer]: TVpGanttWeekRec read GetWeekRec;
property NumDays: Integer read GetNumDays; property NumDays: Integer read GetNumDays;
property NumEvents: Integer read GetNumEvents; property NumEvents: Integer read GetNumEvents;
property NumMonths: Integer read GetNumMonths; property NumMonths: Integer read GetNumMonths;
property NumWeeks: Integer read GetNumWeeks;
published published
// inherited properties // inherited properties
@ -408,12 +430,15 @@ constructor TVpGanttColHeaderAttributes.Create(AOwner: TVpGanttView);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
FDayFont := TVpFont.Create(AOwner); FDayFont := TVpFont.Create(AOwner);
FWeekFont := TVpFont.Create(AOwner);
FMonthFont := TVpFont.Create(AOwner); FMonthFont := TVpFont.Create(AOwner);
FVisible := [gchMonth, gchDay];
end; end;
destructor TVpGanttColHeaderAttributes.Destroy; destructor TVpGanttColHeaderAttributes.Destroy;
begin begin
FDayFont.Free; FDayFont.Free;
FWeekFont.Free;
FMonthFont.Free; FMonthFont.Free;
inherited; inherited;
end; end;
@ -438,6 +463,25 @@ begin
end; end;
end; end;
procedure TVpGanttColHeaderAttributes.SetVisible(AValue: TVpGanttColHeaderKinds);
begin
if FVisible <> AValue then
begin
FVisible := AValue;
UpdateGanttView;
end;
end;
procedure TVpGanttColHeaderAttributes.SetWeekFont(AValue: TVpFont);
begin
if FWeekFont <> AValue then
begin
FWeekFont := AValue;
FWeekFont.Owner := FGanttView;
UpdateGanttView;
end;
end;
{******************************************************************************} {******************************************************************************}
{ TVpGanttView } { TVpGanttView }
@ -557,14 +601,25 @@ var
h: Integer; h: Integer;
begin begin
h := GetCanvasTextHeight(Canvas, FColHeaderAttributes.MonthFont); h := GetCanvasTextHeight(Canvas, FColHeaderAttributes.MonthFont);
FMonthColHeaderHeight := h + 2 * FTextMargin; FMonthColHeaderHeight := h; // + 2 * FTextMargin;
h := GetCanvasTextHeight(Canvas, FColHeaderAttributes.WeekFont);
FWeekColHeaderHeight := h; // + 2 * FTextMargin;
// A typical date string to measure the text height (line breaks in DayFormat allowed) // A typical date string to measure the text height (line breaks in DayFormat allowed)
s := FormatDateTime(DayFormat, EncodeDate(2000, 12, 28)); s := FormatDateTime(DayFormat, EncodeDate(2000, 12, 28));
h := GetCanvasTextHeight(Canvas, FColHeaderAttributes.DayFont, s); h := GetCanvasTextHeight(Canvas, FColHeaderAttributes.DayFont, s);
FDayColHeaderHeight := h + FTextMargin; FDayColHeaderHeight := h; // + FTextMargin;
FTotalColHeaderHeight := FMonthColHeaderHeight + FDayColHeaderHeight; FTotalColHeaderHeight := 0;
if (gchMonth in FColHeaderAttributes.Visible) then
inc(FTotalColHeaderHeight, FMonthColHeaderHeight + FTextMargin);
if (gchWeek in FColHeaderAttributes.Visible) then
inc(FTotalColHeaderHeight, FWeekColHeaderHeight + FTextMargin);
if (gchDay in FColHeaderAttributes.Visible) then
inc(FTotalColHeaderHeight, FDayColHeaderHeight + FTextMargin);
if FTotalColHeaderHeight > 0 then
inc(FTotalColHeaderHeight, FTextMargin);
end; end;
procedure TVpGanttView.CalcRowHeight; procedure TVpGanttView.CalcRowHeight;
@ -818,8 +873,8 @@ begin
end; end;
end; end;
{ Determines the date when the earliest event starts, and the date when the { Determines the dates when the earliest event in the entire Schedule starts,
latest event ends. } and when the latest event ends. }
procedure TVpGanttView.GetEventDateRange(out AFirstDate, ALastDate: TDate); procedure TVpGanttView.GetEventDateRange(out AFirstDate, ALastDate: TDate);
var var
i: Integer; i: Integer;
@ -894,6 +949,56 @@ begin
Result := 0; Result := 0;
end; end;
{ Determines the number of weeks (complete or partial) between the first and
last Gantt events.
NOTE: Week calculations are based on ISO week numbers only! }
function TVpGanttView.GetNumWeeks: Integer;
var
d1, d2: TVpDayType;
dt1, dt2: TDate;
wn1, wn2: Integer;
begin
if (FRealStartDate <> NO_DATE) then
begin
d1 := GetVpDayType(FRealStartDate);
d2 := GetVpDayType(FRealEndDate);
if (FRealEndDate - FRealStartDate < 7) then
begin
wn1 := WeekOfTheYear(FRealStartDate);
wn2 := WeekOfTheYear(FRealEndDate);
if wn1 = wn2 then
Result := 1
else
Result := 2;
exit;
end;
if d1 = dtMonday then
begin
// No partial week at start
Result := 0;
dt1 := FRealStartDate;
end else
begin
// Partial week at start
Result := 1;
dt1 := StartOfTheWeek(FRealStartDate) + 7; // Start of next week
end;
if d2 = dtSunday then
// No partial week at end
dt2 := FRealEndDate
else begin
// Partial week at the end
Inc(Result);
dt2 := StartOfTheWeek(FRealEndDate) - 1;
end;
Result := Result + (trunc(dt2) - trunc(dt1) + 1) div 7;
end else
Result := 0;
end;
{ Calculates the first and last date to be displayed in the GanttView. This { Calculates the first and last date to be displayed in the GanttView. This
is necessary because the properties StartDate and EndDate may be 0 which is necessary because the properties StartDate and EndDate may be 0 which
means the very first/last event. } means the very first/last event. }
@ -921,6 +1026,11 @@ begin
Result := -1; Result := -1;
end; end;
function TVpGanttView.GetWeekRec(AIndex: Integer): TVpGanttWeekRec;
begin
Result := FWeekRecords[AIndex];
end;
{ If the component is being dropped on a form at designtime, then { If the component is being dropped on a form at designtime, then
automatically hook up to the first datastore component found. } automatically hook up to the first datastore component found. }
procedure TVpGanttView.HookUp; procedure TVpGanttView.HookUp;
@ -947,6 +1057,7 @@ begin
FRowCount := GetNumEvents; FRowCount := GetNumEvents;
PopulateDayRecords; PopulateDayRecords;
PopulateWeekRecords;
PopulateMonthRecords; PopulateMonthRecords;
PopulateEventRecords; PopulateEventRecords;
end; end;
@ -1202,7 +1313,11 @@ var
begin begin
SetLength(FDayRecords, GetNumDays); SetLength(FDayRecords, GetNumDays);
x1 := FixedColWidth; x1 := FixedColWidth;
y1 := FMonthColHeaderHeight; y1 := 0;
if (gchMonth in FColHeaderAttributes.Visible) then
inc(y1, FMonthColHeaderHeight + FTextMargin);
if (gchWeek in FColHeaderAttributes.Visible) then
inc(y1, FWeekColHeaderHeight + FTextMargin);
y2 := FTotalColHeaderHeight; y2 := FTotalColHeaderHeight;
for i := 0 to High(FDayRecords) do for i := 0 to High(FDayRecords) do
begin begin
@ -1333,6 +1448,49 @@ begin
end; end;
end; end;
procedure TVpGanttView.PopulateWeekRecords;
var
i: Integer;
x1, y1, x2, y2: Integer;
d: TVpDayType;
dt1, dt2: TDateTime;
begin
SetLength(FWeekRecords, GetNumWeeks);
x1 := FixedColWidth;
y1 := 0;
if (gchMonth in FColHeaderAttributes.Visible) then
inc(y1, FMonthColHeaderHeight + FTextMargin);
if (gchDay in FColHeaderAttributes.Visible) then
y2 := y1 + FWeekColHeaderHeight + FTextMargin
else
y2 := FTotalColHeaderHeight;
d := GetVpDayType(FRealStartDate);
dt1 := FRealStartDate;
if d = dtMonday then
dt2 := dt1 + 6
else
dt2 := StartOfTheWeek(FRealStartDate + 7) - 1;
if dt2 > FRealEndDate then
dt2 := FRealEndDate;
x2 := x1 + (trunc(dt2) - trunc(dt1) + 1) * FColWidth;
FWeekRecords[0].Rect := Rect(x1, y1, x2, y2);
FWeekRecords[0].Date := dt1;
FWeekRecords[0].WeekNo := WeekOfTheYear(dt1);
for i := 1 to High(FWeekRecords) do
begin
dt1 := dt2 + 1;
dt2 := Min(dt1 + 6, FRealEndDate);
x1 := x2;
x2 := x1 + (trunc(dt2) - trunc(dt1) + 1) * FColWidth;
FWeekRecords[i].Rect := Rect(x1, y1, x2, y2);
FWeekRecords[i].Date := dt1;
FWeekRecords[i].WeekNo := WeekOfTheYear(dt1);
end;
end;
procedure TVpGanttView.RenderToCanvas(RenderCanvas: TCanvas; RenderIn: TRect; procedure TVpGanttView.RenderToCanvas(RenderCanvas: TCanvas; RenderIn: TRect;
Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime; Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime;
StartLine, StopLine: Integer; UseGran: TVpGranularity; DisplayOnly: Boolean); StartLine, StopLine: Integer; UseGran: TVpGranularity; DisplayOnly: Boolean);

View File

@ -15,6 +15,7 @@ type
FDayFont: TFont; FDayFont: TFont;
FMonthFont: TFont; FMonthFont: TFont;
FWeekFont: TFont;
FEventFont: TFont; FEventFont: TFont;
FScaledColWidth: Integer; FScaledColWidth: Integer;
@ -39,11 +40,14 @@ type
procedure DrawActiveDate; procedure DrawActiveDate;
procedure DrawBorders; procedure DrawBorders;
procedure DrawColHeader; procedure DrawColHeader;
procedure DrawDayColHeaders;
procedure DrawEvents; procedure DrawEvents;
procedure DrawGrid; procedure DrawGrid;
procedure DrawMonthColHeaders;
procedure DrawRowHeader; procedure DrawRowHeader;
procedure FixFontHeights;
procedure DrawSpecialDays; procedure DrawSpecialDays;
procedure DrawWeekColHeaders;
procedure FixFontHeights;
procedure InitColors; procedure InitColors;
procedure SetMeasurements; override; procedure SetMeasurements; override;
@ -60,7 +64,7 @@ implementation
uses uses
DateUtils, DateUtils,
VpConst, VpMisc, VpCanvasUtils, VpData; VpSR, VpConst, VpMisc, VpCanvasUtils, VpData;
constructor TVpGanttViewPainter.Create(AGanttView: TVpGanttView; constructor TVpGanttViewPainter.Create(AGanttView: TVpGanttView;
ARenderCanvas: TCanvas); ARenderCanvas: TCanvas);
@ -137,14 +141,7 @@ end;
procedure TVpGanttViewPainter.DrawColHeader; procedure TVpGanttViewPainter.DrawColHeader;
var var
i, n: Integer;
R, R1: TRect; R, R1: TRect;
P: TPoint;
monthRec: TVpGanttMonthRec;
dayRec: TVpGanttDayRec;
str: String;
strLen, strH: Integer;
dx: Integer;
begin begin
RenderCanvas.Brush.Color := RealColHeadAttrColor; RenderCanvas.Brush.Color := RealColHeadAttrColor;
RenderCanvas.Pen.Color := RealLineColor; RenderCanvas.Pen.Color := RealLineColor;
@ -179,59 +176,29 @@ begin
TPSLineTo(RenderCanvas, Angle, RenderIn, RealRight, R.Bottom); TPSLineTo(RenderCanvas, Angle, RenderIn, RealRight, R.Bottom);
end; end;
// Draw the month column headers
DrawMonthColHeaders;
// Draw the week column headers
DrawWeekColHeaders;
// Draw the day column headers
DrawDayColHeaders;
end;
procedure TVpGanttViewPainter.DrawDayColHeaders;
var
dayRec: TVpGanttDayRec;
dx: Integer;
strH, strLen: Integer;
str: String;
i, n: Integer;
R, R1: TRect;
P: TPoint;
begin
// Offset due to scrolling // Offset due to scrolling
dx := FGanttView.LeftCol * FScaledColWidth; 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);
// 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;
if i > 0 then
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;
// Draw day captions (always centered) and dividing lines (always at right side). // Draw day captions (always centered) and dividing lines (always at right side).
RenderCanvas.Font.Assign(FDayFont); RenderCanvas.Font.Assign(FDayFont);
strH := RenderCanvas.TextHeight('Tg'); strH := RenderCanvas.TextHeight('Tg');
@ -296,7 +263,6 @@ begin
// strLen := GetCanvasTextWidth(RenderCanvas, FDayFont, str); // strLen := GetCanvasTextWidth(RenderCanvas, FDayFont, str);
// TPSTextRect(RencerCanvas, Angle, RenderIn, R, P.X, P.Y, str); // TPSTextRect(RencerCanvas, Angle, RenderIn, R, P.X, P.Y, str);
// BUT: TPSTextRect does not yet exist... // BUT: TPSTextRect does not yet exist...
end; end;
end; end;
@ -429,6 +395,70 @@ begin
end; end;
end; end;
procedure TVpGanttViewPainter.DrawMonthColHeaders;
var
dx: Integer;
i, n: Integer;
monthRec: TVpGanttMonthRec;
R, R1: TRect;
P: TPoint;
str: String;
strLen: Integer;
begin
// 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);
// 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;
if i > 0 then
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;
procedure TVpGanttViewPainter.DrawRowHeader; procedure TVpGanttViewPainter.DrawRowHeader;
var var
R: TRect; R: TRect;
@ -552,10 +582,92 @@ begin
end; end;
end; end;
procedure TVpGanttViewPainter.DrawWeekColHeaders;
var
dx: Integer;
i, n: Integer;
weekRec: TVpGanttWeekRec;
weekNo, yearNo: Integer;
R, R1: TRect;
P: TPoint;
str: String;
strLen: Integer;
begin
// 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);
// 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;
if i > 0 then
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
)
(*
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 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;
procedure TVpGanttViewPainter.FixFontHeights; procedure TVpGanttViewPainter.FixFontHeights;
begin begin
with FGanttView do begin with FGanttView do begin
ColHeaderAttributes.DayFont.Height := GetRealFontHeight(ColHeaderAttributes.DayFont); ColHeaderAttributes.DayFont.Height := GetRealFontHeight(ColHeaderAttributes.DayFont);
ColHeaderAttributes.WeekFont.Height := GetRealFontHeight(ColHeaderAttributes.WeekFont);
ColHeaderAttributes.MonthFont.Height := GetRealFontHeight(ColHeaderAttributes.MonthFont); ColHeaderAttributes.MonthFont.Height := GetRealFontHeight(ColHeaderAttributes.MonthFont);
RowHeaderAttributes.EventFont.Height := GetRealFontHeight(RowHeaderAttributes.EventFont); RowHeaderAttributes.EventFont.Height := GetRealFontHeight(RowHeaderAttributes.EventFont);
end; end;
@ -585,6 +697,7 @@ begin
FDayFont := FGanttView.ColHeaderAttributes.DayFont; FDayFont := FGanttView.ColHeaderAttributes.DayFont;
FMonthFont := FGanttView.ColHeaderAttributes.MonthFont; FMonthFont := FGanttView.ColHeaderAttributes.MonthFont;
FWeekFont := FGanttView.ColHeaderAttributes.WeekFont;
FEventFont := FGanttView.RowHeaderAttributes.EventFont; FEventFont := FGanttView.RowHeaderAttributes.EventFont;
end; end;

View File

@ -150,6 +150,7 @@ function DatePart(ADateTime: TDateTime): TDateTime; inline;
function TimePart(ADateTime: TDateTime): TDateTime; inline; function TimePart(ADateTime: TDateTime): TDateTime; inline;
function GetJulianDate(Date: TDateTime): Word; function GetJulianDate(Date: TDateTime): Word;
function GetVpDayType(ADate: TDateTime): TVpDayType;
function GetWeekOfYear(ADate: TDateTime): byte; function GetWeekOfYear(ADate: TDateTime): byte;
function IsWeekend(ADate: TDateTime): Boolean; function IsWeekend(ADate: TDateTime): Boolean;
function SameDate(dt1, dt2: TDateTime): Boolean; function SameDate(dt1, dt2: TDateTime): Boolean;
@ -893,6 +894,12 @@ begin
Result := SameTime(t1, t2) or (t1 > t2); Result := SameTime(t1, t2) or (t1 > t2);
end; end;
// Determines the TVpDayType for the given date, i.e. dtSunday, dtMonday, etc.
function GetVpDayType(ADate: TDateTime): TVpDayType;
begin
Result := TVpDayType(DayOfWeek(ADate) - 1);
end;
// Calculates ISO week number (checked with Jan 1, 2016, which is in week 53). // Calculates ISO week number (checked with Jan 1, 2016, which is in week 53).
function GetWeekOfYear(ADate: TDateTime): byte; function GetWeekOfYear(ADate: TDateTime): byte;
// wp: was in TvWeekView. // wp: was in TvWeekView.