I just want to share my button include to make such buttons:
It works on Windows and Linux in single-byte or unicode-mode. I did not test on x64 architecture.
Update on 14th April 2012: added multi window capabilities and horizontal icon (left from text) using rbutton_CreateH()
Update on 16th July 2012: added rbutton_Hide() function to effectively hide/unhide buttons
Code of rbutton_include.pbi:
Code: Select all
; Compiles on Windows and Linux (tested 32 Bit, 64bit, single-byte and unicode)
; works with EnableExplicit
; Usage example with loaded backgrounds (normal and hover):
; rbutton_SetFont("Verdana", 16, 0, RGB(255,255,255), -120)
; rbutton_Init(CatchImage(#PB_Any, ?Back), CatchImage(#PB_Any, ?BackHover))
; Define regButton1.i = rbutton_Create(#PB_Any, "display", 10, 10, LoadImage(#PB_Any, "display.png"))
;
; Usage example with self drawn background
; rbutton_SetFont("Verdana", 16, 0, RGB(255,255,255), -120)
; rbutton_Init_OwnerDrawn(120, 120, RGBA(255,255,255,255), RGBA(214,226,236,255), RGBA(120,158,191,255), RGBA(255,255,255,255), RGBA(90,167,255,255),15, 2)
; Define regButton1.i = rbutton_Create(#PB_Any, WindowID, "display", 10, 10, LoadImage(#PB_Any, "display.png"))
;
; Do a call to rbutton_CheckHover(WinID) in your event-loop to enable hover effect
;
; HINT: You can call rbutton_Init(), rbutton_Init_OwnerDrawn() and rbutton_SetFont() multiple
; times to make different buttons on the same window/screen.
UsePNGImageDecoder()
#button_ShaddowWidth = 5 ; how wide the shaddow will be around the button (default 5)
#button_ShaddowOpacity = 30 ; 'darkness' of the surrounding shaddow: 10 = light 100 = heavy (default 30)
#button_HoverDimm = 20 ; hover-effect dimming of the background gradient (>0 = lighten, <0 = darken) (default 20)
#button_ScaleFactor = 2 ; making smoother, do not change (default 2)
Structure structrButtonList
Caption.s ; Gadget Caption
Disabled.b ; #True or #False
Hidden.b ; #True or #False
GadgetID.i ; image-gadget ID
ButtonImageID_draw.i ; image-id of image to draw onto
ButtonImageID_normal.i ; image-id of background image normal
ButtonImageID_hover.i ; image-id of background image hover
X.i ; Gadget X
Y.i ; Gadget Y
Width.i ; Gadget Width
Height.i ; Gadget Height
IconImageID.i ; Icon image-id
IconWidth.i ; Icon Width
IconHeight.i ; Icon Height
IconX.i ; Icon position X in Gadget
IconY.i ; Icon position Y in Gadget
TextX.i ; Text Position X in Gadget
TextY.i ; Text Position Y in Gadget
FontName.s
FontSize.i
FontStyle.i
FontColor.i
ShaddowDimm.i
WindowID.i ; ID of the window this button is drawn on
EndStructure
Structure structrButton
rButtonImageID_normal.i
rButtonImageID_hover.i
FontName.s
FontSize.i
FontStyle.i
FontColor.i
ShaddowDimm.i
LineThickness.i
List ButtonList.structrButtonList()
EndStructure
Global rButton.structrButton
; Makes the cursor in the window (parent of given Gadget) to a hand
; Works both windows and linux
Procedure.b rbutton_MakeCursorHand(GadgetID.i)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
; WINDOWS
Static *cursor
If *cursor = 0
*cursor = LoadCursor_(0, #IDC_HAND)
EndIf
SetCursor_(*cursor)
CompilerCase #PB_OS_Linux
; LINUX
Static *cursor.GdkCursor
If *cursor = 0
*cursor = gdk_cursor_new_(#GDK_HAND1);
EndIf
gdk_window_set_cursor_(gtk_widget_get_parent_window_(GadgetID(GadgetID.i)), *cursor)
CompilerCase #PB_OS_MacOS
; MAC
; write me!
CompilerEndSelect
EndProcedure
; Checks, if the current mouse position is over the given gadget.
; Returns #True in case of success, otherwise #False.
; Use this in your GUI loop (for example to change the cursor in
; conjunction with rbutton_MakeCursorHand()).
Procedure.b rbutton_MouseOverGadget(WindowID.i, GadgetID.i)
Protected MX.i = WindowMouseX(WindowID.i)
Protected MY.i = WindowMouseY(WindowID.i)
Protected GX.i = GadgetX(GadgetID.i)
Protected GY.i = GadgetY(GadgetID.i)
Protected GW.i = GadgetWidth(GadgetID.i)
Protected GH.i = GadgetHeight(GadgetID.i)
If MX.i > GX.i And MX.i < (GX.i + GW.i) And MY.i > GY.i And MY.i < (GY.i + GH.i)
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
; Helping function to dimm a color.
; Example:
; NewColor.i = rbutton_DimmColor(OriginalColor.i, -50); reduce by 50
Procedure.i rbutton_DimmColor(OriginalColor.i, Dimm.i)
Protected R.i = Red(OriginalColor.i)
Protected G.i = Green(OriginalColor.i)
Protected B.i = Blue(OriginalColor.i)
R.i = R.i + Dimm.i: If R.i < 0: R.i = 0: EndIf: If R.i > 255: R.i = 255: EndIf
G.i = G.i + Dimm.i: If G.i < 0: G.i = 0: EndIf: If G.i > 255: G.i = 255: EndIf
B.i = B.i + Dimm.i: If B.i < 0: B.i = 0: EndIf: If B.i > 255: B.i = 255: EndIf
ProcedureReturn RGB(R.i, G.i, B.i)
EndProcedure
; Set the font for the r-style buttons.
; Need to be called before creating the first button.
; FontStyle.i follows the purebasic LoadFont() constants like #PB_Font_Bold.
Procedure.b rbutton_SetFont(FontName.s, FontSize.i, FontStyle.i = 0, FontColor.i = 0, ShaddowDimm.i = 0)
With rButton
\FontName = FontName.s
\FontSize = FontSize.i
\FontStyle = FontStyle.i
\FontColor = FontColor.i
\ShaddowDimm = ShaddowDimm.i
EndWith
ProcedureReturn #True
EndProcedure
; Initialize main rbutton preferences with own drawn images
Procedure.b rbutton_Init_OwnerDrawn(Width.i, Height.i, BackgroundColor.i, TopColor.i, BottomColor.i, LineColor.i, LineColorSelected.i, EdgeRadius.f = 15, LineThickness.i = 2)
Protected x.i, EdgeRadiusUse.f
Width.i = Width.i * #button_ScaleFactor
Height.i = Height.i * #button_ScaleFactor
EdgeRadiusUse.f = EdgeRadius.f * #button_ScaleFactor
LineThickness.i = LineThickness.i * #button_ScaleFactor
Protected BackImage.i = CreateImage(#PB_Any, Width.i, Height.i, #PB_Image_Transparent | 32)
Protected ShaddowWidth.f = #button_ShaddowWidth
Protected CenterX.f = Width.i / 2
Protected CenterY.f = Height.i / 2
Protected XRadius.f = Width.i / 2 + #button_ScaleFactor
Protected YRadius.f = Height.i / 2 + #button_ScaleFactor
StartDrawing(ImageOutput(BackImage.i))
DrawingMode(#PB_2DDrawing_AlphaBlend)
; make background with background color
Box(0, 0, Width.i, Height.i, RGBA(Red(BackgroundColor.i), Green(BackgroundColor.i), Blue(BackgroundColor.i), 255))
LineColor.i = RGBA(Red(LineColor.i), Green(LineColor.i), Blue(LineColor.i), 255)
LineColorSelected.i = RGBA(Red(LineColorSelected.i), Green(LineColorSelected.i), Blue(LineColorSelected.i), 255)
; make shaddows
DrawingMode(#PB_2DDrawing_AlphaBlend)
Protected ShaddowStep.f = #button_ShaddowOpacity / ShaddowWidth.f
For x.i = 1 To ShaddowWidth.f
XRadius.f = XRadius.f - #button_ScaleFactor
YRadius.f = YRadius.f - #button_ScaleFactor
EdgeRadiusUse.f = EdgeRadiusUse.f - #button_ScaleFactor / 2
If EdgeRadiusUse.f < 0: EdgeRadiusUse.f = 0: EndIf
RoundBox(CenterX.f - XRadius.f, CenterY.f - YRadius.f, XRadius.f * 2, YRadius.f * 2, EdgeRadiusUse.f, EdgeRadiusUse.f, RGBA(0,0,0, x.i * ShaddowStep.f))
Next
; make border with LineColor
DrawingMode(#PB_2DDrawing_AllChannels)
RoundBox(CenterX.f - XRadius.f, CenterY.f - YRadius.f, XRadius.f * 2, YRadius.f * 2, EdgeRadiusUse.f, EdgeRadiusUse.f, LineColor.i)
XRadius.f = XRadius.f - LineThickness.i
YRadius.f = YRadius.f - LineThickness.i
EdgeRadiusUse.f = EdgeRadiusUse.f - LineThickness.i
If EdgeRadiusUse.f < 0: EdgeRadiusUse.f = 0: EndIf
; background gradient
DrawingMode(#PB_2DDrawing_Gradient)
BackColor(TopColor.i)
FrontColor(BottomColor.i)
Protected Rotate.f = YRadius.f / 2
LinearGradient(CenterX.f, CenterY.f - YRadius.f, CenterX.f + Rotate.f, CenterY.f + YRadius.f)
RoundBox(CenterX.f - XRadius.f, CenterY.f - YRadius.f, XRadius.f * 2, YRadius.f * 2, EdgeRadiusUse.f, EdgeRadiusUse.f)
StopDrawing()
ResizeImage(BackImage.i, Width.i / #button_ScaleFactor, Height.i / #button_ScaleFactor, #PB_Image_Smooth)
Protected ButtonImageNormalID.i = BackImage.i
; HOVER IMAGE
Protected BackImageHover.i = CreateImage(#PB_Any, Width.i, Height.i, #PB_Image_Transparent | 32)
EdgeRadiusUse.f = EdgeRadius.f * #button_ScaleFactor
XRadius.f = Width.i / 2 + #button_ScaleFactor
YRadius.f = Height.i / 2 + #button_ScaleFactor
StartDrawing(ImageOutput(BackImageHover.i))
DrawingMode(#PB_2DDrawing_AlphaBlend)
; make background with background color
Box(0, 0, Width.i, Height.i, RGBA(Red(BackgroundColor.i), Green(BackgroundColor.i), Blue(BackgroundColor.i), 255))
; dimm colors for hover effect
TopColor.i = rbutton_DimmColor(TopColor.i, #button_HoverDimm)
BottomColor.i = rbutton_DimmColor(BottomColor.i, #button_HoverDimm)
; make shaddows
DrawingMode(#PB_2DDrawing_AlphaBlend)
ShaddowStep.f = #button_ShaddowOpacity / ShaddowWidth.f
For x.i = 1 To ShaddowWidth.f
XRadius.f = XRadius.f - #button_ScaleFactor
YRadius.f = YRadius.f - #button_ScaleFactor
EdgeRadiusUse.f = EdgeRadiusUse.f - #button_ScaleFactor / 2
If EdgeRadiusUse.f < 0: EdgeRadiusUse.f = 0: EndIf
RoundBox(CenterX.f - XRadius.f, CenterY.f - YRadius.f, XRadius.f * 2, YRadius.f * 2, EdgeRadiusUse.f, EdgeRadiusUse.f, RGBA(0,0,0, x.i * ShaddowStep.f))
Next
; make border with LineColor
DrawingMode(#PB_2DDrawing_AllChannels)
RoundBox(CenterX.f - XRadius.f, CenterY.f - YRadius.f, XRadius.f * 2, YRadius.f * 2, EdgeRadiusUse.f, EdgeRadiusUse.f, LineColorSelected.i)
XRadius.f = XRadius.f - LineThickness.i
YRadius.f = YRadius.f - LineThickness.i
EdgeRadiusUse.f = EdgeRadiusUse.f - LineThickness.i
If EdgeRadiusUse.f < 0: EdgeRadiusUse.f = 0: EndIf
; background gradient
DrawingMode(#PB_2DDrawing_Gradient)
BackColor(TopColor.i)
FrontColor(BottomColor.i)
Rotate.f = YRadius.f / 2
LinearGradient(CenterX.f, CenterY.f - YRadius.f, CenterX.f + Rotate.f, CenterY.f + YRadius.f)
RoundBox(CenterX.f - XRadius.f, CenterY.f - YRadius.f, XRadius.f * 2, YRadius.f * 2, EdgeRadiusUse.f, EdgeRadiusUse.f)
StopDrawing()
ResizeImage(BackImageHover.i, Width.i / #button_ScaleFactor, Height.i / #button_ScaleFactor, #PB_Image_Smooth)
Protected ButtonImageHoverID.i = BackImageHover.i
With rButton
\rButtonImageID_normal = ButtonImageNormalID.i
\rButtonImageID_hover = ButtonImageHoverID.i
\LineThickness = LineThickness.i ; for later use while drawing
EndWith
EndProcedure
; Initialize main rbutton preferences:
; ButtonImageNormalID.i = ImageID of an image to use as button background
; ButtonImageHoverID.i = ImageID of an image to use as button background in case of mouse-hover (same size!)
Procedure.b rbutton_Init(ButtonImageNormalID.i, ButtonImageHoverID.i)
With rButton
\rButtonImageID_normal = ButtonImageNormalID.i
\rButtonImageID_hover = ButtonImageHoverID.i
EndWith
EndProcedure
; Filter-procedure for disabled icons in rbutton_Redraw-Function
Procedure rbutton_FilterCallback(x, y, SourceColor, DestinationColor)
Protected AlphaVal = Alpha(SourceColor)
Protected AlphaValNeg = 255-Alpha(SourceColor)
Protected NewRed = (Green(SourceColor) * 0.7 * AlphaVal + Red(DestinationColor) * AlphaValNeg) / 255
Protected NewBlu = (Green(SourceColor) * 0.7 * AlphaVal + Blue(DestinationColor) * AlphaValNeg) / 255
Protected NewGre = (Green(SourceColor) * 0.7 * AlphaVal + Green(DestinationColor) * AlphaValNeg) / 255
If NewRed > 255: NewRed = 255: EndIf
If NewBlu > 255: NewBlu = 255: EndIf
If NewGre > 255: NewGre = 255: EndIf
Protected NewColor = RGBA(NewRed, NewGre, NewBlu, 255)
ProcedureReturn NewColor
EndProcedure
; Redraws an existing r button
; state=0 -> normal
; state=1 -> hover / highlighted
Procedure.b rbutton_Redraw(rGadgetID.i, State.i)
Protected Found.b = #False
Protected TextColor.i
Protected IconLift.i
Protected FontName.s, FontSize.i, FontColor.i, FontStyle.i, ShaddowColor.i
Protected XP.i, YP.i, Caption.s
ForEach rButton\ButtonList()
If rButton\ButtonList()\GadgetID = rGadgetID.i
Found.b = #True
Break
EndIf
Next
If Found.b = #False
; Debug "rGadgetID " + Str(rGadgetID.i) + " not found (Redraw)!"
ProcedureReturn #False
EndIf
If rButton\ButtonList()\Caption <> ""
Protected MyFontID.i = LoadFont(#PB_Any, rButton\ButtonList()\FontName, rButton\ButtonList()\FontSize, rButton\ButtonList()\FontStyle) ; load font in desired size
EndIf
; draw background
StartDrawing(ImageOutput(rButton\ButtonList()\ButtonImageID_draw))
Box(0, 0, rButton\ButtonList()\Width, rButton\ButtonList()\Height, RGBA(0,0,0,0)) ; init as transparent background
If rButton\ButtonList()\Caption <> ""
DrawingFont(FontID(MyFontID.i))
EndIf
DrawingMode(#PB_2DDrawing_AlphaBlend)
If rButton\ButtonList()\Disabled = #False
; -- ENABLED --
If State.i = 0
DrawImage(ImageID(rButton\ButtonList()\ButtonImageID_normal), 0, 0)
FontColor.i = rbutton_DimmColor(rButton\ButtonList()\FontColor, -10)
ShaddowColor.i = rbutton_DimmColor(rButton\ButtonList()\FontColor, rButton\ButtonList()\ShaddowDimm - 10)
IconLift.i = 0
EndIf
If State.i = 1
DrawImage(ImageID(rButton\ButtonList()\ButtonImageID_hover), 0, 0)
FontColor.i = rButton\ButtonList()\FontColor
ShaddowColor.i = rbutton_DimmColor(rButton\ButtonList()\FontColor, rButton\ButtonList()\ShaddowDimm)
IconLift.i = -1
EndIf
; draw icon
If rButton\ButtonList()\IconImageID <> 0
DrawImage(ImageID(rButton\ButtonList()\IconImageID), rButton\ButtonList()\IconX, rButton\ButtonList()\IconY + IconLift.i)
EndIf
If rButton\ButtonList()\Caption <> ""
; draw caption
DrawingMode(#PB_2DDrawing_Transparent)
Caption.s = rButton\ButtonList()\Caption
If ShaddowColor.i <> FontColor.i
DrawText(rButton\ButtonList()\TextX + 1, rButton\ButtonList()\TextY + 1 + IconLift.i, Caption.s, ShaddowColor.i); shaddow
EndIf
DrawText(rButton\ButtonList()\TextX, rButton\ButtonList()\TextY + IconLift.i, Caption.s, FontColor.i) ; real
EndIf
Else
; -- DISABLED --
DrawImage(ImageID(rButton\ButtonList()\ButtonImageID_normal), 0, 0)
; draw icon
If rButton\ButtonList()\IconImageID <> 0
DrawingMode(#PB_2DDrawing_CustomFilter)
CustomFilterCallback(@rbutton_FilterCallback())
DrawImage(ImageID(rButton\ButtonList()\IconImageID), rButton\ButtonList()\IconX, rButton\ButtonList()\IconY)
EndIf
If rButton\ButtonList()\Caption <> ""
; draw caption
FontColor.i = rbutton_DimmColor(rButton\ButtonList()\FontColor, 120)
ShaddowColor.i = rbutton_DimmColor(rButton\ButtonList()\FontColor, 180)
IconLift.i = 0
DrawingMode(#PB_2DDrawing_Transparent)
Caption.s = rButton\ButtonList()\Caption
If ShaddowColor.i <> FontColor.i
DrawText(rButton\ButtonList()\TextX+1, rButton\ButtonList()\TextY + 1, Caption.s, ShaddowColor.i); shaddow
EndIf
DrawText(rButton\ButtonList()\TextX, rButton\ButtonList()\TextY, Caption.s, FontColor.i) ; real
EndIf
EndIf
StopDrawing()
If IsFont(MyFontID.i)
FreeFont(MyFontID.i)
EndIf
; set final image to ImageGadget
SetGadgetState(rGadgetID.i, ImageID(rButton\ButtonList()\ButtonImageID_draw))
ProcedureReturn #True
EndProcedure
; Creates a new r-style button in vertical mode (icon on top of text).
; The size depends on the used background-image.
Procedure.i rbutton_Create(Gadget.i, WindowID.i, Caption.s, PosX.i, PosY.i, IconImageID.i = 0)
Protected FontName.s, FontSize.i, FontColor.i, FontStyle.i, ShaddowColor.i
With rButton
If \FontName = "" : FontName.s = "Verdana": Else : FontName.s = \FontName: EndIf ; use defaults
If \FontSize = 0 : FontSize.i = 16 : Else : FontSize.i = \FontSize: EndIf ; use defaults
FontStyle.i = \FontStyle
FontColor.i = rbutton_DimmColor(\FontColor, -10)
ShaddowColor.i = rbutton_DimmColor(\FontColor, \ShaddowDimm - 10)
; load images, if needed
If \rButtonImageID_normal = 0
Debug "Need to call rbutton_Init() at first!"
ProcedureReturn
EndIf
If \rButtonImageID_hover = 0
Debug "Need to call rbutton_Init() at first!"
ProcedureReturn
EndIf
; prepare button and load images
AddElement(\ButtonList())
\ButtonList()\ButtonImageID_normal = \rButtonImageID_normal
\ButtonList()\ButtonImageID_hover = \rButtonImageID_hover
\ButtonList()\IconImageID = IconImageID.i
\ButtonList()\X = PosX.i
\ButtonList()\Y = PosY.i
\ButtonList()\Width = ImageWidth(\rButtonImageID_normal)
\ButtonList()\Height = ImageHeight(\rButtonImageID_normal)
\ButtonList()\Caption = Caption.s
\ButtonList()\ButtonImageID_draw = CreateImage(#PB_Any, \ButtonList()\Width, \ButtonList()\Height, 32)
\ButtonList()\FontName = \FontName
\ButtonList()\FontSize = \FontSize
\ButtonList()\FontStyle = \FontStyle
\ButtonList()\FontColor = \FontColor
\ButtonList()\ShaddowDimm = \ShaddowDimm
\ButtonList()\WindowID = WindowID.i
If IconImageID.i <> 0
\ButtonList()\IconWidth = ImageWidth(\ButtonList()\IconImageID)
\ButtonList()\IconHeight = ImageHeight(\ButtonList()\IconImageID)
Else
\ButtonList()\IconWidth = 0
\ButtonList()\IconHeight = 0
EndIf
Protected XP.i
Protected YP.i
If \ButtonList()\Caption <> ""
; with caption (icon shifted up)
XP.i = \ButtonList()\Width / 2 - \ButtonList()\IconWidth / 2
YP.i = (\ButtonList()\Height * 0.8) / 2 - \ButtonList()\IconHeight / 2
Else
; no caption (center icon)
XP.i = \ButtonList()\Width / 2 - \ButtonList()\IconWidth / 2
YP.i = \ButtonList()\Height / 2 - \ButtonList()\IconHeight / 2
EndIf
\ButtonList()\IconX = XP.i
\ButtonList()\IconY = YP.i
; draw caption
; start drawing only for gathering the correct values for textwidth/height
; generate image values
Protected MyFontID.i = LoadFont(#PB_Any, FontName.s, FontSize.i, FontStyle.i) ; load font in desired size
StartDrawing(ImageOutput(\ButtonList()\ButtonImageID_draw))
DrawingFont(FontID(MyFontID.i))
If IconImageID.i <> 0
; text lowered
XP.i = \ButtonList()\Width / 2 - TextWidth(Caption.s) / 2
YP.i = \ButtonList()\Height * 0.75 - TextHeight(Caption.s) / 2
Else
; text centered
XP.i = \ButtonList()\Width / 2 - TextWidth(Caption.s) / 2
YP.i = \ButtonList()\Height / 2 - TextHeight(Caption.s) / 2
EndIf
\ButtonList()\TextX = XP.i
\ButtonList()\TextY = YP.i
StopDrawing()
FreeFont(MyFontID.i)
; create gadget
Protected newGadgetID.i = ImageGadget(Gadget.i, PosX.i, PosY.i, \ButtonList()\Width, \ButtonList()\Height, ImageID(\ButtonList()\ButtonImageID_draw))
If Gadget.i = #PB_Any
\ButtonList()\GadgetID = newGadgetID.i
Else
\ButtonList()\GadgetID = Gadget.i
EndIf
rbutton_Redraw(\ButtonList()\GadgetID, 0)
EndWith
ProcedureReturn newGadgetID.i
EndProcedure
; Creates a new r-style button in horizontal mode (icon left from text).
; The size depends on the used background-image.
Procedure.i rbutton_CreateH(Gadget.i, WindowID.i, Caption.s, PosX.i, PosY.i, IconImageID.i = 0)
Protected FontName.s, FontSize.i, FontColor.i, FontStyle.i, ShaddowColor.i
With rButton
If \FontName = "" : FontName.s = "Verdana": Else : FontName.s = \FontName: EndIf ; use defaults
If \FontSize = 0 : FontSize.i = 16 : Else : FontSize.i = \FontSize: EndIf ; use defaults
FontStyle.i = \FontStyle
FontColor.i = rbutton_DimmColor(\FontColor, -10)
ShaddowColor.i = rbutton_DimmColor(\FontColor, \ShaddowDimm - 10)
; load images, if needed
If \rButtonImageID_normal = 0
Debug "Need to call rbutton_Init() at first!"
ProcedureReturn
EndIf
If \rButtonImageID_hover = 0
Debug "Need to call rbutton_Init() at first!"
ProcedureReturn
EndIf
; prepare button and load images
AddElement(\ButtonList())
\ButtonList()\ButtonImageID_normal = \rButtonImageID_normal
\ButtonList()\ButtonImageID_hover = \rButtonImageID_hover
\ButtonList()\IconImageID = IconImageID.i
\ButtonList()\X = PosX.i
\ButtonList()\Y = PosY.i
\ButtonList()\Width = ImageWidth(\rButtonImageID_normal)
\ButtonList()\Height = ImageHeight(\rButtonImageID_normal)
\ButtonList()\Caption = Caption.s
\ButtonList()\ButtonImageID_draw = CreateImage(#PB_Any, \ButtonList()\Width, \ButtonList()\Height, 32)
\ButtonList()\FontName = \FontName
\ButtonList()\FontSize = \FontSize
\ButtonList()\FontStyle = \FontStyle
\ButtonList()\FontColor = \FontColor
\ButtonList()\ShaddowDimm = \ShaddowDimm
\ButtonList()\WindowID = WindowID.i
If IconImageID.i <> 0
\ButtonList()\IconWidth = ImageWidth(\ButtonList()\IconImageID)
\ButtonList()\IconHeight = ImageHeight(\ButtonList()\IconImageID)
Else
\ButtonList()\IconWidth = 0
\ButtonList()\IconHeight = 0
EndIf
Protected MyFontID.i = LoadFont(#PB_Any, FontName.s, FontSize.i, FontStyle.i) ; load font in desired size
; start drawing only for gathering the correct values for textwidth/height
; generate image values
StartDrawing(ImageOutput(\ButtonList()\ButtonImageID_draw))
DrawingFont(FontID(MyFontID.i))
Protected XP.i
Protected YP.i
Protected IconSpace.i = \ButtonList()\IconWidth * 0.1
If \ButtonList()\Caption <> ""
; with caption (icon shifted left)
XP.i = \ButtonList()\Width / 2 - (\ButtonList()\IconWidth + TextWidth(Caption.s) + IconSpace.i) / 2
YP.i = \ButtonList()\Height / 2 - \ButtonList()\IconHeight / 2
; take care about the left position of icon...
If XP.i < #button_ShaddowWidth + \LineThickness
XP.i = #button_ShaddowWidth + \LineThickness
EndIf
Else
; no caption (center icon)
XP.i = \ButtonList()\Width / 2 - \ButtonList()\IconWidth / 2
YP.i = \ButtonList()\Height / 2 - \ButtonList()\IconHeight / 2
EndIf
\ButtonList()\IconX = XP.i
\ButtonList()\IconY = YP.i
; draw caption
If IconImageID.i <> 0
; text right
XP.i = \ButtonList()\IconX + \ButtonList()\IconWidth + IconSpace.i
YP.i = \ButtonList()\Height / 2 - TextHeight(Caption.s) / 2
Else
; text centered
XP.i = \ButtonList()\Width / 2 - TextWidth(Caption.s) / 2
YP.i = \ButtonList()\Height / 2 - TextHeight(Caption.s) / 2
EndIf
\ButtonList()\TextX = XP.i
\ButtonList()\TextY = YP.i
StopDrawing()
FreeFont(MyFontID.i)
; create gadget
Protected newGadgetID.i = ImageGadget(Gadget.i, PosX.i, PosY.i, \ButtonList()\Width, \ButtonList()\Height, ImageID(\ButtonList()\ButtonImageID_draw))
If Gadget.i = #PB_Any
\ButtonList()\GadgetID = newGadgetID.i
Else
\ButtonList()\GadgetID = Gadget.i
EndIf
rbutton_Redraw(\ButtonList()\GadgetID, 0)
EndWith
ProcedureReturn newGadgetID.i
EndProcedure
; Checks, if the mouse in the given window is over a r-style button.
; In that case, the button will get hover-effect.
; Simply add this to the event-loop of your window.
Procedure rbutton_CheckHover(WindowID.i)
Static LastHighlightGadgetID.i
Protected x.i
Protected FoundSome.b = #False
; remove dead elements
ForEach rButton\ButtonList()
If Not IsGadget(rButton\ButtonList()\GadgetID)
DeleteElement(rButton\ButtonList())
EndIf
Next
For x.i = 0 To ListSize(rButton\ButtonList()) - 1
SelectElement(rButton\ButtonList(), x.i)
With rButton\ButtonList()
If \WindowID = WindowID.i
; actualize gadget position information
\X = GadgetX(\GadgetID)
\Y = GadgetY(\GadgetID)
\Width = GadgetWidth(\GadgetID)
\Height = GadgetHeight(\GadgetID)
If rbutton_MouseOverGadget(WindowID.i, \GadgetID) = #True
; matching
FoundSome.b = #True
; enable cursor symbol on this gadget
If \Disabled = #False And \Hidden = #False
rbutton_MakeCursorHand(\GadgetID) ; change current cursor to a hand
EndIf
If LastHighlightGadgetID.i <> \GadgetID
; remove old hover gadget
Protected CurrentGadget.i = \GadgetID
; set state of new gadget
rbutton_Redraw(CurrentGadget.i, 1)
; remove state of previous gadget
If LastHighlightGadgetID.i <> 0
rbutton_Redraw(LastHighlightGadgetID.i, 0)
EndIf
LastHighlightGadgetID.i = CurrentGadget.i
Break
EndIf
EndIf
EndIf
EndWith
Next
If FoundSome.b = #False
If LastHighlightGadgetID.i <> 0
rbutton_Redraw(LastHighlightGadgetID.i, 0)
EndIf
LastHighlightGadgetID.i = 0
EndIf
EndProcedure
; disable/enable a rbutton (State = #False -> enabled, State = #True -> disabled)
Procedure rbutton_Disable(rGadgetID.i, State.b)
Protected Found.b = #False
ForEach rButton\ButtonList()
If rButton\ButtonList()\GadgetID = rGadgetID.i
Found.b = #True
Break
EndIf
Next
If Found.b = #False
Debug "rGadgetID " + Str(rGadgetID.i) + " not found (Disable)!"
ProcedureReturn #False
EndIf
rButton\ButtonList()\Disabled = State.b
DisableGadget(rGadgetID.i, State.b)
rbutton_Redraw(rButton\ButtonList()\GadgetID, 0)
EndProcedure
; Hide or unhide a given rbutton (use this instead
; of HideGadget() function for rbutton gadgets).
Procedure rbutton_Hide(rGadgetID.i, State.b)
Protected Found.b = #False
ForEach rButton\ButtonList()
If rButton\ButtonList()\GadgetID = rGadgetID.i
Found.b = #True
Break
EndIf
Next
If Found.b = #False
Debug "rGadgetID " + Str(rGadgetID.i) + " not found (Hide)!"
ProcedureReturn #False
EndIf
rButton\ButtonList()\Hidden = State.b
HideGadget(rGadgetID.i, State.b)
EndProcedure
; Determine the maximum space needed for the buttons. You can give multiple captions
; to the routine, if you divide the captions with the PIPE character (|).
; You will get the maximum button width needed.
; This makes only sense, if you are using the rbutton_Init_OwnerDrawn() with this value as width.
Procedure.i rbutton_GetButtonWidth(Captions.s)
Static TextImage
Protected MaxWidth.i = 0
Protected Width.i = 0
Protected Caption.s = ""
If rButton\FontName = ""
Debug "You can not call rbutton_GetButtonWidth() before calling rbutton_SetFont()!"
ProcedureReturn 0
EndIf
Protected MyFontID.i = LoadFont(#PB_Any, rButton\FontName, rButton\FontSize, rButton\FontStyle) ; load font in desired size
If IsImage(TextImage) = 0
TextImage = CreateImage(#PB_Any, 500, 30)
EndIf
StartDrawing(ImageOutput(TextImage))
DrawingFont(FontID(MyFontID.i))
Protected Idx = 0
Repeat
Idx = Idx + 1
Caption.s = StringField(Captions.s, Idx, "|")
Width.i = TextWidth(Caption.s) + (#button_ShaddowWidth * #button_ScaleFactor) + #button_ScaleFactor
If Width.i > MaxWidth.i
MaxWidth.i = Width.i
EndIf
Until Caption.s = ""
StopDrawing()
ProcedureReturn MaxWidth.i
EndProcedure
Code: Select all
; TEST AND EXAMPLE CODE
XIncludeFile "rbutton_include.pbi"
OpenWindow(0, 100, 200, 300, 400, "rButton test window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
SetWindowColor(0, RGB(255, 255, 255))
; rbutton_Init(LoadImage(#PB_Any, "regButton_normal.png"), LoadImage(#PB_Any, "regButton_hover.png"))
rbutton_SetFont("Georgia", 9, 0, RGB(255,255,255), -120)
;Define ButtonWidth.i = rbutton_GetButtonWidth("display|print|disabled");
rbutton_Init_OwnerDrawn(120, 120, GetWindowColor(0), RGBA(214,226,236,255), RGBA(120,158,191,255), RGBA(255,255,255,255), RGBA(90,167,255,255),15, 2)
Define regDisplay.i = rbutton_Create(#PB_Any, 0, "display", 10, 10, LoadImage(#PB_Any, "display.png"))
Define regPrint.i = rbutton_Create(#PB_Any, 0, "print (disabled)", 160, 10, LoadImage(#PB_Any, "print.png"))
Define regDisplayD.i = rbutton_Create(#PB_Any, 0, "no image", 10, 150, 0)
Define regNoCaption.i= rbutton_Create(#PB_Any, 0, "", 160, 150, LoadImage(#PB_Any, "print.png"))
rbutton_SetFont("Arial", 9, #PB_Font_Bold | #PB_Font_Italic, RGB(255,255,255), -120)
rbutton_Init_OwnerDrawn(80, 30, GetWindowColor(0), RGBA(214,236,226,255), RGBA(120,191,158,255), RGBA(255,255,255,255), RGBA(60,225,137,255),5, 2)
Define regSmall1.i = rbutton_Create(#PB_Any, 0, "yes", 10, 280, 0)
Define regSmall2.i = rbutton_Create(#PB_Any, 0, "no", 105, 280, 0)
rbutton_Init_OwnerDrawn(80, 30, GetWindowColor(0), RGBA(236,214,214,255), RGBA(191,120,120,255), RGBA(255,255,255,255), RGBA(225,60,60,255),5, 2)
Define regSmall3.i = rbutton_Create(#PB_Any, 0, "cancel", 200, 280, 0)
rbutton_SetFont("Courier New", 16, #PB_Font_Bold, RGB(40,30,50), 150)
rbutton_Init_OwnerDrawn(130, 70, GetWindowColor(0), RGBA(206,200,216,255), RGBA(120,100,158,255), RGBA(255,255,255,255), RGBA(100,90,140,255),10, 2)
Define Printer.i = LoadImage(#PB_Any, "print.png")
ResizeImage(Printer.i, 28, 28)
Define regHoriz1.i = rbutton_CreateH(#PB_Any, 0, "print", 10, 320, Printer.i)
Define regHoriz1.i = rbutton_CreateH(#PB_Any, 0, "OK", 150, 320, Printer.i)
rbutton_Disable(regPrint.i, #True)
Define Quit.i = 0
Repeat
Define Event.i = WaitWindowEvent()
If Event.i = #PB_Event_CloseWindow ; If the user has pressed on the close button
Quit.i = 1
EndIf
If Event.i = #PB_Event_Gadget
If EventGadget() = regSmall3.i
Quit.i = 1
EndIf
EndIf
rbutton_CheckHover(0)
Until Quit.i = 1
End
- display.png
- print.png
You may find some on iconfinder.com.
Best,
Kukulkan