Hello all,
I am trying to place a window with a listctrl next to a
widget derived from a textctrl. On Linux/Windows I am using
a PopupWindow. On MacOSX I use a wxWindow instead (I am
aware others use wxFrame as a PopupWindow replacement).
Both are instantiated in the __init__ of the TextCtrl and
are passed the TextCtrl's parent as their parent:
try:
self.__picklist_dropdown = wx.PopupWindow(parent)
add_picklist_to_sizer = False
except NotImplementedError:
# on MacOSX wx.PopupWindow is not implemented
self.__picklist_dropdown = wx.Window(parent=parent, style = wx.SIMPLE_BORDER)
szr_scroll = wx.BoxSizer(wx.VERTICAL)
self.__picklist_dropdown.SetSizer(szr_scroll)
add_picklist_to_sizer = True
if add_picklist_to_sizer:
szr_scroll.Add(self._picklist, 1, wx.EXPAND)
Later on, when the window is to be shown the best size and
position are calculated (pw stands for phrasewheel which is
the textctrl):
# recalculate size
rows = len(self.__current_matches)
if rows < 2: # 2 rows minimum
rows = 2
if rows > 20: # 20 rows maximum
rows = 20
dropdown_size = self.__picklist_dropdown.GetSize()
pw_size = self.GetSize()
dropdown_size.SetWidth(pw_size.width)
dropdown_size.SetHeight((pw_size.height * rows) + 4) # adjust for border width
# recalculate position
(pw_x_abs, pw_y_abs) = self.ClientToScreenXY(0,0)
dropdown_new_x = pw_x_abs
dropdown_new_y = pw_y_abs + pw_size.height
self.mac_log('desired dropdown position (on screen): x:%s-%s, y:%s-%s' % (dropdown_new_x, (dropdown_new_x+dropdown_size.width), dropdown_new_y, (dropdown_new_y+dropdown_size.height)))
self.mac_log('desired dropdown size: %s' % dropdown_size)
# reaches beyond screen ?
if (dropdown_new_y + dropdown_size.height) > self._screenheight:
self.mac_log('dropdown extends offscreen (screen max y: %s)' % self._screenheight)
max_height = self._screenheight - dropdown_new_y - 4
self.mac_log('max dropdown height would be: %s' % max_height)
if max_height > ((pw_size.height * 2) + 4):
dropdown_size.SetHeight(max_height)
self.mac_log('possible dropdown position (on screen): x:%s-%s, y:%s-%s' % (dropdown_new_x, (dropdown_new_x+dropdown_size.width), dropdown_new_y, (dropdown_new_y+dropdown_size.height)))
self.mac_log('possible dropdown size: %s' % dropdown_size)
# now set dimensions
self.__picklist_dropdown.SetSize(dropdown_size)
self._picklist.SetSize(self.__picklist_dropdown.GetClientSize())
self.mac_log('dropdown size set to: %s' % self.__picklist_dropdown.GetClientSize())
self.__picklist_dropdown.MoveXY(dropdown_new_x, dropdown_new_y)
Now, on Linux/Windows this works nicely, the dropdown
windows is placed right below the textctrl. On MacOSX,
however, it is placed way off.
One thing I am uncertain about is the MoveXY() call. Note
that the dropdown_new_x and *_new_y are absolute screen
coordinates -- they initially come from the
ClientToScreenXY() call to the phrasewheel textctrl. They
may need to be mapped to the parent windows relative
coordinate system, perhaps. Strange, though, why it does
work on Linux/Windows.
(self.mac_log is simply a MacOSX-specific logging wrapper as
we first noticed this on Mac - however, the problem
manifests itself on Linux, too, when forced to use a
wxWindow instead of the PopupWindow)
The full source of the phrasewheel class is here:
The file can be run with "python gmPhraseWheel.py" to call
up a widget test (if you've got a local copy of the CVS tree).
Any help would be appreciated,
Karsten
···
--
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346