[wxPython] How do I redefine a wxControl's SetSize, SetDimensions methods?

I am trying to make a wxPython control that responds to changes in its size
by possibly
changing fonts. I want to embed this control in a sizer (currently I an
using wxFlexGridSizer),
and I am expecting that when the sizer calls my control's SetSize or
setDimensions methods,
I can do something.

I am finding that these methods are not being called at all. I looked in
wxPython/lib/grids.py,
and that code calls "item.SetDimension(ipt, isz)", to resize children. This
method is defined
for sizer children, but not for window children, but with four arguments,
x,y, width, height, not two,
as in grids.py. But it seems that the wxFlexGridSizer apperently defined in
grids.py is not
being used at all.

So, my simple question is: How can I make a control of my own that can
become aware of
resizing actions taken by automatic sizers?

···

-------------------------
class Gauge(wxControl):

    def __init__(self, parent, ID, dev,
                 pos = wxDefaultPosition, size = (100,10),
                 style = 0, name=None):
        if style == 0:
            style = wxSUNKEN_BORDER
        if not name:
            name = dev.key + "." + str(ID)
        wxControl.__init__(self, parent, ID, pos, size, style,
            validator = wxDefaultValidator, name=name)
        self.lo = dev.lo
        self.hi = dev.hi
        self.rValue = 0.0
        self.txtlo = sstr(self.lo)
        self.txthi = sstr(self.hi)

        EVT_PAINT(self, self.OnPaint)

    def SetValue(self, value, dev, opt):
            self.rValue = min(1.0, max(0.0,
(value-self.lo)/(self.hi-self.lo)))
        self.Refresh()

    def OnPaint(self, event):
        self.Draw(wxPaintDC(self))

    def SetSize(self,size):
        wxLogMessage("SetSize: ", str(size))
        wxControl.SetSize(self, size)
    def SetDimensions(self, x, y, width, height, sizeFlags=wxSIZE_AUTO):
        wxLogMessage("SetDimensions: x=%d, y=%d, w=%d,h=%d"
%(x,y,width,height))
        wxControl.SetDimensions(self, x, y, width, height, sizeFlags)
    def SetPosition(self,point):
        wxLogMessage("SetPosition: ", str(point))
        wxControl.SetPosition(self, point)

    def Draw(self,dc):
        w, h = self.GetClientSizeTuple()
        dc.BeginDrawing()
        ch = dc.GetCharHeight()
        hbar = max(4, h - ch)
        ytext = hbar
        twlo,th = dc.GetTextExtent(self.txtlo)
        twhi,th = dc.GetTextExtent(self.txthi)
        dc.Clear()
        dc.SetBrush(wxBLUE_BRUSH)
        dc.DrawRectangle(0,0, int(w*self.rValue), hbar)
        xtext = max(0, w-twhi)
        dc.DrawText(self.txthi, xtext, ytext)
        if xtext > twlo + ch:
            dc.DrawText(self.txtlo, 0, ytext)
        dc.EndDrawing()

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Use a message handler instead of overloading SetDimensions or SetSize.

   EVT_SIZE(self, self.OnSize)

···

----- Original Message -----

From: "Parzival Herzog" <parz@home.com>
To: <wxpython-users@lists.sourceforge.net>
Sent: Friday, January 19, 2001 2:34 PM
Subject: [wxPython] How do I redefine a wxControl's SetSize, SetDimensions
methods?

I am trying to make a wxPython control that responds to changes in its

size

by possibly
changing fonts. I want to embed this control in a sizer (currently I an
using wxFlexGridSizer),
and I am expecting that when the sizer calls my control's SetSize or
setDimensions methods,
I can do something.

I am finding that these methods are not being called at all. I looked in
wxPython/lib/grids.py,
and that code calls "item.SetDimension(ipt, isz)", to resize children.

This

method is defined
for sizer children, but not for window children, but with four arguments,
x,y, width, height, not two,
as in grids.py. But it seems that the wxFlexGridSizer apperently defined

in

grids.py is not
being used at all.

So, my simple question is: How can I make a control of my own that can
become aware of
resizing actions taken by automatic sizers?

-------------------------
class Gauge(wxControl):

    def __init__(self, parent, ID, dev,
                 pos = wxDefaultPosition, size = (100,10),
                 style = 0, name=None):
        if style == 0:
            style = wxSUNKEN_BORDER
        if not name:
            name = dev.key + "." + str(ID)
        wxControl.__init__(self, parent, ID, pos, size, style,
            validator = wxDefaultValidator, name=name)
        self.lo = dev.lo
        self.hi = dev.hi
        self.rValue = 0.0
        self.txtlo = sstr(self.lo)
        self.txthi = sstr(self.hi)

        EVT_PAINT(self, self.OnPaint)

    def SetValue(self, value, dev, opt):
            self.rValue = min(1.0, max(0.0,
(value-self.lo)/(self.hi-self.lo)))
        self.Refresh()

    def OnPaint(self, event):
        self.Draw(wxPaintDC(self))

    def SetSize(self,size):
        wxLogMessage("SetSize: ", str(size))
        wxControl.SetSize(self, size)
    def SetDimensions(self, x, y, width, height, sizeFlags=wxSIZE_AUTO):
        wxLogMessage("SetDimensions: x=%d, y=%d, w=%d,h=%d"
%(x,y,width,height))
        wxControl.SetDimensions(self, x, y, width, height, sizeFlags)
    def SetPosition(self,point):
        wxLogMessage("SetPosition: ", str(point))
        wxControl.SetPosition(self, point)

    def Draw(self,dc):
        w, h = self.GetClientSizeTuple()
        dc.BeginDrawing()
        ch = dc.GetCharHeight()
        hbar = max(4, h - ch)
        ytext = hbar
        twlo,th = dc.GetTextExtent(self.txtlo)
        twhi,th = dc.GetTextExtent(self.txthi)
        dc.Clear()
        dc.SetBrush(wxBLUE_BRUSH)
        dc.DrawRectangle(0,0, int(w*self.rValue), hbar)
        xtext = max(0, w-twhi)
        dc.DrawText(self.txthi, xtext, ytext)
        if xtext > twlo + ch:
            dc.DrawText(self.txtlo, 0, ytext)
        dc.EndDrawing()

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

I am trying to make a wxPython control that responds to changes in its size
by possibly
changing fonts. I want to embed this control in a sizer (currently I an
using wxFlexGridSizer),
and I am expecting that when the sizer calls my control's SetSize or
setDimensions methods,
I can do something.

I am finding that these methods are not being called at all.

Most methods in wxPython are one-way only. IOW, you can call from Python code to the C++ method, but not from C++ to the Python method. In order to do that it takes a lot of work and overhead in the wrappers, and so I only do it where it is necessary to implement the desired (normal) functionality of the particular class. For all other methods when it is called from C++ code then the C++ method is called and it is not reflected into Python even if there is a matching method in the Python class.

But it seems that the wxFlexGridSizer apperently defined in
grids.py is not
being used at all.

It was implemented first in Python, and then Robert R. ported it to C++, and that is the one you get unless you explicitly import it from wxPython.lib.grids.

So, my simple question is: How can I make a control of my own that can
become aware of
resizing actions taken by automatic sizers?

The same way you catch and respond to any other event in the GUI. Use events, EVT_SIZE in this case.

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

O.K. So I am still wrestling with re-sizing! I've got my own control, it
figures out
what font size to use, and draws itself in a window without borders, all
thanks
to Robin's help. My control works well in a wxFlexGridSizer cell, when that
cell is marked stretcheable.

Now I want to use that control with wxPython automatic sizing system, using
my own sizer class.

I used a copy of the wxPython lib.grids.py.wxGridSizer class. Without
changing
the class except to add some logging messages, I found that
the sizer's "CalcMin" method is invoked, but the sizer's children's CalcMin
methods
are never invoked, instead the lib.grids.py.wxGridSizer.CalcMin, when it
calls
CalcMin on a child, gets the initial size of the wxControl that my own
control is derived from.
I imagine that this is what the base wxControl or wxWindow class returns for
CalcMin.

Now lib.grids.py.wxGridSizer is implemented in Python, and its children
should be the class
I wrote and added to the sizer. So I think the CalcMin method that
lib.grids.py.wxGridSizer
invokes is the method of my class, not a virtual method of some base class
implemented in C++. But apparently I am wrong.

With the present state of my knowledge, It seems to me that the sizing
system
is all but unusable in the presence of derived controls that have sizing
behaviour
that differs from what the wxWindows base class delivers. Your comment below
about using EVT_SIZE events seemt to confirm this.
Please tell me I'm so so wrong!

Can I write my own control, have my own sizer, and get the wxPython sizing
system to respond to these?

- Parzival

P.S. I apologise for the lack of quiting in the "quoted" message. I'm using
Outlook Express,
Robin, you are using Outlook Express, and for some reason, O.E. will not
quote your
messages. I tried quite a few other messages on this list, and all the
others get quoted,
(even mine also composed with O.E.), but not yours. You must be special!

···

----- Original Message -----
From: "Robin Dunn" <robin@alldunn.com>
To: <wxpython-users@lists.sourceforge.net>
Sent: Friday, January 19, 2001 3:40 PM
Subject: Re: [wxPython] How do I redefine a wxControl's SetSize,
SetDimensions methods?

Most methods in wxPython are one-way only. IOW, you can call from Python
code to the C++ method, but not from C++ to the Python method. In order to
do that it takes a lot of work and overhead in the wrappers, and so I only
do it where it is necessary to implement the desired (normal) functionality
of the particular class. For all other methods when it is called from C++
code then the C++ method is called and it is not reflected into Python even
if there is a matching method in the Python class.

So, my simple question is: How can I make a control of my own that can
become aware of
resizing actions taken by automatic sizers?

The same way you catch and respond to any other event in the GUI. Use
events, EVT_SIZE in this case.

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users

Now I want to use that control with wxPython automatic sizing system, using
my own sizer class.

I used a copy of the wxPython lib.grids.py.wxGridSizer class. Without
changing
the class except to add some logging messages, I found that
the sizer's "CalcMin" method is invoked, but the sizer's children's CalcMin
methods
are never invoked, instead the lib.grids.py.wxGridSizer.CalcMin, when it
calls
CalcMin on a child, gets the initial size of the wxControl that my own
control is derived from.
I imagine that this is what the base wxControl or wxWindow class returns for
CalcMin.

When the sizer iterates through its children they are actually wxSizerItem objects, not windows or sizers directly, so the CalcMin that is being called is in the wxSizerItem object. When the item is holding a sub-sizer then it calls its CalcMin method, but if it is a window or a spacer then the minimum size is assumed to be the size it had when it was added to the sizer plus any borders, as you've discovered. This is by design. If you want to specify a different minimum size you can, with

    sizer.SetItemMinSize(theWindow, width, height)

···

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

_______________________________________________
wxPython-users mailing list
wxPython-users@lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/wxpython-users