planner calendar cells with custom colors

Hello! It seems not to be any calendar sub-forum and we are using a TPlannerCalendar, so...

We have to arrange an schedule where each day has many superposing atributes. For example: we have a recommended day range, different types of events each day, ad-hoc day exclusions inside the recommended range, etc, etc, etc.

We are doing that with a TDBPlanner and a TPlannerCalendar.

We want to be able to paint the calendar cells with different font and bakground colors, or mark them with different shapes, give them hint windows, etc depending on different combinations of attributes.

At first we thought that the OnGetDateHint and OnGetEventProp events of the TPlannerCalendar would allow us to do that: In the GetDateHint handler we marked the day as an "event" following a certain logic, and in the OnGetEventProp handler we gave it the appropiate appearance.

But:
1- The Event parameter in OnGetEventProp is always nil. We solved this calling:
    FCalendar.Event.Add;
once when creating the form, and always initialize the Event parameter in the OnGetEventProp handler to it:
    Event := FCalendar.Events[0];
But this seems weird. Is this the right way to do it?

2- No matter what we set in the Event parameter (colors, etc) they were never used to paint the calendar. The global EventMarkerColor, etc were used, but that is not what we need (see above). After much debugging we found that the Event parameter of that event is ignored: it seems to be assigned to a local variable and discarded by the calling code (in TPlannerCalendar).

Sooo, how do we do this? (give the each calendar cell diferent appearance, depending on certain conditions)? We have an unbound number of days with special attributes (for example: all the days outside the recommended range). We could add handler for OnCellDraw, but that means almost redoing the calendar again, isn't it?

Any hints will be appreciated!

Thanks in advance,
Mario

The design is that for seeing events on a specific day, the event is created (added) for the day where this event occurs. So, it is not really designed to dynamically insert events from an event handler but add the events to the PlannerCalendar once (with PlannerCalendar.Event.Add and set the date)


With OnGetEventProp, you can on the fly modify properties for an event on a specific day (not change the day though)

Example code:

procedure TForm4.FormCreate(Sender: TObject);
begin
  with PlannerCalendar1.Events.Add do
  begin
    Date := encodedate(2013,1,13);
    Shape := evsTriangle;
    Color := clRed;
  end;
  with PlannerCalendar1.Events.Add do
  begin
    Date := encodedate(2013,1,15);
    Shape := evsCircle;
    Color := clYellow;
  end;
end;

procedure TForm4.PlannerCalendar1GetEventProp(Sender: TObject; dt: TDateTime;
  var Event: TEventProp);
begin
  if dt = encodedate(2013,1,15) then
  begin
    Event.Color:= clWhite;
  end;
end;

This creates 2 events and for the 2nd event, changes the color on the fly from yellow to white.

Wow! That was fast.

You are right of course: I must setup the "event" days in the form creation and the let the calendar do the drawing all by itself as needed...

I also solved the "unbounded number of events" problem by only filling the current month events,  and then adding new events "on demand' only when user changes the month or year. To the user it is as if every all the events were already in place, but internally I only add the events of the months that the user wants to see.

Thanks!