www.pudn.com > TMSSkinFactoryv1.27.zip > VsSlider.pas


{***************************************************************************} 
{ TMS Skin Factory                                                          } 
{ for Delphi 4.0,5.0,6.0 & C++Builder 4.0,5.0                               } 
{                                                                           } 
{ Copyright 1996 - 2002 by TMS Software                                     } 
{ Email : info@tmssoftware.com                                              } 
{ Web : http://www.tmssoftware.com                                          } 
{                                                                           } 
{ The source code is given as is. The author is not responsible             } 
{ for any possible damage done due to the use of this code.                 } 
{ The component can be freely used in any application. The complete         } 
{ source code remains property of the author and may not be distributed,    } 
{ published, given or sold in any form as such. No parts of the source      } 
{ code can be included in any other component or application without        } 
{ written authorization of the author.                                      } 
{***************************************************************************} 
 
unit VsSlider; 
 
{$I VSLIB.INC} 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  VsClasses, VsControls, VsGraphics, VsSkin, VsSysUtils; 
 
type 
  TVsSliderDirection = (sdHorz, sdVert); 
  TVsSlider = class(TVsSkinGraphicControl) 
  private 
    FThumbRect: TRect; 
    FMinValue: Integer; 
    FMaxValue: Integer; 
    FPosition: Integer; 
    FDragging: Boolean; 
    FDirection: TVsSliderDirection; 
    FHit: Integer; 
    FGraphic: TVsGraphic; 
    FGraphicName: TVsGraphicName; 
    FMaskColor: TColor; 
    FClipRect: TVsClipRect; 
    FOnChange: TNotifyEvent; 
    procedure SetMinValue(Value: Integer); 
    procedure SetMaxValue(Value: Integer); 
    procedure SetPosition(Value: Integer); 
    procedure SetDirection(Value: TVsSliderDirection); 
    procedure SetGraphicName(Value: TVsGraphicName); 
    procedure SetMaskColor(Value: TColor); 
    procedure SetClipRect(Value: TVsClipRect); 
    procedure ClipRectChanged(Sender: TObject); 
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED; 
  protected 
    procedure Paint; override; 
    procedure Loaded; override; 
    function GlyphIndex: Integer; 
    procedure UpdateGraphic(Clip: Boolean); override; 
    procedure SetThumbTop(ATop: Integer); 
    procedure SetThumbLeft(ALeft: Integer); 
    procedure CenterThumb; 
    function ViewWidth: Integer; 
    function GetOffsetByValue(Value: Integer): Integer; 
    function GetValueByOffset(Offset: Integer): Integer; 
    function GetMinIndent(Rect: TRect): Integer; 
    procedure SetThumbOffset(Value: Integer); 
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; 
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; 
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; 
    procedure Changed; 
  public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    procedure GetGraphicBitmap(Bitmap: TBitmap); override; 
    function ThumbWidth: Integer; 
    function ThumbHeight: Integer; 
    procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override; 
    procedure ReadConfig(IniFile: TVsIni); override; 
    procedure WriteConfig(IniFile: TVsIni); override; 
  published 
    property GraphicName: TVsGraphicName read FGraphicName write SetGraphicName; 
    property ClipRect: TVsClipRect read FClipRect write SetClipRect; 
    property MaxValue: Integer read FMaxValue write SetMaxValue; 
    property MinValue: Integer read FMinValue write SetMinValue; 
    property Position: Integer read FPosition write SetPosition; 
    property Direction: TVsSliderDirection read FDirection write SetDirection; 
    property MaskColor: TColor read FMaskColor write SetMaskColor; 
    property OnChange: TNotifyEvent read FOnChange write FOnChange; 
    property Anchors; 
    property Constraints; 
    property DragCursor; 
    property DragKind; 
    property DragMode; 
    property Enabled; 
    property Font; 
    property Hint; 
    property ParentFont; 
    property ParentShowHint; 
    property PopupMenu; 
    property ShowHint; 
    property Visible; 
    property OnClick; 
{$IFDEF VER130} 
    property OnContextPopup; 
{$ENDIF} 
    property OnDragDrop; 
    property OnDragOver; 
    property OnEndDock; 
    property OnEndDrag; 
    property OnMouseDown; 
    property OnMouseMove; 
    property OnMouseUp; 
    property OnStartDock; 
    property OnStartDrag; 
  end; 
 
 
implementation 
 
const 
  Glyphs = 2; 
  EnabledThumb = 0; 
  DisabledThumb = 1; 
 
{ TVsSlider } 
 
constructor TVsSlider.Create(AOwner: TComponent); 
begin 
  inherited Create(AOwner); 
  ControlStyle := ControlStyle + [csReplicatable]; 
  SetBounds(0, 0, 150, 20); 
  FMinValue := 0; 
  FMaxValue := 100; 
  FPosition := 0; 
  FDirection := sdHorz; 
  FMaskColor := clNone; 
  FClipRect := TVsClipRect.Create; 
  FClipRect.OnChange := ClipRectChanged; 
end; 
 
destructor TVsSlider.Destroy; 
begin 
  FClipRect.Free; 
  inherited Destroy; 
end; 
 
procedure TVsSlider.Loaded; 
begin 
  inherited Loaded; 
end; 
 
procedure TVsSlider.GetGraphicBitmap(Bitmap: TBitmap); 
begin 
  inherited; 
  if (FGraphic <> nil) then 
    Bitmap.Assign(FGraphic.Bitmap); 
end; 
 
procedure TVsSlider.SetThumbLeft(ALeft: Integer); 
begin 
  FThumbRect := Bounds(ALeft, FThumbRect.Top, ThumbWidth, ThumbHeight); 
end; 
 
procedure TVsSlider.SetThumbTop(ATop: Integer); 
begin 
  FThumbRect := Bounds(FThumbRect.Left, ATop, ThumbWidth, ThumbHeight); 
end; 
 
procedure TVsSlider.CenterThumb; 
begin 
  if Direction = sdVert then 
    SetThumbLeft((Width - ThumbWidth) div 2) 
  else SetThumbTop((Height - ThumbHeight) div 2); 
end; 
 
procedure TVsSlider.SetBounds(ALeft, ATop, AWidth, AHeight: Integer); 
begin 
  inherited SetBounds(ALeft, ATop, AWidth, AHeight); 
  CenterThumb; 
  RepaintControl; 
end; 
 
function TVsSlider.ThumbWidth: Integer; 
begin 
  Result := 0; 
  if FClipRect <> nil then 
    Result := FClipRect.Width div Glyphs; 
end; 
 
function TVsSlider.ThumbHeight: Integer; 
begin 
  Result := 0; 
  if FClipRect <> nil then 
    Result := FClipRect.Height; 
end; 
 
function TVsSlider.GlyphIndex: Integer; 
begin 
  Result := Ord(not Enabled); 
end; 
 
procedure TVsSlider.SetClipRect(Value: TVsClipRect); 
begin 
  FClipRect.Assign(Value); 
end; 
 
procedure TVsSlider.ClipRectChanged(Sender: TObject); 
begin 
  RepaintControl; 
end; 
 
procedure TVsSlider.UpdateGraphic(Clip: Boolean); 
begin 
  FGraphic := Skin.GetGraphic(FGraphicName); 
  if (FGraphic <> nil) and Clip then 
    FClipRect.BoundsRect := Bounds(0, 0, Gw(FGraphic), Gh(FGraphic)); 
  CenterThumb; 
end; 
 
procedure TVsSlider.Paint; 
var 
  Value: Integer; 
  W, H: Integer; 
  S: TRect; 
begin 
  PaintBackImage; 
 
  Value := GetOffsetByValue(Position); 
  if Direction = sdVert then 
  SetThumbTop(Value) else SetThumbLeft(Value); 
 
  if FGraphic <> nil then 
  begin 
    H := ClipRect.Height; 
    W := ClipRect.Width div Glyphs; 
    S := Bounds(ClipRect.Left + (GlyphIndex * W), ClipRect.Top, W, H); 
    SetBrushStyle(BitmapCanvas.Brush, MaskColor); 
    BitmapCanvas.BrushCopy(FThumbRect, FGraphic.Bitmap, S, MaskColor); 
  end; 
  inherited Paint; 
end; 
 
procedure TVsSlider.Changed; 
begin 
  if Assigned(FOnChange) then 
    FOnChange(Self); 
end; 
 
procedure TVsSlider.SetMinValue(Value: Integer); 
begin 
  if (Value <> FMinValue) and (Value < FMaxValue) then 
  begin 
    FMinValue := Value; 
    if FPosition < Value then Position := Value 
    else RepaintControl; 
  end; 
end; 
 
procedure TVsSlider.SetMaxValue(Value: Integer); 
begin 
  if (Value <> FMaxValue) and (Value > FMinValue) then 
  begin 
    FMaxValue := Value; 
    if FPosition > Value then Position := Value 
    else RepaintControl; 
  end; 
end; 
 
procedure TVsSlider.SetPosition(Value: Integer); 
begin 
  if Value < FMinValue then Value := FMinValue; 
  if Value > FMaxValue then Value := FMaxValue; 
  if FPosition <> Value then 
  begin 
    FPosition := Value; 
    RepaintControl; 
    Changed; 
  end; 
end; 
 
procedure TVsSlider.SetDirection(Value: TVsSliderDirection); 
begin 
  if FDirection <> Value then 
  begin 
    FDirection := Value; 
    CenterThumb; 
    RepaintControl; 
  end; 
end; 
 
procedure TVsSlider.SetGraphicName(Value: TVsGraphicName); 
begin 
  if FGraphicName <> Value then 
  begin 
    FGraphicName := Value; 
    UpdateGraphic(True); 
  end; 
end; 
 
procedure TVsSlider.SetMaskColor(Value: TColor); 
begin 
  if FMaskColor <> Value then 
  begin 
    FMaskColor := Value; 
    RepaintControl; 
  end; 
end; 
 
function TVsSlider.GetMinIndent(Rect: TRect): Integer; 
begin 
  if Direction = sdVert then 
    Result := IMax(0, Rect.Top) 
  else 
    Result := IMax(0, Rect.Left); 
end; 
 
function TVsSlider.ViewWidth: Integer; 
var 
  R: TRect; 
begin 
  R := ClientRect; 
  if Direction = sdVert then 
  Result := HeightOf(R) - ThumbHeight 
  else Result := WidthOf(R) - ThumbWidth; 
end; 
 
function TVsSlider.GetOffsetByValue(Value: Integer): Integer; 
var 
  Range: Double; 
  R: TRect; 
  MinIndent: Integer; 
begin 
  R := ClientRect; 
  MinIndent := GetMinIndent(R); 
  Range := MaxValue - MinValue; 
  Result := Round((Value - MinValue) / Range * ViewWidth) + MinIndent; 
  if (Direction = sdVert) then 
    Result := R.Top + R.Bottom - Result - ThumbHeight; 
end; 
 
function TVsSlider.GetValueByOffset(Offset: Integer): Integer; 
var 
  R: TRect; 
  Range: Double; 
  MinIndent: Integer; 
begin 
  R := ClientRect; 
  MinIndent := GetMinIndent(R); 
  if Direction = sdVert then 
    Offset := ClientHeight - Offset - ThumbHeight; 
  Range := FMaxValue - FMinValue; 
  Result := Round((Offset - MinIndent) * Range / ViewWidth); 
  Result := IMin(FMinValue + IMax(Result, 0), FMaxValue); 
end; 
 
procedure TVsSlider.SetThumbOffset(Value: Integer); 
var 
  R: TRect; 
  MinIndent: Integer; 
begin 
  R := ClientRect; 
  MinIndent := GetMinIndent(R); 
  Value := IMin(IMax(Value, MinIndent), MinIndent + ViewWidth); 
  Position := GetValueByOffset(Value) 
end; 
 
procedure TVsSlider.CMEnabledChanged(var Message: TMessage); 
begin 
  RepaintControl; 
  inherited; 
end; 
 
procedure TVsSlider.MouseDown(Button: TMouseButton; Shift: TShiftState; 
  X, Y: Integer); 
var 
  P: TPoint; 
begin 
  inherited MouseDown(Button, Shift, X, Y); 
  if (Button = mbLeft) and (Enabled) then 
  begin 
    P := Point(X, Y); 
    if PtInRect(FThumbRect, P) then 
    begin 
      FDragging := True; 
      if Direction = sdHorz then FHit := X - FThumbRect.Left 
      else FHit := Y - FThumbRect.Top; 
    end else 
    begin 
      if Direction = sdHorz then 
        FHit := X - ThumbWidth div 2 
      else FHit := Y - ThumbHeight div 2; 
      SetThumbOffset(FHit); 
    end; 
  end; 
end; 
 
procedure TVsSlider.MouseMove(Shift: TShiftState; X, Y: Integer); 
begin 
  if FDragging then 
  begin 
    if FDirection = sdVert then 
      SetThumbOffset(Y - FHit) 
    else 
      SetThumbOffset(X - FHit); 
  end; 
  inherited MouseMove(Shift, X, Y); 
end; 
 
procedure TVsSlider.MouseUp(Button: TMouseButton; Shift: TShiftState; 
  X, Y: Integer); 
begin 
  if FDragging then 
  begin 
    FDragging := false; 
    RepaintControl; 
  end; 
  inherited MouseUp(Button, Shift, X, Y); 
end; 
 
procedure TVsSlider.ReadConfig(IniFile: TVsIni); 
begin 
  ClipRect.BoundsRect := IniFile.ReadRect(Self.Name, 'ClipRect', EmptyRect); 
  MaskColor := IniFile.ReadColor(Self.Name, 'MaskColor', clNone); 
  Direction := TVsSliderDirection(IniFile.ReadInteger(Self.Name, 'Direction', 0)); 
  inherited; 
end; 
 
procedure TVsSlider.WriteConfig(IniFile: TVsIni); 
begin 
  inherited; 
  IniFile.WriteRect(Self.Name, 'ClipRect', ClipRect.BoundsRect); 
  IniFile.WriteColor(Self.Name, 'MaskColor', MaskColor); 
  IniFile.WriteInteger(Self.Name, 'Direction', Ord(Direction)); 
end; 
 
 
 
end.