Difference between revisions of "CalLite"

From Lazarus wiki
m (minor tweaks)
(Multi-selection)
 
(22 intermediate revisions by 4 users not shown)
Line 3: Line 3:
 
==About==
 
==About==
 
[[Image:callite.png|right|CalLite]]
 
[[Image:callite.png|right|CalLite]]
TCalendarLite is a light-weight calendar component, a TCustomControl descendant which consequently is not dependent on any widgetset.
+
TCalendarLite is a lightweight calendar component, a TCustomControl descendant which consequently is not dependent on any widgetset.
 
It is not a fixed-size component, as are most calendars, but will align and resize as needed. Various properties give access to almost every aspect of its appearance.
 
It is not a fixed-size component, as are most calendars, but will align and resize as needed. Various properties give access to almost every aspect of its appearance.
  
===Authors===
+
==Authors==
 
Howard Page-Clark, Ariel Rodriguez and Werner Pamler
 
Howard Page-Clark, Ariel Rodriguez and Werner Pamler
  
===License===
+
==License==
 
Modified LGPL (with linking exception, like Lazarus LCL)
 
Modified LGPL (with linking exception, like Lazarus LCL)
  
===Download and Installation===
+
==Download and Installation==
 
====Release version====
 
====Release version====
 
A zip file with the most recent release version can be found at [https://sourceforge.net/projects/lazarus-ccr/files/CalLite/ Lazarus CCR at SourceForge]. Unzip the file into any folder.
 
A zip file with the most recent release version can be found at [https://sourceforge.net/projects/lazarus-ccr/files/CalLite/ Lazarus CCR at SourceForge]. Unzip the file into any folder.
  
The current release version is 0.2
+
The current release version is 0.3.1
  
 
====Development version====
 
====Development version====
Line 22: Line 22:
  
 
====Installation====
 
====Installation====
In Lazarus, go to ''"Package"'' > ''"Open Package File .lpk"''. Navigate to the folder with the callite sources, and select '''callight_pkg.lkp'''. Click ''"Compile"'', then ''"Use"'' > ''"Install"''. This will rebuild the IDE (it may take some time). When the process is finished the IDE will restart, and you'll find TCalendarLite in the component palette '''Misc'''.
+
[[Image:tcalendarlite_150.png|left]]
 +
In Lazarus, go to ''"Package"'' > ''"Open Package File .lpk"''. Navigate to the folder with the callite sources, and select '''callight_pkg.lkp'''. Click ''"Compile"'', then ''"Use"'' > ''"Install"''. This will rebuild the IDE (it may take some time). When the process is finished the IDE will restart, and you'll find TCalendarLite in the component palette '''[[Misc_tab|Misc]]'''.
  
==Usage==
+
== Navigation ==
Simply drop a TCalendarLite component on the form and get a functional month-calendar.
 
 
 
=== Navigation ===
 
 
* Click on any date
 
* Click on any date
 
* Use the arrow keys on the keyboard
 
* Use the arrow keys on the keyboard
Line 33: Line 31:
 
* Click on the month name to open a popdown menu with month names, or click on the year number to open a popdown menu with the last and next ten years.
 
* Click on the month name to open a popdown menu with month names, or click on the year number to open a popdown menu with the last and next ten years.
  
===Changing colors===
+
== Multi-selection ==
The property <code>Colors</code> of the calendar collects all settings affecting the colors used for the various items:
+
If the property <code>MultiSelect</code> is set to <code>true</code> then several days can be selected in the calendar. All selected days are drawn with a highlighted background. Multi-selection is controlled by holding special keys down while selecting a day either by a mouse click or a key press:
* '''ArrowBorderColor''': the color of the border of the arrows above the calendar (default: clSilver)
 
* '''ArrowColor''': the fill color of the arrows above the calendar (default: clSilver)
 
* '''BackgroundColor''': the background color of the entire calendar (default: clWhite)
 
* '''BorderColor''': the color of an optional border around the calenard (default: clSilver). Add <code>coShowBorder</code> to the calendar's <code>Options</code> to display the border.
 
* '''DayLineColor''': the color of an optional separating line between the top navigation pane and the calendar's day area (default: clSilver). Add <code>coDayLine</code> to the calendar's <code>Options</code> to display the line.
 
* '''HolidayColor''': the text color used to display holidays (default: clRed). Add an event handler to <code>OnGetHolidays</code> to define which days are holidays.
 
* '''PastMonthColor''': the text color used to display the days of the previous or next month (default: clSilver).
 
* '''SelectedDateColor''': fill color of the currently selected day (default: clMoneyGreen)
 
* '''TextColor''': text color used for paint the regular calendar days (default: clBlack)
 
* '''TodayFrameColor''': color used to draw a rectangular line around the "today" cell (default: clLime)
 
* '''TopRowColor''': background color used for the top navigation line (default: clHighlight)
 
* '''TopRowTextColor''': text color used in the top navigation line (default: clHighlightText)
 
* '''WeekendColor''': text color used for painting weekend days (default: clRed)
 
 
 
===Using the calendar's Options===
 
The display of the calendar can be modified by changing the calendar's Options, an enumeration of flags:
 
<syntaxhighlight>
 
type
 
  TCalOption = (coBoldDayNames, coBoldHolidays, coBoldToday, coBoldTopRow,
 
                coBoldWeekend, coDayLine, coShowBorder, coShowHolidays,
 
                coShowTodayFrame, coShowTodayName, coShowTodayRow,
 
                coShowWeekend, coUseTopRowColors);
 
</syntaxhighlight>
 
* '''coBoldDayNames''': Draws the line with the day names using bold characters
 
* '''coBoldHolidays''': Draws the day number of holidays using bold characters. Holidays are normally off, but you an add an event handler to <code>OnGetHolidays</code> in order to define holidays.
 
* '''coBoldToday''': Draws today's cell using bold characters
 
* '''coBoldTopRow''': Draws the month name and year number in the top row using bold characters
 
* '''coBoldWeekend''': Draws the cells of weekend days using bold characters
 
* '''coDayLine''': Adds a separating line between the top navigation line and the calendar's day area.
 
* '''coShowBorder''': Paints a thin border rectangle around the calendar
 
* '''coShowHolidays''': Activate highlighting holidays. Note that there must be also an event handler for <code>OnGetHolidays</code> which defines the holidays.
 
* '''coShowTodayFrame''': Draws a rectangle around the "today" cell.
 
* '''coShowTodayName''': Adds the day name to the line displaying today's date (see also: <code>coShowTodayRow</code>)
 
* '''coShowTodayRow''': Shows a line at the bottom of the calendar to display today's date (see also: <code>coShowTodayName</code>).
 
* '''coShowWeekend''': Highlights weekend days (see also: <code>Colors.WeekendColor</code>).
 
* '''coUseTopRowColors''': Paints background and text of the top navigation row using the colors defined by <code>Colors.TopRowColor</code> and <code>Colors.TopRowTextColor</code>
 
 
 
===Events===
 
In addition to the standard events TCalendarLite fires the following events. Some events get year, month and day numbers of the currently painted cell as a parameter. A set of state flags indicates whether this day is selected, today or belongs to the previous or next month:
 
<syntaxhighlight>
 
type
 
  TCalCellState = (csSelectedDay, csToday, csOtherMonth);
 
  TCalCellStates = set of TCalCellState;
 
</syntaxhighlight>
 
 
 
*'''OnDateChange''': Fires whenever another date is selected in the calendar.
 
*'''OnDrawCell''': Can be used to override the painting process of a day cell completely or partially. If the boolean parameter <code>AContinueDrawing</code> is set to true the normal painting process continues after leaving the event handler; if it is false then no default painting occurs for this day. The event can be used, for example, to add birthday or holiday icons to the day cells.
 
*'''OnGetDayText''': Can be used to modify the text display for the specified day. The default is a string showing the day value. Using this event, the names of holidays can be added to calendar, for example.
 
*'''OnGetHolidays''': Defines which days of current month are holidays. The day number of the holidays are encoded as set bits in a 32-bit integer.
 
*'''OnHint''': Defines a hint which can be displayed in a popup hint window for each day. Useful, for example, to show the name of holidays if the mouse hovers over a holiday.
 
*'''OnPrepareCanvas''': Is called immediately before a cell is painted. Can be used to override Brush and Pen properties, for example, in order to draw different backgrounds for appointments and important events.
 
 
 
===Holidays===
 
The calendar does not "know" any holidays. You must write an event handler to define which days in the current month are holidays. Month and year values of the respective month are passed as parameters. The information that a day is a holiday or not is encoded as set bits in a 32-bit integer. The unit ''callite'' simplifies this by providing these general-purpose procedures:
 
 
 
*procedure '''AddHoliday'''(ADay: Integer; var AHolidays: THolidays): Adds the specified day to the holiday bit list in parameter <code>AHolidays</code>.
 
*function  '''IsHoliday'''(ADay: Integer; AHolidays: THolidays): Boolean: Checks whether the specified day is listed in <code>AHolidays</code>
 
*'''ClearHolidays'''(var AHolidays: THolidays): Clears the holiday list
 
 
 
Here is a simple example defining the holidays New Year, Christman, Easter and Whit Sunday:
 
<syntaxhighlight>
 
function Easter(year:integer): TDateTime;
 
var
 
  Day, Month    : integer;
 
  a,b,c,d,e,m,n : integer;
 
begin
 
  case Year div 100 of
 
    17    : begin m := 23; n := 3; end;
 
    18    : begin m := 23; n := 4; end;
 
    19,20 : begin m := 24; n := 5; end;
 
    21    : begin m := 24; n := 6; end;
 
    else    raise Exception.Create('Only years after 1700 supported.');
 
  end;
 
  a := Year mod 19;
 
  b := Year mod 4;
 
  c := Year mod 7;
 
  d := (19*a + m) mod 30;
 
  e := (2*b + 4*c + 6*d + n) mod 7;
 
  day := 22 + d + e;
 
  Month := 3;
 
  if Day>31 then begin
 
    Day := d + e - 9;
 
    Month := 4;
 
    if (d=28) and (e=6) and (a>10) then begin
 
      if day=26 then day := 19;
 
      if day=25 then day := 18;
 
    end;
 
  end;
 
  result := EncodeDate(year, month, day);
 
end;
 
 
 
procedure TForm1.CalendarLite1GetHolidays(Sender: TObject; AMonth, AYear: Integer;
 
  var Holidays: THolidays);
 
var
 
  d, m, y: Word;
 
  e: TDate;
 
begin
 
  ClearHolidays(Holidays);
 
  if not FNoHolidays then
 
  begin
 
    // Fixed holidays
 
    case AMonth of
 
      1: AddHoliday(1, Holidays);          // New Year
 
    12: AddHoliday(25, Holidays);        // Christmas
 
    end;
 
    // Easter
 
    e := Easter(AYear);
 
    DecodeDate(e, y,m,d);
 
    if m = AMonth then
 
      AddHoliday(d, Holidays);
 
    // Whit Sunday --> 49 days after easter
 
    DecodeDate(e+49, y,m,d);
 
    if m = AMonth then
 
      AddHoliday(d, Holidays);
 
  end;
 
end;
 
</syntaxhighlight>
 
 
 
Make sure to have the calendar Option <code>coShowHolidays</code> set in order to highlight the holidays in the calendar.
 
 
 
==== Hints for holidays ====
 
If you want to display the holiday name as a mouse popup hint window then you should set the calendar's <code>ShowHint</code> to <code>true</code> and add this event handler for <code>OnHint</code>:
 
  
<syntaxhighlight>
+
*'''CTRL''': If the {{keypress|CTRL}} key is pressed while selecting another day then this day is added to the selection. This way a non-contiguous array of dates can be selected.
procedure TForm1.CalendarLite1Hint(Sender: TObject; AYear, AMonth, ADay: Word;
+
*'''SHIFT''': If the {{keypress|SHIFT}} key is held down during day selection then all day between the prevsiously and the currently selected day are added to the selection.
  var AText: String);
+
*'''Double-click''': A double click on a workday selects all workdays of the same week. Holding the {{keypress|CTRL}} or {{keypress|SHIFT}} key down extends the selection by the workdays of one or more weeks.
var
+
*The selection can be extended into neighboring months if the arrow keys of the keyboard are pressed with the {{keypress|CTRL}} key held down.
  dt, e: TDate;
+
*Selection is cleared if any date is selected without pressed any of these keys, or if the arrows or dropdown menus in the top bar are used.
begin
+
*If previously selected days are added for a second time then they are unselected.
  AText := '';
 
  case AMonth of
 
    1: if ADay = 1 then AText := 'New Year';
 
  12: if ADay = 25 then AText := 'Christmas';
 
  else
 
      e := Easter(AYear);
 
      dt := EncodeDate(AYear, AMonth, ADay);
 
      if (dt = e) then
 
        AText := 'Easter'
 
      else if (dt = e + 49) then
 
        AText := 'Whit Sunday';
 
  end;
 
end; </syntaxhighlight>
 
  
==== Embedded holiday names ====
+
At '''run-time''', the selected data can be controlled or queried by these methods of the calendar:
In addition, you can also add the holiday name to the calendar grid directly. Add the next event handler for <code>OnGetDayText</code>. Note that the size of the calendar must be large enough to provide space for the additional text:
+
* <tt>procedure AddSelectedDate(ADate: TDate)</tt> - adds the specified date to the list of selected dates
 +
* <tt>procedure ClearSelectedDates</tt> - clears all selected dates
 +
* <tt>function IsSelected(ADate: TDate): Boolean</tt> - returns <tt>true</tt> when the given date is selected, <tt>false</tt> otherwise.
 +
* <tt>function SelectedDates: TCalDateArray</tt> - returns an array of TDate elements which contains the selected dates.
  
<syntaxhighlight>
+
==Documentation==
procedure TForm1.CalendarLite1GetDayText(Sender: TObject; AYear, AMonth, ADay: Word;
 
  var AText: String);
 
var
 
  s: String;
 
begin
 
  GetHintText(Sender, AYear, AMonth, ADay, s);
 
  if s <> '' then
 
    AText := IntToStr(ADay) + LineEnding + s;
 
end;
 
</syntaxhighlight>
 
  
=== Drawing icons for specific days ===
+
* [[CalLite: Usage]]
The next example paint a birthday icon into the Nov 11 cell of each year. The icon is stored in an image list at index 0:
+
* [[CalLite: Flag days in Finland]]
  
<syntaxhighlight>
+
== See also ==
procedure TForm1.CalendarLite1DrawCell(Sender: TObject; ACanvas: TCanvas;
+
*[[Turbopower_Visual_PlanIt|TurboPower Visual PlanIt]]
  AYear,AMonth,ADay: Word; AState: TCalCellStates; var ARect: TRect;
+
*[[DateTimeCtrls_Package|DateTimeCtrls Package]]
  var AContinueDrawing: Boolean);
 
var
 
  bmp: TBitmap;
 
begin
 
  if (AMonth = 11) and (ADay = 11) and not (csOtherMonth in AState) then begin
 
    bmp := TBitmap.Create;
 
    try
 
      ImageList1.GetBitmap(0, bmp);
 
      ACanvas.Draw(ARect.Left, (ARect.Top + ARect.Bottom - bmp.Height) div 2, bmp);
 
      inc(ARect.Left, bmp.Width + 2);
 
      // Not changing AContinueDrawing from its default value (true) means
 
      // that the day text is drawn by the built-in procedure into the reduced rectangle
 
    finally
 
      bmp.Free;
 
    end;
 
  end;
 
end;
 
</syntaxhighlight>
 

Latest revision as of 17:03, 29 December 2018

English (en) suomi (fi) русский (ru)

About

CalLite

TCalendarLite is a lightweight calendar component, a TCustomControl descendant which consequently is not dependent on any widgetset. It is not a fixed-size component, as are most calendars, but will align and resize as needed. Various properties give access to almost every aspect of its appearance.

Authors

Howard Page-Clark, Ariel Rodriguez and Werner Pamler

License

Modified LGPL (with linking exception, like Lazarus LCL)

Download and Installation

Release version

A zip file with the most recent release version can be found at Lazarus CCR at SourceForge. Unzip the file into any folder.

The current release version is 0.3.1

Development version

Use an svn client to download the current trunk version from svn://svn.code.sf.net/p/lazarus-ccr/svn/components/callite/

Installation

tcalendarlite 150.png

In Lazarus, go to "Package" > "Open Package File .lpk". Navigate to the folder with the callite sources, and select callight_pkg.lkp. Click "Compile", then "Use" > "Install". This will rebuild the IDE (it may take some time). When the process is finished the IDE will restart, and you'll find TCalendarLite in the component palette Misc.

Navigation

  • Click on any date
  • Use the arrow keys on the keyboard
  • Click on the arrow keys above the calendar; the single arrow advances by one month, the double arrow advances by one year
  • Click on the month name to open a popdown menu with month names, or click on the year number to open a popdown menu with the last and next ten years.

Multi-selection

If the property MultiSelect is set to true then several days can be selected in the calendar. All selected days are drawn with a highlighted background. Multi-selection is controlled by holding special keys down while selecting a day either by a mouse click or a key press:

  • CTRL: If the CTRL key is pressed while selecting another day then this day is added to the selection. This way a non-contiguous array of dates can be selected.
  • SHIFT: If the Shift key is held down during day selection then all day between the prevsiously and the currently selected day are added to the selection.
  • Double-click: A double click on a workday selects all workdays of the same week. Holding the CTRL or Shift key down extends the selection by the workdays of one or more weeks.
  • The selection can be extended into neighboring months if the arrow keys of the keyboard are pressed with the CTRL key held down.
  • Selection is cleared if any date is selected without pressed any of these keys, or if the arrows or dropdown menus in the top bar are used.
  • If previously selected days are added for a second time then they are unselected.

At run-time, the selected data can be controlled or queried by these methods of the calendar:

  • procedure AddSelectedDate(ADate: TDate) - adds the specified date to the list of selected dates
  • procedure ClearSelectedDates - clears all selected dates
  • function IsSelected(ADate: TDate): Boolean - returns true when the given date is selected, false otherwise.
  • function SelectedDates: TCalDateArray - returns an array of TDate elements which contains the selected dates.

Documentation

See also