📄 jvqarrowbutton.pas
字号:
{******************************************************************************}
{* WARNING: JEDI VCL To CLX Converter generated unit. *}
{* Manual modifications will be lost on next release. *}
{******************************************************************************}
{-----------------------------------------------------------------------------
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: JvArrowBtn.PAS, released on 2002-05-26.
The Initial Developer of the Original Code is Peter Th鰎nqvist [peter3 at sourceforge dot net]
Portions created by Peter Th鰎nqvist are Copyright (C) 2002 Peter Th鰎nqvist.
All Rights Reserved.
Contributor(s):
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Description:
The TJvArrowButton component implements an arrow button like
the ones used in Office 97: one button and one arrow with
separate events.
Known Issues:
-----------------------------------------------------------------------------}
// $Id: JvQArrowButton.pas,v 1.23 2005/02/06 14:06:00 asnepvangers Exp $
unit JvQArrowButton;
{$I jvcl.inc}
interface
uses
Classes, QWindows, QMessages, QControls, QGraphics, QButtons, QMenus,
QImgList,
JvQComponent, JvQTypes;
type
TJvArrowButton = class(TJvGraphicControl)
private
FGroupIndex: Integer;
FGlyph: Pointer;
FDown: Boolean;
FArrowClick: Boolean;
FPressBoth: Boolean;
FArrowWidth: Integer;
FAllowAllUp: Boolean;
FLayout: TButtonLayout;
FSpacing: Integer;
FFillFont: TFont;
FMargin: Integer;
FFlat: Boolean;
FMouseInControl: Boolean;
FDropDown: TPopupMenu;
FOnDrop: TNotifyEvent;
procedure GlyphChanged(Sender: TObject);
procedure UpdateExclusive;
function GetGlyph: TBitmap;
procedure SetGlyph(Value: TBitmap);
function GetNumGlyphs: TNumGlyphs;
procedure SetNumGlyphs(Value: TNumGlyphs);
procedure SetDown(Value: Boolean);
procedure SetFlat(Value: Boolean);
procedure SetAllowAllUp(Value: Boolean);
procedure SetGroupIndex(Value: Integer);
procedure SetLayout(Value: TButtonLayout);
procedure SetSpacing(Value: Integer);
procedure SetMargin(Value: Integer);
procedure SetArrowWidth(Value: Integer);
procedure SetFillFont(Value: TFont);
procedure UpdateTracking;
procedure CMButtonPressed(var Msg: TCMButtonPressed); message CM_BUTTONPRESSED;
protected
FState: TButtonState;
procedure Loaded; override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure Paint; override;
procedure MouseEnter(Control: TControl); override;
procedure MouseLeave(Control: TControl); override;
function WantKey(Key: Integer; Shift: TShiftState;
const KeyText: WideString): Boolean; override;
procedure EnabledChanged; override;
procedure FontChanged; override;
procedure TextChanged; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Align;
property Anchors;
property Constraints;
property AllowAllUp: Boolean read FAllowAllUp write SetAllowAllUp default False;
property ArrowWidth: Integer read FArrowWidth write SetArrowWidth default 13;
property GroupIndex: Integer read FGroupIndex write SetGroupIndex default 0;
property Down: Boolean read FDown write SetDown default False;
property DropDown: TPopupMenu read FDropDown write FDropDown;
property Caption;
property Enabled;
property Flat: Boolean read FFlat write SetFlat default False;
property Font;
property FillFont: TFont read FFillFont write SetFillFont;
property Glyph: TBitmap read GetGlyph write SetGlyph;
property Layout: TButtonLayout read FLayout write SetLayout default blGlyphLeft;
property Margin: Integer read FMargin write SetMargin default -1;
property NumGlyphs: TNumGlyphs read GetNumGlyphs write SetNumGlyphs default 1;
property ParentFont default True;
property ParentShowHint;
property PressBoth: Boolean read FPressBoth write FPressBoth default True;
property ShowHint;
property Spacing: Integer read FSpacing write SetSpacing default 4;
property Visible;
property OnDrop: TNotifyEvent read FOnDrop write FOnDrop;
property OnClick;
property OnDblClick;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
implementation
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
SysUtils, QConsts, QForms,
JvQConsts, JvQThemes, JvQJCLUtils;
type
TGlyphList = class(TImageList)
private
FUsed: TBits;
FCount: Integer;
function AllocateIndex: Integer;
public
constructor CreateSize(AWidth, AHeight: Integer);
destructor Destroy; override;
function AddMasked(Image: TBitmap; MaskColor: TColor): Integer; override;
procedure Delete(Index: Integer);
property Count: Integer read FCount;
end;
TGlyphCache = class(TObject)
private
FGlyphLists: TList;
public
constructor Create;
destructor Destroy; override;
function GetList(AWidth, AHeight: Integer): TGlyphList;
procedure ReturnList(var List: TGlyphList);
function Empty: Boolean;
end;
TButtonGlyph = class(TObject)
private
FOriginal: TBitmap;
FGlyphList: TGlyphList;
FIndexs: array [TButtonState] of Integer;
FTransparentColor: TColor;
FNumGlyphs: TNumGlyphs;
FOnChange: TNotifyEvent;
procedure GlyphChanged(Sender: TObject);
procedure SetGlyph(Value: TBitmap);
procedure SetNumGlyphs(Value: TNumGlyphs);
procedure Invalidate;
function CreateButtonGlyph(State: TButtonState): Integer;
procedure DrawButtonGlyph(Canvas: TCanvas; const GlyphPos: TPoint;
State: TButtonState; Transparent: Boolean);
procedure DrawButtonText(Canvas: TCanvas; const Caption: string;
TextBounds: TRect; State: TButtonState);
procedure CalcButtonLayout(Canvas: TCanvas; const Client: TRect;
const Offset: TPoint; const Caption: string; Layout: TButtonLayout;
Margin, Spacing: Integer; var GlyphPos: TPoint; var TextBounds: TRect);
public
constructor Create;
destructor Destroy; override;
{ return the text rectangle }
function Draw(Canvas: TCanvas; const Client: TRect; const Offset: TPoint;
const Caption: string; Layout: TButtonLayout; Margin, Spacing: Integer;
State: TButtonState; Transparent: Boolean): TRect;
property Glyph: TBitmap read FOriginal write SetGlyph;
property NumGlyphs: TNumGlyphs read FNumGlyphs write SetNumGlyphs;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;
procedure DrawLine(Canvas: TCanvas; X, Y, X2, Y2: Integer);
begin
Canvas.MoveTo(X, Y);
Canvas.LineTo(X2, Y2);
end;
// (rom) best move to JCL
procedure GrayBitmap(Bmp: TBitmap);
var
I, J, W, H: Integer;
ColT: TColor;
Col: TColor;
begin
if Bmp.Empty then
Exit;
W := Bmp.Width;
H := Bmp.Height;
ColT := Bmp.Canvas.Pixels[0, 0];
// (rom) speed up by using Scanline
for I := 0 to W do
for J := 0 to H do
begin
Col := Bmp.Canvas.Pixels[I, J];
if (Col <> clWhite) and (Col <> ColT) then
Col := clBlack
else
Col := ColT;
Bmp.Canvas.Pixels[I, J] := Col;
end;
end;
//=== { TGlyphList } =========================================================
constructor TGlyphList.CreateSize(AWidth, AHeight: Integer);
begin
inherited CreateSize(AWidth, AHeight);
FUsed := TBits.Create;
end;
destructor TGlyphList.Destroy;
begin
FUsed.Free;
inherited Destroy;
end;
function TGlyphList.AllocateIndex: Integer;
begin
Result := FUsed.OpenBit;
if Result >= FUsed.Size then
begin
Result := inherited Add(nil, nil);
FUsed.Size := Result + 1;
end;
FUsed[Result] := True;
end;
function TGlyphList.AddMasked(Image: TBitmap; MaskColor: TColor): Integer;
begin
Result := AllocateIndex;
ReplaceMasked(Result, Image, MaskColor);
Inc(FCount);
end;
procedure TGlyphList.Delete(Index: Integer);
begin
if FUsed[Index] then
begin
Dec(FCount);
FUsed[Index] := False;
end;
end;
//=== { TGlyphCache } ========================================================
constructor TGlyphCache.Create;
begin
inherited Create;
FGlyphLists := TList.Create;
end;
destructor TGlyphCache.Destroy;
begin
FGlyphLists.Free;
inherited Destroy;
end;
function TGlyphCache.GetList(AWidth, AHeight: Integer): TGlyphList;
var
I: Integer;
begin
for I := FGlyphLists.Count - 1 downto 0 do
begin
Result := FGlyphLists[I];
if (AWidth = Result.Width) and (AHeight = Result.Height) then
Exit;
end;
Result := TGlyphList.CreateSize(AWidth, AHeight);
FGlyphLists.Add(Result);
end;
procedure TGlyphCache.ReturnList(var List: TGlyphList);
begin
if (List <> nil) and (List.Count = 0) then
begin
FGlyphLists.Remove(List);
FreeAndNil(List);
end;
end;
function TGlyphCache.Empty: Boolean;
begin
Result := FGlyphLists.Count = 0;
end;
var
GlyphCache: TGlyphCache = nil;
Pattern: TBitmap = nil;
ButtonCount: Integer = 0;
//=== { TButtonGlyph } =======================================================
procedure CreateBrushPattern;
var
X, Y: Integer;
begin
Pattern.Free; // (rom) just to be sure
Pattern := TBitmap.Create;
Pattern.Width := 8;
Pattern.Height := 8;
with Pattern.Canvas do
begin
Brush.Style := bsSolid;
Brush.Color := clBtnFace;
FillRect(Rect(0, 0, Pattern.Width, Pattern.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 pixles }
Pixels[X, Y] := clBtnHighlight; { on even/odd rows }
end;
end;
constructor TButtonGlyph.Create;
var
I: TButtonState;
begin
inherited Create;
FOriginal := TBitmap.Create;
FOriginal.OnChange := GlyphChanged;
FTransparentColor := clOlive;
FNumGlyphs := 1;
for I := Low(I) to High(I) do
FIndexs[I] := -1;
if GlyphCache = nil then
GlyphCache := TGlyphCache.Create;
end;
destructor TButtonGlyph.Destroy;
begin
FOriginal.Free;
Invalidate;
if Assigned(GlyphCache) and GlyphCache.Empty then
FreeAndNil(GlyphCache);
inherited Destroy;
end;
procedure TButtonGlyph.Invalidate;
var
I: TButtonState;
begin
for I := Low(TButtonState) to High(TButtonState) do
begin
if FIndexs[I] <> -1 then
FGlyphList.Delete(FIndexs[I]);
FIndexs[I] := -1;
end;
GlyphCache.ReturnList(FGlyphList);
end;
procedure TButtonGlyph.GlyphChanged(Sender: TObject);
begin
if Sender = FOriginal then
begin
FTransparentColor := FOriginal.TransparentColor;
Invalidate;
if Assigned(FOnChange) then
FOnChange(Self);
end;
end;
procedure TButtonGlyph.SetGlyph(Value: TBitmap);
var
Glyphs: Integer;
begin
Invalidate;
FOriginal.Assign(Value);
if (Value <> nil) and (Value.Height > 0) then
begin
FTransparentColor := Value.TransparentColor;
if Value.Width mod Value.Height = 0 then
begin
Glyphs := Value.Width div Value.Height;
if Glyphs > 4 then
Glyphs := 1;
SetNumGlyphs(Glyphs);
end;
end;
end;
procedure TButtonGlyph.SetNumGlyphs(Value: TNumGlyphs);
begin
if (Value <> FNumGlyphs) and (Value > 0) then
begin
Invalidate;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -