Rounded textgadget using canvasgadget

Just starting out? Need help? Post your questions and find answers here.
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Rounded textgadget using canvasgadget

Post by Fangbeast »

I've never used canvasgadgets yet as these seems to be a shedload of code associated with it, but...

Is there a simple way to use it to make textgadgets with nicely rounded borders (like i've seen with mac apps) where the text is perfectly in the middle of the gadget horizontally?

And then add fonts and colours to it as I get the hang of it.

I want to make a 'pretty' appointment manager for all my doctor's appointments and the whiteboard that I use is getting unmanageable.

Wish I could do this with a visual designer so that I could see what I was doing (Don't want much, LOL)
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Rounded textgadget using canvasgadget

Post by TI-994A »

Fangbeast wrote:...textgadgets with nicely (1)rounded borders (like i've seen with mac apps) where the (2)text is perfectly in the middle of the gadget horizontally? And then add (3)fonts and (4)colours to it as I get the hang of it...
Hi Fangbeast. Perhaps you could take a look at my ButtonGadgetEx() and TextGadgetEx() functions.

There're no rounded corners, but they're fully-functional gadgets, capable of displaying colours and font styles, and the text on the buttons are centred automatically. Three out of four isn't so bad. :wink:
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
blueb
Addict
Addict
Posts: 1116
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: Rounded textgadget using canvasgadget

Post by blueb »

Fangbeast...

Do a search for JustinJack's excellent 'jelly_button' include file.
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 641
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Rounded textgadget using canvasgadget

Post by captain_skank »

Hi,

This will center the text in a canvasgadget() - horizontaly and verticaly

Code: Select all

Procedure calendar_button(btn_id.i, btn_text.s, btn_colour, btn_text_colour)
  
  StartDrawing(CanvasOutput(btn_id))
    Box(0, 0, GadgetWidth(btn_id), GadgetHeight(btn_id), btn_colour)
    DrawingMode(#PB_2DDrawing_Transparent)
    full_width.i = TextWidth(btn_text)
    text_width.i = full_width / 2
    text_height.i = TextHeight(btn_text)
    text_height.i = text_height / 2
    DrawText((GadgetWidth(btn_id)/2) - text_width, (GadgetHeight(btn_id)/2) - text_height, btn_text, btn_text_colour)
  StopDrawing() 
  
EndProcedure
The problem with rounded corners and the canvasgadget is that the canvasgadget can't be transparent so blending the non-coloured corners is a pain in the rear
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4790
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Re: Rounded textgadget using canvasgadget

Post by Fangbeast »

There're no rounded corners, but they're fully-functional gadgets, capable of displaying colours and font styles, and the text on the buttons are centred automatically. Three out of four isn't so bad. :wink:[/quote]

What? No rounder corners??? (GRIN)! The text is centred in the middle horizontally but not vertically and that looks 'wrong' somehow. Of course, if I remove the border and set the gadget background to the same colour as what it is set on, then it can be aligned 'invisibly' so to speak.

Nice code.
Amateur Radio/VK3HAF, (D-STAR/DMR and more), Arduino, ESP32, Coding, Crochet
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Rounded textgadget using canvasgadget

Post by TI-994A »

Fangbeast wrote:The text is centred in the middle horizontally but not vertically and that looks 'wrong' somehow. Of course, if I remove the border and set the gadget background to the same colour as what it is set on, then it can be aligned 'invisibly' so to speak.

Nice code.
Hi Fangbeast. Firstly, thank you. Secondly, just a small clarification: the captions in ButtonGadgetEx() are already being centered automatically, both horizontally as well as vertically.

In TextGadgetEx(), however, the text placement simulates PureBasic's TextGadget() alignments, using the standard flags, #PB_Text_Center, #PB_Text_Right and #PB_Text_Border. But, since you seem to require absolute text centering for this as well, here's a modification of TextGadgetEx() which will center the text, both horizontally and vertically, if the #PB_Text_Center flag is used:

Code: Select all

;==============================================================
;   modified version especially for Fangbeast - 7th May 2014
;   #PB_Text_Center will center text horizontally & vertically 
;==============================================================
;   TextGadgetEx() enables border settings, text alignment,
;   foreground & background colours, and text formatting 
;   including italics, bold & underline.
;   
;   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
;==============================================================

;TextGadgetEx() wrapped into a single procedure
Procedure TextGadgetEx(gadgetNo, txtXPos, txtYPos, txtWidth, txtHeight, caption.s, flags = 0, foreColor = 0, backColor = 16777215)
  If flags & #PB_Text_Border
    border = 1
    borderOffset = 4
  EndIf
  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)
  If gadgetNo = #PB_Any 
    gadgetNo = CanvasGadget(gadgetNo, txtXPos, txtYPos, txtWidth, txtHeight, border)
  Else
    CanvasGadget(gadgetNo, txtXPos, txtYPos, txtWidth, txtHeight, border)
  EndIf
  If StartDrawing(CanvasOutput(gadgetNo))
    Box(0, 0, txtWidth, txtHeight, 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
      captionY = 0
      If flags & #PB_Text_Center
        captionX = (txtWidth - captionWidth) / 2
        captionY = ((txtHeight - TextHeight(caption)) / 2) - borderOffset
      ElseIf flags & #PB_Text_Right  
        captionX = (txtWidth - captionWidth) - borderOffset
      Else
        captionX = borderOffset
      EndIf
      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 gadgetNo
EndProcedure

;demo code
Enumeration 
  #MainWindow
  #txtGadget1
  #txtGadget2
EndEnumeration

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

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

;instantiated with constant - foreground & background colours and center flag set
formattedCaption.s = "<i>Just</i> <b>for</b> <u>Fangbeast!</u>"
TextGadgetEx(#txtGadget2, 125, 75, 250, 30, formattedCaption, #PB_Text_Center, RGB(0, 0, 100), RGB(220, 220, 250))

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

;instantiated with #PB_Any - foreground & background colours and right & border flags set
formattedCaption = "<b><u>Bold & Underlined</b></u>   or   <i><b><u>Italics, Bold & Underlined</i></b></u>"
txtGadget4 = TextGadgetEx(#PB_Any, 25, 165, 450, 30, formattedCaption, #PB_Text_Right | #PB_Text_Border, RGB(0, 100, 0), RGB(200, 250, 220))

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Especially for you! :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Rounded textgadget using canvasgadget

Post by Danilo »

On Windows you could add rounded corners by using regions:

Code: Select all

Procedure RoundGadgetCorners(gadget,radius)
    Protected w = GadgetWidth(gadget)
    Protected h = GadgetHeight(gadget)
    If radius > h*0.5 : radius = h*0.5 : EndIf
    If radius > w*0.5 : radius = w*0.5 : EndIf
    Protected corner1 = CreateEllipticRgn_(0,0       ,radius*2+1,radius*2+1         )
    Protected corner2 = CreateEllipticRgn_(0,h-radius*2,radius*2+1,h-radius*2+radius*2+1)
    CombineRgn_(corner1,corner1,corner2,#RGN_OR)
    Protected corner3 = CreateEllipticRgn_(w-radius*2,0,w+1,radius*2+1)
    Protected corner4 = CreateEllipticRgn_(w-radius*2,h-radius*2,w+1,h-radius*2+radius*2+1)
    CombineRgn_(corner3,corner3,corner4,#RGN_OR)
    Protected block1  = CreateRectRgn_(0,radius,w,h-radius)
    Protected block2  = CreateRectRgn_(radius,0,w-radius,h)
    CombineRgn_(block1,block1,block2,#RGN_OR)
    CombineRgn_(block1,block1,corner1,#RGN_OR)
    CombineRgn_(block1,block1,corner3,#RGN_OR)
    SetWindowRgn_(GadgetID(gadget),block1,#True)
    DeleteObject_(corner1)
    DeleteObject_(corner2)
    DeleteObject_(corner3)
    DeleteObject_(corner4)
    DeleteObject_(block2)
EndProcedure

RoundGadgetCorners(#txtGadget2,15)
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Rounded textgadget using canvasgadget

Post by davido »

@TI-994A, Thank you for sharing this excellent work.

I happen to like rounded buttons and text gadgets.
So I tried the following by replacing line 37 with:

Code: Select all

    Box(0, 0, txtWidth, txtHeight, $eeeeee)
    RoundBox(0, 0, txtWidth, txtHeight, 8, 8, backColor)
It seemed to work: is this ok?
DE AA EB
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Rounded textgadget using canvasgadget

Post by TI-994A »

Danilo wrote:On Windows you could add rounded corners by using regions...
Hi Danilo. Really nice. If he doesn't mind a Windows-only solution, Fangbeast's wishlist is now complete.
davido wrote:I happen to like rounded buttons and text gadgets...
Hi davido. Very nice and simple workaround. And cross-platform too.

Thank you guys! :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: Rounded textgadget using canvasgadget

Post by davido »

@TI-994A,

Thank you, but ....
You did all the hard work.
DE AA EB
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Rounded textgadget using canvasgadget

Post by RASHAD »

Round Corners TextGadget() with Workaround to support
SetGadgetColor()

Code: Select all

LoadFont(0,"Broadway",12)

OpenWindow(0,0,0,400,300,"", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowColor(0,#Gray)
ContainerGadget(0,10,10,300,40)
		TextGadget(1,0,0,300,40,"Round Corners TextGadget",#SS_CENTERIMAGE | #SS_CENTER)
		SetGadgetFont(1,FontID(0))
		SetGadgetColor(1,#PB_Gadget_BackColor,#Yellow)
		SetGadgetColor(1,#PB_Gadget_FrontColor,#Red)
CloseGadgetList()

hrgn = CreateRoundRectRgn_(0,0,300,40,15,15)
SetWindowRgn_(GadgetID(0),hrgn,1)
DeleteObject_(hrgn)

Repeat
  Select WaitWindowEvent()
      
      Case #PB_Event_CloseWindow
            Quit = 1
      
      Case #PB_Event_Gadget
          Select EventGadget()
           Case 1            
          EndSelect
          
  EndSelect 

Until Quit = 1
End
Egypt my love
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Rounded textgadget using canvasgadget

Post by TI-994A »

Hi Danilo, davido and RASHAD. Just FYI, I've linked your solutions for implementing rounded gadget corners into my TextGadgetEx() and ButtonGadgetEx() threads in the Tricks 'n' Tips forum. Here are the links for your reference:

- ButtonGadgetEx()
- TextGadgetEx()

@davido: Your solution for the canvas implementation of TextGadgetEx() is really good, especially in its simplicity. But, as you know, the ButtonGadgetEx() makes use of PureBasic's ButtonImageGadget(), and that's why your link is not included there. :)

Once again, thanks guys! :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
Post Reply