StringGadget Text Vertically Centred
Posted: Thu Sep 07, 2017 12:04 am
				
				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!  
 
Windows work-around: 
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.
			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
EndIfThis 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.