📄 jvqspeedbutton.pas
字号:
end;
function TJvSpeedButton.GetHotTrackGlyph: TBitmap;
begin
Result := TJvxButtonGlyph(FHotTrackGlyph).Glyph;
end;
function TJvSpeedButton.GetNumGlyphs: TJvNumGlyphs;
begin
Result := TJvxButtonGlyph(FGlyph).NumGlyphs;
end;
procedure TJvSpeedButton.GlyphChanged(Sender: TObject);
begin
Invalidate;
end;
procedure TJvSpeedButton.HotTrackGlyphChanged(Sender: TObject);
begin
Invalidate;
end;
procedure TJvSpeedButton.PaintImage(Canvas: TCanvas; ARect: TRect; const Offset: TPoint;
AState: TJvButtonState; DrawMark: Boolean);
begin
if (MouseOver or FDragging) and HotTrack and not HotTrackGlyph.Empty then
begin
SyncHotGlyph;
TJvxButtonGlyph(FHotTrackGlyph).Draw(Canvas, ARect, Offset, Caption, FLayout,
FMargin, FSpacing, DrawMark, AState, DrawTextBiDiModeFlags(Alignments[Alignment]));
end
else
TJvxButtonGlyph(FGlyph).Draw(Canvas, ARect, Offset, Caption, FLayout,
FMargin, FSpacing, DrawMark, AState, DrawTextBiDiModeFlags(Alignments[Alignment]));
end;
procedure TJvSpeedButton.SetGlyph(Value: TBitmap);
begin
TJvxButtonGlyph(FGlyph).Glyph := Value;
Invalidate;
end;
procedure TJvSpeedButton.SetHotTrackGlyph(const Value: TBitmap);
begin
TJvxButtonGlyph(FHotTrackGlyph).Glyph := Value;
Invalidate;
end;
procedure TJvSpeedButton.SetNumGlyphs(Value: TJvNumGlyphs);
begin
if Value < 0 then
Value := 1
else
if Value > Ord(High(TJvButtonState)) + 1 then
Value := Ord(High(TJvButtonState)) + 1;
if Value <> TJvxButtonGlyph(FGlyph).NumGlyphs then
begin
TJvxButtonGlyph(FGlyph).NumGlyphs := Value;
Invalidate;
end;
end;
procedure TJvSpeedButton.SyncHotGlyph;
begin
with TJvxButtonGlyph(FHotTrackGlyph) do
begin
OnChange := nil;
try
Alignment := TJvxButtonGlyph(FGlyph).Alignment;
GrayNewStyle := TJvxButtonGlyph(FGlyph).GrayNewStyle;
NumGlyphs := TJvxButtonGlyph(FGlyph).NumGlyphs;
WordWrap := TJvxButtonGlyph(FGlyph).WordWrap;
finally
OnChange := HotTrackGlyphChanged;
end;
end;
end;
//=== { TJvSpeedButtonActionLink } ===========================================
procedure TJvSpeedButtonActionLink.AssignClient(AClient: TObject);
begin
inherited AssignClient(AClient);
FClient := AClient as TJvSpeedButton;
end;
function TJvSpeedButtonActionLink.IsCheckedLinked: Boolean;
begin
Result := inherited IsCheckedLinked and (FClient.GroupIndex <> 0) and
FClient.AllowAllUp and (FClient.Down = (Action as TCustomAction).Checked);
end;
procedure TJvSpeedButtonActionLink.SetChecked(Value: Boolean);
begin
if IsCheckedLinked then
TJvSpeedButton(FClient).Down := Value;
end;
//=== { TJvxButtonGlyph } ====================================================
procedure TJvxButtonGlyph.CalcButtonLayout(Canvas: TCanvas; const Client: TRect; const Offset: TPoint;
var Caption: string; Layout: TButtonLayout; Margin, Spacing: Integer;
PopupMark: Boolean; var GlyphPos: TPoint; var TextBounds: TRect;
Flags: Word; Images: TCustomImageList; ImageIndex: Integer);
var
TextPos: TPoint;
MaxSize, ClientSize, GlyphSize, TextSize: TPoint;
TotalSize: TPoint;
{ Parameter nCount of DrawText specifies the length of the string. For the
ANSI function it is a BYTE count }
CString: array [0..255] of Char;
begin
{ calculate the item sizes }
ClientSize := Point(Client.Right - Client.Left, Client.Bottom - Client.Top);
if Assigned(Images) and (Images.Width > 0) and (ImageIndex >= 0) and
(ImageIndex < Images.Count) then
GlyphSize := Point(Images.Width, Images.Height)
else
if FOriginal <> nil then
GlyphSize := Point(FOriginal.Width div FNumGlyphs, FOriginal.Height)
else
GlyphSize := Point(0, 0);
if Layout in [blGlyphLeft, blGlyphRight] then
begin
MaxSize.X := ClientSize.X - GlyphSize.X;
if Margin <> -1 then
Dec(MaxSize.X, Margin);
if Spacing <> -1 then
Dec(MaxSize.X, Spacing);
if PopupMark then
Dec(MaxSize.X, 9);
MaxSize.Y := ClientSize.Y;
end
else { blGlyphTop, blGlyphBottom }
begin
MaxSize.X := ClientSize.X;
MaxSize.Y := ClientSize.Y - GlyphSize.Y;
if Margin <> -1 then
Dec(MaxSize.Y, Margin);
if Spacing <> -1 then
Dec(MaxSize.Y, Spacing);
end;
MaxSize.X := Max(0, MaxSize.X);
MaxSize.Y := Max(0, MaxSize.Y);
MinimizeCaption(Canvas, Caption, CString, SizeOf(CString) - 1, MaxSize.X);
Caption := StrPas(CString);
if Length(Caption) > 0 then
begin
TextBounds := Rect(0, 0, MaxSize.X, 0);
DrawText(Canvas, CString, -1, TextBounds, DT_CALCRECT or DT_CENTER or
DT_VCENTER or WordWraps[FWordWrap] or Flags);
end
else
TextBounds := Rect(0, 0, 0, 0);
TextBounds.Bottom := Max(TextBounds.Top, TextBounds.Top +
Min(MaxSize.Y, RectHeight(TextBounds)));
TextBounds.Right := Max(TextBounds.Left, TextBounds.Left +
Min(MaxSize.X, RectWidth(TextBounds)));
TextSize := Point(TextBounds.Right - TextBounds.Left, TextBounds.Bottom -
TextBounds.Top);
if PopupMark then
if ((GlyphSize.X = 0) or (GlyphSize.Y = 0)) or (Layout = blGlyphLeft) then
Inc(TextSize.X, 9)
else
if GlyphSize.X > 0 then
Inc(GlyphSize.X, 6);
{ If the layout has the glyph on the right or the left, then both the
text and the glyph are centered vertically. If the glyph is on the top
or the bottom, then both the text and the glyph are centered horizontally.}
if Layout in [blGlyphLeft, blGlyphRight] then
begin
GlyphPos.Y := (ClientSize.Y div 2) - (GlyphSize.Y div 2);
TextPos.Y := (ClientSize.Y div 2) - (TextSize.Y div 2);
end
else
begin
GlyphPos.X := (ClientSize.X div 2) - (GlyphSize.X div 2);
TextPos.X := (ClientSize.X div 2) - (TextSize.X div 2);
end;
{ if there is no text or no bitmap, then Spacing is irrelevant }
if (TextSize.X = 0) or (GlyphSize.X = 0) then
Spacing := 0;
{ adjust Margin and Spacing }
if Margin = -1 then
begin
if Spacing = -1 then
begin
TotalSize := Point(GlyphSize.X + TextSize.X, GlyphSize.Y + TextSize.Y);
if Layout in [blGlyphLeft, blGlyphRight] then
Margin := (ClientSize.X - TotalSize.X) div 3
else
Margin := (ClientSize.Y - TotalSize.Y) div 3;
Spacing := Margin;
end
else
begin
TotalSize := Point(GlyphSize.X + Spacing + TextSize.X, GlyphSize.Y +
Spacing + TextSize.Y);
if Layout in [blGlyphLeft, blGlyphRight] then
Margin := (ClientSize.X div 2) - (TotalSize.X div 2)
else
Margin := (ClientSize.Y div 2) - (TotalSize.Y div 2);
end;
end
else
begin
if Spacing = -1 then
begin
TotalSize := Point(ClientSize.X - (Margin + GlyphSize.X), ClientSize.Y -
(Margin + GlyphSize.Y));
if Layout in [blGlyphLeft, blGlyphRight] then
Spacing := (TotalSize.X div 2) - (TextSize.X div 2)
else
Spacing := (TotalSize.Y div 2) - (TextSize.Y div 2);
end;
end;
case Layout of
blGlyphLeft:
begin
GlyphPos.X := Margin;
TextPos.X := GlyphPos.X + GlyphSize.X + Spacing;
end;
blGlyphRight:
begin
GlyphPos.X := ClientSize.X - Margin - GlyphSize.X;
TextPos.X := GlyphPos.X - Spacing - TextSize.X;
end;
blGlyphTop:
begin
GlyphPos.Y := Margin;
TextPos.Y := GlyphPos.Y + GlyphSize.Y + Spacing;
end;
blGlyphBottom:
begin
GlyphPos.Y := ClientSize.Y - Margin - GlyphSize.Y;
TextPos.Y := GlyphPos.Y - Spacing - TextSize.Y;
end;
end;
{ fixup the result variables }
with GlyphPos do
begin
Inc(X, Client.Left + Offset.X);
Inc(Y, Client.Top + Offset.Y);
end;
{ Themed text is not shifted, but gets a different color. }
OffsetRect(TextBounds, TextPos.X + Client.Left + Offset.X, TextPos.Y + Client.Top + Offset.Y);
end;
constructor TJvxButtonGlyph.Create;
var
I: TJvButtonState;
begin
inherited Create;
FOriginal := TBitmap.Create;
FOriginal.OnChange := GlyphChanged;
FTransparentColor := clFuchsia;
FAlignment := taCenter;
FNumGlyphs := 1;
for I := Low(I) to High(I) do
FIndexs[I] := -1;
if GlyphCache = nil then
GlyphCache := TJvGlyphCache.Create;
end;
function TJvxButtonGlyph.CreateButtonGlyph(State: TJvButtonState): Integer;
var
TmpImage, MonoBmp: TBitmap;
iWidth, iHeight, X, Y: Integer;
IRect, ORect: TRect;
I: TJvButtonState;
begin
if (State = rbsDown) and (NumGlyphs < 3) then
State := rbsUp;
Result := FIndexs[State];
if (Result <> -1) or (FOriginal.Width = 0) or (FOriginal.Height = 0) or
FOriginal.Empty then
Exit;
iWidth := FOriginal.Width div FNumGlyphs;
iHeight := FOriginal.Height;
if FGlyphList = nil then
begin
if GlyphCache = nil then
GlyphCache := TJvGlyphCache.Create;
FGlyphList := GlyphCache.GetList(iWidth, iHeight);
end;
TmpImage := TBitmap.Create;
try
TmpImage.Width := iWidth;
TmpImage.Height := iHeight;
IRect := Rect(0, 0, iWidth, iHeight);
TmpImage.Canvas.Brush.Color := clBtnFace;
I := State;
if Ord(I) >= NumGlyphs then
I := rbsUp;
ORect := Rect(Ord(I) * iWidth, 0, (Ord(I) + 1) * iWidth, iHeight);
case State of
rbsUp, rbsDown, rbsExclusive:
begin
TmpImage.Canvas.CopyRect(IRect, FOriginal.Canvas, ORect);
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(TmpImage,
FTransparentColor);
end;
rbsDisabled:
if NumGlyphs > 1 then
begin
TmpImage.Canvas.CopyRect(IRect, FOriginal.Canvas, ORect);
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(TmpImage,
FTransparentColor);
end
else
begin
if FGrayNewStyle then
begin
MonoBmp := CreateDisabledBitmap_NewStyle(FOriginal, FTransparentColor);
try
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(MonoBmp,
FTransparentColor);
finally
MonoBmp.Free;
end;
end
else
begin
MonoBmp := CreateDisabledBitmap(FOriginal, clWhite);
// MonoBmp := CreateMonoBitmap(FOriginal, clNone);
try
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(MonoBmp,
ColorToRGB(clBtnFace));
finally
MonoBmp.Free;
end;
end;
end;
rbsInactive:
if NumGlyphs > 4 then
begin
TmpImage.Canvas.CopyRect(IRect, FOriginal.Canvas, ORect);
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(TmpImage,
FTransparentColor);
end
else
begin
with TmpImage do
for X := 0 to Width - 1 do
for Y := 0 to Height - 1 do
Canvas.Pixels[X, Y] := MapColor(FOriginal.Canvas.Pixels[X, Y]);
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(TmpImage,
FTransparentColor);
end;
end;
finally
TmpImage.Free;
end;
Result := FIndexs[State];
FOriginal.Dormant;
end;
function TJvxButtonGlyph.CreateImageGlyph(State: TJvButtonState;
Images: TCustomImageList; Index: Integer): Integer;
var
TmpImage, Mask: TBitmap;
iWidth, iHeight, X, Y: Integer;
begin
if State = rbsDown then
State := rbsUp;
Result := FIndexs[State];
if (Result <> -1) or (Images.Width = 0) or (Images.Height = 0) or
(Images.Count = 0) then
Exit;
iWidth := Images.Width;
iHeight := Images.Height;
if FGlyphList = nil then
begin
if GlyphCache = nil then
GlyphCache := TJvGlyphCache.Create;
FGlyphList := GlyphCache.GetList(iWidth, iHeight);
end;
TmpImage := TBitmap.Create;
try
TmpImage.Width := iWidth;
TmpImage.Height := iHeight;
case State of
rbsUp, rbsDown, rbsExclusive:
begin
with TmpImage.Canvas do
begin
FillRect(Rect(0, 0, iWidth, iHeight));
Images.Draw(TmpImage.Canvas, 0, 0, Index, itImage);
end;
Mask := TBitmap.Create;
try
with Mask do
begin
Monochrome := True;
Height := iHeight;
Width := iWidth;
end;
with Mask.Canvas do
begin
FillRect(Rect(0, 0, iWidth, iHeight));
Images.Draw(TmpImage.Canvas, 0, 0, Index, itMask);
end;
FIndexs[State] := TJvGlyphList(FGlyphList).Add(TmpImage, Mask);
finally
Mask.Free;
end;
end;
rbsDisabled:
begin
TmpImage.Canvas.Brush.Color := clBtnFace;
TmpImage.Canvas.FillRect(Rect(0, 0, iWidth, iHeight));
ImageListDrawDisabled(Images, TmpImage.Canvas, 0, 0, Index,
clBtnHighlight, clBtnShadow, True);
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(TmpImage,
ColorToRGB(clBtnFace));
end;
rbsInactive:
begin
TmpImage.Canvas.Brush.Color := clBtnFace;
TmpImage.Canvas.FillRect(Rect(0, 0, iWidth, iHeight));
Images.Draw(TmpImage.Canvas, 0, 0, Index, itImage);
with TmpImage do
begin
for X := 0 to Width - 1 do
for Y := 0 to Height - 1 do
Canvas.Pixels[X, Y] := MapColor(Canvas.Pixels[X, Y]);
end;
FIndexs[State] := TJvGlyphList(FGlyphList).AddMasked(TmpImage,
ColorToRGB(clBtnFace));
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -