home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / colorwhl.zip / ColorWheel.PAS < prev    next >
Pascal/Delphi Source File  |  1999-08-15  |  18KB  |  736 lines

  1. Unit ColorWheel;
  2.  
  3. Interface
  4.  
  5. Uses
  6.   Classes, Forms, Graphics;
  7.  
  8. Type
  9.   TValueBar=Class;
  10.  
  11.   TColorWheel=Class( TControl )
  12.   Protected
  13.     FValueBar: TValueBar;
  14.     FHue: longint;
  15.     FSaturation: real;
  16.     FCursorDrawn: boolean;
  17.     FOldCursorX, FOldCursorY: longint;
  18.     FOldCursorSize: longint;
  19.     FMarginWidth: longint;
  20.     FCursorSize: longint;
  21.     FWhiteAreaPercent: longint; // 0 to 50 percent of circle radius that is pure white
  22.     FOnChange: TNotifyEvent;
  23.  
  24.     Procedure SetupComponent; Override;
  25.     Procedure SetupShow; Override;
  26.     Procedure HSFromPoint( X, Y: longint;
  27.                            Var H: longint;
  28.                            Var S: real );
  29.     Procedure DrawCursor;
  30.  
  31.     Procedure Resize; override;
  32.     Procedure SetMarginWidth( NewWidth: longint );
  33.     Procedure SetCursorSize( NewSize: longint );
  34.     Procedure SetValueBar( ValueBar: TValueBar );
  35.     Procedure SetWhiteAreaPercent( WhiteAreaPercent: longint );
  36.     Procedure Notification(AComponent:TComponent;Operation:TOperation); override;
  37.  
  38.     Function DrawWidth: longint;
  39.     Function DrawHeight: longint;
  40.  
  41.     Procedure MouseDown( Button: TMouseButton;
  42.                          ShiftState: TShiftState;
  43.                          X, Y: Longint ); Override;
  44.     Procedure MouseMove( ShiftState: TShiftState;
  45.                          X, Y: Longint ); Override;
  46.     Procedure MouseUp( Button: TMouseButton;
  47.                        ShiftState: TShiftState;
  48.                        X, Y: Longint ); Override;
  49.     Procedure Change;
  50.     Property OnCloseQuery; // hide it
  51.   Public
  52.     Destructor Destroy; Override;
  53.     Procedure Redraw( const rec: Trect ); override;
  54.     Property Hue: longint read FHue;
  55.     Property Saturation: real read FSaturation;
  56.     Procedure SetSelectedColor( const NewColor: TColor );
  57.   Published
  58.     Property Color;
  59.     Property ParentColor;
  60.     Property ValueBar: TValueBar read FValueBar write SetValueBar;
  61.  
  62.     Property MarginWidth: longint read FMarginWidth write SetMarginWidth;
  63.     Property CursorSize: longint read FCursorSize write SetCursorSize;
  64.     Property ZOrder;
  65.     Property WhiteAreaPercent: longint read FWhiteAreaPercent write SetWhiteAreaPercent;
  66.  
  67.     Property OnChange: TNotifyEvent read FOnChange write FOnChange;
  68.   End;
  69.  
  70.   TValueBar=Class( TControl )
  71.   Protected
  72.     FColorWheel: TColorWheel;
  73.     FHue: longint;
  74.     FSaturation: real;
  75.     FValue: real;
  76.     FCursorDrawn: boolean;
  77.     FOldCursorY: longint;
  78.     FMarginWidth: longint;
  79.     FCursorHeight: longint;
  80.     FOnChange: TNotifyEvent;
  81.     FDither: boolean;
  82.  
  83.     Procedure SetupComponent; Override;
  84.     Procedure SetupShow; Override;
  85.     Procedure DrawCursor;
  86.  
  87.     Procedure Resize; override;
  88.     Procedure SetMarginWidth( NewWidth: longint );
  89.     Procedure SetValue( Value: real );
  90.     Procedure SetDither( Dither: boolean );
  91.     Procedure SetCursorHeight( CursorHeight: longint );
  92.  
  93.     Function GetSelectedColor: TColor;
  94.  
  95.     Procedure Change;
  96.  
  97.     Function DrawWidth: longint;
  98.     Function DrawHeight: longint;
  99.  
  100.     Procedure MouseDown( Button: TMouseButton;
  101.                          ShiftState: TShiftState;
  102.                          X, Y: Longint ); Override;
  103.     Procedure MouseMove( ShiftState: TShiftState;
  104.                          X, Y: Longint ); Override;
  105.     Procedure MouseUp( Button: TMouseButton;
  106.                        ShiftState: TShiftState;
  107.                        X, Y: Longint ); Override;
  108.     Function ValueFromY( Y: longint ): real;
  109.     Procedure DrawLine( Y: longint );
  110.     Property OnCloseQuery; // hide it
  111.   Public
  112.     Destructor Destroy; Override;
  113.     Procedure Redraw( const rec: Trect ); override;
  114.     Procedure SetHS( Hue: longint; Sat: real );
  115.   Published
  116.     Property Color;
  117.     Property ParentColor;
  118.     Property Value: real read FValue write SetValue;
  119.     Property SelectedColor: TColor read GetSelectedColor;
  120.  
  121.     property Dither: boolean read FDither write SetDither;
  122.  
  123.     Property MarginWidth: longint read FMarginWidth write SetMarginWidth;
  124.     Property CursorHeight: longint read FCursorHeight write SetCursorHeight;
  125.     Property ZOrder;
  126.  
  127.     Property OnChange: TNotifyEvent read FOnChange write FOnChange;
  128.   End;
  129.  
  130. Exports
  131.   TColorWheel,'User','ColorWheel.bmp',
  132.   TValueBar, 'User', 'ValueBar.bmp';
  133.  
  134. Implementation
  135.  
  136. Uses
  137.   ColorMapping, PMGPI;
  138.  
  139. Const
  140.   RadToHue: real = 1536/(2*pi);
  141.  
  142. Procedure TColorWheel.SetupComponent;
  143. Begin
  144.   Inherited SetupComponent;
  145.   FMarginWidth:= 5;
  146.   FCursorSize:= 5;
  147.   Width:= 100;
  148.   Height:= 100;
  149.   Name:= 'ColorWheel';
  150.   ParentColor:= True;
  151.   Exclude(ComponentState, csAcceptsControls);
  152.   FWhiteAreaPercent:= 10;
  153. End;
  154.  
  155. Procedure TColorWheel.SetupShow;
  156. Begin
  157.   Inherited SetupShow;
  158. End;
  159.  
  160. Destructor TColorWheel.Destroy;
  161. Begin
  162.   Inherited Destroy;
  163. End;
  164.  
  165. Procedure TColorWheel.ReDraw( const rec: Trect );
  166. Var
  167.  x,y : longint;
  168.  Hue: longint;
  169.  saturation: real;
  170.  c: tcolor;
  171.  r: TRect;
  172. Begin
  173.   Canvas.ClipRect:= rec;
  174.   // clear background rectangle
  175.   Canvas.FillRect( rec, Color );
  176.  
  177.   if ( Width < MarginWidth * 2 ) or
  178.     ( Height < MarginWidth * 2 ) then
  179.     // margins too big
  180.     exit;
  181.  
  182. {  Bugger there is a bug in Arc - it starts drawing
  183.    from last position
  184.   Canvas.Pen.Color:= clBtnHighlight;
  185.   Canvas.Arc( Width div 2, Height div 2,
  186.               DrawWidth div 2 + 1, DrawHeight div 2 + 1,
  187.               45, 180 );
  188.   Canvas.Pen.Color:= clBtnShadow;
  189.   Canvas.Arc( Width div 2, Height div 2,
  190.               DrawWidth div 2 + 1, DrawHeight div 2 + 1,
  191.               225, 180 );}
  192.  
  193.   if Designed then
  194.   begin
  195.     // When designing, don't draw colors
  196.     // but draw an outline
  197.     Canvas.Pen.Style:= psDash;
  198.     r.Left:= 0;
  199.     r.Right:= Width - 1;
  200.     r.Bottom:= 0;
  201.     r.Top:= Height - 1;
  202.     Canvas.Rectangle( r );
  203.     Canvas.Ellipse( Width div 2, Height div 2,
  204.                     DrawWidth div 2 + 1, DrawHeight div 2 + 1 );
  205.     exit;
  206.   end;
  207.  
  208.   if ( Width < MarginWidth * 2 ) or ( Height < MarginWIdth * 2 ) then
  209.     exit;
  210.  
  211.   // scan all potential pixels and draw points on the wheel
  212.   for X:=0 to DrawWidth-1 do
  213.   begin
  214.     for Y:=0 to DrawHeight-1 do
  215.     begin
  216.       // work out hue and saturation for point
  217.       HSFromPoint( X, Y, Hue, Saturation );
  218.       if Saturation<=1.0 then
  219.       begin
  220.         // point is within wheel
  221.         C:= HSVToRGB( Hue, Saturation, 1.0 );
  222.         // draw the pixel
  223.         Canvas.Pixels[ X+FMarginWidth, Y+FMarginWidth ]:= C;
  224.       end;
  225.     end;
  226.   end;
  227.  
  228.   FCursorDrawn:= false; // make cursor draw without erasing first
  229.   DrawCursor;
  230.   Canvas.DeleteClipRegion;
  231. End;
  232.  
  233. Function TColorWheel.DrawWidth: longint;
  234. Begin
  235.   Result:= Width - FMarginWidth*2;
  236. End;
  237.  
  238. Function TColorWheel.DrawHeight: longint;
  239. Begin
  240.   Result:= Height - FMarginWidth*2;
  241. End;
  242.  
  243. Procedure TColorWheel.SetSelectedColor( const NewColor: TColor );
  244. Var
  245.   Value: real;
  246. Begin
  247.   RGBToHSV( NewColor, FHue, FSaturation, Value );
  248.   Change;
  249.   if FValueBar<>nil then
  250.     FValueBar.Value:= Value;
  251. End;
  252.  
  253. Procedure TColorWheel.Change;
  254. Var
  255.   C: TColor;
  256.   H: longint;
  257.   S, V: real;
  258. Begin
  259.   DrawCursor;
  260.   C:= HSVToRGB( FHue, FSaturation, 1.0 );
  261.   RGBToHSV( C, H, S, V );
  262.   if FValueBar<>nil then
  263.     FValueBar.SetHS( H, S );
  264.   if FOnChange <> nil then
  265.     FOnChange( self );
  266. End;
  267.  
  268. Function AngleFrom( x, y: real ): real;
  269. //
  270. //     1|0
  271. //   ---+----
  272. //     2|3
  273. Begin
  274.   if X = 0 then
  275.   begin
  276.     if Y > 0 then
  277.       Result:= pi/2
  278.     else
  279.       Result:= 3*pi/2;
  280.   end
  281.   else
  282.   begin
  283.     Result:= arctan( abs( y ) / abs( x ) );
  284.     if ( x < 0 ) and ( y>=0 ) then
  285.       // quadrant 1
  286.       Result:= pi-Result
  287.     else if ( x < 0 ) and ( y<0 ) then
  288.       // quadrant 2
  289.       Result:= Result+pi
  290.     else if ( x >= 0 ) and ( y<0 ) then
  291.       // quadrant 3
  292.       Result:= 2*pi-Result;
  293.   end;
  294. end;
  295.  
  296. // Calculate hue and saturation for a given point in the color wheel
  297. Procedure TColorWheel.HSFromPoint( X, Y: longint;
  298.                                    Var H: longint;
  299.                                    Var S: real );
  300. Var
  301.   xp, yp: real;
  302.   halfw, halfh: longint;
  303. Begin
  304.   halfw:= DrawWidth div 2;
  305.   halfh:= DrawHeight div 2;
  306.   xp:= ( x- halfw )/halfw; // x as -1..1
  307.   yp:= ( y- halfh )/halfh; // y as -1..1
  308.   H:= RadToHue * AngleFrom( xp, yp );
  309.   S:= sqrt( xp*xp+yp*yp );
  310.   // scale saturation and limit to white, for white area
  311.   S:= S * ( 1 + ( FWhiteAreaPercent / 100.0 ) ) - ( FWhiteAreaPercent / 100.0 );
  312.   if S < 0 then
  313.     S:= 0;
  314. end;
  315.  
  316. Procedure TColorWheel.DrawCursor;
  317. Var
  318.   Angle: real;
  319.   X, Y: longint;
  320.   OldMode: TPenMode;
  321.   S: real;
  322. Begin
  323.   if Handle = 0 then
  324.     exit;
  325.  
  326.   if ( Width < MarginWidth * 2 ) or
  327.      ( Height < MarginWidth * 2 ) then
  328.     exit;
  329.  
  330.   Canvas.Pen.Width:= 2;
  331.  
  332.   Angle:= FHue/RadToHue;
  333.  
  334.   // Scale distance from centre for white area
  335.   S:= FSaturation;
  336.   if S > 0 then
  337.     S:= S * ( 1 - ( FWhiteAreaPercent / 100.0 ) ) + ( FWhiteAreaPercent / 100.0 );
  338.  
  339.   // work out point for selected hue and saturation
  340.   X:= Width div 2+cos( Angle )*S* ( DrawWidth div 2 );
  341.   Y:= Height div 2+sin( Angle )*S* ( DrawHeight div 2 );
  342.  
  343.   OldMode:= Canvas.Pen.Mode;
  344.   Canvas.Pen.Mode:= pmNot; // invert pixels
  345.   if FCursorDrawn then
  346.   begin
  347.     // erase
  348.     Canvas.Line( FOldCursorX-FOldCursorSize, FOldCursorY,
  349.                  FOldCursorX+FOldCursorSize, FOldCursorY );
  350.     Canvas.Line( FOldCursorX, FOldCursorY-FOldCursorSize,
  351.                  FOldCursorX, FOldCursorY+FOldCursorSize );
  352.   end;
  353.  
  354.   // draw cursor
  355.   Canvas.Line( X-FCursorSize, Y,
  356.                X+FCursorSize, Y );
  357.   Canvas.Line( X, Y-FCursorSize,
  358.                X, Y+FCursorSize );
  359.   FOldCursorX:= X;
  360.   FOldCursorY:= Y;
  361.   FOldCursorSize:= FCursorSize;
  362.   FCursorDrawn:= true;
  363.   Canvas.Pen.Mode:= OldMode;
  364. End;
  365.  
  366. Procedure TColorWheel.Resize;
  367. Begin
  368.   Invalidate;
  369. End;
  370.  
  371. Procedure TColorWheel.SetMarginWidth( NewWidth: longint );
  372. Begin
  373.   FMarginWidth:= NewWidth;
  374.   if Handle = 0 then
  375.     exit;
  376.   Invalidate;
  377. End;
  378.  
  379. Procedure TColorWheel.SetCursorSize( NewSize: longint );
  380. Begin
  381.   FCursorSize:= NewSize;
  382.   if Handle = 0 then
  383.     exit;
  384.   DrawCursor;
  385. End;
  386.  
  387. Procedure TColorWheel.SetValueBar( ValueBar: TValueBar );
  388. Begin
  389.   if FValueBar<>nil then
  390.     // tell the old value bar it's no longer controlled by this wheel
  391.     FValueBar.FColorWheel:= nil;
  392.   FValueBar:= ValueBar;
  393.   if FValueBar<>nil then
  394.   begin
  395.     // Tell value bar it is controlled by this component
  396.     FValueBar.FColorWheel:= Self;
  397.     // request notification when other is freed
  398.     FValueBar.FreeNotification(Self);
  399.   end;
  400.  
  401. End;
  402.  
  403. Procedure TColorWheel.SetWhiteAreaPercent( WhiteAreaPercent: longint );
  404. begin
  405.   if WhiteAreaPercent > 50 then
  406.     WhiteAreaPercent:= 50;
  407.  
  408.   if WhiteAreaPercent < 0 then
  409.     WhiteAreaPercent:= 0;
  410.  
  411.   FWhiteAreaPercent:= WhiteAreaPercent;
  412.  
  413.   Invalidate;
  414. end;
  415.  
  416. Procedure TColorWheel.Notification(AComponent:TComponent;Operation:TOperation);
  417. Begin
  418.   Inherited Notification(AComponent,Operation);
  419.   If Operation = opRemove Then
  420.   Begin
  421.     If AComponent = FValueBar Then
  422.       FValueBar:= Nil;
  423.   end;
  424. end;
  425.  
  426. Procedure TColorWheel.MouseDown( Button: TMouseButton;
  427.                                  ShiftState: TShiftState;
  428.                                  X, Y: Longint );
  429. Begin
  430.   dec( X, FMarginWidth );
  431.   dec( Y, FMarginWidth );
  432.   HSFromPoint( X, Y, FHue, FSaturation );
  433.   if FSaturation>1.0 then
  434.     FSaturation:= 1.0;
  435.   Change;
  436.   MouseCapture:= True;
  437. End;
  438.  
  439. Procedure TColorWheel.MouseMove( ShiftState: TShiftState;
  440.                                  X, Y: Longint );
  441. Begin
  442.   if not MouseCapture then
  443.     exit;
  444.   dec( X, FMarginWidth );
  445.   dec( Y, FMarginWidth );
  446.   HSFromPoint( X, Y, FHue, FSaturation );
  447.   if FSaturation>1.0 then
  448.     FSaturation:= 1.0;
  449.   Change;
  450. End;
  451.  
  452. Procedure TColorWheel.MouseUp( Button: TMouseButton;
  453.                                ShiftState: TShiftState;
  454.                                X, Y: Longint );
  455. Begin
  456.   if not MouseCapture then
  457.     exit;
  458.   MouseCapture:= false;
  459. End;
  460.  
  461. // --------------------------------
  462. // Value bar
  463.  
  464. Procedure TValueBar.SetupComponent;
  465. Begin
  466.   Inherited SetupComponent;
  467.   FMarginWidth:= 5;
  468.   Width:= 100;
  469.   Height:= 100;
  470.   Name:= 'ValueBar';
  471.   ParentColor:= True;
  472.   Exclude(ComponentState, csAcceptsControls);
  473.   FDither:= false;
  474.   FCursorHeight:= 10;
  475. End;
  476.  
  477. Procedure TValueBar.SetupShow;
  478. Begin
  479.   Inherited SetupShow;
  480. End;
  481.  
  482. Destructor TValueBar.Destroy;
  483. Begin
  484.   Inherited Destroy;
  485. End;
  486.  
  487. Procedure TValueBar.DrawLine( Y: longint );
  488. var
  489.  DrawVal: real;
  490.  c: tcolor;
  491.  r: TRect;
  492. begin
  493.   DrawVal:= ValueFromY( Y );
  494.  
  495.   C:= HSVToRGB( FHue, FSaturation, DrawVal );
  496.  
  497.   if FDither then
  498.   begin
  499.     // draw using fillrect, which will dither
  500.     r.left:= FMarginWidth;
  501.     r.bottom:= Y;
  502.     r.Right:= Width-FMarginWidth;
  503.     r.top:= Y;
  504.  
  505.     Canvas.FillRect( r, C );
  506.   end
  507.   else
  508.   begin
  509.     // draw using line, which will not dither
  510.     Canvas.Pen.Color:= C;
  511.     Canvas.Line( FMarginWidth, Y ,
  512.                  Width-FMarginWidth-1, Y );
  513.   end;
  514. end;
  515.  
  516. Procedure TValueBar.ReDraw( const rec: Trect );
  517. Var
  518.  y : longint;
  519.  r: TRect;
  520. Begin
  521.   Canvas.ClipRect:= rec;
  522.   if Designed then
  523.   begin
  524.     // when designing just drwa
  525.     // a rectangle to indicate
  526.     Canvas.FillRect( rec, Color );
  527.     Canvas.Pen.Style:= psDash;
  528.     r.Left:= 0;
  529.     r.Right:= Width - 1;
  530.     r.Bottom:= 0;
  531.     r.Top:= Height - 1;
  532.     Canvas.Rectangle( r );
  533.     if ( Width < MarginWidth * 2 ) or
  534.        ( Height < MarginWidth * 2 ) then
  535.       exit;
  536.     r.left:= FMarginWidth;
  537.     r.top:= Height - FMarginWidth - 1;
  538.     r.right:= Width - FMarginWidth;
  539.     r.bottom:= FMarginWidth;
  540.     Canvas.Rectangle( r );
  541.     exit;
  542.   end;
  543.  
  544.   // Draw margins
  545.   r.left:=0;
  546.   r.bottom:=0;
  547.   r.right:= FMarginWidth-1;
  548.   r.top:= Height-1;
  549.   Canvas.FillRect( r, Color ); // left
  550.   r.left:= Width-FMarginWidth;
  551.   r.right:= Width-1;
  552.   Canvas.FillRect( r, Color ); // right
  553.  
  554.   r.left:= FMarginWidth;
  555.   r.right:=Width-FMarginWidth - 1;
  556.   r.bottom:= Height - FMarginWidth;
  557.   r.top:= Height - 1;
  558.   Canvas.FillRect( r, Color ); // top
  559.   r.bottom:= 0;
  560.   r.top:= FMarginWidth - 1;
  561.   Canvas.FillRect( r, Color ); // bottom
  562.  
  563.   if ( Width < MarginWidth * 2 ) or
  564.      ( Height < MarginWidth * 2 ) then
  565.     exit;
  566.  
  567.   for Y:=0 to DrawHeight - 1 do
  568.     DrawLine( Y + FMarginWidth );
  569.  
  570.   FCursorDrawn:= false;
  571.   DrawCursor;
  572.   Canvas.DeleteClipRegion;
  573. End;
  574.  
  575. Procedure TValueBar.SetHS( Hue: longint; Sat: real );
  576. Begin
  577.   FHue:= Hue;
  578.   FSaturation:= Sat;
  579.   Invalidate;
  580.   Change;
  581. End;
  582.  
  583. Procedure TValueBar.SetValue( Value: real );
  584. Begin
  585.   FValue:= Value;
  586.   Change;
  587. End;
  588.  
  589. Function TValueBar.DrawWidth: longint;
  590. Begin
  591.   Result:= Width - FMarginWidth*2;
  592. End;
  593.  
  594. Function TValueBar.DrawHeight: longint;
  595. Begin
  596.   Result:= Height - FMarginWidth*2;
  597. End;
  598.  
  599. Procedure TValueBar.DrawCursor;
  600. Var
  601.   Y: longint;
  602.   OldMode: TPenMode;
  603.   r: TRect;
  604. Begin
  605.   if Handle = 0 then
  606.     exit;
  607.   if ( Width < MarginWidth * 2 ) or
  608.      ( Height < MarginWidth * 2 ) then
  609.     exit;
  610.  
  611.   if FCursorDrawn then
  612.   begin
  613.     // erase
  614.     // redraw margins
  615.     r.left:= 0;
  616.     r.right:= FMarginWidth - 1;
  617.     r.top:= FOldCursorY + FCursorHeight div 2;
  618.     r.bottom:= FOldCursorY - FCursorHeight div 2;
  619.     Canvas.FillRect( r, Color ); // left
  620.     r.left:= Width - FMarginWidth;
  621.     r.right:= Width - 1;
  622.     Canvas.FillRect( r, Color ); // left
  623.     for Y:= r.bottom to r.top do
  624.       if ( Y < FMarginWidth ) or ( Y >= ( Height - FMarginWidth ) ) then
  625.       begin
  626.         // top/ bottom margin
  627.         Canvas.Pen.Color:= Color;
  628.         Canvas.Line( FMarginWidth, Y, Width - FMarginWidth - 1, Y );
  629.       end
  630.       else
  631.         DrawLine( Y );
  632.   end;
  633.  
  634.   Y:= FValue * ( DrawHeight-1 ) + FMarginWidth ;
  635.  
  636.   r.left:= FMarginWidth;
  637.   r.right:= Width - FMarginWidth - 1;
  638.   r.top:= Y + FCursorHeight div 2;
  639.   r.bottom:= Y - FCursorHeight div 2;
  640.   Canvas.FillRect( r, GetSelectedColor );
  641.   Canvas.Pen.Color:= clBlack;
  642.   Canvas.ShadowedBorder( r, clBtnHighlight, clBtnShadow );
  643.  
  644.   FOldCursorY:= Y;
  645.   FCursorDrawn:= true;
  646. //  Canvas.Pen.Mode:= OldMode;
  647. End;
  648.  
  649. Procedure TValueBar.Resize;
  650. Begin
  651.   if Handle = 0 then
  652.     exit;
  653.   Invalidate;
  654. End;
  655.  
  656. Procedure TValueBar.SetMarginWidth( NewWidth: longint );
  657. Begin
  658.   if MarginWidth<0 then
  659.     MarginWidth:= 0;
  660.   FMarginWidth:= NewWidth;
  661.   Invalidate;
  662. End;
  663.  
  664. Procedure TValueBar.SetDither( Dither: boolean );
  665. Begin
  666.   FDither:= Dither;
  667.   Invalidate;
  668. End;
  669.  
  670. Procedure TValueBar.SetCursorHeight( CursorHeight: longint );
  671. begin
  672.   if CursorHeight < 3 then
  673.     CursorHeight:= 3;
  674.   FCursorHeight:= CursorHeight;
  675.   Invalidate;
  676. end;
  677.  
  678. Function TValueBar.GetSelectedColor: TColor;
  679. Begin
  680.   Result:= HSVToRGB( FHue, FSaturation, FValue );
  681.   if not FDither then
  682.     Result:= GpiQueryNearestColor( Screen.Canvas.Handle,
  683.                                    0,
  684.                                    Result );
  685. End;
  686.  
  687. Function TValueBar.ValueFromY( Y: longint ): real;
  688. begin
  689.   Result:= ( Y-MarginWidth )/( DrawHeight-1 );
  690.   if Result<0 then
  691.     Result:= 0;
  692.   if Result>1.0 then
  693.     Result:= 1.0;
  694.  
  695. end;
  696.  
  697. Procedure TValueBar.MouseDown( Button: TMouseButton;
  698.                                ShiftState: TShiftState;
  699.                                X, Y: Longint );
  700. Begin
  701.   FValue:= ValueFromY( Y );
  702.   Change;
  703.   MouseCapture:= True;
  704. End;
  705.  
  706. Procedure TValueBar.MouseMove( ShiftState: TShiftState;
  707.                                  X, Y: Longint );
  708. Begin
  709.   if not MouseCapture then
  710.     exit;
  711.   FValue:= ValueFromY( Y );
  712.   Change;
  713. End;
  714.  
  715. Procedure TValueBar.MouseUp( Button: TMouseButton;
  716.                                ShiftState: TShiftState;
  717.                                X, Y: Longint );
  718. Begin
  719.   if not MouseCapture then
  720.     exit;
  721.   MouseCapture:= false;
  722. End;
  723.  
  724. Procedure TValueBar.Change;
  725. begin
  726.   DrawCursor;
  727.   if FOnChange <> nil then
  728.     FOnChange( self );
  729. end;
  730.  
  731. Initialization
  732.   {Register classes}
  733.   RegisterClasses([TColorWheel, TValueBar]);
  734. End.
  735.  
  736.