📄 tntjvbutton.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvButton.PAS, released on 2001-02-28.
The Initial Developer of the Original Code is Sébastien Buysse [sbuysse att buypin dott com]
Portions created by Sébastien Buysse are Copyright (C) 2001 Sébastien Buysse.
All Rights Reserved.
Contributor(s): Michael Beck [mbeck att bigfoot dott com].
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvButton.pas,v 1.62 2005/08/09 10:15:02 obones Exp $
unit TntJvButton;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
{$IFDEF VisualCLX}
Qt,
{$ENDIF VisualCLX}
Windows, Messages, Classes, Graphics, Controls, Menus, Buttons, TntButtons,
JvComponent, TntJvComponent, JvConsts, JvTypes, JvExStdCtrls, TntJvExStdCtrls, JvButton;
type
(**
TJvButtonMouseState = (bsMouseInside, bsMouseDown);
TJvButtonMouseStates = set of TJvButtonMouseState;
**)
TTntJvCustomGraphicButton = class(TTntJvGraphicControl)
private
FStates: TJvButtonMouseStates;
FBuffer: TBitmap;
FFlat: Boolean;
FDropDownMenu: TPopupMenu;
FDown: Boolean;
FForceSameSize: Boolean;
FAllowAllUp: Boolean;
FGroupIndex: Integer;
FHotTrack: Boolean;
FHotFont: TFont;
FHotTrackFontOptions: TJvTrackFontOptions;
FOnDropDownMenu: TContextPopupEvent;
FDropArrow: Boolean;
FOnDropDownClose: TNotifyEvent;
function GetPattern: TBitmap;
procedure SetFlat(const Value: Boolean);
procedure SetDown(Value: Boolean);
procedure CMButtonPressed(var Msg: TCMButtonPressed); message CM_JVBUTTONPRESSED;
procedure CMForceSize(var Msg: TCMForceSize); message CM_FORCESIZE;
{$IFDEF VCL}
procedure CMSysColorChange(var Msg: TMessage); message CM_SYSCOLORCHANGE;
{$ENDIF VCL}
procedure SetForceSameSize(const Value: Boolean);
procedure SetAllowAllUp(const Value: Boolean);
procedure SetGroupIndex(const Value: Integer);
procedure SetHotFont(const Value: TFont);
procedure SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
procedure SetDropArrow(const Value: Boolean);
procedure SetDropDownMenu(const Value: TPopupMenu);
protected
procedure ButtonPressed(Sender: TTntJvCustomGraphicButton; AGroupIndex: Integer); virtual;
procedure ForceSize(Sender: TControl; AWidth, AHeight: Integer);
function DoDropDownMenu(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean; virtual;
procedure DropDownClose;
procedure UpdateExclusive;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
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 MouseEnter(Control: TControl); override;
procedure MouseLeave(Control: TControl); override;
procedure Paint; override;
procedure PaintButton(Canvas: TCanvas); virtual;
procedure PaintFrame(Canvas: TCanvas); virtual;
function InsideBtn(X, Y: Integer): Boolean; virtual;
function WantKey(Key: Integer; Shift: TShiftState;
const KeyText: WideString): Boolean; override;
procedure EnabledChanged; override;
procedure FontChanged; override;
procedure RepaintBackground; virtual;
procedure TextChanged; override;
property AllowAllUp: Boolean read FAllowAllUp write SetAllowAllUp default False;
property GroupIndex: Integer read FGroupIndex write SetGroupIndex default 0;
property MouseStates: TJvButtonMouseStates read FStates write FStates default [];
property ForceSameSize: Boolean read FForceSameSize write SetForceSameSize default False;
property Pattern: TBitmap read GetPattern;
property Flat: Boolean read FFlat write SetFlat default False;
property HotTrack: Boolean read FHotTrack write FHotTrack default False;
property HotTrackFont: TFont read FHotFont write SetHotFont;
property HotTrackFontOptions: TJvTrackFontOptions read FHotTrackFontOptions write SetHotTrackFontOptions default
DefaultTrackFontOptions;
property Down: Boolean read FDown write SetDown default False;
property DropDownMenu: TPopupMenu read FDropDownMenu write SetDropDownMenu;
property DropArrow: Boolean read FDropArrow write SetDropArrow default False;
property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
property OnDropDownClose: TNotifyEvent read FOnDropDownClose write FOnDropDownClose;
public
procedure Click; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure DrawDropArrow(Canvas: TCanvas; ArrowRect: TRect); virtual;
end;
TTntJvCustomButton = class(TTntJvExButton)
private
FDropDownMenu: TPopupMenu;
FHotTrack: Boolean;
FHotFont: TFont;
FFontSave: TFont;
FWordWrap: Boolean;
FForceSameSize: Boolean;
FHotTrackFontOptions: TJvTrackFontOptions;
FOnDropDownMenu: TContextPopupEvent;
FDropArrow: Boolean;
procedure SetHotFont(const Value: TFont);
procedure SetWordWrap(const Value: Boolean);
procedure SetForceSameSize(const Value: Boolean);
procedure CMForceSize(var Msg: TCMForceSize); message CM_FORCESIZE;
procedure SetHotTrackFontOptions(const Value: TJvTrackFontOptions);
procedure SetDropArrow(const Value: Boolean);
procedure SetDropDownMenu(const Value: TPopupMenu);
protected
function DoDropDownMenu(X, Y: Integer): Boolean; virtual;
procedure ForceSize(Sender: TControl; AWidth, AHeight: Integer);
procedure MouseEnter(Control: TControl); override;
procedure MouseLeave(Control: TControl); override;
procedure FontChanged; override;
{$IFDEF VCL}
procedure CreateParams(var Params: TCreateParams); override;
{$ENDIF VCL}
function GetRealCaption: WideString; dynamic;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
property WordWrap: Boolean read FWordWrap write SetWordWrap default True;
property ForceSameSize: Boolean read FForceSameSize write SetForceSameSize default False;
property DropArrow: Boolean read FDropArrow write SetDropArrow default False;
property DropDownMenu: TPopupMenu read FDropDownMenu write SetDropDownMenu;
property HotTrack: Boolean read FHotTrack write FHotTrack default False;
property HotTrackFont: TFont read FHotFont write SetHotFont;
property HotTrackFontOptions: TJvTrackFontOptions read FHotTrackFontOptions write SetHotTrackFontOptions default
DefaultTrackFontOptions;
property HintColor;
property OnParentColorChange;
property OnDropDownMenu: TContextPopupEvent read FOnDropDownMenu write FOnDropDownMenu;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Click;override;
procedure DrawDropArrow(Canvas: TCanvas; ArrowRect: TRect); virtual;
procedure SetBounds(ALeft: Integer; ATop: Integer; AWidth: Integer; AHeight: Integer); override;
end;
// TJvDropDownButton draws a DropDown button with the DropDown glyph
// (also themed). It ignores the properties Glyph and Flat
TJvDropDownButton = class(TTntSpeedButton)
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvButton.pas,v $';
Revision: '$Revision: 1.62 $';
Date: '$Date: 2005/08/09 10:15:02 $';
LogPath: 'JVCL'run'
);
{$ENDIF UNITVERSIONING}
implementation
uses
SysUtils, Forms,
{$IFDEF COMPILER6_UP}
Types,
{$ENDIF COMPILER6_UP}
JvJVCLUtils, JvThemes, TntSysUtils;
const
JvBtnLineSeparator = '|';
var
GlobalPattern: TBitmap = nil;
function CreateBrushPattern: TBitmap;
var
X, Y: Integer;
begin
if GlobalPattern = nil then
begin
GlobalPattern := TBitmap.Create;
try
GlobalPattern.Width := 8; { must have this size }
GlobalPattern.Height := 8;
with GlobalPattern.Canvas do
begin
Brush.Style := bsSolid;
Brush.Color := clBtnFace;
FillRect(Rect(0, 0, GlobalPattern.Width, GlobalPattern.Height));
for Y := 0 to 7 do
for X := 0 to 7 do
if (Y mod 2) = (X mod 2) then { toggles between even/odd pixels }
Pixels[X, Y] := clWhite; { on even/odd rows }
end;
except
FreeAndNil(GlobalPattern);
end;
end;
Result := GlobalPattern;
end;
//=== { TTntJvCustomGraphicButton } =============================================
constructor TTntJvCustomGraphicButton.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle -
[csOpaque, csDoubleClicks {$IFDEF VisualCLX}, csCaptureMouse {$ENDIF}];
FStates := [];
SetBounds(0, 0, 40, 40);
FBuffer := TBitmap.Create;
FFlat := False;
FDropArrow := False;
FForceSameSize := False;
FHotFont := TFont.Create;
FHotTrackFontOptions := DefaultTrackFontOptions;
end;
destructor TTntJvCustomGraphicButton.Destroy;
begin
FBuffer.Free;
FHotFont.Free;
inherited Destroy;
end;
procedure TTntJvCustomGraphicButton.DrawDropArrow(Canvas: TCanvas; ArrowRect: TRect);
var
I: Integer;
begin
if not Enabled then
Canvas.Pen.Color := clInactiveCaption
else
Canvas.Pen.Color := clWindowText;
for I := 0 to 3 do
begin
if ArrowRect.Left + I <= ArrowRect.Right - I then
begin
Canvas.MoveTo(ArrowRect.Left + I, ArrowRect.Top + I);
Canvas.LineTo(ArrowRect.Right - I, ArrowRect.Top + I);
end;
end;
end;
{ Handle speedkeys (Alt + key) }
function TTntJvCustomGraphicButton.WantKey(Key: Integer; Shift: TShiftState;
const KeyText: WideString): Boolean;
begin
Result := IsAccel(Key, Caption) and Enabled and (Shift * KeyboardShiftStates = [ssAlt]);
if Result then
Click
else
Result := inherited WantKey(Key, Shift, KeyText);
end;
procedure TTntJvCustomGraphicButton.EnabledChanged;
begin
inherited EnabledChanged;
if not Enabled then
FStates := [];
RepaintBackground;
end;
procedure TTntJvCustomGraphicButton.MouseEnter(Control: TControl);
begin
if csDesigning in ComponentState then
Exit;
if Enabled and not MouseOver then
begin
Include(FStates, bsMouseInside);
inherited MouseEnter(Control);
if Flat then
RepaintBackground;
if HotTrack then
Repaint;
end;
end;
procedure TTntJvCustomGraphicButton.MouseLeave(Control: TControl);
begin
if Enabled and MouseOver then
begin
Exclude(FStates, bsMouseInside);
inherited MouseLeave(Control);
if Flat then
RepaintBackground;
if HotTrack then
Repaint;
end;
end;
procedure TTntJvCustomGraphicButton.Paint;
var
ArrowRect: TRect;
begin
// FBuffer.Width := Width;
// FBuffer.Height := Height;
PaintFrame(Canvas);
PaintButton(Canvas);
if DropArrow and Assigned(DropDownMenu) then
begin
ArrowRect := Rect(Width - 16, Height div 2, Width - 9, Height div 2 + 9);
if bsMouseDown in FStates then
OffsetRect(ArrowRect, 1, 1);
DrawDropArrow(Canvas, ArrowRect);
end;
// BitBlt(Canvas.Handle, 0, 0, Width,Height, FBuffer.Canvas.Handle, 0, 0, SRCCOPY);
end;
procedure TTntJvCustomGraphicButton.PaintFrame(Canvas: TCanvas);
begin
// do nothing
end;
procedure TTntJvCustomGraphicButton.PaintButton(Canvas: TCanvas);
begin
if (bsMouseInside in FStates) and HotTrack then
Canvas.Font := FHotFont
else
Canvas.Font := Font;
end;
function TTntJvCustomGraphicButton.InsideBtn(X, Y: Integer): Boolean;
begin
Result := PtInRect(Rect(0, 0, Width, Height), Point(X, Y));
end;
procedure TTntJvCustomGraphicButton.MouseDown(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
Tmp: TPoint;
begin
if not Enabled then
Exit;
inherited MouseDown(Button, Shift, X, Y);
if InsideBtn(X, Y) then
begin
FStates := [bsMouseDown, bsMouseInside];
RepaintBackground;
end;
{$IFDEF VCL}
SetCaptureControl(Self);
{$ENDIF VCL}
Tmp := ClientToScreen(Point(0, Height));
DoDropDownMenu(Button, Shift, Tmp.X, Tmp.Y);
end;
procedure TTntJvCustomGraphicButton.MouseMove(Shift: TShiftState;
X, Y: Integer);
begin
inherited MouseMove(Shift, X, Y);
if MouseCapture then
begin
if not InsideBtn(X, Y) then
begin
if bsMouseInside in FStates then
begin
Exclude(FStates, bsMouseInside);
RepaintBackground;
end;
end
else
begin
if not (bsMouseInside in FStates) then
begin
Include(FStates, bsMouseInside);
RepaintBackground;
end;
end;
end;
end;
procedure TTntJvCustomGraphicButton.MouseUp(Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
{$IFDEF VCL}
if GetCaptureControl = Self then
ReleaseCapture;
{$ENDIF VCL}
if not Enabled then
Exit;
inherited MouseUp(Button, Shift, X, Y);
Exclude(FStates, bsMouseDown);
RepaintBackground;
end;
function TTntJvCustomGraphicButton.DoDropDownMenu(Button: TMouseButton; Shift: TShiftState; X, Y: Integer): Boolean;
var
{$IFDEF VCL}
Msg: TMsg;
{$ENDIF VCL}
Handled: Boolean;
begin
Result := (Button = mbLeft) and (DropDownMenu <> nil);
if Result then
begin
DropDownMenu.PopupComponent := Self;
case DropDownMenu.Alignment of
paRight:
Inc(X, Width);
paCenter:
Inc(X, Width div 2);
end;
Handled := False;
if Assigned(FOnDropDownMenu) then
FOnDropDownMenu(Self, Point(X, Y), Handled);
if not Handled then
DropDownMenu.Popup(X, Y)
else
Exit;
{$IFDEF VCL}
{ wait 'til menu is done }
while PeekMessage(Msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) do
{nothing};
{$ENDIF VCL}
{$IFDEF VisualCLX}
repeat
Application.ProcessMessages;
until not QWidget_isVisible(DropDownMenu.Handle);
{$ENDIF VisualCLX}
{ release button }
MouseUp(Button, Shift, X, Y);
DropDownClose;
end;
end;
procedure TTntJvCustomGraphicButton.SetFlat(const Value: Boolean);
begin
if FFlat <> Value then
begin
FFlat := Value;
if FFlat then
ControlStyle := ControlStyle - [csOpaque]
else
ControlStyle := ControlStyle + [csOpaque];
RepaintBackground;
end;
end;
procedure TTntJvCustomGraphicButton.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = DropDownMenu) then
DropDownMenu := nil;
end;
procedure TTntJvCustomGraphicButton.SetDown(Value: Boolean);
begin
if GroupIndex = 0 then
Value := False;
if FDown <> Value then
begin
if FDown and not AllowAllUp then
Exit;
FDown := Value;
UpdateExclusive;
Invalidate;
end;
end;
procedure TTntJvCustomGraphicButton.SetForceSameSize(const Value: Boolean);
begin
if FForceSameSize <> Value then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -