StringGadget Text Vertically Centred

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

StringGadget Text Vertically Centred

Post by IdeasVacuum »

It would be good to have Vertically Centred text, either via a flag option or as the default. Currently, text is set top-left in the String Gadget and it's very ugly! :mrgreen:

Windows work-around:

Code: Select all

Enumeration
#Win
#Pnl
#Tab0
#Cont
#Str1
#Str2
#Font16
EndEnumeration

LoadFont(#Font16, "Arial", 16, #PB_Font_HighQuality)

Procedure StrGdgtVertCtr(iGdgtID.i, iLeftMargin.i)
;#------------------------------------------------
;NOTE, for this to work, the StringGadget MUST have the #ES_MULTILINE flag applied
;
Protected      rRect.RECT
Protected      fSize.SIZE
Protected      iHwnd.i = GadgetID(iGdgtID)
Protected   iLineCnt.i = SendMessage_(iHwnd, #EM_GETLINECOUNT, 0, 0)
Protected       iHdc.i = GetDC_(iHwnd)
Protected       sStr.s = "ABgy"        ;length = 4 chars
Protected    iStrLen.i = Len(sStr)
Protected iVertTweak.i = 0 ;corrects the displayed result (requires more logic!)

                      SelectObject_(iHdc, GetGadgetFont(iGdgtID))
              GetTextExtentPoint32_(iHdc, sStr, iStrLen, fSize) ;width & height of sStr
                     GetClientRect_(iHwnd, rRect)
                         ReleaseDC_(iHwnd, iHdc)

                   rRect\left = iLeftMargin
                    rRect\top = ((GadgetHeight(iGdgtID) - (fSize\cy * iLineCnt)) / 2)
                 rRect\bottom = (rRect\top + (fSize\cy * iLineCnt) + iVertTweak)

              Debug "                 Text-->" + GetGadgetText(iGdgtID) + "<--"
              Debug "              iGdgtID-->" + Str(iGdgtID) + "<--"
              Debug "             fSize\cy-->" + Str(fSize\cy) + "<--"
              Debug "             iLineCnt-->" + Str(iLineCnt) + "<--"
              Debug "            rRect\Top-->" + Str(rRect\Top) + "<--"
              Debug "         rRect\Bottom-->" + Str(rRect\Bottom) + "<--"
              Debug "GadgetHeight(iGdgtID)-->" + Str(GadgetHeight(iGdgtID)) + "<--"
              Debug "========================================="
              Debug " "

              If rRect\bottom < GadgetHeight(iGdgtID)

                      SendMessage_(iHwnd, #EM_SETRECT, 0, rRect)
              EndIf
EndProcedure

If OpenWindow(#Win,0,0,500,250,"STRING GADGET TEXT",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

        SetGadgetFont(#PB_All,FontID(#Font16))
          PanelGadget(#Pnl,0,0,500,250)
        AddGadgetItem(#Pnl, #Tab0, "Tab 0")
      ContainerGadget(#Cont,10,10,470,190)
         StringGadget(#Str1,10,10,450,50,"TEXT")
         StringGadget(#Str2,10,80,450,50,"TEXT VERTICALLY CENTERED", #ES_MULTILINE|#PB_String_BorderLess)
       SetGadgetColor(#Cont, #PB_Gadget_BackColor, RGB(96,96,96))
      CloseGadgetList()
      CloseGadgetList()
       StrGdgtVertCtr(#Str2, 6)

       Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf


This can also be achieved without API using a StringGadget() set inside a ContainerGadget().

EDIT: Tweaked the above code, should all make sense with the exception of how the Vertical Tweak value is determined. I have found that single lines of text look fine without tweaking, it's all a matter of preference.
Last edited by IdeasVacuum on Thu Sep 07, 2017 3:40 pm, edited 1 time in total.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
Bisonte
Addict
Addict
Posts: 1232
Joined: Tue Oct 09, 2007 2:15 am

Re: StringGadget Text Vertically Centred

Post by Bisonte »

+1 I also want to...

@IdeasVacuum: Your Windows workaround... It is very important, that the StringGadget have the flag #ES_MULTILINE. Otherwise it don't work.
It cost much time and searching to find this out ;)
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
English is not my native language... (I often use DeepL to translate my texts.)
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: StringGadget Text Vertically Centred

Post by IdeasVacuum »

Hi Bisonte

Sorry about that, I thought the code explained - it's not my work, it is listed in RS Basic's API library. In actual fact, I think it can be enhanced - the "magic number" 4 for example - there should be some logic behind that value. I should point out that I added the left-side margin rRect\left = 6. This would be better if the value was passed to the Procedure, since it's firstly a matter of preference and secondly it is only good if the StringGadget is Left or Right Justified.

It is good that PB works so seamlessly with Windows API but I think this is one of many examples where PB should have it's own cross-platform function.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: StringGadget Text Vertically Centred

Post by collectordave »

+1

When I design a form with a string gadget the caption is shown centered but when the programme is run it is top left?

Not using the code above and running on windows.

CD
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
mestnyi
Addict
Addict
Posts: 1000
Joined: Mon Nov 25, 2013 6:41 am

Re: StringGadget Text Vertically Centred

Post by mestnyi »

+1
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: StringGadget Text Vertically Centred

Post by davido »

+1
DE AA EB
Post Reply