TTimePanel - A freeware Delphi component for selecting a range in time

(c) Copyright 1999 Dave Hughes

Contents
===============================================================================

  * Introduction
  * Compatibility
  * Installation
  * Properties
  * Methods
  * Events
  * Known Bugs
  * Legal stuff
  * Author Details

Introduction
===============================================================================

  TTimePanel is, among other things, the first Delphi component I've ever
  written! I've been using Delphi 2 for many projects over the last 5 or so
  years - but I've never written a component before. Why? Well, it just seems
  that every time I needed an extra bit of functionality I've managed to find
  it in one of the many extremely high quality freeware components that have
  been released by various generous soles on the web.

  But I guess the day had to come eventually when I'd need something that
  wasn't already out there (though it is a testament to the Delphi community
  in general that it's taken 5 years to get to that day!).

  In giving a background as to why I wrote this component you should hopefully
  gain some insight into what it's actually capable of (and what it can't do
  as well!). The component was written for a Time Recording application (just
  a personal project). The application needed a control capable of selecting
  a range of work in time, that would be no longer than 24 hours, and could
  start and finish at ANY point in the day. It should be capable of simple
  mouse operation (dragging the start and end points of the range - and the
  duration point if necessary to shift the whole range). It should be capable
  of calculating the duration in time of the range.

  Therefore, to give some examples, it should be capable of handling the
  following ranges :

  09:00 - 17:00 (dur. 8 hours)
  22:00 - 05:00 (dur. 5 hours, crossing midnight line)

  I figured I'd come across some components that handled the first example -
  but oddly enough I didn't. I suspect in part this is due to the inclusion
  of a TDateTimePanel in Delphi 3 which I suspect may handle that functionality
  (though I haven't seen it - I'm just guessing from the name - feel free to
  correct me anyone! Does it just handle dates and not times?)

  So, failing that I figured it was about time I got my feet wet and I dived
  into creating the component. I was pleasantly surprised that it only took
  two days (if this is a long time in writing components, forgive me - it was
  my first time!).

  To summarise, the functionality of the component is as follows :

  * Select a time range no longer than 24 hours
  * Mouse driven operation - drag start and end time and duration
  * Configuration includes ability to cross midnight line

  And some extra stuff I figured I'd put in :

  * Configure start and end times of a working day for different colours
  * Configure colours and fonts of start, duration and end time boxes
  * Configure border of panel (inherited stuff - nothing special there!)
  * Configure format of text in start, duration and end boxes
  * Configure mouse-over colours of scroll arrows
  * Configure display of duration box and connecting line
  * Configure 1 or 2 days shown (to allow/disallow midnight line crossing)

  So, onto the bit you've actually been reading this file for (sorry about
  all the above rubbish - it's just included for those curious few who
  have nothing else better to read!).

  Finally, a quick apology - sorry this isn't in a "real" Delphi help file
  with keywords and all that. I still haven't found time to produce this
  in a proper help file (just got to work out the keyword production system
  and find a decent freeware / extremely cheap help file creation tool - can
  anybody recommend one that isn't M$ Word based?).

Compatibility
===============================================================================

  I've only tested this component under Delphi 2, unfortunately I don't have
  Delphi 3, 4, or 5 to test this on. But from what I've read of these later
  versions I can't see any reason that this component wouldn't work under
  them - so for the time being I'm claiming Delphi 3, 4 and 5 compatibility.

  If anyone could let me know for sure that these work under the above
  versions I'd be very grateful (contact details at the bottom of the file).

  Also - I _think_ this should work with little alteration under Delphi 1, but
  I'm not so sure about this - but again, if anyone wants to drop me a note
  with the results I'd be very grateful!

Installation
===============================================================================

  As I've only got Delphi 2 to play around with I can only be sure about the
  installation procedures for this version - but I've tried to include
  installation instructions for the other versions based on instructions
  I've seen in other freeware components. Apologies if they're a little
  incorrect (if anyone wants to post me some corrections / additions etc.
  please feel free!)...

  As with installing any component - MAKE A BACKUP OF YOUR COMPONENT LIBRARY
  FILE FIRST! For Delphi 2, this is the cmplib32.dcl file in your
  Delphi 2.0\Bin directory.

  The component should install itself to the "Time" tab of the component
  library, which will be created if it doesn't already exist.

  Delphi 2
  --------

  1. Extract the files from the ZIP file to a directory in your library
     search path.
  2. From within the Delphi 2 IDE, select Install... from the Component
     menu.
  3. In the window that appears, click on the Add... button.
  4. Select the Browse button from the window that appears, and select
     the file TimePanel.pas which was extracted from the ZIP in step 1.
  5. Click on Open in the File Open dialog.
  6. Click on Ok in the Add Module dialog.
  7. Click on Ok in the Install Components dialog.

  Delphi 3
  --------

  These instructions assume you will place the component into the standard
  user package "DCLUSR30.DPK".  Advanced developers may want to use a
  different package, or to make a new package.

  1. Extract the files from the ZIP file to a directory on your hard disk.
  2. From within the Delphi 3 IDE, select Install Component from the
     Component menu.
  3. Check to see if the package "DCLUSR30.DPK" is already selected, if
     it isn't you should locate "DCLUSR30.DPK".
  4. Add the directory that you extracted the files to, to the search path
     (unless you extracted the files to a directory already in your search
     path).
  5. In the Unit name block, enter TimePanel.pas.
  6. Click on Ok.
  7. You will be asked if you wish to rebuild the Component Library, select
     Yes.
  8. If it does not automatically install the new component to the
     component palette, then click on the Install button of the package
     option dialog box.
  9. When done, close the package option dialog box by clicking on it's
     upper right corner. Select Yes to keep the changes.

  Delphi 4
  --------

  I haven't managed to find many "complete" instructions for Delphi 4
  component installation, so this is a little sparse :

  1. Extract the files from the ZIP file to a directory on your hard disk.
  2. From within the Delphi 4 IDE, select Install Component from the
     Component menu.
  3. Specify TimePanel.pas as the component unit name.
  4. Select the package of your choice.
  5. Select Ok.

  Delphi 5
  --------

  No idea! Haven't seen any instructions for this yet - I'll add some when
  I've seen an example!

Properties
===============================================================================

(Alphabetical order)

  DurationColor     Changes the colour of the background of the duration box
                    (if shown)

  DurationFormat    Changes the format of the duration shown in the duration
                    box (if shown). Uses same format as Format function. The
                    first parameter is an integer representing the number
                    of hours, the second is an integer representing the number
                    of minutes. For example with a duration of 9 hours and 5
                    minutes, the following format string :

                    %dh %.2m

                    Would generate the duration box as holding the text ;

                    9h 05m

  DurationHours     The number of hours represented by the currently selected
                    range in time. Setting this value causes the end time
                    to shift (and possibly the start time if necessary).

  DurationMins      The number of minutes represented by the currently selected
                    range in time. Setting this value causes the end time to
                    shift (and possibly the start time if necessary).

  FinishColor       Changes the colour of the background of the end time box.

  FinishDay         The day (1 or 2) which the range ends in. If ShowDays is
                    1, this can only be 1 - otherwise if the range crosses the
                    midnight line, this will be 2.

  FinishHours       The hours on which the range ends (in twenty-four hour
                    format).

  FinishMins        The minutes in the hour on which the range ends.

  FinishTime        (Run time) The finish time as TDateTime. The date part of
                    the TDateTime is undefined, reading or setting it has no
                    effect. The component will attempt to be intelligent about
                    the value passed when setting the property if ShowDays is
                    2. In this case, if the FinishTime passed is before the
                    current StartTime it is assumed that the FinishDay should
                    be 2. If ShowDays is 1 and the FinishTime passed is before
                    the StartTime, FinishTime becomes StartTime.

  Font              Changes the font for all boxes in the panel (start,
                    duration and end boxes) and the times on the left.

  SelColor          The colour the scroll arrows change when the mouse is
                    moved over them.

  ShowConnect       Show or don't show the line connecting the start and end
                    boxes (passing under the duration box).

  ShowDays          Can be 1 or 2. If 2, allows the range to cross the midnight
                    line, but still the range cannot be greater than 24 hours
                    (if the user attempts to drag beyond 24 hours, the start
                    time is shifted to keep the duration within the limit).

  ShowDuration      Whether or not to show the duration box in the middle.

  StartColor        The background colour of the start time box.

  StartHours        The hours on which the range starts (in twenty-four hour
                    format).

  StartMins         The minutes in the hour on which the range ends.

  StartTime         (Run time) The start time as a TDateTime. The Date part of
                    the TDateTime is undefined, reading or setting it has no
                    effect.

  TabStop           Inherited - doesn't mean anything in this case (the control
                    cannot be controlled from the keyboard - sorry, maybe in
                    the next version?).

  TimeColor         The colour for the font of the time labels shown down the
                    left hand side.

  TimeFormat        The format for the times shown in the start and end boxes,
                    this uses the same format as the FormatDateTime function
                    so the format string hh:mm produces the following results
                    in the boxes (for example) :

                    09:00
                    11:00
                    12:30
                    14:45

  TopDay            The day of the time at the top of the panel (1 or 2).

  TopHour           The hour at the top of the panel (sort of like TopIndex
                    in TListBoxes).

  TopMin            The minute at the top of the panel.

  WorkFinish        24 hour based end of working day. Used when formatting
                    the colour of the working day hours differently. For
                    example, 17 = 5pm.

  WorkStart         24 hour based start of working day. Used when formatting
                    the colour of the working day hours, see WorkFinish.

  WorkTimeColour    The colour of hours within the working day as defined by
                    WorkStart and WorkFinish. Make this the same as TimeColour
                    to "disable" display of working days.

Methods
===============================================================================

(Alphabetical order)

  constructor Create(Owner: TComponent);
                    The usual for components. Simply takes the component's
                    owner as the only parameter.

  procedure DecTime(StartFinish: TTPStartFinish; Hours: TTPHours;
    Mins: TTPMins);
                    Takes three arguments to increment the time. The first
                    is an enumerated type TTPStartFinish which can hold the
                    values sfStart or sfFinish which indicates whether you
                    wish to decrement the time of the start or finish.
                    The second parameter is of type TTPHours and is an integer
                    number from 0 to 23 indicating the number of hours you
                    wish to decrement the time by. The third parameter is of
                    type TTPMins and is a number from 0 to 59 indicating the
                    number of minutes you wish to decrement the time by.
                    For example :

                    TimePanel1.DecTime(sfFinish, 2, 30);

                    Moves the finish time back two and a half hours.

  destructor Destroy;
                    The usual.

  procedure IncTime(StartFinish: TTPStartFinish; Hours: TTPHours;
    Mins: TTPMins);
                    See DecTime for an explanation of the parameters. This
                    method is simply used to increment the time by a specified
                    amount. For example :

                    TimePanel1.IncTime(sfStart, 1, 5);

                    Moves the start time forward one hour and five minutes.

Events
===============================================================================

(Alphabetical order)

  property OnTimeChange: TNotifyEvent;
                    An OnTimeChange event occurs every time the user changes
                    the time selected by dragging either the start, finish
                    or duration time box. Use this event to update an
                    alternate display of the time, for example a set of
                    TUpDown components, or a TEdit box containing the times
                    selected along with dates selected from a date selecting
                    control.


Known Bugs
===============================================================================

  At the moment, there is only one bug I know of. If you compile a project
  using this component with Range Checking turned On, then if you attempt to
  move the end time box over the midnight line a Range Check error occurs.

  It turns out this is completely erroneous and not really an error at all -
  I think I've just screwed up one of the sub-ranges somewhere. If you turn
  Range Checking Off everything works just fine.

  If anyone discovers anything else, please EMail me and I'll see what I
  can do!

Legal Stuff
===============================================================================

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

Author Details
===============================================================================

Dave Hughes
Manchester, UK

I seem to have a plethora of EMail addresses at the moment. Some of which
may disappear at some point in the future, the most useful ones are :

hughesd6@cs.man.ac.uk           (will disappear end of 06/2000)
dave@waveform.free-online.co.uk (may disappear if my ISP changes - unlikely)
