Verticaly center text in string gadget.

Just starting out? Need help? Post your questions and find answers here.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Verticaly center text in string gadget.

Post by Shardik »

RASHAD wrote:StringGadget() is the requested not the TextGadget()
There is a big difference you know
Yes, after realizing to have posted an example for the wrong Gadget, I found the following Windows examples for the StringGadget in my example collection (one posted by you):
- Sparkie (2005)
- TerryHough (2006)
- Fluid Byte (2007)
- IdeasVacuum (2007)
- RASHAD (2008)
The examples from FluidByte, TerryHough and you seem to be derived from Sparkie's because they use the same variable name eRect.RECT... :wink:
RASHAD wrote:Hi Shardik
Can you check ?
viewtopic.php?f=12&t=72996
I have posted directly in your linked thread.
Shardik wrote:Tomorrow I will try to find a cross-platform solution to vertically align text in a StringGadget...
I had to find out that on Linux PureBasic utilizes the GtkEntry which is only for single line text input and which doesn't allow vertical alignment at all. So on Linux the text in a StringGadget is always vertically centered by default.

Nevertheless, this is my cross-platform solution for toggling the vertical position of text in the StringGadget (on Linux only an information is displayed) :

Code: Select all

EnableExplicit

Define CenterVertically.I

Procedure AlignTextVertically(StringGadgetID, CenterVertically.I)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      MessageRequester("Info",
        "On Linux the text in a StringGadget (GtkEntry) is always " +
        "vertically centered by default and this cannot be changed!")
    CompilerCase #PB_OS_MacOS
      CocoaMessage(0, CocoaMessage(0, GadgetID(StringGadgetID), "cell"),
        "_setVerticallyCentered:", CenterVertically)
      CocoaMessage(0, GadgetID(StringGadgetID), "setNeedsDisplay:", #True)
    CompilerCase #PB_OS_Windows
      Protected ClientRect.RECT
      Protected DCHandle.I
      Protected Text.S = GetGadgetText(StringGadgetID)
      Protected TextXY.SIZE
 
      DCHandle = GetDC_(GadgetID(StringGadgetID))
      SelectObject_(DCHandle, GetGadgetFont(StringGadgetID))
      GetTextExtentPoint32_(DCHandle, Text, Len(Text), @TextXY)
      ReleaseDC_(GadgetID(StringGadgetID), DCHandle)
      GetClientRect_(GadgetID(StringGadgetID), ClientRect)

      If CenterVertically
        ClientRect\top = (ClientRect\bottom - TextXY\cy) / 2 - 1
      EndIf

      SendMessage_(GadgetID(StringGadgetID), #EM_SETRECT, 0, ClientRect)
      InvalidateRect_(GadgetID(0), 0, #True)
  CompilerEndSelect
EndProcedure

OpenWindow(0, 270, 100, 330, 100, "Center text vertically")

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  StringGadget(0, 10, 10, 310, 40,
    "The quick brown fox jumps over the lazy dog.", #ES_MULTILINE)
CompilerElse
  StringGadget(0, 10, 10, 310, 40,
    "The quick brown fox jumps over the lazy dog.")
CompilerEndIf

ButtonGadget(1, 70, 60, 180, 25, "Toggle vertical centering")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 1
        CenterVertically ! 1
        AlignTextVertically(0, CenterVertically)
      EndIf
  EndSelect
ForEver
Edit 1: In Windows the StringGadget is now created with #ES_MULTILINE.
Edit 2: I have added the following line in the Windows-specific code to correctly handle different font sizes:

Code: Select all

SelectObject_(DCHandle, GetGadgetFont(StringGadgetID))
Last edited by Shardik on Wed Jun 12, 2019 12:56 pm, edited 4 times in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Verticaly center text in string gadget.

Post by RASHAD »

1- You forgot that srod snippet based on Sparkie's too
2- Your link for my snippet is wrong it links to this thread :)
3- Your last code does not work with Windows
Egypt my love
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Verticaly center text in string gadget.

Post by Shardik »

RASHAD wrote:1- You forgot that srod snippet based on Sparkie's too
I am sure that I have still missed some other examples too... :wink:
RASHAD wrote:2- Your link for my snippet is wrong it links to this thread :)
Sorry, but the link to your snippet correctly links to your example in the thread "Set Center Align in StringGadget : Vertical 'n' Horizontal" from 2018. It doesn't link to this thread named "Verticaly center text in string gadget." started by captain_skank.
RASHAD wrote:3- Your last code does not work with Windows
I should never post cross-platform examples after having made short changes when testing the code on other operating systems and being too tired... :wink:
I had forgotten to remark that on Windows the StringGadget has to be set into multiline mode (#ES_MULTILINE) in order to center the text vertically. In my Windows specific code I had removed the flag #ES_MULTILINE from the StringGadget() definition line (because it's not cross-platform) and moved it to the Windows-specific code. But in Windows it seems that you can't change a StringGadget's style after its declaration to be multilined:

Code: Select all

SetWindowLongPtr_(GadgetID(0), #GWL_STYLE, GetWindowLongPtr_(GadgetID(0), #GWL_STYLE) ! #ES_MULTILINE)
Even a following InvalidateRect_() and UpdateWindow_() doesn't help...

Thank you for testing and reporting! I have modified my example above.
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 639
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Verticaly center text in string gadget.

Post by captain_skank »

This is making my head hurt.

Testing with the code Shardik provided the results look fine with the default font, but off center with any other font

Code: Select all

    EnableExplicit

    Define CenterVertically.I
    
    ;Global f_12.i = LoadFont(#PB_Any,"Calibri Light", 12, #PB_Font_HighQuality)
    Global f_12.i = LoadFont(#PB_Any,"Arial", 12, #PB_Font_HighQuality)
    
    Procedure AlignTextVertically(StringGadgetID, CenterVertically.I)

      Protected ClientRect.RECT
      Protected DCHandle.I
      Protected Text.S = GetGadgetText(StringGadgetID)
      Protected TextXY.SIZE
      
      DCHandle = GetDC_(GadgetID(StringGadgetID))
      GetTextExtentPoint32_(DCHandle, Text, Len(Text), @TextXY)
      ReleaseDC_(GadgetID(StringGadgetID), DCHandle)
      GetClientRect_(GadgetID(StringGadgetID), ClientRect)
      
      If CenterVertically
        ClientRect\top = (ClientRect\bottom - TextXY\cy) / 2
      EndIf
      
      SendMessage_(GadgetID(StringGadgetID), #EM_SETRECT, 0, ClientRect)
      InvalidateRect_(GadgetID(0), 0, #True)

    EndProcedure

    OpenWindow(0, 270, 100, 330, 200, "Center text vertically")
    
    StringGadget(0, 10, 10, 310, 40, "The quick brown fox jumps over the lazy dog.", #ES_MULTILINE)
    
    StringGadget(1, 10, 60, 310, 40, "The quick brown fox jumps over the lazy dog.", #ES_MULTILINE)
      SetGadgetFont(1, FontID(f_12))
    
    ButtonGadget(2, 70, 110, 180, 25, "Toggle vertical centering")

    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
        Case #PB_Event_Gadget
          If EventGadget() = 2
            CenterVertically ! 1
            AlignTextVertically(0, CenterVertically)
            AlignTextVertically(1, CenterVertically)
          EndIf
      EndSelect
    ForEver
I got rid of the non windows code for my purposes.
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Verticaly center text in string gadget.

Post by Shardik »

Sorry, I didn't take the font size into account. I had to add

Code: Select all

      SelectObject_(DCHandle, GetGadgetFont(StringGadgetID))
in my example above. This is your modified Windows example:

Code: Select all

    EnableExplicit

    Define CenterVertically.I
   
    ;Global f_12.i = LoadFont(#PB_Any,"Calibri Light", 12, #PB_Font_HighQuality)
    Global f_12.i = LoadFont(#PB_Any,"Arial", 12, #PB_Font_HighQuality)
   
    Procedure AlignTextVertically(StringGadgetID, CenterVertically.I)

      Protected ClientRect.RECT
      Protected DCHandle.I
      Protected Text.S = GetGadgetText(StringGadgetID)
      Protected TextXY.SIZE
     
      DCHandle = GetDC_(GadgetID(StringGadgetID))
      SelectObject_(DCHandle, GetGadgetFont(StringGadgetID))
      GetTextExtentPoint32_(DCHandle, Text, Len(Text), @TextXY)
      ReleaseDC_(GadgetID(StringGadgetID), DCHandle)
      GetClientRect_(GadgetID(StringGadgetID), ClientRect)

      If CenterVertically
        ClientRect\top = (ClientRect\bottom - TextXY\cy) / 2 - 1
      EndIf
     
      SendMessage_(GadgetID(StringGadgetID), #EM_SETRECT, 0, ClientRect)
      InvalidateRect_(GadgetID(StringGadgetID), 0, #True)

    EndProcedure

    OpenWindow(0, 270, 100, 330, 200, "Center text vertically")
   
    StringGadget(0, 10, 10, 310, 40, "The quick brown fox jumps over the lazy dog.", #ES_MULTILINE)
   
    StringGadget(1, 10, 60, 310, 40, "The quick brown fox jumps over the lazy dog.", #ES_MULTILINE)
      SetGadgetFont(1, FontID(f_12))
   
    ButtonGadget(2, 70, 110, 180, 25, "Toggle vertical centering")

    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
        Case #PB_Event_Gadget
          If EventGadget() = 2
            CenterVertically ! 1
            AlignTextVertically(0, CenterVertically)
            AlignTextVertically(1, CenterVertically)
          EndIf
      EndSelect
    ForEver
User avatar
captain_skank
Enthusiast
Enthusiast
Posts: 639
Joined: Fri Oct 06, 2006 3:57 pm
Location: England

Re: Verticaly center text in string gadget.

Post by captain_skank »

Thanks Shardik, this is really appreciated.
Post Reply