YOUSEFUL / DELPHI / COMPONENTS

TAtlasScheduler

Day or week view over a TAtlasSchedule with hour rows, side-by-side lanes for overlapping appointments, selection, keyboard movement and host edit events.

Visual control Palette: Atlas Unit Atlas.Scheduler · Inherits TCustomControl · Product Atlas VCL

Description

TAtlasScheduler paints the appointments of its Schedule for DaysShown consecutive days starting at Date: a time axis from 00:00 to 23:00 on the left, one column per day with the day header (ddd dd), and one block per appointment placed by its start and end time. Appointments that overlap within a day are laid out in lanes side by side; an appointment spanning midnight is drawn in every day it touches, clipped to that day. When Resource is not empty only that resource is shown.

The control listens to the schedule and repaints after every change; assigning a new Schedule or losing the selected appointment resets SelectedID to 0. A left click selects the appointment under the mouse (or nothing) and fires OnSelect; a double-click on a selected appointment fires OnEdit, where the application opens its own dialog and calls TAtlasSchedule.Update. With the keyboard focus, Up and Down move the selected appointment by 15 minutes and Left and Right by one day, through MoveSelected; a move that would conflict raises EAtlasScheduleError from the model and the appointment stays where it was. Limitation: the control does not answer WM_GETDLGCODE with DLGC_WANTARROWS, so inside a form the VCL takes the arrow keys as dialog keys and moves the focus instead (verified on Windows 11; the product's tests call MoveSelected directly). A descendant that adds DLGC_WANTARROWS in a WM_GETDLGCODE handler fixes this; the SchedulerAndGantt sample shows one, or call MoveSelected from your own commands.

Render draws the same view onto any canvas and records the hit rectangles, so HitTest works after a Render or a normal paint. Only day (1) and week (7) views exist; there is no month view, drag and drop, resizing by mouse, in-place editing or printing of the view. The published VCL properties Align, Anchors, Color, Font, ParentFont and TabStop are available; Color is the background and Font the axis and caption font.

Members

MemberKindWhat it does
CreateconstructorCreates the control 980 × 660 pixels, white, double-buffered, with TabStop on, Date set to today and DaysShown 7.
DestroydestructorDetaches from the schedule (listener and free notification) and frees the hit rectangles.
RendermethodDraws the view into Bounds on Target and rebuilds the hit rectangles used by HitTest.
HitTestmethodID of the appointment whose block contains the point (X, Y) in the coordinates of the last Render or paint, or 0 when there is none.
MoveSelectedmethodShifts the selected appointment by Minutes (negative moves it earlier) by calling TAtlasSchedule.Update with the same caption, resource and colour.
SelectedIDpropertyID of the selected appointment or 0.
SchedulepropertyThe model to display.
DatepropertyFirst day shown; the time part is discarded.
DaysShownproperty1 for a day view or 7 for a week view; any other value raises EAtlasScheduleError (Choose day (1) or week (7) view).
ResourcepropertyWhen not empty, only appointments of this resource are shown (exact, case-sensitive match).
OnSelecteventFires after every left mouse click with the ID of the appointment now selected, or 0 when the click hit empty space.
OnEditeventFires on a double-click while an appointment is selected, with its ID.

Constructors

Create constructor

constructor Create(AOwner: TComponent); override;

Creates the control 980 × 660 pixels, white, double-buffered, with TabStop on, Date set to today and DaysShown 7. Set Parent before it is shown.

Destructors

Destroy destructor

destructor Destroy; override;

Detaches from the schedule (listener and free notification) and frees the hit rectangles.

Properties

SelectedID property

property SelectedID: Integer read FSelected;

ID of the selected appointment or 0. Set by a left click; cleared when the schedule changes and the appointment no longer exists, or when Schedule is assigned. There is no setter: selection is a user gesture.

Schedule property

property Schedule: TAtlasSchedule read FSchedule write SetSchedule;

The model to display. The control registers a listener and a free notification, so freeing the schedule detaches the view. Assigning clears the selection and repaints. Several schedulers can share one schedule.

pascal
Scheduler.Schedule := Schedule;
Scheduler.Date := StartOfTheWeek(Date);
Scheduler.DaysShown := 7;

Date property

property Date: TDateTime read FDate write SetDate;

First day shown; the time part is discarded. Defaults to today. Raises EAtlasScheduleError (View date out of range) outside the TDateTime values 1 .. 2958457 (31 December 1899 to 23 December 9999), so that a full week still fits.

DaysShown property

property DaysShown: Integer read FDays write SetDays default 7;

1 for a day view or 7 for a week view; any other value raises EAtlasScheduleError (Choose day (1) or week (7) view). The week always starts at Date, whatever weekday that is.

Resource property

property Resource: string read FResource write SetResource;

When not empty, only appointments of this resource are shown (exact, case-sensitive match). Empty shows every resource, with overlapping appointments of different resources side by side.

Events

OnSelect event

property OnSelect: TAtlasAppointmentEvent read FOnSelect write FOnSelect;

Fires after every left mouse click with the ID of the appointment now selected, or 0 when the click hit empty space. It does not fire when the selection is cleared by a model change.

pascal
procedure TMainForm.Selected(Sender: TObject; ID: Integer);
begin
  if ID = 0 then StatusBar.SimpleText := ''
  else StatusBar.SimpleText := Schedule.Appointment(ID).Caption;
end;

OnEdit event

property OnEdit: TAtlasAppointmentEvent read FOnEdit write FOnEdit;

Fires on a double-click while an appointment is selected, with its ID. The control has no editor of its own: show your dialog here and apply the result with TAtlasSchedule.Update or Delete.

pascal
procedure TMainForm.Edit(Sender: TObject; ID: Integer);
var
  Item: TAtlasAppointment;
  Text: string;
begin
  Item := Schedule.Appointment(ID);
  Text := Item.Caption;
  if InputQuery('Appointment', 'Caption', Text) then
    Schedule.Update(ID, Text, Item.Resource, Item.StartsAt, Item.EndsAt, Item.Color);
end;

Methods

Render method

procedure Render(Target: TCanvas; const Bounds: TRect);

Draws the view into Bounds on Target and rebuilds the hit rectangles used by HitTest. Fills the background with Color and uses Font. When Bounds is smaller than 150 × 100 only the background is drawn. Paint calls this with the control's canvas and client rectangle; call it yourself to draw the week into a bitmap or onto a printer canvas.

pascal
Bitmap.SetSize(980, 660);
Scheduler.Render(Bitmap.Canvas, Rect(0, 0, 980, 660));
Bitmap.SaveToFile('week.bmp');

HitTest method

function HitTest(X, Y: Integer): Integer;

ID of the appointment whose block contains the point (X, Y) in the coordinates of the last Render or paint, or 0 when there is none. Appointments in a lane are tested in drawing order.

MoveSelected method

procedure MoveSelected(Minutes: Integer);

Shifts the selected appointment by Minutes (negative moves it earlier) by calling TAtlasSchedule.Update with the same caption, resource and colour. Does nothing when no schedule is attached or nothing is selected. Raises EAtlasScheduleError when the new slot conflicts with another appointment of the same resource or leaves the valid date range; the appointment is then unchanged. The arrow keys call this with ±15 and ±1440, provided the control receives them (see the class description).

pascal
Scheduler.MoveSelected(30);     // half an hour later
Scheduler.MoveSelected(-1440);  // one day earlier

Examples

Render a week off screen and hit-test it

The control does not need a parent window to draw into a bitmap; Render also records the hit rectangles that HitTest reads.

pascal
uses System.Types, Vcl.Graphics, Atlas.Schedule, Atlas.Scheduler;

procedure RenderWeek(Schedule: TAtlasSchedule; WeekStart: TDateTime; const FileName: string);
var
  View: TAtlasScheduler;
  Bitmap: TBitmap;
begin
  View := TAtlasScheduler.Create(nil);
  Bitmap := TBitmap.Create;
  try
    View.Schedule := Schedule;
    View.Date := WeekStart;
    View.DaysShown := 7;
    Bitmap.SetSize(980, 660);
    View.Render(Bitmap.Canvas, Rect(0, 0, 980, 660));   // also records the hit rectangles
    Writeln('Appointment at (100, 272): ', View.HitTest(100, 272));
    Bitmap.SaveToFile(FileName);
  finally
    Bitmap.Free;
    View.Free;
  end;
end;

Week view in a form

Attach the model, choose the week and handle selection.

pascal
uses System.SysUtils, System.DateUtils, Vcl.Controls, Vcl.Forms, Atlas.Schedule, Atlas.Scheduler;

procedure AddWeekView(Form: TForm; Schedule: TAtlasSchedule; OnSelect: TAtlasAppointmentEvent);
var
  Scheduler: TAtlasScheduler;
begin
  Scheduler := TAtlasScheduler.Create(Form);
  Scheduler.Parent := Form;
  Scheduler.Align := alClient;
  Scheduler.Date := StartOfTheWeek(Date);   // Monday of this week
  Scheduler.DaysShown := 7;
  Scheduler.Schedule := Schedule;
  Scheduler.OnSelect := OnSelect;
end;

TAtlasSchedule · TAtlasAppointment · TAtlasAppointmentEvent · TAtlasAppointmentRect · EAtlasScheduleError · TAtlasThemer

Also in Atlas VCL

TAtlasTable · TAtlasGrid · TAtlasValueEdit · TAtlasTree · TAtlasWorkbook · TAtlasSheetGrid · TAtlasPivot · TAtlasInspector · TAtlasRichEdit · TAtlasSpellChecker · TAtlasChart · TAtlasGauge · TAtlasThemer · TAtlasWizard · TAtlasWorkspace · TAtlasCommandBar · TAtlasActionTile · TAtlasTileBoard · TAtlasNavigation · TAtlasMap · TAtlasGraph · TAtlasDiagram · TAtlasPrintDocument · TAtlasSchedule · TAtlasTaskPlan · TAtlasGantt · TAtlasPdfDocument · TAtlasPdfViewer