Any ideas?
Thanks!
Tom
Hi Tom,
the tags of the text widget have an underline option which you could
use like
---
pack [text .t]
.t tag configure ul -underline 1
.t insert end "Some "
# "tag" any text you want
.t insert end "T" ul
.t insert end "ext"
---
Uups, re-reading your post I just notice that you are talking of a
text item on a canvas. Now, the canvas supports the tagging mechanism
as well, but I don't know if 'underline' is available for its text
items.
HTH nonetheless
Helmut Giese
Tom
>No, the canvas items don't have a -underline option.
>But thanks anyway :)
Sorry,
but you _could_ of course put a text widget on the canvas (setting -bd
to 0 will remove any border line, so you just have a white area where
you can place text - probably no visual difference to a canvas' text
item).
Is the user supposed to interact with the text you display (like
clicking on it) ? Then a text widget might make life actually a bit
easier.
If not, you would probably want to disable the text widget after
updating it (else adventurous users will start putting text into it).
Good luck
Helmut Giese
The underlining code (which the canvas widget doesn't expose IIRC) and
the [font measure] implementation share the same text measuring engine.
You're probably just making some simple error (like assuming that all
characters are the same width - they aren't in general). That said, it
is fairly easy to underline a character, as you can see from this little
script:
# Basic setup
set s "qwertyuiopasdfghjklzxcvbnm"
set c s
pack [canvas .c]
.c create text 10 10 -anchor nw -tags txt -text $s
# Make an underlined font
eval font create foo [font actual [.c itemcget txt -font]]
font config foo -underline 1
# Make an underlined item and align it precisely in the right spot
# First, make the item with the text to underline in the right font
.c create text 10 10 -anchor nw -tags ul -text $c -font foo
# Use an RE trick to get the text *before* the char to underline
set precedingSubstring [regexp -inline ".*(?=$c)" $s]
# Now compute the offset relative to the main text and move that
# underlined character.
.c move ul [font measure foo $precedingSubstring] 0
You probably do not need to create the font afresh each time. ;-)
Donal.
Helmut: The reason I'm using a canvas is so I can have a background
image on the canvas (I am writing a canvas menu widget) - so putting in
a text widget will give a white square over the bg image, not what I
want ;) But thanks anyway.
Donal: Thank you for your reply!
I didn't assume each character was the same width - I had something
like this going on:
# index of char to underline
set uidx
# text to display
set text "item text"
# create text on canvas
set txtid [$canvas create text 0 0 -anchor nw -text $text]
# get char to underline
set char [string index $text $uidx]
# get text tag's font
set textf [$canvas itemcget $txtid -font]
# get width of char
set charw [font measure $textf $char]
# get text before underlined-char-to-be
set beforechar [string range 0 [expr {$uidx -1}]]
# get width of that text
set beforew [font measure $textf $beforechar]
# get bottom coord of text tag
set y [lindex [$canvas bbox $txtid] 3]
# draw line on canvas
set ulineid [$canvas create line $beforew $y [expr {$beforew +
$charw}]]
The reason I did it this way was so the text was all one tag, with a
line tag for the underline - It is possible the item may have it's
underline character changed, meaning i need to move the underline -
this would (I think) be easier to do if I just have to move the line
rather than create two text tags from a string...but your way does work
very nicely :) If you can see a glaring problem with the above code, do
point it out ;)
Thank you again! :D
Tom
Ooh, totally manual underlining. Your main problem is that the underline
is not being drawn as part of the font (try changing the font size on a
button with an underline to see why this matters) and is not drawn at
the height or thickness that the font itself states is for underlines;
Tk's built-in underlining engine knows exactly what the correct thing to
do is, especially given platform conventions. (For some reason, the
underline position is different to the vertical position of the visible
part of the underline character; go figure!)
Aside from that, what you're doing is right. And it would not be a bad
thing to expose the underlining capabilities of the text drawing engine
to canvas text items. Indeed, it's just a matter of putting a call to
Tk_UnderlineTextLayout in the correct place (just under the calls to
Tk_DrawTextLayout in tkCanvText.c I'd guess), adding a couple of bits to
give control over the underline position, and updating docs+tests. (OK,
it would need a TIP too, but that'd be a very easy and short one to
write and I'd be happy to help.) There's no reason why canvas's text
items shouldn't support underlining; it's just not been done yet.
Donal.
I'd love for underline capabilities to be added to canvas tags, it
would make things easier for me that's for sure! Hehe.
It would be great if you could help me write a TIP. Can anyone submit a
TIP or do you have to be a tcl/tk dev..?
I have no experience of C, but as you said it would be an easy feature
to code and I hope someone doesn't mind doing it :)
Thanks!
Tom
As changes go, this is just about as easy as it gets.
The TIP is really just a summary of what you want done (as seen at the
script level, which means "add an -underline option to the canvas
widget's text items") and why ("so that it is easier to underline a
single character in the same way that buttons can").
Bah, for that matter it's probably easier for me to just write it
directly myself. Explaining myself here will take at least as long. :-)
It's now TIP#260, online at http://tip.tcl.tk/260.html
In terms of implementation, it's a very small change most of which can
be done using largely "cut-n-paste programming". :-) The slowest bit is
going to be updating the tests.
Donal.
Thanks again!
Tom