VrSwitch.pas
上传用户:hbszzs
上传日期:2008-08-20
资源大小:628k
文件大小:19k
- {*****************************************************}
- { }
- { Varian Component Workshop }
- { }
- { Varian Software NL (c) 1996-2000 }
- { All Rights Reserved }
- { }
- {*****************************************************}
- unit VrSwitch;
- {$I VRLIB.INC}
- interface
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- VrConst, VrTypes, VrClasses, VrControls, VrSysUtils, VrSystem;
- type
- TVrSwitchOption = (soActiveClick, soMouseClip, soHandPoint, soThumbOpaque);
- TVrSwitchOptions = set of TVrSwitchOption;
- TVrSwitch = class(TVrCustomImageControl)
- private
- FOffset: Integer;
- FPositions: Integer;
- FOrientation: TVrOrientation;
- FBevel: TVrBevel;
- FStyle: TVrProgressStyle;
- FOptions: TVrSwitchOptions;
- FBorderColor: TColor;
- FBorderWidth: Integer;
- FFocusColor: TColor;
- FBackImageIndex: Integer;
- FThumbImageIndex: Integer;
- FBitmapList: TVrBitmapList;
- FBitmapListLink: TVrChangeLink;
- FOnChange: TNotifyEvent;
- FHit: Integer;
- FFocused: Boolean;
- FClipOn: Boolean;
- FThumbRect: TRect;
- FThumbWidth: Integer;
- FThumbHeight: Integer;
- FThumbImage: TBitmap;
- FThumbStates: TVrNumGlyphs;
- FThumbIndent: Integer;
- FThumbDown: Boolean;
- FThumbHasMouse: Boolean;
- procedure SetThumbStates(Value: TVrNumGlyphs);
- procedure SetThumbIndent(Value: Integer);
- procedure SetOrientation(Value: TVrOrientation);
- procedure SetOffset(Value: Integer);
- procedure SetPositions(Value: Integer);
- procedure SetStyle(Value: TVrProgressStyle);
- procedure SetOptions(Value: TVrSwitchOptions);
- procedure SetBorderColor(Value: TColor);
- procedure SetBorderWidth(Value: Integer);
- procedure SetFocusColor(Value: TColor);
- procedure SetBevel(Value: TVrBevel);
- procedure SetBackImageIndex(Value: Integer);
- procedure SetThumbImageIndex(Value: Integer);
- procedure SetBitmapList(Value: TVrBitmapList);
- procedure BevelChanged(Sender: TObject);
- procedure BitmapListChanged(Sender: TObject);
- procedure AdjustControlSize;
- procedure WMSize(var Message: TWMSize); message WM_SIZE;
- procedure WMSetCursor(var Message: TWMSetCursor); message WM_SETCURSOR;
- procedure WMGetDlgCode(var Msg: TWMGetDlgCode); message WM_GETDLGCODE;
- procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
- procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
- protected
- procedure SetThumbTop(ATop: Integer);
- procedure SetThumbLeft(ALeft: Integer);
- procedure CenterThumb;
- procedure Paint; override;
- procedure PaintThumb;
- procedure Notification(AComponent: TComponent; Operation: TOperation); override;
- procedure CreateParams(var Params: TCreateParams); override;
- procedure GetThumbImage;
- procedure Change; dynamic;
- function GetBitmap(Index: Integer): TBitmap;
- function GetViewWidth: Integer;
- function GetOffsetByValue(Value: Integer): Integer;
- function GetValueByOffset(Offset: Integer): Integer;
- function GetSliderRect: TRect;
- 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 KeyDown(var Key: Word; Shift: TShiftState); override;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- published
- property Positions: Integer read FPositions write SetPositions default 4;
- property Offset: Integer read FOffset write SetOffset default 0;
- property Orientation: TVrOrientation read FOrientation write SetOrientation default voVertical;
- property BackImageIndex: Integer read FBackImageIndex write SetBackImageIndex default -1;
- property ThumbImageIndex: Integer read FThumbImageIndex write SetThumbImageIndex default -1;
- property BitmapList: TVrBitmapList read FBitmapList write SetBitmapList;
- property ThumbStates: TVrNumGlyphs read FThumbStates write SetThumbStates default 1;
- property ThumbIndent: Integer read FThumbIndent write SetThumbIndent default 1;
- property Style: TVrProgressStyle read FStyle write SetStyle default psBottomLeft;
- property Bevel: TVrBevel read FBevel write SetBevel;
- property Options: TVrSwitchOptions read FOptions write SetOptions
- default [soActiveClick, soMouseClip, soHandPoint, soThumbOpaque];
- property BorderColor: TColor read FBorderColor write SetBorderColor default clBtnFace;
- property BorderWidth: Integer read FBorderWidth write SetBorderWidth default 1;
- property FocusColor: TColor read FFocusColor write SetFocusColor default clBlue;
- property OnChange: TNotifyEvent read FOnChange write FOnChange;
- {$IFDEF VER110}
- property Anchors;
- property Constraints;
- {$ENDIF}
- property Color default clBlack;
- property ParentColor default false;
- property DragCursor;
- {$IFDEF VER110}
- property DragKind;
- {$ENDIF}
- property DragMode;
- property Enabled;
- property ParentShowHint;
- property PopupMenu;
- property ShowHint;
- property TabOrder;
- property TabStop default False;
- property Visible;
- property OnClick;
- {$IFDEF VER130}
- property OnContextPopup;
- {$ENDIF}
- property OnKeyDown;
- property OnKeyPress;
- property OnKeyUp;
- property OnDragDrop;
- property OnDragOver;
- {$IFDEF VER110}
- property OnEndDock;
- {$ENDIF}
- property OnEndDrag;
- property OnEnter;
- property OnExit;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- {$IFDEF VER110}
- property OnStartDock;
- {$ENDIF}
- property OnStartDrag;
- end;
- implementation
- {$R VRSWITCH.D32}
- const
- ThumbNames: array[0..1] of PChar =
- ('VRSWITCHTHUMB_VERT', 'VRSWITCHTHUMB_HORI');
- { TVrSwitch }
- constructor TVrSwitch.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- ControlStyle := ControlStyle + [csOpaque] - [csSetCaption];
- Width := 29;
- Height := 60;
- Tabstop := False;
- Color := clBlack;
- ParentColor := false;
- FPositions := 4;
- FOffset := 0;
- FOrientation := voVertical;
- FOptions := [soActiveClick, soMouseClip, soHandPoint, soThumbOpaque];
- FStyle := psBottomLeft;
- FBorderColor := clBtnFace;
- FBorderWidth := 1;
- FFocusColor := clBlue;
- FBevel := TVrBevel.Create;
- with FBevel do
- begin
- InnerSpace := 0;
- OuterOutline := osNone;
- OnChange := BevelChanged;
- end;
- FBackImageIndex := -1;
- FThumbImageIndex := -1;
- FBitmapListLink := TVrChangeLink.Create;
- FBitmapListLink.OnChange := BitmapListChanged;
- FThumbStates := 1;
- FThumbIndent := 1;
- FThumbImage := TBitmap.Create;
- GetThumbImage;
- end;
- destructor TVrSwitch.Destroy;
- begin
- FThumbImage.Free;
- FBevel.Free;
- FBitmapListLink.Free;
- inherited Destroy;
- end;
- procedure TVrSwitch.CreateParams(var Params: TCreateParams);
- begin
- inherited CreateParams(Params);
- with Params do
- WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
- end;
- procedure TVrSwitch.GetThumbImage;
- begin
- FThumbImage.Assign(GetBitmap(FThumbImageIndex));
- if FThumbImage.Empty then
- begin
- if Orientation = voVertical then
- FThumbImage.LoadFromResourceName(hInstance, ThumbNames[0])
- else FThumbImage.LoadFromResourceName(hInstance, ThumbNames[1]);
- end;
- FThumbHeight := FThumbImage.Height;
- FThumbWidth := FThumbImage.Width div ThumbStates;
- AdjustControlSize;
- CenterThumb;
- end;
- procedure TVrSwitch.SetThumbLeft(ALeft: Integer);
- begin
- FThumbRect := Bounds(ALeft, FThumbRect.Top, FThumbWidth, FThumbHeight);
- end;
- procedure TVrSwitch.SetThumbTop(ATop: Integer);
- begin
- FThumbRect := Bounds(FThumbRect.Left, ATop, FThumbWidth, FThumbHeight);
- end;
- procedure TVrSwitch.CenterThumb;
- begin
- if Orientation = voVertical then
- SetThumbLeft((Width - FThumbWidth) div 2)
- else SetThumbTop((Height - FThumbHeight) div 2);
- end;
- function TVrSwitch.GetSliderRect: TRect;
- begin
- Result := ClientRect;
- InflateRect(Result, -BorderWidth - ThumbIndent, -BorderWidth - ThumbIndent);
- end;
- function TVrSwitch.GetMinIndent(Rect: TRect): Integer;
- begin
- if Orientation = voVertical then
- Result := MaxIntVal(0, Rect.Top)
- else
- Result := MaxIntVal(0, Rect.Left);
- end;
- function TVrSwitch.GetViewWidth: Integer;
- var
- R: TRect;
- begin
- R := GetSliderRect;
- if Orientation = voVertical then
- Result := HeightOf(R) - FThumbHeight
- else Result := WidthOf(R) - FThumbWidth;
- end;
- function TVrSwitch.GetOffsetByValue(Value: Integer): Integer;
- var
- Range: Double;
- R: TRect;
- MinIndent: Integer;
- begin
- R := GetSliderRect;
- MinIndent := GetMinIndent(R);
- Range := Positions - 1;
- Result := Round(Value / Range * GetViewWidth) + MinIndent;
- if (FOrientation = voVertical) and (FStyle = psBottomLeft) then
- Result := R.Top + R.Bottom - Result - FThumbHeight
- else
- if (FOrientation = voHorizontal) and (FStyle = psTopRight) then
- Result := R.Left + R.Right - Result - FThumbWidth;
- end;
- function TVrSwitch.GetValueByOffset(Offset: Integer): Integer;
- var
- R: TRect;
- Range: Double;
- MinIndent: Integer;
- begin
- R := GetSliderRect;
- MinIndent := GetMinIndent(R);
- if Orientation = voVertical then
- Offset := ClientHeight - Offset - FThumbHeight;
- Range := Positions - 1;
- Result := Round((Offset - MinIndent) * Range / GetViewWidth);
- Result := MinIntVal(MaxIntVal(Result, 0), Positions - 1);
- end;
- procedure TVrSwitch.SetThumbOffset(Value: Integer);
- var
- R: TRect;
- MinIndent: Integer;
- begin
- R := GetSliderRect;
- MinIndent := GetMinIndent(R);
- Value := MinIntVal(MaxIntVal(Value, MinIndent),
- MinIndent + GetViewWidth);
- if FStyle = psBottomLeft then Offset := GetValueByOffset(Value)
- else Offset := Pred(Positions) - GetValueByOffset(Value);
- end;
- procedure TVrSwitch.BitmapListChanged(Sender: TObject);
- begin
- GetThumbImage;
- UpdateControlCanvas;
- end;
- procedure TVrSwitch.BevelChanged(Sender: TObject);
- begin
- UpdateControlCanvas;
- end;
- procedure TVrSwitch.Paint;
- var
- R: TRect;
- aGlyph: TBitmap;
- Value: Integer;
- CurrentColor: TColor;
- begin
- ClearBitmapCanvas;
- R := ClientRect;
- if BorderWidth > 0 then
- begin
- if FFocused then CurrentColor := FFocusColor
- else CurrentColor := FBorderColor;
- DrawFrame3D(BitmapCanvas, R,
- CurrentColor, CurrentColor, BorderWidth);
- end;
- FBevel.Paint(BitmapCanvas, R);
- aGlyph := GetBitmap(BackImageIndex);
- if aGlyph <> nil then BitmapCanvas.StretchDraw(R, aGlyph);
- Value := GetOffsetByValue(Offset);
- if Orientation = voVertical then
- SetThumbTop(Value) else SetThumbLeft(Value);
- PaintThumb;
- inherited Paint;
- end;
- procedure TVrSwitch.PaintThumb;
- var
- Index: Integer;
- SrcRect: TRect;
- TransColor: TColor;
- begin
- Index := 0;
- if not Enabled then Index := 1;
- if FThumbDown then Index := 2;
- if (FThumbHasMouse) and (not FThumbDown) then Index := 3;
- if Index > ThumbStates - 1 then Index := 0;
- SrcRect := Bounds(Index * FThumbWidth, 0, FThumbWidth, FThumbHeight);
- with BitmapCanvas do
- begin
- TransColor := FThumbImage.TransparentColor;
- Brush.Color := TransColor;
- if soThumbOpaque in Options then Brush.Style := bsSolid
- else Brush.Style := bsClear;
- BrushCopy(FThumbRect, FThumbImage, SrcRect, TransColor);
- end;
- end;
- procedure TVrSwitch.AdjustControlSize;
- var
- NewWidth, NewHeight: Integer;
- begin
- if Orientation = voHorizontal then
- begin
- NewWidth := (FThumbWidth * FPositions) + (BorderWidth * 2);
- NewHeight := MaxIntVal(FThumbHeight + FBorderWidth * 2, Height);
- end
- else
- begin
- NewWidth := MaxIntVal(FThumbWidth + FBorderWidth * 2, Width);
- NewHeight := (FThumbHeight * FPositions) + (BorderWidth * 2);
- end;
- BoundsRect := Bounds(Left, Top, NewWidth, NewHeight);
- end;
- procedure TVrSwitch.WMSize(var Message: TWMSize);
- begin
- inherited;
- AdjustControlSize;
- CenterThumb;
- end;
- procedure TVrSwitch.WMSetCursor(var Message: TWMSetCursor);
- var
- P: TPoint;
- begin
- GetCursorPos(P);
- if (not Designing) and PtInRect(FThumbRect, ScreenToClient(P)) then
- begin
- if (soHandPoint in Options) then
- Windows.SetCursor(Screen.Cursors[VrCursorHandPoint]);
- end else inherited;
- end;
- procedure TVrSwitch.WMGetDlgCode(var Msg: TWMGetDlgCode);
- begin
- Msg.Result := DLGC_WANTARROWS;
- end;
- procedure TVrSwitch.CMFocusChanged(var Message: TCMFocusChanged);
- var
- Active: Boolean;
- begin
- with Message do Active := (Sender = Self);
- if Active <> FFocused then
- begin
- FFocused := Active;
- UpdateControlCanvas;
- end;
- inherited;
- end;
- procedure TVrSwitch.CMEnabledChanged(var Message: TMessage);
- begin
- inherited;
- UpdateControlCanvas;
- end;
- procedure TVrSwitch.Notification(AComponent: TComponent;
- Operation: TOperation);
- begin
- inherited Notification(AComponent, Operation);
- if (Operation = opRemove) then
- if AComponent = BitmapList then BitmapList := nil;
- end;
- function TVrSwitch.GetBitmap(Index: Integer): TBitmap;
- begin
- Result := nil;
- if Assigned(FBitmapList) then
- Result := FBitmapList.GetBitmap(Index);
- end;
- procedure TVrSwitch.Change;
- begin
- if Assigned(FOnChange) then FOnChange(Self);
- end;
- procedure TVrSwitch.SetThumbStates(Value: TVrNumGlyphs);
- begin
- if FThumbStates <> Value then
- begin
- FThumbStates := Value;
- if not Loading then
- GetThumbImage;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetThumbIndent(Value: Integer);
- begin
- if (FThumbIndent <> Value) and (Value >= 0) then
- begin
- FThumbIndent := Value;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetBackImageIndex(Value: Integer);
- begin
- if FBackImageIndex <> Value then
- begin
- FBackImageIndex := Value;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetThumbImageIndex(Value: Integer);
- begin
- if FThumbImageIndex <> Value then
- begin
- FThumbImageIndex := Value;
- GetThumbImage;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetBitmapList(Value: TVrBitmapList);
- begin
- if FBitmapList <> nil then
- FBitmapList.RemoveLink(FBitmapListLink);
- FBitmapList := Value;
- if FBitmapList <> nil then
- FBitmapList.InsertLink(FBitmapListLink);
- GetThumbImage;
- UpdateControlCanvas;
- end;
- procedure TVrSwitch.SetOrientation(Value: TVrOrientation);
- begin
- if FOrientation <> Value then
- begin
- FOrientation := Value;
- GetThumbImage;
- if not Loading then
- begin
- BoundsRect := Bounds(Left, Top, Height, Width);
- AdjustControlSize;
- end;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetStyle(Value: TVrProgressStyle);
- begin
- if FStyle <> Value then
- begin
- FStyle := Value;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetOffset(Value: Integer);
- begin
- if Value < 0 then Value := 0;
- if Value > Positions - 1 then Value := Positions - 1;
- if FOffset <> Value then
- begin
- FOffset := Value;
- UpdateControlCanvas;
- Change;
- end;
- end;
- procedure TVrSwitch.SetPositions(Value: Integer);
- begin
- if FPositions <> Value then
- begin
- FPositions := Value;
- AdjustControlSize;
- end;
- end;
- procedure TVrSwitch.SetOptions(Value: TVrSwitchOptions);
- begin
- if FOptions <> Value then
- begin
- FOptions := Value;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetBorderColor(Value: TColor);
- begin
- if FBorderColor <> Value then
- begin
- FBorderColor := Value;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetBorderWidth(Value: Integer);
- begin
- if (FBorderWidth <> Value) and (Value >= 0) then
- begin
- FBorderWidth := Value;
- AdjustControlSize;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetFocusColor(Value: TColor);
- begin
- if FFocusColor <> Value then
- begin
- FFocusColor := Value;
- UpdateControlCanvas;
- end;
- end;
- procedure TVrSwitch.SetBevel(Value: TVrBevel);
- begin
- FBevel.Assign(Value);
- end;
- procedure TVrSwitch.MouseDown(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- var
- R: TRect;
- P: TPoint;
- begin
- inherited MouseDown(Button, Shift, X, Y);
- if (Button = mbLeft) then
- begin
- if TabStop then SetFocus;
- P := Point(X, Y);
- if PtInRect(FThumbRect, P) then
- begin
- FThumbDown := True;
- if Orientation = voHorizontal then FHit := X - FThumbRect.Left
- else FHit := Y - FThumbRect.Top;
- if (soMouseClip in Options) then
- begin
- R := Bounds(ClientOrigin.X, ClientOrigin.Y,
- ClientWidth, ClientHeight);
- ClipCursor(@R);
- FClipOn := True;
- end;
- UpdateControlCanvas;
- end
- else
- if (soActiveClick in Options) then
- begin
- if Orientation = voHorizontal then
- FHit := X - FThumbWidth div 2
- else FHit := Y - FThumbHeight div 2;
- SetThumbOffset(FHit);
- end;
- end;
- end;
- procedure TVrSwitch.MouseMove(Shift: TShiftState; X, Y: Integer);
- var
- OldValue: Boolean;
- begin
- if FThumbDown then
- begin
- if FOrientation = voVertical then
- SetThumbOffset(Y - FHit)
- else
- SetThumbOffset(X - FHit);
- end
- else
- begin
- OldValue := FThumbHasMouse;
- FThumbHasMouse := PtInRect(FThumbRect, Point(X, Y));
- if OldValue <> FThumbHasMouse then UpdateControlCanvas;
- end;
- inherited MouseMove(Shift, X, Y);
- end;
- procedure TVrSwitch.MouseUp(Button: TMouseButton; Shift: TShiftState;
- X, Y: Integer);
- begin
- if FThumbDown then
- begin
- FThumbDown := false;
- UpdateControlCanvas;
- end;
- if FClipOn then
- begin
- ClipCursor(nil);
- FClipOn := false;
- end;
- inherited MouseUp(Button, Shift, X, Y);
- end;
- procedure TVrSwitch.KeyDown(var Key: Word; Shift: TShiftState);
- function Adjust(Value: Integer): Integer;
- begin
- Result := Value;
- if Style = psTopRight then Result := -Result;
- end;
- begin
- if Shift = [] then
- begin
- if Key = VK_HOME then Offset := 0
- else if Key = VK_END then Offset := Positions - 1;
- if Orientation = voHorizontal then
- begin
- if Key = VK_LEFT then Offset := Offset + Adjust(-1)
- else if Key = VK_RIGHT then Offset := Offset + Adjust(1);
- end
- else
- begin
- if Key = VK_UP then Offset := Offset + Adjust(1)
- else if Key = VK_DOWN then Offset := Offset + Adjust(-1);
- end;
- end;
- inherited KeyDown(Key, Shift);
- end;
- end.