mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 21:39:12 +02:00
implement tbitbtn.spacing for win32
allow -1 for tbitbtn.spacing; means center text fix transparent (xpm typically) images drawing on bitbtns git-svn-id: trunk@7388 -
This commit is contained in:
parent
7e1b82da00
commit
9e7bfb96b9
@ -152,7 +152,7 @@ end;
|
|||||||
|
|
||||||
Procedure TCustomBitBtn.SetSpacing(AValue: Integer);
|
Procedure TCustomBitBtn.SetSpacing(AValue: Integer);
|
||||||
Begin
|
Begin
|
||||||
if (FSpacing = AValue) or (AValue < 0) then Exit;
|
if (FSpacing = AValue) or (AValue < -1) then Exit;
|
||||||
FSpacing := AValue;
|
FSpacing := AValue;
|
||||||
if HandleAllocated
|
if HandleAllocated
|
||||||
then TWSBitBtnClass(WidgetSetClass).SetSpacing(Self, FSpacing);
|
then TWSBitBtnClass(WidgetSetClass).SetSpacing(Self, FSpacing);
|
||||||
|
@ -35,7 +35,7 @@ uses
|
|||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
Windows, Buttons, Graphics, Controls,
|
Windows, Buttons, Graphics, Controls,
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
WSButtons, WSLCLClasses, Win32WSControls, LCLType;
|
WSControls, WSButtons, WSLCLClasses, Win32WSControls, LCLType;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -56,6 +56,8 @@ type
|
|||||||
TWin32WSBitBtn = class(TWSBitBtn)
|
TWin32WSBitBtn = class(TWSBitBtn)
|
||||||
class function CreateHandle(const AWinControl: TWinControl;
|
class function CreateHandle(const AWinControl: TWinControl;
|
||||||
const AParams: TCreateParams): HWND; override;
|
const AParams: TCreateParams): HWND; override;
|
||||||
|
class procedure SetBounds(const AWinControl: TWinControl;
|
||||||
|
const ALeft, ATop, AWidth, AHeight: integer); override;
|
||||||
class procedure SetGlyph(const ABitBtn: TCustomBitBtn; const AValue: TBitmap); override;
|
class procedure SetGlyph(const ABitBtn: TCustomBitBtn; const AValue: TBitmap); override;
|
||||||
class procedure SetLayout(const ABitBtn: TCustomBitBtn; const AValue: TButtonLayout); override;
|
class procedure SetLayout(const ABitBtn: TCustomBitBtn; const AValue: TButtonLayout); override;
|
||||||
class procedure SetMargin(const ABitBtn: TCustomBitBtn; const AValue: Integer); override;
|
class procedure SetMargin(const ABitBtn: TCustomBitBtn; const AValue: Integer); override;
|
||||||
@ -185,62 +187,82 @@ var
|
|||||||
|
|
||||||
procedure DrawBitmap(Enabled: boolean);
|
procedure DrawBitmap(Enabled: boolean);
|
||||||
var
|
var
|
||||||
SrcDC, MaskDC: HBITMAP;
|
SrcDC, MaskDC, MonoDC: HDC;
|
||||||
MaskBmp, OldSrcBmp, OldMaskBmp: HBITMAP;
|
MaskBmp, MonoBmp, OldSrcBmp, OldMaskBmp, OldMonoBmp: HBITMAP;
|
||||||
BkColor: TColorRef;
|
BkColor: TColorRef;
|
||||||
|
|
||||||
OldBitmapHandle: HBITMAP; // Handle of the provious bitmap in hdcNewBitmap
|
OldBitmapHandle: HBITMAP; // Handle of the provious bitmap in hdcNewBitmap
|
||||||
BitmapFlags: integer; // flags for glyph (enabled or disabled)
|
|
||||||
TextFlags: integer; // flags for caption (enabled or disabled)
|
TextFlags: integer; // flags for caption (enabled or disabled)
|
||||||
|
themesActive: boolean;
|
||||||
begin
|
begin
|
||||||
BitmapFlags := DST_BITMAP;
|
|
||||||
TextFlags := DST_PREFIXTEXT;
|
TextFlags := DST_PREFIXTEXT;
|
||||||
|
|
||||||
OldBitmapHandle := SelectObject(hdcNewBitmap, NewBitmap);
|
OldBitmapHandle := SelectObject(hdcNewBitmap, NewBitmap);
|
||||||
if Enabled or TWin32WidgetSet(InterfaceObject).ThemesActive
|
MaskDC := CreateCompatibleDC(hdcNewBitmap);
|
||||||
then begin
|
if BitBtn.Glyph.MaskHandleAllocated then
|
||||||
// themed
|
begin
|
||||||
if not Enabled
|
// Create a mask DC
|
||||||
then begin
|
MaskBmp := CreateCompatibleBitmap(hdcNewBitmap, BitmapInfo.bmWidth, BitmapInfo.bmHeight);
|
||||||
BitmapFlags := BitmapFlags or DSS_DISABLED;
|
OldMaskBmp := SelectObject(MaskDC, MaskBmp);
|
||||||
TextFlags := TextFlags or DSS_DISABLED;
|
SrcDC := CreateCompatibleDC(hdcNewBitmap);
|
||||||
end;
|
OldSrcBmp := SelectObject(SrcDC, BitmapHandle);
|
||||||
|
FillRect(MaskDC, BitmapRect, BitBtn.Brush.Handle);
|
||||||
Windows.FillRect(hdcNewBitmap, BitmapRect, BitBtn.Brush.Handle);
|
TWin32WidgetSet(InterfaceObject).MaskBlt(MaskDC, 0, 0, BitmapInfo.bmWidth, BitmapInfo.bmHeight, SrcDC,
|
||||||
if BitmapHandle <> 0
|
0, 0, BitBtn.Glyph.MaskHandle, 0, 0);
|
||||||
then DrawState(hdcNewBitmap, 0, nil, BitmapHandle, 0, XDestBitmap, YDestBitmap, 0, 0, BitmapFlags);
|
end else begin
|
||||||
end
|
MaskBmp := BitmapHandle;
|
||||||
else begin
|
OldMaskBmp := SelectObject(MaskDC, MaskBmp);
|
||||||
// non themed
|
end;
|
||||||
// When disabled only create a black and white image
|
|
||||||
// Let windows itself draw the disabled state
|
// fill with background color
|
||||||
Windows.FillRect(hdcNewBitmap, BitmapRect, Windows.GetStockObject(WHITE_BRUSH));
|
Windows.FillRect(hdcNewBitmap, BitmapRect, BitBtn.Brush.Handle);
|
||||||
if BitmapHandle <> 0
|
if Enabled then
|
||||||
then begin
|
begin
|
||||||
// Create a source DC
|
if MaskBmp <> 0 then
|
||||||
SrcDC := CreateCompatibleDC(hdcNewBitmap);
|
BitBlt(hdcNewBitmap, XDestBitmap, YDestBitmap, BitmapInfo.bmWidth,
|
||||||
OldSrcBmp := SelectObject(SrcDC, BitmapHandle);
|
BitmapInfo.bmHeight, MaskDC, 0, 0, SRCCOPY);
|
||||||
// Create a mask DC
|
end else begin
|
||||||
MaskBmp := CreateBitmap(BitmapInfo.bmWidth, BitmapInfo.bmHeight, 1, 1, nil);
|
TextFlags := TextFlags or DSS_DISABLED;
|
||||||
MaskDC := CreateCompatibleDC(hdcNewBitmap);
|
// when not themed, windows wants a white background picture for disabled button image
|
||||||
OldMaskBmp := SelectObject(MaskDC, MaskBmp);
|
themesActive := TWin32WidgetSet(InterfaceObject).ThemesActive;
|
||||||
|
if not themesActive then
|
||||||
|
FillRect(hdcNewBitmap, BitmapRect, GetStockObject(WHITE_BRUSH));
|
||||||
|
if BitmapHandle <> 0 then
|
||||||
|
begin
|
||||||
|
// Create a Mono DC
|
||||||
|
MonoBmp := CreateBitmap(BitmapInfo.bmWidth, BitmapInfo.bmHeight, 1, 1, nil);
|
||||||
|
MonoDC := CreateCompatibleDC(hdcNewBitmap);
|
||||||
|
OldMonoBmp := SelectObject(MonoDC, MonoBmp);
|
||||||
// Create the black and white image
|
// Create the black and white image
|
||||||
BkColor := SetBkColor(SrcDC, BitBtn.Brush.Color);
|
BkColor := SetBkColor(MaskDC, ColorToRGB(BitBtn.Brush.Color));
|
||||||
BitBlt(MaskDC, 0, 0, BitmapInfo.bmWidth, BitmapInfo.bmHeight, SrcDC, 0, 0, SrcCopy);
|
BitBlt(MonoDC, 0, 0, BitmapInfo.bmWidth, BitmapInfo.bmHeight, MaskDC, 0, 0, SRCCOPY);
|
||||||
SetBkColor(SrcDC, BkColor);
|
SetBkColor(MaskDC, BkColor);
|
||||||
|
if themesActive then
|
||||||
|
begin
|
||||||
|
// non-themed winapi wants white/other as background/picture-disabled colors
|
||||||
|
// themed winapi draws bitmap-as, with transparency defined by bitbtn.brush color
|
||||||
|
BkColor := SetBkColor(hdcNewBitmap, ColorToRGB(BitBtn.Brush.Color));
|
||||||
|
SetTextColor(hdcNewBitmap, GetSysColor(COLOR_BTNSHADOW));
|
||||||
|
end;
|
||||||
// Draw the black and white image
|
// Draw the black and white image
|
||||||
BitBlt(hdcNewBitmap, XDestBitmap, YDestBitmap, BitmapInfo.bmWidth, BitmapInfo.bmHeight,
|
BitBlt(hdcNewBitmap, XDestBitmap, YDestBitmap, BitmapInfo.bmWidth, BitmapInfo.bmHeight,
|
||||||
MaskDC, 0, 0, SRCCOPY);
|
MonoDC, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
SelectObject(SrcDC, OldSrcBmp);
|
SelectObject(MonoDC, OldMonoBmp);
|
||||||
DeleteDC(SrcDC);
|
DeleteDC(MonoDC);
|
||||||
|
DeleteObject(MonoBmp);
|
||||||
SelectObject(MaskDC, OldMaskBmp);
|
|
||||||
DeleteDC(MaskDC);
|
|
||||||
DeleteObject(MaskBmp);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if BitBtn.Glyph.MaskHandleAllocated then
|
||||||
|
begin
|
||||||
|
SelectObject(SrcDC, OldSrcBmp);
|
||||||
|
DeleteDC(SrcDC);
|
||||||
|
DeleteObject(MaskBmp);
|
||||||
|
end;
|
||||||
|
SelectObject(MaskDC, OldMaskBmp);
|
||||||
|
DeleteDC(MaskDC);
|
||||||
|
|
||||||
SetBkMode(hdcNewBitmap, TRANSPARENT);
|
SetBkMode(hdcNewBitmap, TRANSPARENT);
|
||||||
DrawState(hdcNewBitmap, 0, nil, LPARAM(ButtonCaption), 0, XDestText, YDestText, 0, 0, TextFlags);
|
DrawState(hdcNewBitmap, 0, nil, LPARAM(ButtonCaption), 0, XDestText, YDestText, 0, 0, TextFlags);
|
||||||
SelectObject(hdcNewBitmap, OldBitmapHandle);
|
SelectObject(hdcNewBitmap, OldBitmapHandle);
|
||||||
@ -267,47 +289,72 @@ begin
|
|||||||
case BitBtnLayout of
|
case BitBtnLayout of
|
||||||
blGlyphLeft, blGlyphRight:
|
blGlyphLeft, blGlyphRight:
|
||||||
begin
|
begin
|
||||||
newWidth := TextSize.cx + BitmapInfo.bmWidth;
|
if BitBtn.Spacing = -1 then
|
||||||
|
newWidth := BitBtn.Width - 10
|
||||||
|
else
|
||||||
|
newWidth := TextSize.cx + BitmapInfo.bmWidth + BitBtn.Spacing;
|
||||||
if BitmapHandle <> 0 then
|
if BitmapHandle <> 0 then
|
||||||
inc(newWidth, 2);
|
inc(newWidth, 2);
|
||||||
newHeight := TextSize.cy;
|
newHeight := TextSize.cy;
|
||||||
if newHeight < BitmapInfo.bmHeight then
|
if newHeight < BitmapInfo.bmHeight then
|
||||||
newHeight := BitmapInfo.bmHeight;
|
newHeight := BitmapInfo.bmHeight;
|
||||||
YDestBitmap := (newHeight - BitmapInfo.bmHeight) shr 1;
|
YDestBitmap := (newHeight - BitmapInfo.bmHeight) div 2;
|
||||||
YDestText := (newHeight - TextSize.cy) shr 1;
|
YDestText := (newHeight - TextSize.cy) div 2;
|
||||||
|
case BitBtnLayout of
|
||||||
|
blGlyphLeft:
|
||||||
|
begin
|
||||||
|
XDestBitmap := 0;
|
||||||
|
XDestText := BitmapInfo.bmWidth;
|
||||||
|
if BitBtn.Spacing = -1 then
|
||||||
|
inc(XDestText, (newWidth - BitmapInfo.bmWidth - TextSize.cx) div 2)
|
||||||
|
else
|
||||||
|
inc(XDestText, BitBtn.Spacing);
|
||||||
|
end;
|
||||||
|
blGlyphRight:
|
||||||
|
begin
|
||||||
|
XDestBitmap := newWidth - BitmapInfo.bmWidth;
|
||||||
|
XDestText := XDestBitmap - TextSize.cx;
|
||||||
|
if BitBtn.Spacing = -1 then
|
||||||
|
dec(XDestText, (newWidth - BitmapInfo.bmWidth - TextSize.cx) div 2)
|
||||||
|
else
|
||||||
|
dec(XDestText, BitBtn.Spacing);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
blGlyphTop, blGlyphBottom:
|
blGlyphTop, blGlyphBottom:
|
||||||
begin
|
begin
|
||||||
newWidth := TextSize.cx;
|
newWidth := TextSize.cx;
|
||||||
if newWidth < BitmapInfo.bmWidth then
|
if newWidth < BitmapInfo.bmWidth then
|
||||||
newWidth := BitmapInfo.bmWidth;
|
newWidth := BitmapInfo.bmWidth;
|
||||||
newHeight := TextSize.cy + BitmapInfo.bmHeight;
|
if BitBtn.Spacing = -1 then
|
||||||
|
newHeight := BitBtn.Height - 10
|
||||||
|
else
|
||||||
|
newHeight := TextSize.cy + BitmapInfo.bmHeight + BitBtn.Spacing;
|
||||||
if BitmapHandle <> 0 then
|
if BitmapHandle <> 0 then
|
||||||
inc(newHeight, 2);
|
inc(newHeight, 2);
|
||||||
XDestBitmap := (newWidth - BitmapInfo.bmWidth) shr 1;
|
XDestBitmap := (newWidth - BitmapInfo.bmWidth) shr 1;
|
||||||
XDestText := (newWidth - TextSize.cx) shr 1;
|
XDestText := (newWidth - TextSize.cx) shr 1;
|
||||||
|
case BitBtnLayout of
|
||||||
|
blGlyphTop:
|
||||||
|
begin
|
||||||
|
YDestBitmap := 0;
|
||||||
|
YDestText := BitmapInfo.bmHeight;
|
||||||
|
if BitBtn.Spacing = -1 then
|
||||||
|
inc(YDestText, (newHeight - BitmapInfo.bmHeight - TextSize.cy) div 2)
|
||||||
|
else
|
||||||
|
inc(YDestText, BitBtn.Spacing);
|
||||||
|
end;
|
||||||
|
blGlyphBottom:
|
||||||
|
begin
|
||||||
|
YDestBitmap := newHeight - BitmapInfo.bmHeight;
|
||||||
|
YDestText := YDestBitmap - TextSize.cy;
|
||||||
|
if BitBtn.Spacing = -1 then
|
||||||
|
dec(YDestText, (newHeight - BitmapInfo.bmHeight - TextSize.cy) div 2)
|
||||||
|
else
|
||||||
|
dec(YDestText, BitBtn.Spacing);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
case BitBtnLayout of
|
|
||||||
blGlyphLeft:
|
|
||||||
begin
|
|
||||||
XDestBitmap := 0;
|
|
||||||
XDestText := newWidth - TextSize.cx;
|
|
||||||
end;
|
|
||||||
blGlyphRight:
|
|
||||||
begin
|
|
||||||
XDestBitmap := newWidth - BitmapInfo.bmWidth;
|
|
||||||
XDestText := 0;
|
|
||||||
end;
|
|
||||||
blGlyphTop:
|
|
||||||
begin
|
|
||||||
YDestBitmap := 0;
|
|
||||||
YDestText := newHeight - TextSize.cy;
|
|
||||||
end;
|
|
||||||
blGlyphBottom: begin
|
|
||||||
YDestBitmap := newHeight - BitmapInfo.bmHeight;
|
|
||||||
YDestText := 0;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
// create new
|
// create new
|
||||||
if (newWidth = 0) and (newHeight = 0) then
|
if (newWidth = 0) and (newHeight = 0) then
|
||||||
@ -329,10 +376,10 @@ begin
|
|||||||
if NewBitmap <> 0 then
|
if NewBitmap <> 0 then
|
||||||
begin
|
begin
|
||||||
ButtonImageList.himl := ImageList_Create(newWidth, newHeight, ILC_COLORDDB or ILC_MASK, 5, 0);
|
ButtonImageList.himl := ImageList_Create(newWidth, newHeight, ILC_COLORDDB or ILC_MASK, 5, 0);
|
||||||
ButtonImageList.margin.left := 2;
|
ButtonImageList.margin.left := 5;
|
||||||
ButtonImageList.margin.right := 2;
|
ButtonImageList.margin.right := 5;
|
||||||
ButtonImageList.margin.top := 2;
|
ButtonImageList.margin.top := 5;
|
||||||
ButtonImageList.margin.bottom := 2;
|
ButtonImageList.margin.bottom := 5;
|
||||||
ButtonImageList.uAlign := BUTTON_IMAGELIST_ALIGN_CENTER;
|
ButtonImageList.uAlign := BUTTON_IMAGELIST_ALIGN_CENTER;
|
||||||
// for some reason, if bitmap added to imagelist, need to redrawn, otherwise it's black!?
|
// for some reason, if bitmap added to imagelist, need to redrawn, otherwise it's black!?
|
||||||
for I := 0 to 4 do
|
for I := 0 to 4 do
|
||||||
@ -359,6 +406,7 @@ begin
|
|||||||
SelectObject(hdcNewBitmap, OldFontHandle);
|
SelectObject(hdcNewBitmap, OldFontHandle);
|
||||||
DeleteDC(hdcNewBitmap);
|
DeleteDC(hdcNewBitmap);
|
||||||
ReleaseDC(BitBtnHandle, BitBtnDC);
|
ReleaseDC(BitBtnHandle, BitBtnDC);
|
||||||
|
BitBtn.Invalidate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TWin32WSBitBtn.CreateHandle(const AWinControl: TWinControl;
|
function TWin32WSBitBtn.CreateHandle(const AWinControl: TWinControl;
|
||||||
@ -384,6 +432,14 @@ begin
|
|||||||
Result := Params.Window;
|
Result := Params.Window;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TWin32WSBitBtn.SetBounds(const AWinControl: TWinControl;
|
||||||
|
const ALeft, ATop, AWidth, AHeight: integer);
|
||||||
|
begin
|
||||||
|
TWin32WSWinControl.SetBounds(AWinControl, ALeft, ATop, AWidth, AHeight);
|
||||||
|
if TCustomBitBtn(AWinControl).Spacing = -1 then
|
||||||
|
DrawBitBtnImage(TCustomBitBtn(AWinControl), PChar(AWinControl.Caption));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TWin32WSBitBtn.SetGlyph(const ABitBtn: TCustomBitBtn;
|
procedure TWin32WSBitBtn.SetGlyph(const ABitBtn: TCustomBitBtn;
|
||||||
const AValue: TBitmap);
|
const AValue: TBitmap);
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user