mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 16:39:15 +02:00
implement drawing different state images (Up, Down, Disabled, Hot) for gtk1/gtk2 bitbtns
git-svn-id: trunk@13331 -
This commit is contained in:
parent
1dc6d33ab1
commit
7c484cc832
@ -130,7 +130,6 @@ type
|
|||||||
FLayout: TButtonLayout;
|
FLayout: TButtonLayout;
|
||||||
FMargin: integer;
|
FMargin: integer;
|
||||||
FSpacing: Integer;
|
FSpacing: Integer;
|
||||||
FMultiGlyph: TBitmap;
|
|
||||||
function GetGlyph: TBitmap;
|
function GetGlyph: TBitmap;
|
||||||
function GetNumGlyphs: Integer;
|
function GetNumGlyphs: Integer;
|
||||||
Function IsGlyphStored: Boolean;
|
Function IsGlyphStored: Boolean;
|
||||||
|
@ -38,7 +38,6 @@ end;
|
|||||||
destructor TCustomBitBtn.Destroy;
|
destructor TCustomBitBtn.Destroy;
|
||||||
Begin
|
Begin
|
||||||
FreeThenNil(FButtonGlyph);
|
FreeThenNil(FButtonGlyph);
|
||||||
FreeThenNil(FMultiGlyph);
|
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -55,8 +55,10 @@ type
|
|||||||
TGtkWSBitBtn = class(TWSBitBtn)
|
TGtkWSBitBtn = class(TWSBitBtn)
|
||||||
private
|
private
|
||||||
protected
|
protected
|
||||||
|
class procedure UpdateGlyph(const ABitBtn: TCustomBitBtn; const AValue: TButtonGlyph; const AButtonState: TButtonState); virtual;
|
||||||
class procedure UpdateLayout(const AInfo: PBitBtnWidgetInfo; const ALayout: TButtonLayout; const AMargin: Integer);
|
class procedure UpdateLayout(const AInfo: PBitBtnWidgetInfo; const ALayout: TButtonLayout; const AMargin: Integer);
|
||||||
class procedure UpdateMargin(const AInfo: PBitBtnWidgetInfo; const ALayout: TButtonLayout; const AMargin: Integer);
|
class procedure UpdateMargin(const AInfo: PBitBtnWidgetInfo; const ALayout: TButtonLayout; const AMargin: Integer);
|
||||||
|
class procedure SetCallbacks(const AGtkWidget: PGtkWidget; const AWidgetInfo: PWidgetInfo); virtual;
|
||||||
public
|
public
|
||||||
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
|
||||||
class procedure SetGlyph(const ABitBtn: TCustomBitBtn; const AValue: TButtonGlyph); override;
|
class procedure SetGlyph(const ABitBtn: TCustomBitBtn; const AValue: TButtonGlyph); override;
|
||||||
@ -66,8 +68,8 @@ type
|
|||||||
class procedure SetText(const AWinControl: TWinControl; const AText: String); override;
|
class procedure SetText(const AWinControl: TWinControl; const AText: String); override;
|
||||||
class procedure SetColor(const AWinControl: TWinControl); override;
|
class procedure SetColor(const AWinControl: TWinControl); override;
|
||||||
class procedure SetFont(const AWinControl: TWinControl; const AFont : tFont); override;
|
class procedure SetFont(const AWinControl: TWinControl; const AFont : tFont); override;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
TGtkWSBitBtnClass = class of TGtkWSBitBtn;
|
||||||
|
|
||||||
{ TGtkWSSpeedButton }
|
{ TGtkWSSpeedButton }
|
||||||
|
|
||||||
@ -85,7 +87,28 @@ uses
|
|||||||
GtkProc, GtkInt, GtkGlobals,
|
GtkProc, GtkInt, GtkGlobals,
|
||||||
GtkWSControls, GtkWSStdCtrls;
|
GtkWSControls, GtkWSStdCtrls;
|
||||||
|
|
||||||
|
const
|
||||||
|
GtkStateToButtonState: array[GTK_STATE_NORMAL..GTK_STATE_INSENSITIVE] of TButtonState =
|
||||||
|
(
|
||||||
|
{GTK_STATE_NORMAL } bsUp,
|
||||||
|
{GTK_STATE_ACTIVE } bsDown,
|
||||||
|
{GTK_STATE_PRELIGHT } bsHot,
|
||||||
|
{GTK_STATE_SELECTED } bsDown,
|
||||||
|
{GTK_STATE_INSENSITIVE} bsDisabled
|
||||||
|
);
|
||||||
|
|
||||||
|
type
|
||||||
|
TCustomBitBtnAccess = class(TCustomBitBtn)
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure GtkWSBitBtn_StateChanged(AWidget: PGtkWidget; AState: TGtkStateType; AInfo: PWidgetInfo); cdecl;
|
||||||
|
begin
|
||||||
|
//WriteLn(Astate, ' :: ', GTK_WIDGET_STATE(AWidget));
|
||||||
|
TGtkWSBitBtnClass(TCustomBitBtn(AInfo^.LCLObject).WidgetSetClass).UpdateGlyph(
|
||||||
|
TBitBtn(AInfo^.LCLObject),
|
||||||
|
TCustomBitBtnAccess(AInfo^.LCLObject).FButtonGlyph,
|
||||||
|
GtkStateToButtonState[GTK_WIDGET_STATE(AWidget)]);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TGtkWSBitBtn }
|
{ TGtkWSBitBtn }
|
||||||
|
|
||||||
@ -148,61 +171,16 @@ begin
|
|||||||
Allocation.Height := AParams.Height;
|
Allocation.Height := AParams.Height;
|
||||||
gtk_widget_size_allocate(PGtkWidget(Result), @Allocation);
|
gtk_widget_size_allocate(PGtkWidget(Result), @Allocation);
|
||||||
|
|
||||||
TGtkWSButton.SetCallbacks(PGtkWidget(Result), WidgetInfo);
|
SetCallbacks(PGtkWidget(Result), WidgetInfo);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class procedure TGtkWSBitBtn.SetGlyph(const ABitBtn: TCustomBitBtn;
|
class procedure TGtkWSBitBtn.SetGlyph(const ABitBtn: TCustomBitBtn;
|
||||||
const AValue: TButtonGlyph);
|
const AValue: TButtonGlyph);
|
||||||
var
|
|
||||||
WidgetInfo: PWidgetInfo;
|
|
||||||
BitBtnInfo: PBitBtnWidgetInfo;
|
|
||||||
GDIObject: PGDIObject;
|
|
||||||
Mask: PGdkBitmap;
|
|
||||||
AGlyph: TBitmap;
|
|
||||||
AIndex: Integer;
|
|
||||||
AEffect: TGraphicsDrawEffect;
|
|
||||||
begin
|
begin
|
||||||
if not WSCheckHandleAllocated(ABitBtn, 'SetGlyph')
|
if not WSCheckHandleAllocated(ABitBtn, 'SetGlyph')
|
||||||
then Exit;
|
then Exit;
|
||||||
|
|
||||||
WidgetInfo := GetWidgetInfo(Pointer(ABitBtn.Handle));
|
UpdateGlyph(ABitBtn, AValue, GtkStateToButtonState[GTK_WIDGET_STATE(PGtkWidget(ABitBtn.Handle))]);
|
||||||
BitBtnInfo := WidgetInfo^.UserData;
|
|
||||||
|
|
||||||
AGlyph := TBitmap.Create;
|
|
||||||
AValue.GetImageIndexAndEffect(bsUp, AIndex, AEffect);
|
|
||||||
if (AIndex <> -1) and (AValue.Images <> nil) then
|
|
||||||
AValue.Images.GetBitmap(AIndex, AGlyph, AEffect);
|
|
||||||
// check if an image is needed
|
|
||||||
if (AGlyph.Handle = 0)
|
|
||||||
or (AGlyph.Width = 0)
|
|
||||||
or (AGlyph.Height = 0)
|
|
||||||
then begin
|
|
||||||
if BitBtnInfo^.ImageWidget <> nil
|
|
||||||
then begin
|
|
||||||
gtk_container_remove(BitBtnInfo^.TableWidget, BitBtnInfo^.ImageWidget);
|
|
||||||
BitBtnInfo^.ImageWidget := nil;
|
|
||||||
end;
|
|
||||||
AGlyph.Free;
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
GDIObject := PgdiObject(AGlyph.Handle);
|
|
||||||
Mask := CreateGdkMaskBitmap(AValue.Glyph.Handle, AValue.Glyph.MaskHandle);
|
|
||||||
|
|
||||||
// check for image
|
|
||||||
if BitBtnInfo^.ImageWidget = nil
|
|
||||||
then begin
|
|
||||||
BitBtnInfo^.ImageWidget :=
|
|
||||||
gtk_pixmap_new(GDIObject^.GDIPixmapObject.Image, Mask);
|
|
||||||
gtk_widget_show(BitBtnInfo^.ImageWidget);
|
|
||||||
UpdateLayout(BitBtnInfo, ABitBtn.Layout, ABitBtn.Margin);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
gtk_pixmap_set(BitBtnInfo^.ImageWidget, GDIObject^.GDIPixmapObject.Image, Mask);
|
|
||||||
end;
|
|
||||||
|
|
||||||
gdk_pixmap_unref(Mask);
|
|
||||||
AGlyph.Free;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class procedure TGtkWSBitBtn.SetLayout(const ABitBtn: TCustomBitBtn;
|
class procedure TGtkWSBitBtn.SetLayout(const ABitBtn: TCustomBitBtn;
|
||||||
@ -297,6 +275,57 @@ begin
|
|||||||
GtkWidgetSet.SetWidgetFont(BitBtnInfo^.LabelWidget, AFont);
|
GtkWidgetSet.SetWidgetFont(BitBtnInfo^.LabelWidget, AFont);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class procedure TGtkWSBitBtn.UpdateGlyph(const ABitBtn: TCustomBitBtn;
|
||||||
|
const AValue: TButtonGlyph; const AButtonState: TButtonState);
|
||||||
|
var
|
||||||
|
WidgetInfo: PWidgetInfo;
|
||||||
|
BitBtnInfo: PBitBtnWidgetInfo;
|
||||||
|
GDIObject: PGDIObject;
|
||||||
|
Mask: PGdkBitmap;
|
||||||
|
AGlyph: TBitmap;
|
||||||
|
AIndex: Integer;
|
||||||
|
AEffect: TGraphicsDrawEffect;
|
||||||
|
begin
|
||||||
|
WidgetInfo := GetWidgetInfo(Pointer(ABitBtn.Handle));
|
||||||
|
BitBtnInfo := WidgetInfo^.UserData;
|
||||||
|
|
||||||
|
AGlyph := TBitmap.Create;
|
||||||
|
AValue.GetImageIndexAndEffect(AButtonState, AIndex, AEffect);
|
||||||
|
if (AIndex <> -1) and (AValue.Images <> nil) then
|
||||||
|
AValue.Images.GetBitmap(AIndex, AGlyph, AEffect);
|
||||||
|
// check if an image is needed
|
||||||
|
if (AGlyph.Handle = 0)
|
||||||
|
or (AGlyph.Width = 0)
|
||||||
|
or (AGlyph.Height = 0)
|
||||||
|
then begin
|
||||||
|
if BitBtnInfo^.ImageWidget <> nil
|
||||||
|
then begin
|
||||||
|
gtk_container_remove(BitBtnInfo^.TableWidget, BitBtnInfo^.ImageWidget);
|
||||||
|
BitBtnInfo^.ImageWidget := nil;
|
||||||
|
end;
|
||||||
|
AGlyph.Free;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
GDIObject := PgdiObject(AGlyph.Handle);
|
||||||
|
Mask := CreateGdkMaskBitmap(AValue.Glyph.Handle, AValue.Glyph.MaskHandle);
|
||||||
|
|
||||||
|
// check for image
|
||||||
|
if BitBtnInfo^.ImageWidget = nil
|
||||||
|
then begin
|
||||||
|
BitBtnInfo^.ImageWidget :=
|
||||||
|
gtk_pixmap_new(GDIObject^.GDIPixmapObject.Image, Mask);
|
||||||
|
gtk_widget_show(BitBtnInfo^.ImageWidget);
|
||||||
|
UpdateLayout(BitBtnInfo, ABitBtn.Layout, ABitBtn.Margin);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
gtk_pixmap_set(BitBtnInfo^.ImageWidget, GDIObject^.GDIPixmapObject.Image, Mask);
|
||||||
|
end;
|
||||||
|
|
||||||
|
gdk_pixmap_unref(Mask);
|
||||||
|
AGlyph.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
class procedure TGtkWSBitBtn.UpdateLayout(const AInfo: PBitBtnWidgetInfo;
|
class procedure TGtkWSBitBtn.UpdateLayout(const AInfo: PBitBtnWidgetInfo;
|
||||||
const ALayout: TButtonLayout; const AMargin: Integer);
|
const ALayout: TButtonLayout; const AMargin: Integer);
|
||||||
begin
|
begin
|
||||||
@ -430,6 +459,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class procedure TGtkWSBitBtn.SetCallbacks(const AGtkWidget: PGtkWidget;
|
||||||
|
const AWidgetInfo: PWidgetInfo);
|
||||||
|
begin
|
||||||
|
TGtkWSButton.SetCallbacks(AGtkWidget, AWidgetInfo);
|
||||||
|
|
||||||
|
SignalConnect(AGtkWidget, 'state-changed', @GtkWSBitBtn_StateChanged, AWidgetInfo);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user