Page 1 of 1

Rounded textgadget using canvasgadget

Posted: Tue May 06, 2014 1:17 pm
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)

Re: Rounded textgadget using canvasgadget

Posted: Tue May 06, 2014 1:56 pm
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:

Re: Rounded textgadget using canvasgadget

Posted: Tue May 06, 2014 3:12 pm
by blueb
Fangbeast...

Do a search for JustinJack's excellent 'jelly_button' include file.

Re: Rounded textgadget using canvasgadget

Posted: Tue May 06, 2014 3:50 pm
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

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 3:45 am
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.

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 5:32 am
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

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 7:53 am
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)

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 7:58 am
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?

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 9:43 am
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

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 9:39 pm
by davido
@TI-994A,

Thank you, but ....
You did all the hard work.

Re: Rounded textgadget using canvasgadget

Posted: Wed May 07, 2014 11:16 pm
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

Re: Rounded textgadget using canvasgadget

Posted: Thu May 08, 2014 8:02 am
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