[wxPython] GetFullTextExtent - wrong results - workaround suggestion

I have been trying to create wxTextCtrl with larger
fontsize, using style = wxTE_MULTILINE, and calculating the
needed height to show one line using GetFullTextExtent()
and SetSize(), thereby giving the user the impression of a
one line TextCtrl with a large font

Why do you want to use wxTE_MULTILINE to create a single-line text control?

My problem is that GetFullTextExtent() doesn't seem to give
me correct results, for instance if i try with fontsize 10,
I must use 18 for height:

The textctrl does mor than just draw the text. It potentially has borders
and probably will have at least a bit of empty space around the text area...
And how much space that really is will be platform dependent.

It's also easy to confuse points and pixels when working with text. 10 point
text will be 13 to 16 pixels tall on a Windows desktop.

···

On Thu, 18 Apr 2002 13:03:03 -0700, "Robin Dunn" <robin@alldunn.com> wrote:

--
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

First of all maybe I should present my problems more in depth:

I am adapting a gui for sight week / poor sighted ( whats the propper word in
english??) people to work on data entry, they need large fonts to see whats
happening.

The app is used both on win and unix, develeoped mainly on linux.

Since I actually want to use my computer, setting a perverted system font is
not a serious alternative, also I do a lot of coding while comuting, so I
cant have a sysfont=20 on my laptop - for crying out loud I wouldnt eaven be
able to see my wingIDE main window :wink:

My first hope that a simple SetSize() would do the trick has turned out to be
not the case.

So far the only control where SetSize() works seems to be StaticText and
buttons, all the other I have tried have some kind of issue.

Since I need to get the largefont version out the door asap, for the moment I
have started creating wrapper classes that "fakes" propper behaviour for the
needed controls

Im almost certain that Im doing it the wrong way, that Im missing something.
Shouldnt it be possible to do such a simple thing as displaying a TextCtrl or
a List in a "odd" fontsize???

Surely somebody else must have done that in the past, or am I the only person
that has tried to do that? - seems highly unlikely.

···

--------
Some responses to my first posts on this, from Robin Dunn and to Tim Roberts

Why do you want to use wxTE_MULTILINE to create a single-line text control?

See the online doc for wxTextCtrl, specifically the paragraph
"wxTextCtrl styles"
According to this paragraph only multilines alowes you to set what font to use
So to get at least something that looks as a large wxTextCtrl I set the style
to multiline, and rezize it down to only be one (character) line high.
If somebody inputs to long a text, the control wraps the line, but at least
for normal input values it looks normal, and the odd behaviour when inputing
"to long" data is at least not ruining anything, the users can be instructed
about this odd behaviour.

It's also easy to confuse points and pixels when working with text. 10
point text will be 13 to 16 pixels tall on a Windows desktop.

Ok I was a bit unclear in my first post (dosen't that happen all the time)
I hope that I haven't got that part wrong, more on that below

The textctrl does mor than just draw the text. It potentially has borders
and probably will have at least a bit of empty space around the text area...
And how much space that really is will be platform dependent.

Yup that was my first guess, the problem is that the "error" or diff between
what GetFullTextExtent() reports and what works by try&error is non linear.

At the end of this mail is the code I used

------- A table of what I have measured -----------

Colums
--------
A = FontSize
B = h + d as reported by GetFullTextExtent (),
       since e always returned 0 I didnt care about him
C = Required, after trry and error
D = Result of my height function

A B C D
6 10 16 17
8 12 18 18
9 15 18 21
10 14 18 20
11 17 20 23
12 17 20 23
13 21 23 26
14 19 22 24
15 23 25 27
18 26 27 30
19 31 31 34
20 32 32 35
21 33 33 35
22 36 35 38
23 37 36 39
24 32 35 35
25 39 38 40
30 48 45 48
36 58 55 56
40 64 60 60

My first guess was that if I just add something like 5 or 10 it will be ok,
but that doesnt work, since the measuerd values goes below needed for
fontsize above 20, so something must be seriously wrong.
If I just would need to add a few point for borders etc, it should be the same
for all, and since I get a non linear error it seems that I have to calculate
the desired value.
height = int( 0.81 * (h + d) + 9 + 0.5 )
Is by no means perfect, but it gets close enough until I find something more
apropriate.

Any help would be greatly apretiated, if nothing else I will post my wxfnt
wrappers, but I hope there is a neater solution to this.

  regards /Jacob Lundqvist

------- The code used in the test ----------
class FontHeight:
    def GetHeight( self, txtAttr ):
        #
        # Since I cant figure out how to detect the actual fontsize
        # correctly I do a little equation that hopefully gets it right...
        font = txtAttr.GetFont()
        font_height = font.GetPointSize()
        w,h,d,e = self.GetFullTextExtent( '', font )
        height = int( 0.81 * (h + d) + 9 + 0.5 )
        return height

class wxfntTextCtrl(wxTextCtrl,FontHeight):
    def __init__( self, parent, id, value = '',
      pos=(0,0), size = wxDefaultSize,
                    style = 0, txtAttr = None ):
        if txtAttr and not (style & wxTE_PASSWORD):
      # argh if we do multiline on a password field
      # password is echoed in cleartext!
      # dosnt matter to much people can live with
            # stars in the wrong size...
            style = style | wxTE_MULTILINE
        wxTextCtrl.__init__( self, parent, id, value = value, pos = pos,
                             size = size, style = style )
        if txtAttr:
            self.SetDefaultStyle(txtAttr)
            self.SetSize((-1,self.GetHeight(txtAttr)))
            if value:
                self.Clear()
                self.AppendText(value)
            else:
    # need to set some text before clear to get
    # size updated
                self.AppendText(' ')
                self.Clear()

------- Environment ---------

Distro: Mandrake 8.2

python-2.2-9mdk

wxGTK-2.3.2-1
wxGTK6-2.2.9-3mdk
wxGTK6-gl-2.2.9-3mdk
wxGTK-devel-2.3.2-1
wxGTK-gl-2.3.2-1
wxPython-2.3.2.1-1

Jacob Lundqvist wrote:

I am adapting a gui for sight week / poor sighted ( whats the propper word in
english??) people to work on data entry, they need large fonts to see whats
happening.

I'm not sure about your specific problem, but... just as a minor point, the
official-ish English term is 'vision impaired' (or 'low vision') -- I have a
friend who qualifies, and who is a software tester, so I hear a bit about it from
her.

Out of curiosity... I know that there are screen magnification programs
specifically for vision-impaired people. Is there some reason why those wouldn't
be workable? (Not that I could give you any names, don't even know if any free
ones exist, but it's a thought...)

Jeff Shannon
Technician/Programmer
Credit International

fredagen den 19 april 2002 01.26 skrev Jeff Shannon:

I'm not sure about your specific problem, but... just as a minor point, the
official-ish English term is 'vision impaired' (or 'low vision') -- I have
a friend who qualifies, and who is a software tester, so I hear a bit about
it from her.

Thanks for enligthen me, I'll try to rememebr that!

Out of curiosity... I know that there are screen magnification programs
specifically for vision-impaired people. Is there some reason why those
wouldn't be workable? (Not that I could give you any names, don't even
know if any free ones exist, but it's a thought...)

Had a friend using such a monitor, but this isn't deemed nececary in this
case. Ths employees in this case are not that severly impaired, but they
requested that all vital work flow items use size 20 fonts to make it
convinient for them.

As a side note, these guys and gals are actually scanning hi-res images, and
documenting each image, why I don't know but they have a very good feeling
for working with images, but small fonts bother them.

  regs /Jacob Lundqvist

I assume that you are talking about SetFont(), not SetSize()... SetSize
only sets the number of pixels that a window will cover and does nothing
with what it displays.

...

Im almost certain that Im doing it the wrong way, that Im
missing something. Shouldnt it be possible to do such a simple
thing as displaying a TextCtrl or a List in a "odd" fontsize???

Yes.

> Why do you want to use wxTE_MULTILINE to create a single-line text

control?

See the online doc for wxTextCtrl, specifically the paragraph
"wxTextCtrl styles"
According to this paragraph only multilines alowes you to set what
font to use

No it doesn't. It says that only the multi-line controls support using
*styles* which are attribute objects that let you change the font or colour
of subsections of the content of the control. For example, one word could
be bold. This has nothing to do with the font of the entire control.
SetFont is a method of wxWindow so all window types should have at least
some support of changing the font, if not then it's either a bug that should
be reported at SF or it was designed not to for some reason.

>The textctrl does mor than just draw the text. It potentially has

borders

>and probably will have at least a bit of empty space around the text

area...

>And how much space that really is will be platform dependent.

Yup that was my first guess, the problem is that the "error" or diff

between

what GetFullTextExtent() reports and what works by try&error is non

linear.

BTW, have you tried calling GetBestSize and setting your control size based
on that? Not all controls implement a meaningful GetBestSize but many do.

···

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

In case it wasn't obvious from Robin's comments below, you need to use
SetFont, and the way you change the size of the font is to use the wxFont
SetPointSize() method. If you are running on wxGTK, there is a known bug
that prevents setting the font of a single line text control with 2.3.2.1. I
think this have been fixed in 2.3.3 on GTK, but I can't confirm that since I
use Windows. You might be able to use the wxTE_RICH and wxTE_MULTILINE
styles and just make your text field one line high as a workaround for now.

ka

···

-----Original Message-----
From: wxpython-users-admin@lists.wxwindows.org
[mailto:wxpython-users-admin@lists.wxwindows.org]On Behalf Of Robin Dunn
Sent: Friday, April 19, 2002 12:35 PM
To: wxpython-users@lists.wxwindows.org
Subject: Re: [wxPython] SetSize() issues

I assume that you are talking about SetFont(), not SetSize()... SetSize
only sets the number of pixels that a window will cover and does nothing
with what it displays.

...

> Im almost certain that Im doing it the wrong way, that Im
> missing something. Shouldnt it be possible to do such a simple
> thing as displaying a TextCtrl or a List in a "odd" fontsize???

Yes.

> > Why do you want to use wxTE_MULTILINE to create a single-line text
control?
>
> See the online doc for wxTextCtrl, specifically the paragraph
> "wxTextCtrl styles"
> According to this paragraph only multilines alowes you to set what
> font to use

No it doesn't. It says that only the multi-line controls support using
*styles* which are attribute objects that let you change the font
or colour
of subsections of the content of the control. For example, one word could
be bold. This has nothing to do with the font of the entire control.
SetFont is a method of wxWindow so all window types should have at least
some support of changing the font, if not then it's either a bug
that should
be reported at SF or it was designed not to for some reason.

> >The textctrl does mor than just draw the text. It potentially has
borders
> >and probably will have at least a bit of empty space around the text
area...
> >And how much space that really is will be platform dependent.
>
> Yup that was my first guess, the problem is that the "error" or diff
between
> what GetFullTextExtent() reports and what works by try&error is non
linear.

BTW, have you tried calling GetBestSize and setting your control
size based
on that? Not all controls implement a meaningful GetBestSize but many do.

--
Robin Dunn
Software Craftsman
robin@AllDunn.com Java give you jitters?
http://wxPython.org Relax with wxPython!

_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwindows.org
http://lists.wxwindows.org/mailman/listinfo/wxpython-users