Page 1 of 1

How to put underscored chars in TextGadgets?

Posted: Mon Mar 10, 2014 11:49 am
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.

Re: How to put underscored chars in TextGadgets?

Posted: Mon Mar 10, 2014 12:44 pm
by Fred
If you are Windows only, then you can use SetWindowPtr_() function to remove the #SS_NOPREFIX style

Re: How to put underscored chars in TextGadgets?

Posted: Mon Mar 10, 2014 1:21 pm
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 :|

Re: How to put underscored chars in TextGadgets?

Posted: Mon Mar 10, 2014 9:40 pm
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.

Re: How to put underscored chars in TextGadgets?

Posted: Mon Mar 10, 2014 11:08 pm
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.

Re: How to put underscored chars in TextGadgets?

Posted: Tue Mar 11, 2014 6:26 am
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.

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 2:47 am
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?

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 3:43 am
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.

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 10:25 am
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

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 10:43 am
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
; [...]

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 11:02 am
by PB
> Here's a simple workaround

[Cranky rant removed]

I must be missing a bigger picture somewhere. Can someone explain?

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 11:22 am
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

Re: How to put underscored chars in TextGadgets?

Posted: Sat Mar 15, 2014 11:38 am
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.