A crossplattform Class for Flatbuttons
Features:
- Text only Button
- Image only Button
- Mixed Button (Image left and Text right)
- Autoresize Image
- All Features of other Buttons, but without Toogle-Support
- Highlights on Mouseover with Hotcolor
- Sunken on press
- Gradients
- Focusrectangle
- Shortcuts
IncludeFile:
Code: Select all
;======================================================================
; Library:         FlatButtonEx.pbi
;
; Author:          Thomas (ts-soft) Schulz
; Date:            Feb 22, 2013
; Version:         1.9.1
; Target Compiler: PureBasic 5.1+
; Target OS:       Windows, Linux, MacOS
; License:         Free, unrestricted, no warranty whatsoever
;                  Use at your own risk
;======================================================================
; History
; Version 1.9.1
; fixed a flickering bug on mousemove
;
; Version 1.9 (Feb 26, 2013)
; added: Icon resizing is full supported (windows only)
; optimized code
;
; Version 1.8.4 (Feb 25, 2013)
; fixed a bug with right bottom pixel
;
; Version 1.8.3 (Feb 25, 2013)
; added Icon-Support for Windows
; Attention: Icons can't be resized!
;
; Version 1.8.2 (Feb 25, 2013)
; added default systemcolor for MacOSX, thx to wilbert
;
; Version 1.8.1 (Feb 25, 2013)
; added Support for texthotcolor
; new colorconstant: #FlatButtonEx_Color_TextHotColor
; Version 1.8 (Feb 25, 2013)
; added Gradient-Type: SetGradientType([Type.i[, customcallback.i]])
; with types:
;   #FlatButtonEx_Gradient_Linear (default)
;   #FlatButtonEx_Gradient_Boxed
;   #FlatButtonEx_Gradient_Custom (requires customcallback)
;
; Version 1.7 (Feb 24, 2013)
; added Gradient-Support
; SetGradient() and SetHotGradient()
;
; Version 1.6 (Feb 24, 2013)
; changed GetSpaceSupport() to GetShortCut()
; changed SetSpaceSupport() to SetShortCut(), default is #PB_Shortcut_Space, set to 0 for none shortcutsupport
; added default systemcolor for Linux, thx to uwekel
;
; Version 1.5 (Feb 24, 2013)
; added GetSpaceSupport() and SetSpaceSupport() methodes, to set or get this on runtime
; added GetCursor(), SetCursor() and SetCustomCursor methodes
; some Setter methodes return #TRUE on access
; some codeoptimation and bughunting
;
; Version 1.4 (Feb 23, 2013)
; fixed a bug with SupportKeyboard flag
; optimized the code
;
; Version 1.3 (Feb 23, 2013)
; added support for focusrectangle
; added support for spacebar to click
; changed Example to reflect the new features
;
; Version 1.2
; fixed bug with pressed button outside gadget
;
; Version 1.1
; fixed a memoryleak with images!
Declare.i FlatButtonEx_Update(*this, EventType = #PB_EventType_MouseLeave)
Declare.l FlatButtonEx_GetGadgetColor(Gadget.i, Type.i, State.i = 0)
Enumeration ; colortype
  #FlatButtonEx_Color_TextColor
  #FlatButtonEx_Color_TextHotColor
  #FlatButtonEx_Color_HotColor
  #FlatButtonEx_Color_BackColor
EndEnumeration
Enumeration ; gradienttype
  #FlatButtonEx_Gradient_Linear
  #FlatButtonEx_Gradient_Boxed
  #FlatButtonEx_Gradient_Custom
EndEnumeration
Enumeration ;gtk colortypes
  #GtkGadgetColorBase
  #GtkGadgetColorBg
  #GtkGadgetColorDark
  #GtkGadgetColorFg
  #GtkGadgetColorLight
  #GtkGadgetColorText
EndEnumeration
Enumeration ; gtk states
  #GtkStateNormal
  #GtkStateActive
  #GtkStatePrelight
  #GtkStateSelected
  #GtkStateIntensitive
EndEnumeration
Interface FlatButtonEx
  ; Getter Methodes
  GetID.i()
  GetX.i(Mode.i = #PB_Gadget_ContainerCoordinate)
  GetY.i(Mode.i = #PB_Gadget_ContainerCoordinate)
  GetWidth.i()
  GetHeight.i()
  GetData.i()
  GetColor.l(Type.i)
  GetText.s()
  GetImage.i()
  GetSizedImage.i()
  GetShortCut.i()
  GetCursor.i()
 
  ; Setter Methodes
  SetFont.i(Font.i = -1)
  SetColor.i(Type.i, Color.l)
  SetText.i(Text.s = "")
  SetImage.i(Image.i = -1)
  SetData.i(Value.i)
  SetToolTip.i(Text.s = "")
  SetShortCut.i(ShortCut.i = #PB_Shortcut_Space)
  SetCursor(Cursor.i = #PB_Cursor_Default)
  SetCustomCursor(Cursor.i)
  SetGradient(backcolor.l = -1, forecolor.l = -1)
  SetHotGradient(backcolor.l = -1, forecolor.l = -1)
  SetGradientType(Type.i = #FlatButtonEx_Gradient_Linear, customcallback.i = 0)
 
  ; Other Methodes
  Update(EventType.i = #PB_EventType_MouseLeave)
  Resize(x.i, y.i, w.i, h.i)
  Disable(State.i = #True)
  Hide(State.i = #True)
  Free()
EndInterface
Structure FlatButtonEx_ClassTemplate
  *vTable
  ID.i
  x.i
  y.i
  w.i
  h.i
  inactive.i
  text.s
  textcolor.l
  texthotcolor.l
  hotcolor.l
  backcolor.l
  gradientbackcolor.l
  gradientforecolor.l
  gradienthotbackcolor.l
  gradienthotforecolor.l
  gradienttype.i
  customcallback.i
  Image.i
  sizedImage.i
  IsIco.i
  Font.i
  ShortCut.i
EndStructure
Procedure New_FlatButtonEx(x.i, y.i, w.i, h.i, DrawFocus.i = #False, ShortCut.i = #PB_Shortcut_Space)
  Protected *object.FlatButtonEx_ClassTemplate, Flag.i = 0
 
  If DrawFocus : Flag | #PB_Canvas_DrawFocus : EndIf
 
  *object = AllocateMemory(SizeOf(FlatButtonEx_ClassTemplate))
  If *object
    With *object
      \vTable = ?vTable_FlatButtonEx
      \ID = CanvasGadget(#PB_Any, x, y, w, h, Flag)
      \x = x
      \y = y
      \w = w
      \h = h
      \text = ""
      \Image = -1
      \textcolor = 0
      \texthotcolor = -1
      \backcolor = FlatButtonEx_GetGadgetColor(\ID, #GtkGadgetColorBg)
      \hotcolor = FlatButtonEx_GetGadgetColor(\ID, #GtkGadgetColorLight)
      \gradientbackcolor = -1
      \gradientforecolor = -1
      \gradienthotbackcolor - 1
      \gradienthotforecolor = -1
      \gradienttype = #FlatButtonEx_Gradient_Linear
      \customcallback = 0
      \Image = -1
      \sizedImage = -1
      \Font = -1
      \ShortCut = ShortCut
    EndWith
    FlatButtonEx_Update(*object)
    ProcedureReturn *object
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetID(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn *this\ID
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetX(*this.FlatButtonEx_ClassTemplate, Mode.i = #PB_Gadget_ContainerCoordinate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn GadgetX(*this\ID, Mode)
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetY(*this.FlatButtonEx_ClassTemplate, Mode.i = #PB_Gadget_ContainerCoordinate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn GadgetY(*this\ID, Mode)
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetWidth(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn GadgetWidth(*this\ID)
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetHeight(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn GadgetHeight(*this\ID)
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetData(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn GetGadgetData(*this\ID)
  EndIf
EndProcedure
Procedure.l FlatButtonEx_GetColor(*this.FlatButtonEx_ClassTemplate, Type.i)
  If *this And IsGadget(*this\ID)
    Select Type
      Case #FlatButtonEx_Color_TextColor
        ProcedureReturn *this\textcolor
      Case #FlatButtonEx_Color_TextHotColor
        ProcedureReturn *this\texthotcolor
      Case #FlatButtonEx_Color_HotColor
        ProcedureReturn *this\hotcolor
      Case #FlatButtonEx_Color_BackColor
        ProcedureReturn *this\backcolor
    EndSelect
  EndIf
EndProcedure
Procedure.s FlatButtonEx_GetText(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn *this\text
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetImage(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn *this\Image
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetSizedImage(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn *this\sizedImage
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetShortCut(*this.FlatButtonEx_ClassTemplate)
  If *this And IsGadget(*this\ID)
    ProcedureReturn *this\ShortCut
  EndIf
EndProcedure
Procedure.i FlatButtonEx_GetCursor(*this.FlatButtonEx_ClassTemplate)
  Protected result.i
 
  If *this And IsGadget(*this\ID)
    With *this
      result = GetGadgetAttribute(\ID, #PB_Canvas_Cursor)
      If result = -1
        result = GetGadgetAttribute(\ID, #PB_Canvas_CustomCursor)
      EndIf
      ProcedureReturn result
    EndWith
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetFont(*this.FlatButtonEx_ClassTemplate, Font.i = -1)
  If *this And IsGadget(*this\ID)
    If IsFont(Font)
      *this\Font = Font
    Else
      *this\Font = -1
    EndIf
    FlatButtonEx_Update(*this)
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetColor(*this.FlatButtonEx_ClassTemplate, Type.i, Color.i)
  If *this And IsGadget(*this\ID)
    With *this
      Select Type
        Case #FlatButtonEx_Color_TextColor
          \textcolor = Color
        Case #FlatButtonEx_Color_TextHotColor
          \texthotcolor = Color
        Case #FlatButtonEx_Color_HotColor
          \hotcolor = Color
        Case #FlatButtonEx_Color_BackColor
          \backcolor = Color
      EndSelect
    EndWith
    FlatButtonEx_Update(*this)
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetText(*this.FlatButtonEx_ClassTemplate, Text.s = "")
  If *this And IsGadget(*this\ID)
    *this\text = Text
    FlatButtonEx_Update(*this)
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetImage(*this.FlatButtonEx_ClassTemplate, Image.i = -1)
  Protected img.i
  
  If *this And IsGadget(*this\ID)
    With *this
      If IsImage(\sizedImage)
        FreeImage(\sizedImage)
        \sizedImage = -1
      EndIf
      If \IsIco
        If IsImage(\Image) : FreeImage(\Image) : EndIf
      EndIf
      \IsIco = #False
      If IsImage(Image)
        If ImageFormat(Image) = #PB_ImagePlugin_ICON
          img = CreateImage(#PB_Any, ImageWidth(Image), ImageHeight(Image), 32)
          If img
            StartDrawing(ImageOutput(img))
              DrawingMode(#PB_2DDrawing_AllChannels)
              DrawImage(ImageID(Image), 0, 0)
            StopDrawing()
            Image = img
            \IsIco = #True
          EndIf
        EndIf
        \Image = Image
      Else
        \Image = -1
      EndIf
    EndWith
    FlatButtonEx_Update(*this)
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetData(*this.FlatButtonEx_ClassTemplate, Value.i)
  If *this And IsGadget(*this\ID)
    SetGadgetData(*this\ID, Value)
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetToolTip(*this.FlatButtonEx_ClassTemplate, Text.s = "")
  If *this And IsGadget(*this\ID)
    GadgetToolTip(*this\ID, Text)
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure.i FlatButtonEx_SetShortCut(*this.FlatButtonEx_ClassTemplate, ShortCut.i = #PB_Shortcut_Space)
  If *this And IsGadget(*this\ID)
    *this\ShortCut = ShortCut
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure FlatButtonEx_SetCursor(*this.FlatButtonEx_ClassTemplate, Cursor.i = #PB_Cursor_Default)
  If *this And IsGadget(*this\ID)
    SetGadgetAttribute(*this\ID, #PB_Canvas_Cursor, Cursor)
  EndIf
EndProcedure
Procedure FlatButtonEx_SetCustomCursor(*this.FlatButtonEx_ClassTemplate, Cursor.i)
  If *this And IsGadget(*this\ID)
    SetGadgetAttribute(*this\ID, #PB_Canvas_CustomCursor, Cursor)
  EndIf
EndProcedure
Procedure FlatButtonEx_SetGradient(*this.FlatButtonEx_ClassTemplate, backcolor.l = -1, forecolor.l = -1)
  If *this And IsGadget(*this\ID)
    With *this
      \gradientbackcolor = backcolor
      \gradientforecolor = forecolor
      FlatButtonEx_Update(*this)
    EndWith
  EndIf
EndProcedure
Procedure FlatButtonEx_SetHotGradient(*this.FlatButtonEx_ClassTemplate, backcolor.l = -1, forecolor.l = -1)
  If *this And IsGadget(*this\ID)
    With *this
      \gradienthotbackcolor = backcolor
      \gradienthotforecolor = forecolor
      FlatButtonEx_Update(*this)
    EndWith
  EndIf
EndProcedure
Procedure FlatButtonEx_SetGradientType(*this.FlatButtonEx_ClassTemplate, Type.i = #FlatButtonEx_Gradient_Linear, customcallback.i = 0)
  If *this And IsGadget(*this\ID)
    *this\gradienttype = Type
    *this\customcallback = customcallback
    FlatButtonEx_Update(*this)
  EndIf
EndProcedure
Procedure.l FlatButtonEx_GetGadgetColor(Gadget.i, Type.i, State.i = 0)
  ; by uwekel
  ; see: http://www.purebasic.fr/english/viewtopic.php?p=405822#p405822
  ; OSX part by wilbert
  ; see: http://www.purebasic.fr/english/viewtopic.php?p=405916#p405916
 
  CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
  ;returns a widget color
  Protected *style.GtkStyle, *color.GdkColor
  ;get widget style
  *style = gtk_widget_get_style_(GadgetID(Gadget))
  ;return color according type and state
  Select Type
    Case #GtkGadgetColorBase
      *color = *style\base[State]
    Case #GtkGadgetColorBg
      *color = *style\bg[State]
    Case #GtkGadgetColorDark
      *color = *style\dark[State]
    Case #GtkGadgetColorFg
      *color = *style\fg[State]
    Case #GtkGadgetColorLight
      *color = *style\light[State]
    Case #GtkGadgetColorText
      *color = *style\text[State]
  EndSelect
  ;return color value
  ProcedureReturn RGB(*color\red >> 8, *color\green >> 8, *color\blue >> 8)
  CompilerCase #PB_OS_Windows
  Select Type
    Case #GtkGadgetColorBg, #GtkGadgetColorBase
      If State = #GtkStateSelected
        ProcedureReturn GetSysColor_(#COLOR_HIGHLIGHT)
      Else
        ProcedureReturn GetSysColor_(#COLOR_WINDOW)
      EndIf
    Case #GtkGadgetColorFg, #GtkGadgetColorText
      If State = #GtkStateSelected
        ProcedureReturn GetSysColor_(#COLOR_HIGHLIGHTTEXT)
      Else
        ProcedureReturn GetSysColor_(#COLOR_WINDOWTEXT)
      EndIf
    Case #GtkGadgetColorDark
      ProcedureReturn GetSysColor_(#COLOR_BTNSHADOW)
    Case #GtkGadgetColorLight
      ProcedureReturn GetSysColor_(#COLOR_3DLIGHT)
  EndSelect
  CompilerCase #PB_OS_MacOS
  Protected ColorName.s, Color.i
  Protected.CGFloat R, G, B, A
  Select Type
    Case #GtkGadgetColorBg
      ColorName = "controlBackgroundColor"
    Case #GtkGadgetColorLight
      ColorName = "controlHighlightColor"
  EndSelect
  Color = CocoaMessage(0, 0, "NSColor " + ColorName)
  If Color : Color = CocoaMessage(0, Color, "colorUsingColorSpaceName:$", @"NSDeviceRGBColorSpace") : EndIf
  If Color : CocoaMessage(0, Color, "getRed:", @R, "green:", @G, "blue:", @B, "alpha:", @A) : EndIf
  ProcedureReturn RGBA(R * 255, G * 255, B * 255, A * 255)
  CompilerEndSelect
EndProcedure
CompilerIf Not Defined(IsMouseOverGadget, #PB_Procedure)
Procedure.i IsMouseOverGadget(window.i, gadget.i)
  If (WindowMouseX(window) >= GadgetX(gadget)) And (WindowMouseX(window) <= (GadgetX(gadget) + GadgetWidth(gadget)))
    If (WindowMouseY(window) >= GadgetY(gadget)) And (WindowMouseY(window) <= (GadgetY(gadget) + GadgetHeight(gadget)))
      ProcedureReturn #True
    EndIf
  EndIf
EndProcedure
CompilerEndIf
Macro _FlatButtonExGradient_
  If \gradientbackcolor <> -1 And \gradientforecolor <> -1
    DrawingMode(#PB_2DDrawing_Gradient)
    BackColor(\gradientbackcolor)
    FrontColor(\gradientforecolor)
    Select \gradienttype
      Case #FlatButtonEx_Gradient_Boxed
        BoxedGradient(0, 0, \w -1, \h -1)
      Case #FlatButtonEx_Gradient_Custom
        CustomGradient(\customcallback)
      Default
        LinearGradient(0, \h -1, \w -1, 0)
    EndSelect
    Box(0, 0, \w -1, \h -1)
    DrawingMode(#PB_2DDrawing_Transparent)
  EndIf
EndMacro
Macro _FlatButtonExDrawSunken_
  Box(0, 0, \w -1, \h -1, \backcolor)
  _FlatButtonExGradient_
  Line(0, 0, \w -1, 1, RGB(128, 128, 128))
  Line(0, \h- 1, \w -1, 1, RGB(255, 255, 255))
  Line(0, 0, 1, \h -1, RGB(128, 128, 128))
  Line(\w -1, 0, 1, \h, RGB(255, 255, 255))
  If \Font <> -1
    DrawingFont(FontID(\Font))
  EndIf
  If \Image <> -1
    If IsImage(\sizedImage) And ImageHeight(\sizedImage) = GadgetHeight(\ID) - 10
      If \text = ""
        If ImageWidth(\sizedImage) = GadgetWidth(\ID) - 10
          DrawAlphaImage(ImageID(\sizedImage), 6, GadgetHeight(\ID) - ImageHeight(\sizedImage) - 4)
        Else
          If \sizedImage And IsImage(\sizedImage) : FreeImage(\sizedImage) : EndIf
          img = CopyImage(\Image, #PB_Any)
          ResizeImage(img, GadgetWidth(\ID) - 10, GadgetHeight(\ID) - 10)
          DrawAlphaImage(ImageID(img), 6, GadgetHeight(\ID) - ImageHeight(img) - 4)
          \sizedImage = img
        EndIf
      Else
        If ImageWidth(\sizedImage) = GadgetWidth(\ID) - 10
          FreeImage(\sizedImage)
          img = CopyImage(\Image, #PB_Any)
          ResizeImage(img, GadgetHeight(\ID) - 10, GadgetHeight(\ID) - 10)
          \sizedImage = img
        EndIf
        DrawAlphaImage(ImageID(\sizedImage), 6, GadgetHeight(\ID) - ImageHeight(\sizedImage) - 4)
        DrawText(ImageWidth(\sizedImage) + 11, (GadgetHeight(\ID) - TextHeight(\text)) / 2 + 1, \text, \textcolor)
      EndIf
    Else
      If \text = ""
        img = CopyImage(\Image, #PB_Any)
        ResizeImage(img, GadgetWidth(\ID) - 10, GadgetHeight(\ID) - 10)
        DrawAlphaImage(ImageID(img), 6, GadgetHeight(\ID) - ImageHeight(img) - 4)
        \sizedImage = img     
      Else
        If \sizedImage And IsImage(\sizedImage) : FreeImage(\sizedImage) : EndIf
        img = CopyImage(\Image, #PB_Any)
        ResizeImage(img, GadgetHeight(\ID) - 10, GadgetHeight(\ID) - 10)
        DrawAlphaImage(ImageID(img), 6, GadgetHeight(\ID) - ImageHeight(img) - 4)
        DrawText(ImageWidth(img) + 11, (GadgetHeight(\ID) - TextHeight(\text)) / 2 + 1, \text, \textcolor)
        \sizedImage = img
      EndIf
    EndIf
  Else
    DrawText((GadgetWidth(\ID) - TextWidth(\text)) / 2 + 1, (GadgetHeight(\ID) - TextHeight(\text)) / 2 + 1, \text, \textcolor)
  EndIf
EndMacro
Macro _FlatButtonExDraw_
  If \Font <> -1
    DrawingFont(FontID(\Font))
  EndIf
  If \Image <> -1
    If IsImage(\sizedImage) And ImageHeight(\sizedImage) = GadgetHeight(\ID) - 10
      If \text = ""
        If ImageWidth(\sizedImage) = GadgetWidth(\ID) - 10
          DrawAlphaImage(ImageID(\sizedImage), 5, GadgetHeight(\ID) - ImageHeight(\sizedImage) - 5)
        Else
          If \sizedImage And IsImage(\sizedImage) : FreeImage(\sizedImage) : EndIf
          img = CopyImage(\Image, #PB_Any)
          ResizeImage(img, GadgetWidth(\ID) - 10, GadgetHeight(\ID) - 10)
          DrawAlphaImage(ImageID(img), 5, GadgetHeight(\ID) - ImageHeight(img) - 5)
          \sizedImage = img
        EndIf
      Else
        If ImageWidth(\sizedImage) = GadgetWidth(\ID) - 10 And ImageFormat(\sizedImage) <> #PB_ImagePlugin_ICON
          FreeImage(\sizedImage)
          img = CopyImage(\Image, #PB_Any)
          ResizeImage(img, GadgetHeight(\ID) - 10, GadgetHeight(\ID) - 10)
          \sizedImage = img
        EndIf
        DrawAlphaImage(ImageID(\sizedImage), 5, GadgetHeight(\ID) - ImageHeight(\sizedImage) - 5)
        If hot And \texthotcolor <> -1
          DrawText(ImageWidth(\sizedImage) + 10, (GadgetHeight(\ID) - TextHeight(\text)) / 2, \text, \texthotcolor)
        Else
          DrawText(ImageWidth(\sizedImage) + 10, (GadgetHeight(\ID) - TextHeight(\text)) / 2, \text, \textcolor)
        EndIf
      EndIf
    Else
      If \text = ""
        If \sizedImage And IsImage(\sizedImage) : FreeImage(\sizedImage) : EndIf
        img = CopyImage(\Image, #PB_Any)
        ResizeImage(img, GadgetWidth(\ID) - 10, GadgetHeight(\ID) - 10)
        DrawAlphaImage(ImageID(img), 5, GadgetHeight(\ID) - ImageHeight(img) - 5)
        \sizedImage = img     
      Else
        If \sizedImage And IsImage(\sizedImage) : FreeImage(\sizedImage) : EndIf
        img = CopyImage(\Image, #PB_Any)
        ResizeImage(img, GadgetHeight(\ID) - 10, GadgetHeight(\ID) - 10)
        DrawAlphaImage(ImageID(img), 5, GadgetHeight(\ID) - ImageHeight(img) - 5)
        If hot And \texthotcolor <> -1
          DrawText(ImageWidth(\sizedImage) + 10, (GadgetHeight(\ID) - TextHeight(\text)) / 2, \text, \texthotcolor)
        Else
          DrawText(ImageWidth(img) + 10, (GadgetHeight(\ID) - TextHeight(\text)) / 2, \text, \textcolor)
        EndIf
        \sizedImage = img
      EndIf
    EndIf
  Else
    If hot And \texthotcolor <> -1
      DrawText((GadgetWidth(\ID) - TextWidth(\text)) / 2, (GadgetHeight(\ID) - TextHeight(\text)) / 2, \text, \texthotcolor)
    Else
      DrawText((GadgetWidth(\ID) - TextWidth(\text)) / 2, (GadgetHeight(\ID) - TextHeight(\text)) / 2, \text, \textcolor)
    EndIf
  EndIf
EndMacro
Procedure FlatButtonEx_Update(*this.FlatButtonEx_ClassTemplate, EventType.i = #PB_EventType_MouseLeave)
  Protected img, hot = 0
 
  If *this And IsGadget(*this\ID)
    CompilerSelect #PB_Compiler_OS
      CompilerCase #PB_OS_Linux
        If GadgetWidth(*this\ID) > 10 And GadgetHeight(*this\ID) > 10 And EventType <> #PB_EventType_MouseMove
      CompilerDefault
        If GadgetWidth(*this\ID) > 10 And GadgetHeight(*this\ID) > 10
    CompilerEndSelect
      With *this
        StartDrawing(CanvasOutput(\ID))
          DrawingMode(#PB_2DDrawing_Transparent)
          If \inactive
            Box(0, 0, \w -1, \h -1, \backcolor)
            _FlatButtonExGradient_
            Line(0, 0, \w -1, 1, RGB(128, 128, 128))
            Line(0, \h -1, \w -1, 1, RGB(128, 128, 128))
            Line(0, 0, 1, \h -1, RGB(128, 128, 128))
            Line(\w -1, 0, 1, \h, RGB(128, 128, 128))
            _FlatButtonExDraw_
          ElseIf IsWindow(GetActiveWindow()) And EventType = #PB_EventType_KeyDown
            If GetGadgetAttribute(\ID, #PB_Canvas_Key) = \ShortCut
              _FlatButtonExDrawSunken_
              While WindowEvent() : Wend
            EndIf
           
          ElseIf IsWindow(GetActiveWindow()) And EventType = #PB_EventType_KeyUp
            If GetGadgetAttribute(\ID, #PB_Canvas_Key) = \ShortCut
              Box(0, 0, \w - 1, \h -1, \backcolor)
              _FlatButtonExGradient_
              Line(0, 0, \w -1, 1, RGB(128, 128, 128))
              Line(0, \h -1, \w -1, 1, RGB(128, 128, 128))
              Line(0, 0, 1, \h -1, RGB(128, 128, 128))
              Line(\w -1, 0, 1, \h, RGB(128, 128, 128))
              _FlatButtonExDraw_
              PostEvent(#PB_Event_Gadget, GetActiveWindow(), \ID, #PB_EventType_LeftClick)
            EndIf
 
          ElseIf IsWindow(GetActiveWindow()) And Not IsMouseOverGadget(GetActiveWindow(), \ID)
            Box(0, 0, \w -1, \h -1, \backcolor)
            _FlatButtonExGradient_
            Line(0, 0, \w -1, 1, RGB(128, 128, 128))
            Line(0, \h -1, \w -1, 1, RGB(128, 128, 128))
            Line(0, 0, 1, \h -1, RGB(128, 128, 128))
            Line(\w -1, 0, 1, \h, RGB(128, 128, 128))
            _FlatButtonExDraw_
            WindowEvent()           
          Else
            Select EventType
              Case #PB_EventType_MouseEnter, #PB_EventType_LeftButtonUp
                hot = #True
                Box(0, 0, \w - 1, \h -1, \backcolor)
                _FlatButtonExGradient_
                Line(0, 0, \w -1, 1, RGB(128, 128, 128))
                Line(0, \h -1, \w -1, 1, RGB(128, 128, 128))
                Line(0, 0, 1, \h -1, RGB(128, 128, 128))
                Line(\w -1, 0, 1, \h, RGB(128, 128, 128))
                Box(2, 2, \w -3, \h -3, \hotcolor)
                If \gradienthotbackcolor <> -1 And \gradienthotforecolor <> -1
                  DrawingMode(#PB_2DDrawing_Gradient)
                  BackColor(\gradienthotbackcolor)
                  FrontColor(\gradienthotforecolor)
                  Select \gradienttype
                    Case #FlatButtonEx_Gradient_Boxed
                      BoxedGradient(0, 0, \w -1, \h -1)
                    Case #FlatButtonEx_Gradient_Custom
                      CustomGradient(\customcallback)
                    Default
                      LinearGradient(0, \h -1, \w -1, 0)
                  EndSelect
                  Box(2, 2, \w -3, \h -3)
                  DrawingMode(#PB_2DDrawing_Transparent)
                EndIf
                _FlatButtonExDraw_
               
              Case #PB_EventType_MouseLeave
                Box(0, 0, \w -1, \h -1, \backcolor)
                _FlatButtonExGradient_
                Line(0, 0, \w -1, 1, RGB(128, 128, 128))
                Line(0, \h -1, \w -1, 1, RGB(128, 128, 128))
                Line(0, 0, 1, \h -1, RGB(128, 128, 128))
                Line(\w -1, 0, 1, \h, RGB(128, 128, 128))
                _FlatButtonExDraw_
             
              Case #PB_EventType_LeftButtonDown
                _FlatButtonExDrawSunken_
            EndSelect
          EndIf
        StopDrawing()
      EndWith
    EndIf
  EndIf
EndProcedure
Procedure FlatButtonEx_Resize(*this.FlatButtonEx_ClassTemplate, x.i, y.i, w.i, h.i)
  If *this
    With *this
      If IsGadget(\ID)
        If x <> #PB_Ignore : \x = x : EndIf
        If y <> #PB_Ignore : \y = y : EndIf
        If w <> #PB_Ignore : \w = w : EndIf
        If h <> #PB_Ignore : \h = h : EndIf
        ResizeGadget(\ID, x, y, w, h)
        FlatButtonEx_Update(*this)
      EndIf
    EndWith
  EndIf
EndProcedure
Procedure FlatButtonEx_Disable(*this.FlatButtonEx_ClassTemplate, State.i = #True)
  If *this
    If IsGadget(*this\ID)
      *this\inactive = State
      FlatButtonEx_Update(*this)
      DisableGadget(*this\ID, State)
    EndIf
  EndIf
EndProcedure
Procedure FlatButtonEx_Hide(*this.FlatButtonEx_ClassTemplate, State.i = #True)
  If *this
    If IsGadget(*this\ID)
      HideGadget(*this\ID, State)
      FlatButtonEx_Update(*this)
    EndIf
  EndIf
EndProcedure
Procedure FlatButtonEx_Free(*this.FlatButtonEx_ClassTemplate)
  If *this
    With *this
      If IsGadget(\ID) : FreeGadget(\ID) : EndIf
      If IsImage(\sizedImage) : FreeImage(\sizedImage) : EndIf
      If \IsIco
        If IsImage(\Image) : FreeImage(\Image) : EndIf
      EndIf
    EndWith
    FreeMemory(*this)
    *this = 0
  EndIf
EndProcedure
DataSection
  vTable_FlatButtonEx:
  ; Getter Methodes
  Data.i @FlatButtonEx_GetID()
  Data.i @FlatButtonEx_GetX()
  Data.i @FlatButtonEx_GetY()
  Data.i @FlatButtonEx_GetWidth()
  Data.i @FlatButtonEx_GetHeight()
  Data.i @FlatButtonEx_GetData()
  Data.i @FlatButtonEx_GetColor()
  Data.i @FlatButtonEx_GetText()
  Data.i @FlatButtonEx_GetImage()
  Data.i @FlatButtonEx_GetSizedImage()
  Data.i @FlatButtonEx_GetShortCut()
  Data.i @FlatButtonEx_GetCursor()
 
  ; Setter Methodes
  Data.i @FlatButtonEx_SetFont()
  Data.i @FlatButtonEx_SetColor()
  Data.i @FlatButtonEx_SetText()
  Data.i @FlatButtonEx_SetImage()
  Data.i @FlatButtonEx_SetData()
  Data.i @FlatButtonEx_SetToolTip()
  Data.i @FlatButtonEx_SetShortCut()
  Data.i @FlatButtonEx_SetCursor()
  Data.i @FlatButtonEx_SetCustomCursor()
  Data.i @FlatButtonEx_SetGradient()
  Data.i @FlatButtonEx_SetHotGradient()
  Data.i @FlatButtonEx_SetGradientType()
 
  ; Other Methodes
  Data.i @FlatButtonEx_Update()
  Data.i @FlatButtonEx_Resize()
  Data.i @FlatButtonEx_Disable()
  Data.i @FlatButtonEx_Hide()
  Data.i @FlatButtonEx_Free()
EndDataSection
/ edit
Updated, fixed a memoryleak with images.







