home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / slider1 / slider.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-12-22  |  20.2 KB  |  493 lines

  1. (*-----------------------------------------------------------------------*
  2.  | Slider component for Borland Delphi.                                  |
  3.  |                                                                       |
  4.  | Programmed by Colin Wilson - woozle@cix.compulink.co.uk               |
  5.  *-----------------------------------------------------------------------*)
  6.  
  7. unit Slider;
  8.  
  9. interface
  10.  
  11. uses
  12.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls;
  13.  
  14. type
  15.   TSliderOrientation = (slHoriz, slVertical);
  16.   TSlider = class(TCustomControl)
  17.   private
  18.     Thumb : TRect;               { Current thumb position             }
  19.     MemDC : HDC;                 { DC for saving area under the thumb }
  20.     Bitmap : HBitmap;            { Bitmap handle for saved area.      }
  21.  
  22.     capture : boolean;           { Whether it's currently being moved }
  23.     capturePoint : TPoint;       { Position at start of capture.      }
  24.     captureValue : Integer;      { Value at start of capture.         }
  25.  
  26.                                  { Property values...                 }
  27.     fTrackWidth : Integer;
  28.     fTrackColor : TColor;
  29.     fOrientation : TSliderOrientation;
  30.     fThumbHeight : Integer;
  31.     fThumbColor : TColor;
  32.     fMin : Integer;
  33.     fMax : Integer;
  34.     fValue : Integer;
  35.     fValueChange : TNotifyEvent;
  36.     fCtl3D : boolean;
  37.  
  38.     procedure SetTrackWidth (value : Integer);
  39.     procedure SetTrackColor (value : TColor);
  40.     procedure SetOrientation (value : TSliderOrientation);
  41.     procedure SetThumbHeight (value : Integer);
  42.     procedure SetThumbColor (value : TColor);
  43.     procedure SetMin (v : Integer);
  44.     procedure SetMax (v : Integer);
  45.     procedure SetValue (value : Integer);
  46.     procedure SetCtl3D (value : boolean);
  47.   protected
  48.     procedure Paint; override;
  49.     procedure MouseDown (Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  50.     procedure MouseUp (Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  51.     procedure MouseMove (Shift: TShiftState; X, Y: Integer); override;
  52.     procedure DrawThumb; virtual;
  53.   public
  54.     constructor Create (AOwner : TComponent); override;
  55.     destructor Destroy; override;
  56.   published
  57.     property TrackWidth : Integer read fTrackWidth write SetTrackWidth;
  58.     property TrackColor : TColor read fTrackColor write SetTrackColor;
  59.     property ThumbHeight : Integer read fThumbHeight write SetThumbHeight;
  60.     property ThumbColor : TColor read fThumbColor write SetThumbColor;
  61.     property Orientation : TSliderOrientation read fOrientation write SetOrientation;
  62.     property Minimum : Integer read fMin write SetMin;
  63.     property Maximum : Integer read fMax write SetMax;
  64.     property Value : Integer read fValue write SetValue;
  65.     property Ctl3D : boolean read fCtl3D write SetCtl3D;
  66.     property OnValueChange : TNotifyEvent read fValueChange write fValueChange;
  67.  
  68.     property Color;
  69.     property Enabled;
  70.     property HelpContext;
  71.     property Hint;
  72.     property ParentShowHint;
  73.     property ShowHint;
  74.     property Tag;
  75.     property Visible;
  76.  
  77.     property OnClick;
  78.     property OnDragDrop;
  79.     property OnDragOver;
  80.     property OnEndDrag;
  81.     property OnEnter;
  82.     property OnExit;
  83.     property OnMouseDown;
  84.     property OnMouseMove;
  85.     property OnMouseUp;
  86.  
  87.   end;
  88.  
  89. procedure Register;
  90.  
  91. implementation
  92.  
  93. (*-------------------------------------------------------------------------*
  94.  | constructor TSlider.Create (AOwner);                                    |
  95.  |                                                                         |
  96.  | Create the slider and set initial property values.                      |
  97.  |                                                                         |
  98.  | parameters:                                                             |
  99.  |   AOwner : TComponent              The owner                            |
  100.  *-------------------------------------------------------------------------*)
  101. constructor TSlider.Create (AOwner : TComponent);
  102. begin
  103.   inherited Create (AOwner);
  104.   Width := 50;
  105.   Height := 200;
  106.   fTrackWidth := 10;
  107.   fOrientation := slVertical;
  108.   fTrackColor := clBtnFace;
  109.   fThumbColor := clBtnFace;
  110.   fMin := 0;
  111.   fMax := 100;
  112.   fValue := 0;
  113.   fThumbHeight := 20;
  114.   fValueChange := Nil;
  115.   fCtl3D := True;
  116.   capture := False;
  117.   thumb.left := -1;
  118. end;
  119.  
  120. (*-------------------------------------------------------------------------*
  121.  | destructor TSlider.Destroy                                              |
  122.  |                                                                         |
  123.  | Destroy the slider component.                                           |
  124.  *-------------------------------------------------------------------------*)
  125. destructor TSlider.Destroy;
  126. begin
  127.   if Bitmap <> 0 then DeleteObject (Bitmap);
  128.   if MemDC <> 0 then DeleteDC (MemDC);
  129.   inherited Destroy
  130. end;
  131.  
  132. (*-------------------------------------------------------------------------*
  133.  | procedure TSlider.SetTrackWidth (value)                                 |
  134.  |                                                                         |
  135.  | Write procedure for TrackWidth property.  Sets the track width (the bit |
  136.  | the thumb slides up and down.                                           |
  137.  |                                                                         |
  138.  | parameters:                                                             |
  139.  |   value : Integer        The new track width value                      |
  140.  *-------------------------------------------------------------------------*)
  141. procedure TSlider.SetTrackWidth (value : Integer);
  142. begin
  143.   if fTrackWidth <> value then
  144.   begin
  145.     fTrackWidth := value;
  146.     Invalidate
  147.   end
  148. end;
  149.  
  150. (*-------------------------------------------------------------------------*
  151.  | procedure TSlider.SetOrientation (value)                                |
  152.  |                                                                         |
  153.  | Write procedure for Orientation property.  Sets the slider orientation: |
  154.  | slHorizontal or slVertical.                                             |
  155.  |                                                                         |
  156.  | parameters:                                                             |
  157.  |   value : TSliderOrientation The new orientation                        |
  158.  *-------------------------------------------------------------------------*)
  159. procedure TSlider.SetOrientation (value : TSliderOrientation);
  160. begin
  161.   if value <> fOrientation then
  162.   begin
  163.     fOrientation := value;
  164.     Invalidate
  165.   end
  166. end;
  167.  
  168. (*-------------------------------------------------------------------------*
  169.  | procedure TSlider.SetTrackColor (value)                                 |
  170.  |                                                                         |
  171.  | Write procedure for TrackColor property.  Sets the track colour.        |
  172.  |                                                                         |
  173.  | parameters:                                                             |
  174.  |   value : TColor       The new track colour                             |
  175.  *-------------------------------------------------------------------------*)
  176. procedure TSlider.SetTrackColor (value : TColor);
  177. begin
  178.   if value <> fTrackColor then
  179.   begin
  180.     fTrackColor := value;
  181.     Invalidate
  182.   end
  183. end;
  184.  
  185. (*-------------------------------------------------------------------------*
  186.  | procedure TSlider.SetThumbHeight (value)                                |
  187.  |                                                                         |
  188.  | Write procedure for ThumbHeight property.  Sets the thumb height (or    |
  189.  | width for horizontal sliders).  nb the thumb is always as wide as the   |
  190.  | component itself.                                                       |
  191.  |                                                                         |
  192.  | parameters:                                                             |
  193.  |   value : Integer       The new thumb height                            |
  194.  *-------------------------------------------------------------------------*)
  195. procedure TSlider.SetThumbHeight (value : Integer);
  196. begin
  197.   if value <> fThumbHeight then
  198.   begin
  199.     fThumbHeight := value;
  200.     Invalidate
  201.   end
  202. end;
  203.  
  204. (*-------------------------------------------------------------------------*
  205.  | procedure TSlider.SetThumbColor (value)                                 |
  206.  |                                                                         |
  207.  | Write procedure for ThumbColor property.  Sets the thumb colour         |
  208.  |                                                                         |
  209.  | parameters:                                                             |
  210.  |   value : TColor     The new thumb colour                               |
  211.  *-------------------------------------------------------------------------*)
  212. procedure TSlider.SetThumbColor (value : TColor);
  213. begin
  214.   if value <> fThumbColor then
  215.   begin
  216.     fThumbColor := value;
  217.     Invalidate
  218.   end
  219. end;
  220.  
  221. (*-------------------------------------------------------------------------*
  222.  | procedure TSlider.SetMin (value)                                        |
  223.  |                                                                         |
  224.  | Write procedure for Minimum property.  Sets the minimum value.          |
  225.  |                                                                         |
  226.  | parameters:                                                             |
  227.  |   value : Integer  The new minimum                                      |
  228.  *-------------------------------------------------------------------------*)
  229. procedure TSlider.SetMin (v : Integer);
  230. begin
  231.   if v <> fMin then
  232.   begin
  233.     fMin := V;
  234.     if Value < fMin then Value := fMin;
  235.     Invalidate
  236.   end
  237. end;
  238.  
  239. (*-------------------------------------------------------------------------*
  240.  | procedure TSlider.SetMax (value)                                        |
  241.  |                                                                         |
  242.  | Write procedure for Maximum property.  Sets the maximum value.          |
  243.  |                                                                         |
  244.  | parameters:                                                             |
  245.  |   value : Integer  The new maximum                                      |
  246.  *-------------------------------------------------------------------------*)
  247. procedure TSlider.SetMax (v : Integer);
  248. begin
  249.   if v <> fMax then
  250.   begin
  251.     fMax := V;
  252.     if Value > fMax then Value := fMax;
  253.     Invalidate
  254.   end
  255. end;
  256.  
  257. (*-------------------------------------------------------------------------*
  258.  | procedure TSlider.SetValue (value)                                      |
  259.  |                                                                         |
  260.  | Write procedure for Value property.  Sets the value, updates the thumb, |
  261.  | and generates an OnValueChange event                                    |
  262.  |                                                                         |
  263.  | parameters:                                                             |
  264.  |   value : Integer  The new value                                        |
  265.  *-------------------------------------------------------------------------*)
  266. procedure TSlider.SetValue (value : Integer);
  267. begin
  268.   if value < Minimum then value := Minimum else if value > Maximum then value := Maximum;
  269.   if value <> fValue then
  270.   begin
  271.     fValue := Value;
  272.     if Assigned (fValueChange) then OnValueChange (self);
  273.     DrawThumb
  274.   end
  275. end;
  276.  
  277. (*-------------------------------------------------------------------------*
  278.  | procedure TSlider.SetCtl3D (value)                                      |
  279.  |                                                                         |
  280.  | Write procedure for Ctl3D property.  Setting this property gives both   |
  281.  | th thumb and the track a 3D look.                                       |
  282.  |                                                                         |
  283.  | parameters:                                                             |
  284.  |   value : Boolean    The new ctl3D value                                |
  285.  *-------------------------------------------------------------------------*)
  286. procedure TSlider.SetCtl3D (value : boolean);
  287. begin
  288.   if value <> fCtl3D then
  289.   begin
  290.     fCtl3D := value;
  291.     Invalidate
  292.   end
  293. end;
  294.  
  295. (*-------------------------------------------------------------------------*
  296.  | procedure TSlider.Paint                                                 |
  297.  |                                                                         |
  298.  | Paint the entire slider control.                                        |
  299.  *-------------------------------------------------------------------------*)
  300. procedure TSlider.Paint;
  301. var Rect : TRect;
  302. begin
  303.   with Canvas do
  304.   begin                             { Create memory DC for save bitmap }
  305.     if MemDC = 0 then MemDC := CreateCompatibleDC (Canvas.Handle);
  306.  
  307.                                     { Create thumb & bitmap for vertical slider }
  308.     if fOrientation = slVertical then
  309.     begin
  310.       if Bitmap = 0 then
  311.         Bitmap := CreateCompatibleBitmap (Canvas.Handle, Width, ThumbHeight);
  312.       Rect.top := 0;
  313.       Rect.bottom := Height;
  314.       Rect.left := (Width - TrackWidth) div 2;
  315.       Rect.Right := Rect.Left + TrackWidth
  316.     end
  317.     else
  318.     begin
  319.                                     { Create thumb & bitmap for horiz slider }
  320.       if Bitmap = 0 then
  321.         Bitmap := CreateCompatibleBitmap (Canvas.Handle, ThumbHeight, Height);
  322.  
  323.       Rect.top := (Height - TrackWidth) div 2;
  324.       Rect.bottom := Rect.Top + TrackWidth;
  325.       Rect.left := 0;
  326.       Rect.Right := Width
  327.     end;
  328.                                      { Draw track.                            }
  329.     Brush.Color := TrackColor;
  330.     if Ctl3D then
  331.     begin
  332.       Pen.Color := clBtnHighlight;
  333.       with Rect do
  334.       begin
  335.         Rectangle (left, top, right, bottom);
  336.         Pen.Color := clBtnShadow;
  337.         MoveTo (left, top);
  338.         LineTo (right, top);
  339.         MoveTo (left, top);
  340.         LineTo (left, bottom)
  341.       end
  342.     end
  343.     else FillRect (Rect);            { Not Ctl3D - do a simple rectangle      }
  344.  
  345.     DrawThumb;                       { Now draw the thumb.                    }
  346.  
  347.   end
  348. end;
  349.  
  350. (*-------------------------------------------------------------------------*
  351.  | procedure TSlider.DrawThumb                                             |
  352.  |                                                                         |
  353.  | Draw the thumb at the correct position for the current value.           |
  354.  *-------------------------------------------------------------------------*)
  355. procedure TSlider.DrawThumb;
  356. var
  357.   basePos : Integer;
  358.   rc : bool;
  359.   oldBmp : HBitmap;
  360.   oldThumb : TRect;
  361. begin
  362.   if csLoading in ComponentState then Exit;
  363.  
  364.   oldBmp := SelectObject (MemDC, Bitmap);
  365.  
  366.   { Set thumb color & border color }
  367.   if Enabled then Canvas.Brush.Color := ThumbColor else Canvas.Brush.Color := clGray;
  368.   if Ctl3D then Canvas.Pen.Color := clBtnHighlight else Canvas.Pen.Color := clBlack;
  369.  
  370.   { Save current thum rectangle }
  371.   oldThumb := Thumb;
  372.  
  373.   if Orientation = slVertical then
  374.   begin
  375.  
  376.   { Calculate new thumb rectangle }
  377.     basePos := LongInt (Height - ThumbHeight) * LongInt (Value - Minimum) div (Maximum - Minimum);
  378.     Thumb.left := 0;
  379.     Thumb.right := Width;
  380.     Thumb.Bottom := Height - BasePos;
  381.     Thumb.top := Thumb.Bottom - ThumbHeight;
  382.  
  383.   { Rub out old thumb             }
  384.     if oldThumb.left <> -1 then with oldThumb do
  385.       BitBlt (Canvas.Handle, Left, Top, Width, ThumbHeight, MemDC, 0, 0, SRCCOPY);
  386.  
  387.   { Save what's underneath         }
  388.     with Thumb do
  389.       rc := BitBlt (MemDC, 0, 0, Width, ThumbHeight, Canvas.Handle, Left, Top, SRCCOPY);
  390.   end
  391.   else
  392.   begin
  393.   { Calculate new thumb rectangle for horiz slider}
  394.     basePos := LongInt (Width - ThumbHeight) * LongInt(Value - Minimum) div (Maximum - Minimum);
  395.     Thumb.left := basePos;
  396.     Thumb.Right := Thumb.left + ThumbHeight;
  397.     Thumb.Top := 0;
  398.     Thumb.Bottom := Height;
  399.  
  400.   { Rub out old thumb             }
  401.     if oldThumb.left <> -1 then with oldThumb do
  402.       BitBlt (Canvas.Handle, Left, Top, ThumbHeight, Height, MemDC, 0, 0, SRCCOPY);
  403.  
  404.   { Save what's underneath         }
  405.     with Thumb do
  406.       rc := BitBlt (MemDC, 0, 0, ThumbHeight, Height, Canvas.Handle, Left, Top, SRCCOPY);
  407.   end;
  408.  
  409.   { Draw the thumb                 }
  410.   with Canvas do
  411.   begin
  412.     with Thumb do if Ctl3D then
  413.     begin
  414.       Rectangle (left, top, right-1, bottom-1);
  415.       Pen.Color := clBtnShadow;
  416.       MoveTo (Left + 1, Bottom - 3);
  417.       LineTo (Left + 1, Top+1);
  418.       LineTo (Right - 2, Top+1);
  419.       MoveTo (Left, Bottom - 1);
  420.       LineTo (Right-1, Bottom - 1);
  421.       LineTo (Right-1, Top - 1)
  422.     end
  423.     else
  424.       Rectangle (left, top, right, bottom);
  425.   end;
  426.  
  427.   SelectObject (MemDC, OldBmp);
  428. end;
  429.  
  430. (*-------------------------------------------------------------------------*
  431.  | procedure TSlider.MouseDown (button, Shift, X, Y)                       |
  432.  |                                                                         |
  433.  | Respond to 'MouseDown' events.  Record the position of press for use in |
  434.  | the MouseMove event handler.                                            |
  435.  |                                                                         |
  436.  | Parameters:                                                             |
  437.  |   button : TMouseButton         Set of mouse buttons currently pressed. |
  438.  |   Shift  : TShiftState          Set of shift, ctrl, alt keys            |
  439.  |   X, Y   : Integer              Mouse position relative to top of slider|
  440.  *-------------------------------------------------------------------------*)
  441. procedure TSlider.MouseDown (Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  442. begin
  443.   inherited MouseDown (Button, Shift, X, Y);
  444.   if (Button = mbLeft) and PtInRect (Thumb, Point (X, Y)) then
  445.   begin
  446.     capture := True;
  447.     capturePoint := Point (X, Y);
  448.     captureValue := value;
  449.   end;
  450. end;
  451.  
  452. (*-------------------------------------------------------------------------*
  453.  | procedure TSlider.MouseUp (button, Shift, X, Y)                         |
  454.  |                                                                         |
  455.  | Respond to 'MouseUp' events                                             |
  456.  |                                                                         |
  457.  | Parameters:                                                             |
  458.  |   button : TMouseButton         Set of mouse buttons currently pressed. |
  459.  |   Shift  : TShiftState          Set of shift, ctrl, alt keys            |
  460.  |   X, Y   : Integer              Mouse position relative to top of slider|
  461.  *-------------------------------------------------------------------------*)
  462. procedure TSlider.MouseUp (Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  463. begin
  464.   inherited MouseUp (Button, Shift, X, Y);
  465.   if (Button = mbLeft) then capture := False
  466. end;
  467.  
  468. (*-------------------------------------------------------------------------*
  469.  | procedure TSlider.MouseMove (Shift, X, Y)                               |
  470.  |                                                                         |
  471.  | Respond to 'MouseMove' events                                           |
  472.  |                                                                         |
  473.  | Parameters:                                                             |
  474.  |   Shift  : TShiftState          Set of shift, ctrl, alt keys            |
  475.  |   X, Y   : Integer              Mouse position relative to top of slider|
  476.  *-------------------------------------------------------------------------*)
  477. procedure TSlider.MouseMove (Shift: TShiftState; X, Y: Integer);
  478. begin
  479.   inherited MouseMove (shift, X, Y);
  480.   if capture then
  481.     if Orientation = slVertical then
  482.       value := captureValue + Minimum + LongInt (Maximum - Minimum) * LongInt (capturePoint.Y - Y) div (Height - ThumbHeight)
  483.     else
  484.       value := captureValue + Minimum + LongInt (Maximum - Minimum) * LongInt (X - capturePoint.X) div (Width - ThumbHeight);
  485. end;
  486.  
  487. procedure Register;
  488. begin
  489.   RegisterComponents('Samples', [TSlider]);
  490. end;
  491.  
  492. end.
  493.