an improved segmented control

This was my attempt to mimic Apple’s NSSegmentedControl, which is basically just a set of buttons squished together. I’ve fixed some of the more glaring problems that Robin pointed out on Windows (many months ago), and it’s starting to behave well on all platforms, but there are still some outstanding issues that I need help with:

  1. On Windows (7, with Python 2.7 and wxPython 2.9.1), the lower row of buttons is compressed vertically for no apparent reason. If I enlarge the frame, the button appears normal.

  2. Also on Windows, the set of buttons on the toolbar and the rightmost set of (vertical) buttons have blank strips on the bottom and right, respectively, where the gradient brush obviously isn’t penetrating. I have no idea why this would happen.

  3. Robin previously suggested clearing the device context to the parent background on Windows to eliminate black regions on the margins/corners where I’m not drawing. This does indeed work on Windows, but on Mac (previously okay) it results in a white border. Is there a platform-independent way to do this? None of the custom controls that I’ve looked at in the past had this problem.

There is also a problem redrawing the panel if I shrink and expand it on Windows, but I suspect that’s because I’m really running it inside Parallels on a Mac. I don’t have an actual native Windows installation that I could try this with, unfortunately (or not, depending on how you feel about Windows).

I’m reasonably happy with the way this works so far, but there are still too many platform-specific hacks and random weirdness that I don’t understand. I also suspect that the method I’m using to set the size is brain-dead, although it appears to produce the intended results. There are quite a few enhancements that could be made to cover all the functionality (or at least appearances) of the native Mac control, but I’d like to get the current set of quirks and bugs out of the way first.

thanks,

Nat

segmentedctrl.py (16.7 KB)

This was my attempt to mimic Apple’s NSSegmentedControl, which is basically just a set of buttons squished together. I’ve fixed some of the more glaring problems that Robin pointed out on Windows (many months ago), and it’s starting to behave well on all platforms, but there are still some outstanding issues that I need help with:

  1. On Windows (7, with Python 2.7 and wxPython 2.9.1), the lower row of buttons is compressed vertically for no apparent reason. If I enlarge the frame, the button appears normal.

I’m not seeing this on my Win7. Note that Python 2.7 has many bugs that 2.6 doesn’t. My platform is:

Windows 6.1.7600 <-------- 64-bit Win7
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)]
Wx 2.8.11.0

I thought you might want to see what it looks like on a native win7. See the attached screen shots

  1. Also on Windows, the set of buttons on the toolbar and the rightmost set of (vertical) buttons have blank strips on the bottom and right, respectively, where the gradient brush obviously isn’t penetrating. I have no idea why this would happen.
  1. Robin previously suggested clearing the device context to the parent background on Windows to eliminate black regions on the margins/corners where I’m not drawing. This does indeed work on Windows, but on Mac (previously okay) it results in a white border. Is there a platform-independent way to do this? None of the custom controls that I’ve looked at in the past had this problem.

There is also a problem redrawing the panel if I shrink and expand it on Windows, but I suspect that’s because I’m really running it inside Parallels on a Mac. I don’t have an actual native Windows installation that I could try this with, unfortunately (or not, depending on how you feel about Windows).

I’m reasonably happy with the way this works so far, but there are still too many platform-specific hacks and random weirdness that I don’t understand. I also suspect that the method I’m using to set the size is brain-dead, although it appears to produce the intended results. There are quite a few enhancements that could be made to cover all the functionality (or at least appearances) of the native Mac control, but I’d like to get the current set of quirks and bugs out of the way first.

thanks,

Nat

Ray

···

On Sun, Nov 7, 2010 at 7:26 PM, Nat Echols nathaniel.echols@gmail.com wrote:

I just tried it with Python 2.6.5 and wxPython 2.9.1.1 on Win 7
64bit.

When maximizing the frame they look fine, but if one resizes using

the border, i.e. make the frame smaller that the buttons done fit
and then enlarge it to just make them fit the right and bottom
buttons are ugly - see image.

![moz-screenshot-13.png|526x294](upload://ksddiowSRtmGgEfs1Gn523xntSA.png)

Werner
···

On 08/11/2010 06:40, Ray Pasco wrote:

    On Sun, Nov 7, 2010 at 7:26 PM, Nat > Echols <nathaniel.echols@gmail.com> >         wrote:
      This was my attempt to mimic Apple's

NSSegmentedControl, which is basically just a set of buttons
squished together. I’ve fixed some of the more glaring
problems that Robin pointed out on Windows (many months ago),
and it’s starting to behave well on all platforms, but there
are still some outstanding issues that I need help with:

        1. On Windows (7, with Python 2.7 and wxPython 2.9.1),

the lower row of buttons is compressed vertically for no
apparent reason. If I enlarge the frame, the button appears
normal.

        I'm

not seeing this on my Win7. Note that Python 2.7 has many
bugs that 2.6 doesn’t. My platform is:

Windows 6.1.7600 <-------- 64-bit Win7

                Python    2.6.5 (r265:79096, Mar 19 2010, 21:48:26)

[MSC v.1500 32 bit (Intel)]

      Wx        2.8.11.0

Hi,

Looks nice.

Not sure but these look like typos:

"""
  def OnLeave (self, event) :
    pass
    if self.HasCapture() :
"""

"""
  def OnMotion (self, event) :
    return
    if not self.IsEnabled() :
      return
"""

For when you are generating events it would probably be better to
derive your own event class and event type since this control is a
little different than a simple button. Also should either
PostEvent(self, event) or use self.ProcessEvent(event) so that it is
possible for user code to bind event handlers to the control directly.
Currently you are just posting the event to the parent so only the
parent window and and above in the hierarchy will be able to receive
the event.

Suggest calling CacheBestSize at the end of your DoGetBestSize method,
then also calling InvalidateBestSize in any method that could modify
the size of the control (i.e InsertSegment, AddSegment).

You don't need to manually call DoGetBestSize anywhere, it is used
internally by the framework to set the controls "BestSize" you can use
GetSize or GetClientSize elsewhere in your code to get the controls
current size.

Creating the ClientDC's is unnecessary you can just call
'self.GetTextExtent' to measure the size of a string using the
controls current font.

Cody

This was my attempt to mimic Apple's NSSegmentedControl, which is
basically just a set of buttons squished together. I've fixed some of
the more glaring problems that Robin pointed out on Windows (many months
ago), and it's starting to behave well on all platforms, but there are
still some outstanding issues that I need help with:

1. On Windows (7, with Python 2.7 and wxPython 2.9.1), the lower row of
buttons is compressed vertically for no apparent reason. If I enlarge
the frame, the button appears normal.

Because you are using the size of the panel to set the size of the frame and it is not taking into account the size of the toolbar. Try giving the frame a sizer, put the panel into it, and then doing just frame.Fit(). You'll also want to remove the size=(640,480) when creating the panel.

2. Also on Windows, the set of buttons on the toolbar and the rightmost
set of (vertical) buttons have blank strips on the bottom and right,
respectively, where the gradient brush obviously isn't penetrating. I
have no idea why this would happen.

It has something to do with the border setting. Removing that parameter fixes it here, and also some painting weirdness on the Mac cocoa build with 2.9.

3. Robin previously suggested clearing the device context to the parent
background on Windows to eliminate black regions on the margins/corners
where I'm not drawing. This does indeed work on Windows, but on Mac
(previously okay) it results in a white border. Is there a
platform-independent way to do this? None of the custom controls that
I've looked at in the past had this problem.

Since you are using an auto buffered DC then it will use a buffered DC on Windows and a plain wx.PaintDC on the others, so it's only on Windows then you only need to deal with initializing the buffer.

···

On 11/7/10 4:26 PM, Nat Echols wrote:

--
Robin Dunn
Software Craftsman