Page 1 of 1

ButtonGadgetEx() with colour and text formatting

Posted: Sun Apr 20, 2014 6:45 pm
by TI-994A
*EDIT (22/2/2021): Updated screenshot links, and now tested on Windows 8.1 Professional, MacOS Catalina, and Linux Ubuntu 20.

Since it's been asked quite a number of times, here's a simple cross-platform routine (tested on Windows and OSX only) that wraps the functions of a ButtonImageGadget(), to simulate some extended functionalities of the standard ButtonGadget().

It is called in the same way as a standard ButtonGadget(), with options for foreground and background colours, text formatting like italics, bold, and underlining, and it can also make use of #PB_Any.

Text formatting is handled with HTML-like tags; <i></i>, <b></b>, <u></u>, with the ability to handle multiple formats in a single caption. The captions will be automatically centred, although texts longer than the button would not be wrapped. Also, underlining does not seem to render too well with italics, and is supported only on Windows, as stipulated by PureBasic.

It has been tested with v5.21 x86 on WinXP, v5.22 x64 on Win7, and v5.20 x64 on Mac OSX. Here are some screenshots:

Image

(underlining not supported on OSX)
Image

(underlining not supported on Linux)
Image

Here's the code:

Code: Select all

;==============================================================
;
;   ButtonGadgetEx() enables foreground & background colours
;   and text formatting including italics, bold 
;   (& underline on Windows only)
;   
;   tested & working on WinXP x86, Win7 x64, OSX x64
;   running PureBasic v5.21, v5.22, v5.20 respectively 
;
;   by TI-994A - free to use, improve, share...
;
;   20th April 2014
;
;==============================================================
;
;   22/2/21: re-tested with PureBasic 5.73 LTS (x64) on:
;   - Windows 8.1 Professional
;   - MacOS Catalina 10.15.5
;   - Linux Ubuntu 20.04.2   
;
;==============================================================

;ButtonGadgetEx() wrapped into a single procedure
Procedure ButtonGadgetEx(gadgetNo, buttonXPos, buttonYPos, buttonWidth, buttonHeight, caption.s, foreColor = 0, backColor = 16777215)
  regular = LoadFont(#PB_Any, "Arial", 10)
  bold = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Bold)  
  italics = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Italic)
  underline = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Underline)
  italicBold = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Italic | #PB_Font_Bold)
  boldUnderline = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Bold | #PB_Font_Underline)
  italicUnderline = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Italic | #PB_Font_Underline)
  fullFormat = LoadFont(#PB_Any, "Arial", 10, #PB_Font_Italic | #PB_Font_Bold | #PB_Font_Underline)
  buttonText = CreateImage(#PB_Any, buttonWidth, buttonHeight)
  If StartDrawing(ImageOutput(buttonText))
    Box(0, 0, buttonWidth, buttonHeight, backColor)
    For pass = 1 To 2
      For captionLoop = 1 To Len(caption)
        Select Mid(caption, captionLoop, 3)
          Case "<i>"
            iFlag = 1
            captionLoop + 2
          Case "<b>"
            bFlag = 1
            captionLoop + 2
          Case "<u>"
            uFlag = 1
            captionLoop + 2
          Case "</i"
            iFlag = 0
            captionLoop + 3
          Case "</b"
            bFlag = 0
            captionLoop + 3
          Case "</u"
            uFlag = 0
            captionLoop + 3
          Default
            noFormat = 1
        EndSelect
        If noFormat
          noFormat = 0
          If Not drawFont
            drawFont = FontID(regular)
            DrawingFont(drawFont)
          EndIf
          If pass = 1
            captionWidth + TextWidth(Mid(caption, captionLoop, 1))
          Else
            captionX = DrawText(captionX, captionY, Mid(caption, captionLoop, 1), foreColor, backColor)
          EndIf
        Else
          If iFlag And bFlag And uFlag
            drawFont = FontID(fullFormat)
          ElseIf iFlag And bFlag
            drawFont = FontID(italicBold)
          ElseIf iFlag And uFlag
            drawFont = FontID(italicUnderline)
          ElseIf bFlag And uFlag
            drawFont = FontID(boldUnderline)
          ElseIf iFlag
            drawFont = FontID(italics)
          ElseIf bFlag
            drawFont = FontID(bold)
          ElseIf uFlag 
            drawFont = FontID(underline)
          Else
            drawFont = FontID(regular)
          EndIf
          DrawingFont(drawFont)
        EndIf
      Next captionLoop
      captionX = (buttonWidth - captionWidth) / 2
      captionY = (buttonHeight - TextHeight(caption)) / 2
      drawFont = 0 : iFlag = 0 : bFlag = 0 : uFlag = 0
    Next pass
    StopDrawing() 
  EndIf
  FreeFont(regular)
  FreeFont(italics)
  FreeFont(bold)
  FreeFont(underline)
  FreeFont(italicBold)
  FreeFont(italicUnderline)
  FreeFont(boldUnderline)
  FreeFont(fullFormat)
  ProcedureReturn ButtonImageGadget(gadgetNo, buttonXPos, buttonYPos, buttonWidth, buttonHeight, ImageID(buttonText))
EndProcedure

;demo code
Enumeration 
  #MainWindow
  #textButton1
  #textButton2
EndEnumeration

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#MainWindow, #PB_Any, #PB_Any, 500, 220, "ButtonGadgetEx() by TI-994A", wFlags)

;instantiated with constant - colour parameters not set
ButtonGadgetEx(#textButton1, 175, 30, 150, 30, "<b>Default</b> <i>format</i>")

;instantiated with constant - foreground and background colours set
formattedCaption.s = "<i>Italics</i>, <b>Bold</b> or <u>Underlined</u>"
ButtonGadgetEx(#textButton2, 125, 75, 250, 30, formattedCaption, RGB(0, 0, 100), RGB(220, 220, 250))

;instantiated with #PB_Any - foreground and background colours set
formattedCaption = "<i><b>Italics & Bold</i></b>   or   <i><u>Italics & Underlined</i></u>"
textButton3 = ButtonGadgetEx(#PB_Any, 75, 120, 350, 30, formattedCaption, RGB(100, 0, 0), RGB(250, 220, 220))

;instantiated with #PB_Any - foreground and background colours set
formattedCaption = "<b><u>Bold & Underlined</b></u>   or   <i><b><u>Italics, Bold & Underlined</i></b></u>"
textButton4 = ButtonGadgetEx(#PB_Any, 25, 165, 450, 30, formattedCaption, RGB(0, 100, 0), RGB(200, 250, 220))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      appQuit = 1
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #textButton1
          Debug "button 1 pressed..."
        Case #textButton2
          Debug "button 2 pressed..."
        Case textButton3
          Debug "button 3 pressed..."
        Case textButton4
          Debug "button 4 pressed..."
      EndSelect
  EndSelect
Until appQuit = 1
Suggestions, feedback, and improvements are most welcome. Thank you. :D

Re: ButtonGadgetEx() with colour and text formatting

Posted: Mon Apr 21, 2014 5:32 am
by VB6_to_PBx
Great ButtonGadget code examples !!!

would it be possible to do same coloring of items for ComboBoxGadgets ??


Also 1 more question
"How can i print those Buttons with a Printer ?"

Re: ButtonGadgetEx() with colour and text formatting

Posted: Mon Apr 21, 2014 7:41 am
by TI-994A
VB6_to_PBx wrote:...would it be possible to do same coloring of items for ComboBoxGadgets ??
Hi VB6_to_PBx, and thank you for your kind comments. The ButtonGadgetEx() and TextGadgetEx() functions are actually simulations, using PureBasic's ButtonImageGadget() and CanvasGadget(). To obtain the same results for the ComboBoxGadget() would require either some major code, or some OS-specific subclassing; somethings which are more down RASHAD's lane.
VB6_to_PBx wrote:"How can i print those Buttons with a Printer ?"
Printing of gadgets have to be done either directly off the screen, with some screen capture utility, or direct to the printer through a memory context. The first method would not produce satisfactory results, and the second would entail drawing every control manually.

Sorry I couldn't be of more help. :)

Re: ButtonGadgetEx() with colour and text formatting

Posted: Tue Apr 29, 2014 2:44 pm
by Kwai chang caine
Nice gadgets...works great
Thanks for sharing 8)

Re: ButtonGadgetEx() with colour and text formatting

Posted: Tue Apr 29, 2014 5:49 pm
by TI-994A
Kwaï chang caïne wrote:Nice gadgets...works great
Thanks for sharing 8)
Hi KCC, and thank you for saying so. It's well appreciated. :D

Re: ButtonGadgetEx() with colour and text formatting

Posted: Thu May 08, 2014 7:48 am
by TI-994A
UPDATE:

Here are some nice tricks from Danilo and RASHAD, to implement rounded corners to gadgets, that can be integrated into the ButtonGadgetEx():

- using Windows API (procedure-wrapped)
- using Windows API (direct implementation)

Thanks guys! :D

Re: ButtonGadgetEx() with colour and text formatting

Posted: Wed Nov 26, 2014 10:23 am
by RichardL
Hi TI-994,
Nice job... all it needs now is to be able to change the text and backdrop to an alternate set when #PB_Button_Toggle is specified. :wink:
RichardL

Re: ButtonGadgetEx() with colour and text formatting

Posted: Sun Aug 30, 2020 1:04 am
by BarryG
Screenshot of TI-994A's code because his image links are dead:

Image