Page 1 of 2

TextGadget text align

Posted: Sun Dec 27, 2020 5:45 pm
by l1marik
Is a way how to change align of text inside TextGadget during running program?

Lukas

Re: TextGadget text align

Posted: Sun Dec 27, 2020 6:35 pm
by Saki
Without API this will not work.
For using on all OS you need to remove the gadget temporary and create it again.
Or use a Image based CustomGadget which provides an extended SetGadgetText function.
The PB gadget has also the disadvantage that it can not center the text vertically.

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:56 am
by RASHAD
Hi
Cross Platform

Code: Select all


Procedure AlignText(gad,Text$,width,align)
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  w = TextWidth(Text$)
  w2 = TextWidth(" ")
  StopDrawing()
  If align = 1
    trim = (width - w)/2/w2
    ntext$ = Space(trim)+text$
  ElseIf align = 2
    trim = (width - w)/w2 - 1
    ntext$ = Space(trim)+text$
  EndIf
  SetGadgetText(gad,ntext$)
EndProcedure

LoadFont(0,"Georgia",24)
Text$ = "Hello World"

If OpenWindow(0, 0,0, 400, 200, "Align Text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  TextGadget(0, 10, 10, 10, 10 ,Text$,#PB_Text_Border)
  SetGadgetColor(0,#PB_Gadget_FrontColor,$0001DC)
  SetGadgetColor(0,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(0,FontID(0))
  reqheight = GadgetHeight(0,#PB_Gadget_RequiredSize)  
  ResizeGadget(0,#PB_Ignore,#PB_Ignore,380,reqheight)
  SetGadgetText(0,text$)
  
  TextGadget(1, 10, 60, 10, 10 ,Text$ ,#PB_Text_Border)
  SetGadgetColor(1,#PB_Gadget_FrontColor,$FF3027)
  SetGadgetColor(1,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(1,FontID(0))
  reqheight = GadgetHeight(1,#PB_Gadget_RequiredSize)  
  ResizeGadget(1,#PB_Ignore,#PB_Ignore,380,reqheight)
  
  TextGadget(2, 10, 110, 10, 10 ,Text$,#PB_Text_Border)
  SetGadgetColor(2,#PB_Gadget_FrontColor,$000000)
  SetGadgetColor(2,#PB_Gadget_BackColor,$FFFFFF)
  SetGadgetFont(2,FontID(0))
  reqheight = GadgetHeight(2,#PB_Gadget_RequiredSize)  
  ResizeGadget(2,#PB_Ignore,#PB_Ignore,380,reqheight)
  
  ButtonGadget(10,10,170,60,22,"Left")
  ButtonGadget(20,80,170,60,22,"Center")
  ButtonGadget(30,150,170,60,22,"Right")
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            align = 0
            SetGadgetText(0,text$)
            SetGadgetText(1,text$)
            SetGadgetText(2,text$)
            
          Case 20
            AlignText(0,Text$,380,1)
            AlignText(1,Text$,380,1)
            AlignText(2,Text$,380,1)
            
          Case 30
            AlignText(0,Text$,380,2)
            AlignText(1,Text$,380,2)
            AlignText(2,Text$,380,2)
            
        EndSelect
    EndSelect
  Until Quit = 1
EndIf

Re: TextGadget text align

Posted: Mon Dec 28, 2020 9:35 am
by Saki
Unfortunately, it is not that simple.

Try this changed code and you will see the problem and the solution.

It is therefore many easier to delete the gadget temporarily and create it new again.
This is then also automatically multiline and DPI aware. :wink:

You can spin that any way you want,
with multiline text it never works good.

Code: Select all

          
Procedure AlignText(gad,Text$,width,align)
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  w = TextWidth(Text$)
  w2 = TextWidth(" ")
  StopDrawing()
  If align = 1
    trim = (width - w)/2/w2
    ntext$ = Space(trim)+text$
  ElseIf align = 2
    trim = (width - w)/w2 - 1
    ntext$ = Space(trim)+text$
  EndIf
  SetGadgetText(gad,ntext$)
EndProcedure

LoadFont(0,"Georgia",24)
Text1$="Wrong_W"
Text2$="Wrong_i"
Text3$="Correct_i"

If OpenWindow(0, 0,0, 400, 200, "Align Text", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(0, 10, 10, 10, 10 ,Text1$,#PB_Text_Border)
  SetGadgetColor(0,#PB_Gadget_FrontColor,$0001DC)
  SetGadgetColor(0,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(0,FontID(0))
  reqheight = GadgetHeight(0,#PB_Gadget_RequiredSize) 
  ResizeGadget(0,#PB_Ignore,#PB_Ignore,380,reqheight)
  SetGadgetText(0,text1$)
  
  TextGadget(1, 10, 60, 10, 10 ,Text2$ ,#PB_Text_Border)
  SetGadgetColor(1,#PB_Gadget_FrontColor,$FF3027)
  SetGadgetColor(1,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(1,FontID(0))
  reqheight = GadgetHeight(1,#PB_Gadget_RequiredSize) 
  ResizeGadget(1,#PB_Ignore,#PB_Ignore,380,reqheight)
  
  TextGadget(2, 10, 110, 10, 10 ,Text3$,#PB_Text_Border)
  SetGadgetColor(2,#PB_Gadget_FrontColor,$000000)
  SetGadgetColor(2,#PB_Gadget_BackColor,$FFFFFF)
  SetGadgetFont(2,FontID(0))
  reqheight = GadgetHeight(2,#PB_Gadget_RequiredSize) 
  ResizeGadget(2,#PB_Ignore,#PB_Ignore,380,reqheight)
  
  ButtonGadget(10,10,170,60,22,"Left")
  ButtonGadget(20,80,170,60,22,"Center")
  ButtonGadget(30,150,170,60,22,"Right")
  
  Macro set_gadget_2(flag)
    If IsGadget(2) : FreeGadget(2) : EndIf
    TextGadget(2, 10, 110, 380, GadgetHeight(0,#PB_Gadget_RequiredSize) ,Text3$,#PB_Text_Border | flag)
    SetGadgetColor(2,#PB_Gadget_FrontColor,$000000)
    SetGadgetColor(2,#PB_Gadget_BackColor,$FFFFFF)
    SetGadgetFont(2,FontID(0))
  EndMacro
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 10
            align = 0
            SetGadgetText(0,text1$)
            SetGadgetText(1,text2$)
            FreeGadget(2)
            set_gadget_2(0)
            
          Case 20
            AlignText(0,Text1$,380,1)
            AlignText(1,Text2$,380,1)
            set_gadget_2(#PB_Text_Center)
            
          Case 30
            AlignText(0,Text1$,380,2)
            AlignText(1,Text2$,380,2)
            set_gadget_2(#PB_Text_Right)
            
        EndSelect
    EndSelect
  Until Quit = 1
EndIf

Re: TextGadget text align

Posted: Mon Dec 28, 2020 12:10 pm
by Shardik
RASHAD wrote:Cross Platform
RASHAD, please don't assume an example is cross-platform because it doesn't contain platform specific API functions. On MacOS 11.1 'Big Sur' RASHAD's example code displays right adjusted text like this:

Image


Saki's example also has big problems on MacOS 11.1 'Big Sur' with centered and right adjusted text, for example:

Image


On Linux Mint 18.3 with Cinnamon, Saki's example with right adjusted text looks like this:

Image


Therefore you may try my tested true cross-platform example using the respective OS-specific API functions for more reliability. I have tested my example successfully on these OSes:
  • Linux Mint 18.3 'Tricia' with Cinnamon, GTK3 and PB 5.73 x64
  • MacOS 11.1 'Big Sur' with PB 5.73 x64
  • Windows 10 v1809 x64 with PB 5.71 x86 and PB 5.46 x64

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC ""
    gtk_label_set_xalign(*Label.GtkLabel, xalign.F)
  EndImport
CompilerEndIf

Define SelectedGadget.I

OpenWindow(0, 270, 100, 350, 100, "Toggle text alignment")
TextGadget(0, 10, 20, WindowWidth(0) - 20, 25,
  "The quick brown fox jumps over the lazy dog.",
  #PB_Text_Border)
ButtonGadget(1, 10, 60, 90, 25, "Align left")
ButtonGadget(2, 130, 60, 90, 25, "Center")
ButtonGadget(3, 250, 60, 90, 25, "Align right")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      SelectedGadget = EventGadget()

      If SelectedGadget >= 1 And SelectedGadget <= 3
        Select SelectedGadget
          Case 1
            CompilerSelect #PB_Compiler_OS
              CompilerCase #PB_OS_Linux
                gtk_label_set_xalign(GadgetID(0), 0)
              CompilerCase #PB_OS_MacOS
                CocoaMessage(0, GadgetID(0),
                  "setAlignment:", #NSLeftTextAlignment)
              CompilerCase #PB_OS_Windows
                SetWindowLongPtr_(GadgetID(0), #GWL_STYLE,
                  GetWindowLongPtr_(GadgetID(0),
                  #GWL_STYLE) & ~#SS_CENTER & ~#SS_RIGHT | #SS_LEFT)
                InvalidateRect_(GadgetID(0), 0, #True)
            CompilerEndSelect
          Case 2
            CompilerSelect #PB_Compiler_OS
              CompilerCase #PB_OS_Linux
                gtk_label_set_xalign(GadgetID(0), 0.5)
              CompilerCase #PB_OS_MacOS
                CocoaMessage(0, GadgetID(0),
                  "setAlignment:", #NSCenterTextAlignment)
              CompilerCase #PB_OS_Windows
                SetWindowLongPtr_(GadgetID(0), #GWL_STYLE,
                  GetWindowLongPtr_(GadgetID(0),
                  #GWL_STYLE) & ~#SS_LEFT & ~#SS_RIGHT | #SS_CENTER)
                InvalidateRect_(GadgetID(0), 0, #True)
            CompilerEndSelect
          Case 3
            CompilerSelect #PB_Compiler_OS
              CompilerCase #PB_OS_Linux
                gtk_label_set_xalign(GadgetID(0), 1)
              CompilerCase #PB_OS_MacOS
                CocoaMessage(0, GadgetID(0),
                  "setAlignment:", #NSRightTextAlignment)
              CompilerCase #PB_OS_Windows
                SetWindowLongPtr_(GadgetID(0), #GWL_STYLE,
                  GetWindowLongPtr_(GadgetID(0),
                  #GWL_STYLE) & ~#SS_LEFT & ~#SS_CENTER | #SS_RIGHT)
                InvalidateRect_(GadgetID(0), 0, #True)
            CompilerEndSelect
        EndSelect
      EndIf
  EndSelect
ForEver
Saki wrote:The PB gadget has also the disadvantage that it can not center the text vertically.
That's not true when using API functions. You may take a look into this cross-platform example which dynamically centers text vertically.

Re: TextGadget text align

Posted: Mon Dec 28, 2020 12:51 pm
by RASHAD
@Shardik
- PB native commands should come up to the same results on all OS
- When you want to to compare objects you should use the same Font,same font size & same text
- It is not a good practice to free then recreate any object (Try that with StringGadget() with different flags for example
- The problems raised because of the Border style used by PB
- Try with different font sizes
- FYI ,no problems with DPI

- I am not going to use a huge code because of a simple task (Just SetGadgetText()

- You can use that tech. with different Gadgets() (StringGadget(),EditorGadget(),ListIconGadget()....etc)
- It is just adding Spaces before or After to get the desired apperance
- Can your code do that ? :P
- I do not think it is good to Free ListIconGadget() and recreate it again :mrgreen:

Conclusion : It is another option for the users to choose which is suitable for his case

Code: Select all

ElseIf align = 2
    trim = (width - w)/w2 - 1 ;Increase 1 to 2 you will get a proper function (When you need to)
    ntext$ = Space(trim)+text$
  EndIf

Re: TextGadget text align

Posted: Mon Dec 28, 2020 12:51 pm
by Saki
Hi,
yes, it can be solved cleanly only with API.
This text fumbling has already cost me endless nerves.

Re: TextGadget text align

Posted: Mon Dec 28, 2020 1:31 pm
by Saki
@RASHAD
It's not our code that doesn't work, it's yours :P
I have also only changed so far your code that we can demonstrate what works and what does not work.

What works on Windows doesn't all work on Linux or macOS.
It's also not that easy to get this to work for anything and everything.
Here is also no one to blame, it is very difficult to detect any conceivable misconduct.
Therefore, real, bug-free multi OS solutions are very valuable.

I self have my own solutions that work on all OS, very fine and i think, Shardik also. :mrgreen:

Re: TextGadget text align

Posted: Mon Dec 28, 2020 1:53 pm
by RASHAD
Try to do the next If you can :mrgreen:
- Differnt fonts
- Different font sizes
- Different Gadgets
- For using different operating systems adapt it for your needs
- Your are the coder after all and it's your target OS :lol:
- Do not ask me to do your homework

What else I can do ,let me think :wink:

Code: Select all

Procedure _GetGadgetText(gad)
  text$ = LTrim(GetGadgetText(gad)," ")
  Debug text$
EndProcedure

Procedure _AddGadgetItem(gad,Text$)
  gadw = GadgetWidth(gad,#PB_Gadget_ActualSize); - GadgetWidth(gad,#PB_Gadget_RequiredSize)
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  width = TextWidth(Text$)
  width2 = TextWidth(" ")
  StopDrawing()
  trim = (gadw - width)/2/width2
  text$ = Space(trim)+text$
  AddGadgetItem(gad, -1,text$)
EndProcedure

Procedure AlignText(gad,Text$,width,align)
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(1))
  w = TextWidth(Text$)
  w2 = TextWidth(" ")
  StopDrawing()
  If align = 1
    trim = (width - w)/2/w2
    ntext$ = Space(trim)+text$ 
  EndIf
  SetGadgetText(gad,ntext$)
EndProcedure

LoadFont(0,"Tahoma",14)
LoadFont(1,"Georgia",24)
Text$ = "Hellow World"

If OpenWindow(0, 0, 0, 400, 400, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(0,10,10,300,40,"Hellow World",#PB_Text_Border)
  SetGadgetColor(0,#PB_Gadget_FrontColor,$0001DC)
  SetGadgetColor(0,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(0,FontID(1))
  reqheight = GadgetHeight(0,#PB_Gadget_RequiredSize)  
  ResizeGadget(0,#PB_Ignore,#PB_Ignore,300,reqheight)
  SetGadgetText(0,text$)
  AlignText(0,Text$,300,1)
  
  ComboBoxGadget(1, 10, 60, 300, 20) 
  SetGadgetFont(1,FontID(0))
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  height = TextHeight("Q")+10
  StopDrawing()  
  ResizeGadget(1,#PB_Ignore,#PB_Ignore,#PB_Ignore,height)
  _AddGadgetItem(1,"IdeasVacuum")
  _AddGadgetItem(1,"ComboBox item #!")
  _AddGadgetItem(1,"RASHAD")
  SetGadgetState(1,1)
  ButtonGadget(10,10,370,80,25,"Get Text")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            _GetGadgetText(1)
        EndSelect
    EndSelect
  Until Quit = 1
EndIf

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:14 pm
by Saki
RASHAD wrote: What else I can do ,let me think :wink:
Think simple ! :wink: :mrgreen:

Image

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:17 pm
by Shardik
RASHAD wrote:- It is not a good practice to free then recreate any object (Try that with StringGadget() with different flags for example
Did you find any freeing and recreation of a Gadget in my example in this thread?
RASHAD wrote:- I do not think it is good to Free ListIconGadget() and recreate it again :mrgreen:
My example in this thread is only for a TextGadget (which was asked for by the original poster). It doesn't contain a ListIconGadget at all. I have also already posted cross-platform examples aligning text using API-specific functions for StringGadget and ListIconGadget.
Saki wrote:yes, it can be solved cleanly only with API.
Thank you for that statement. That's also my experience, hence my example.

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:25 pm
by Saki
@Shardik
You are one of the best here ! 8)

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:32 pm
by RASHAD
Code for Coders
OK Shardik waiting for your examples for
1- ComboBox()
2- ListView()
3- ListIcon()
4- StringGadget()

Just center Text
I made the challenge simple for you guys
Didn't I ? :mrgreen:

And more to come
I think I should increase my pocket money for myself :P :mrgreen:

Code: Select all

Procedure _GetGadgetText(gad)
  text$ = LTrim(GetGadgetText(gad)," ")
  Debug text$
EndProcedure

Procedure _AddGadgetItem(gad,Text$)
  gadw = GadgetWidth(gad,#PB_Gadget_ActualSize); - GadgetWidth(gad,#PB_Gadget_RequiredSize)
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  width = TextWidth(Text$)
  width2 = TextWidth(" ")
  StopDrawing()
  trim = (gadw - width)/2/width2
  text$ = Space(trim)+text$
  AddGadgetItem(gad, -1,text$)
EndProcedure

Procedure AlignText(gad,Text$,width,align)
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(1))
  w = TextWidth(Text$)
  w2 = TextWidth(" ")
  StopDrawing()
  If align = 1
    trim = (width - w)/2/w2
    ntext$ = Space(trim)+text$ 
  EndIf
  SetGadgetText(gad,ntext$)
EndProcedure

LoadFont(0,"Tahoma",14)
LoadFont(1,"Georgia",24)
Text$ = "Hellow World"

If OpenWindow(0, 0, 0, 320, 500, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(0,10,10,300,40,"Hellow World",#PB_Text_Border)
  SetGadgetColor(0,#PB_Gadget_FrontColor,$0001DC)
  SetGadgetColor(0,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(0,FontID(1))
  reqheight = GadgetHeight(0,#PB_Gadget_RequiredSize)  
  ResizeGadget(0,#PB_Ignore,#PB_Ignore,300,reqheight)
  SetGadgetText(0,text$)
  AlignText(0,Text$,300,1)
  
  ComboBoxGadget(1, 10, 60, 300, 20) 
  SetGadgetFont(1,FontID(0))
  StartDrawing(WindowOutput(0))
  DrawingFont(FontID(0))
  height = TextHeight("Q")+10
  StopDrawing()  
  ResizeGadget(1,#PB_Ignore,#PB_Ignore,#PB_Ignore,height)
  _AddGadgetItem(1,"IdeasVacuum")
  _AddGadgetItem(1,"ComboBox item #!")
  _AddGadgetItem(1,"RASHAD")
  SetGadgetState(1,1)
  
  ListViewGadget(3,10,105,300,300)
  SetGadgetFont(3,FontID(0))
  _AddGadgetItem(3,"Hellow world")
  _AddGadgetItem(3,"Happy New Year")
  _AddGadgetItem(3,"Be Safe")
  _AddGadgetItem(3,"Good Luck")
  
  StringGadget(4,10,410,300,20,"Hellow Word",#PB_String_ReadOnly)
  SetGadgetFont(4,FontID(0))
  SetGadgetColor(4,#PB_Gadget_FrontColor,$0001DC)
  SetGadgetColor(4,#PB_Gadget_BackColor,$B8FEFD)
  SetGadgetFont(4,FontID(1))
  reqheight = GadgetHeight(4,#PB_Gadget_RequiredSize)  
  ResizeGadget(4,#PB_Ignore,#PB_Ignore,300,reqheight)
  SetGadgetText(4,text$)
  AlignText(4,Text$,300,1)
  
  ButtonGadget(10,10,470,80,25,"Get Text")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 1
            _GetGadgetText(1)
        EndSelect
    EndSelect
  Until Quit = 1
EndIf

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:43 pm
by Saki
No offense RASHAD, but the question was about creating right-aligned text
And it was further about being able to output this on all OS.

If we start with text gimmicks you will quickly realize that there is much more than you know. :wink:

Re: TextGadget text align

Posted: Mon Dec 28, 2020 2:53 pm
by RASHAD
Oh ,really :wink:
Using different Fonts ( non Mono) and different Text to compare cases is that right ?
Is "W" take the same wide like "i".
And you think yourself know everything about the staff .
Keep play with GFX_Wizzard it suits you much

Global solution I made in just few lines of code

End of discussion :wink: