How to put underscored chars in TextGadgets?

Just starting out? Need help? Post your questions and find answers here.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

How to put underscored chars in TextGadgets?

Post by PB »

Okay, now that Fred has "fixed" the ampersand "bug"...

http://www.purebasic.fr/english/viewtop ... 5&p=439991

...can someone please advise on how I can put underscored
characters in my TextBoxes in future? I liked using them for
showing shortcut keys in descriptions, just as they are were
meant to do.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Fred
Administrator
Administrator
Posts: 18207
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: How to put underscored chars in TextGadgets?

Post by Fred »

If you are Windows only, then you can use SetWindowPtr_() function to remove the #SS_NOPREFIX style
User avatar
deeproot
Enthusiast
Enthusiast
Posts: 284
Joined: Thu Dec 17, 2009 12:00 pm
Location: Llangadog, Wales, UK
Contact:

Re: How to put underscored chars in TextGadgets?

Post by deeproot »

Fred's suggestion is probably best, but perhaps here's a cross-platform method to try out? But only for Unicode compile and UTF8 source!

Using Combining Low Line character (U+0332) :

Code: Select all

#CLL = Chr($332)

Procedure.s UnderLine(Text.s)
  Protected i, TextOut.s
  For i = 1 To Len(Text)
    TextOut = TextOut + #CLL + Mid(Text, i, 1)
  Next i
  ProcedureReturn TextOut  
EndProcedure

Procedure OpenTestWindow()
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 400, 300, "Test", #PB_Window_SystemMenu | #PB_Window_TitleBar)    
    TextGadget(1,20,30,200,20,UnderLine("u") + "nderscore on 1st")    
    TextGadget(2,20,60,200,20,UnderLine("underscore all"))     
    TextGadget(3,20,90,200,20,UnderLine("N") + "ot so good with " + Underline("UPPERCASE") + "?")     
  EndIf
EndProcedure

OpenTestWindow()
Repeat
  Select WaitWindowEvent()    
    Case #PB_Event_CloseWindow
      Quit = #True   
  EndSelect   
Until Quit
End
Sorry, no good for ASCII and uppercase looks a bit messy :|
User avatar
kenmo
Addict
Addict
Posts: 2043
Joined: Tue Dec 23, 2003 3:54 am

Re: How to put underscored chars in TextGadgets?

Post by kenmo »

Usually I agree with the PureBasic team's decisions, but I don't really like this change. :?

The ampersand underline on Windows has been around for years and years. It was simple to use, you just need to be aware of it when working cross-platform.

Instead of changing the behavior, I think a note should have been added to the help, like for MenuItem():
On Windows you can use the special '&' character to underline a specific letter:
"&File" will actually display: File
I guess this just concerns me because: if the "&" is changed for gadgets, is it going to change for menus too? I use the "&" in menu titles and menu items all the time (and I remove them automatically for Mac and Linux builds). I just want to avoid Windows API wherever I can.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: How to put underscored chars in TextGadgets?

Post by netmaestro »

if the "&" is changed for gadgets, is it going to change for menus too?
No, it's just a flag added to the text gadget. Menus will be unaffected. Text gadgets are mostly used for labels anyway so that functionality doesn't have much use for them.
BERESHEIT
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: How to put underscored chars in TextGadgets?

Post by BorisTheOld »

PB wrote:...can someone please advise on how I can put underscored
characters in my TextBoxes in future? I liked using them for
showing shortcut keys in descriptions, just as they are were
meant to do.
I found the best solution was to write my own custom classes using the canvas gadget. Now I can write true cross-platform applications without wasting time trying to develop work-arounds for missing gadget features. It has the advantage of not requiring any API code or library references -- just pure PB code.

Three years ago I took a couple of months to write some basic classes. A day for something like a button or label, and a week for something more complex, like a listview or grid. And now we have much more flexibility in writing our applications, since we have the ability to enhance these classes to suit new situations.

It really is worth taking the time to do something like this, and not be tied down by the compromises that PB makes to be cross-platform.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
Zach
Addict
Addict
Posts: 1676
Joined: Sun Dec 12, 2010 12:36 am
Location: Somewhere in the midwest
Contact:

Re: How to put underscored chars in TextGadgets?

Post by Zach »

BorisTheOld wrote:
PB wrote:...can someone please advise on how I can put underscored
characters in my TextBoxes in future? I liked using them for
showing shortcut keys in descriptions, just as they are were
meant to do.
I found the best solution was to write my own custom classes using the canvas gadget. Now I can write true cross-platform applications without wasting time trying to develop work-arounds for missing gadget features. It has the advantage of not requiring any API code or library references -- just pure PB code.

Three years ago I took a couple of months to write some basic classes. A day for something like a button or label, and a week for something more complex, like a listview or grid. And now we have much more flexibility in writing our applications, since we have the ability to enhance these classes to suit new situations.

It really is worth taking the time to do something like this, and not be tied down by the compromises that PB makes to be cross-platform.
Would you be interested in posting one of your custom class sources as an example?
BorisTheOld
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Apr 24, 2012 5:08 pm
Location: Ontario, Canada

Re: How to put underscored chars in TextGadgets?

Post by BorisTheOld »

Zach wrote:
BorisTheOld wrote: I found the best solution was to write my own custom classes using the canvas gadget........
Would you be interested in posting one of your custom class sources as an example?
http://www.purebasic.fr/english/viewtop ... 40&t=57143

This should give you some ideas. For instance, our String gadget class is similar to the Button class used in this example, but has extra code for assembling and displaying text as keyboard events occur, and for drawing a cursor at the appropriate position.

The largest amount of time was spent on developing the basic OOP structure, a simple auto-sizing mechanism, event handling, and the use of callback routines. Once all this was in place, the actual classes were easy to write.
For ten years Caesar ruled with an iron hand, then with a wooden foot, and finally with a piece of string.
~ Spike Milligan
User avatar
TI-994A
Addict
Addict
Posts: 2740
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: How to put underscored chars in TextGadgets?

Post by TI-994A »

PB wrote:...can someone please advise on how I can put underscored characters in my TextBoxes in future? I liked using them for showing shortcut keys in descriptions, just as they are were meant to do.
Hi PB. Here's a simple workaround which can be instantiated in the same way as a standard TextGadget():

Code: Select all

Procedure cTextGadget(gNo, x, y, width, height, text.s, flags = 0)
  sFont = FontID(LoadFont(#PB_Any, "Arial", 11))
  uFont = FontID(LoadFont(#PB_Any, "Arial", 11, #PB_Font_Underline))
  
  If flags => #PB_Text_Border And flags <= #PB_Text_Border | #PB_Text_Right
    border = 1
    borderOffset = 4
  EndIf
  
  CanvasGadget(gNo, x, y, width, height, border)
  
  StartDrawing(CanvasOutput(gNo))
    Box(0, 0, width, height, RGB(200, 220, 240))  
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawingFont(sFont) 
    
    x = 0: y = 0
    textOffset = width - TextWidth(RemoveString(text, "&")) - borderOffset
    If flags = #PB_Text_Center Or flags = #PB_Text_Border | #PB_Text_Center
      x = textOffset / 2
    ElseIf flags = #PB_Text_Right Or flags = #PB_Text_Border | #PB_Text_Right
      x = textOffset
    EndIf
    
    For drawLoop = 1 To Len(text)
      If Mid(text, drawLoop, 1) = "&"
        drawLoop + 1
        DrawingFont(uFont) 
      Else
        DrawingFont(sFont)
      EndIf
      x = DrawText(x, y, Mid(text, drawLoop, 1), RGB(0, 0, 100))
    Next drawLoop
  StopDrawing()
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(0, 0, 0, 250, 500, "Custom TextGadget()", wFlags)
SetWindowColor(0, RGB(255, 255, 255))

cTextGadget(1, 10, 10, 230, 30, "&Custom TextGadget()")
TextGadget(2, 10, 50, 230, 30, "&Standard TextGadget()")

tbFlags = #PB_Text_Center
text.s = "Centered &Text"
cTextGadget(3, 10, 90, 230, 30, text, tbFlags)
TextGadget(4, 10, 130, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Right
text = "Right-&Aligned Text"
cTextGadget(5, 10, 170, 230, 30, text, tbFlags)
TextGadget(6, 10, 210, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Border
text = "TextGadget with &Border"
cTextGadget(7, 10, 250, 230, 30, text, tbFlags)
TextGadget(8, 10, 290, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Center | #PB_Text_Border
text = "&Centered Text with Border"
cTextGadget(9, 10, 330, 230, 30, text, tbFlags)
TextGadget(10, 10, 370, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Right | #PB_Text_Border
text = "&Right-Aligned Text with Border"
cTextGadget(11, 10, 410, 230, 30, text, tbFlags)
TextGadget(12, 10, 450, 230, 30, text, tbFlags)

sFont = FontID(LoadFont(#PB_Any, "Arial", 11))
For setFont = 2 To 12 Step 2
  SetGadgetFont(setFont, sFont)
Next setFont

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
The cTextGadget() function is fully encapsulated and can be implemented right out of the box. Hope it helps. :D
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
c4s
Addict
Addict
Posts: 1981
Joined: Thu Nov 01, 2007 5:37 pm
Location: Germany

Re: How to put underscored chars in TextGadgets?

Post by c4s »

TI-994A wrote:

Code: Select all

; [...]
  If flags => #PB_Text_Border And flags <= #PB_Text_Border | #PB_Text_Right
; [...]
    If flags = #PB_Text_Center Or flags = #PB_Text_Border | #PB_Text_Center
; [...]
Just a small tip: Never ever check for flags like that because what if the value of e.g. #PB_Text_Border changes? Then your code wouldn't work anymore!

So rather use something like:

Code: Select all

; [...]
  If flags & #PB_Text_Border
; [...]
    If flags & #PB_Text_Center
; [...]
If any of you native English speakers have any suggestions for the above text, please let me know (via PM). Thanks!
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: How to put underscored chars in TextGadgets?

Post by PB »

> Here's a simple workaround

[Cranky rant removed]

I must be missing a bigger picture somewhere. Can someone explain?
Last edited by PB on Sat Mar 15, 2014 11:39 am, edited 1 time in total.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Fred
Administrator
Administrator
Posts: 18207
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: How to put underscored chars in TextGadgets?

Post by Fred »

The purpose of PB commanset is to hide internal differences accross OS, so it looks like an issue than "&Word" translate into "Word" on Windows, and "&Word" on Linux on OS X, can we agreed on that ? It was never documented, so that's why it was considered as a legitimate bug. Now, Windows apps usually don't use underscore at all since XP (MS even removed them from menu item by default), so it shouldn't be a problem.

Here is the small code to get back the old behaviour, if you really wants it:

Code: Select all

Procedure cTextGadget(gNo, x, y, width, height, text.s, flags = 0)
  
  result = TextGadget(gNo, x, y, width, height, "", flags)
  If gNo = #PB_Any
    id = result
  Else
    id = gNo
  EndIf
  
  SetWindowLongPtr_(GadgetID(id), #GWL_STYLE, GetWindowLongPtr_(GadgetID(id), #GWL_STYLE) & ~#SS_NOPREFIX)
  SetGadgetText(id, text)
  ProcedureReturn result
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(0, 0, 0, 250, 500, "Custom TextGadget()", wFlags)
SetWindowColor(0, RGB(255, 255, 255))

cTextGadget(1, 10, 10, 230, 30, "&Custom TextGadget()")
TextGadget(2, 10, 50, 230, 30, "&Standard TextGadget()")

tbFlags = #PB_Text_Center
text.s = "Centered &Text"
cTextGadget(3, 10, 90, 230, 30, text, tbFlags)
TextGadget(4, 10, 130, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Right
text = "Right-&Aligned Text"
cTextGadget(5, 10, 170, 230, 30, text, tbFlags)
TextGadget(6, 10, 210, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Border
text = "TextGadget with &Border"
cTextGadget(7, 10, 250, 230, 30, text, tbFlags)
TextGadget(8, 10, 290, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Center | #PB_Text_Border
text = "&Centered Text with Border"
cTextGadget(9, 10, 330, 230, 30, text, tbFlags)
TextGadget(10, 10, 370, 230, 30, text, tbFlags)

tbFlags = #PB_Text_Right | #PB_Text_Border
text = "&Right-Aligned Text with Border"
cTextGadget(11, 10, 410, 230, 30, text, tbFlags)
TextGadget(12, 10, 450, 230, 30, text, tbFlags)

sFont = FontID(LoadFont(#PB_Any, "Arial", 11))
For setFont = 2 To 12 Step 2
  SetGadgetFont(setFont, sFont)
Next setFont

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: How to put underscored chars in TextGadgets?

Post by PB »

> "&Word" translate into "Word" on Windows, and "&Word" on Linux on OS X

Okay, now I see why the change was made. Thank you for clarifying.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply