Hello!
I need special menu control (menu with selection, mayby with another
gadgets:) ) and i write my own class with wxDialog and wxListBox
inside. But this list is always to high…
I need method like FitInside but for items inside list. When list have
3 items and each have 13 pix then list must be about 3*13 pix high?
But list have mayby some space between items? I can use DC i measure each lists item but mayby is anothe, better way?
I write here some code with mouse event - when user click outside “menu” then i close dialog.
################################## E X A M P L E
import wx
my menu control implementation
···
###############################################################################
class MyMenu(wx.Dialog):
###############################################################################
def init(self, parent, choices=None):
wx.Dialog.init(self, parent, -1, style = wx.NO_3D)
self.list = wx.ListBox(self, -1, style=wx.NO_BORDER)
self.list.Bind(wx.EVT_LISTBOX_DCLICK, self.OnListDblClick)
self.list.Bind(wx.EVT_KEY_DOWN, self.OnListKeyDown)
self.list.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
self.list.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
self.list.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
self.list.Bind(wx.EVT_CLOSE, self.OnClose)
self.SetChoices(choices)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
self.mainSizer.Add(self.list, 1, wx.EXPAND|wx.ALL, 1)
self.SetSizer(self.mainSizer)
def Popup(self, pos):
self.SetPosition(pos)
self.list.CaptureMouse()
self.Fit()
return self.ShowModal()
def OnKillFocus(self, event):
event.Skip()
if self.list.HasCapture():
self.list.ReleaseMouse()
def OnSetFocus(self, event):
event.Skip()
if not self.list.HasCapture():
self.list.CaptureMouse()
def OnMouse(self, event):
event.Skip()
if event.LeftDown():
pos = event.GetPosition()
rct = self.list.GetRect()
if not rct.Inside(pos):
event.Skip(False)
self.Close()
def OnClose(self, event):
if self.list.HasCapture():
self.list.ReleaseMouse()
event.Skip()
def SetChoices(self, choices):
self.list.Clear()
for item1 in choices:
self.list.Append(item1)
def GetSelString(self):
sel_indx = self.list.GetSelection()
return self.list.GetString(sel_indx)
def GetString(self, index):
return self.list.GetString(index)
def SetSelection(self, index):
self.list.SetSelection(index)
def GetSelection(self):
return self.list.GetSelection()
def OnListDblClick(self, event):
event.Skip(False)
self.Close()
self.SetReturnCode(wx.ID_OK)
def OnListKeyDown(self, event):
event.Skip()
key_code = event.m_keyCode
if key_code in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):
self.Close()
self.SetReturnCode(wx.ID_OK)
elif key_code == wx.WXK_ESCAPE:
self.Close()
self.SetReturnCode(wx.ID_CANCEL)
###############################################################################
###############################################################################
test APP
ID_B1 = wx.NewId()
ID_B2 = wx.NewId()
ID_B3 = wx.NewId()
class TestDialog(wx.Dialog):
def init(self):
wx.Dialog.init(self, None, -1, “Test dialog”, style=wx.DEFAULT_DIALOG_STYLE)
mainSizer = wx.BoxSizer(wx.HORIZONTAL)
b1 = wx.Button(self, ID_B1, “Menu1”)
b2 = wx.Button(self, ID_B2, “Menu2”)
b3 = wx.Button(self, ID_B3, “Menu3”)
self.selTab = [0,0,0]
mainSizer.Add(b1, 0, wx.ALL, 20)
mainSizer.Add(b2, 0, wx.ALL, 20)
mainSizer.Add(b3, 0, wx.ALL, 20)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_BUTTON, self.OnBtn)
self.SetSizer(mainSizer)
self.Fit()
def OnBtn(self, event):
btn_id = event.GetEventObject().GetId()
btn_indx = btn_id - ID_B1
menu = None
if btn_id == ID_B1:
menu = MyMenu(self, [“Item #11”, “Item #12”, “Item #13”])
elif btn_id == ID_B2:
menu = MyMenu(self, [“Item #21”, “Item #22”, “Item #23”])
elif btn_id == ID_B3:
menu = MyMenu(self, [“Item #31”, “Item #32”, “Item #33”])
if menu:
menu.SetSelection(self.selTab[btn_indx])
but_pos = self.ClientToScreen(event.GetEventObject().GetPosition())
mr = menu.Popup(but_pos)
if(mr==wx.ID_OK):
sel_indx = menu.GetSelection()
event.GetEventObject().SetLabel(menu.GetString(sel_indx))
self.selTab[btn_indx] = sel_indx
menu.Destroy()
def OnClose(self, event):
self.Destroy()
if name == ‘main’:
class MyApp(wx.App):
def OnInit(self):
wx.InitAllImageHandlers()
dlg = TestDialog()
dlg.Centre();
dlg.Show(True);
self.SetTopWindow(dlg);
return True
app = MyApp(False)
app.MainLoop()