5858l1 Listing 1. Mediator Example Program # This is just example code on how to use the mediator to orchestrate dialog box/form/panel under Python from wxPython.wx import * import re, string # this is the base class mediator, implemented # as a template pattern. your form/dialog box/panel should inherit from this class Mediator: def __init__(self): pass def ColleagueChanged(self, colleague, event): """Template pattern interface method, intended to be called directly""" self._ColleagueChanged(colleague, event) def _ColleagueChanged(self, colleague, event): """Template pattern polymorphic method, intended to be inherited""" # this is the base class colleague, implemented # as a template patter. your controls on the form/dialog box/panel should # inherit from this class Colleague: def __init__(self, mediator): self.mediator = mediator def Changed(self, colleague, event): """Template pattern inteface method, intended to be called directly""" self._Changed(colleague, event) def _Changed(self, colleague, event): """Template pattern interface method, intended to be inherited""" self.mediator.ColleagueChanged(colleague, event) class myTextCtrl(wxTextCtrl, Colleague): """This is the overloaded wxTextCtrl which takes part in the Mediator/Colleague pattern""" def __init__(self, mediator, *_args, **_kwargs): # somewhat wacky initialization of parent control apply(wxTextCtrl.__init__, (self,) + _args, _kwargs) Colleague.__init__(self, mediator) EVT_CHAR(self, self.OnChar) def OnChar(self, event): if not chr(event.GetKeyCode()) in string.digits: self.Changed(self, event) event.Skip() class myButton(wxButton, Colleague): """This is the overloaded wxButton control""" def __init__(self, mediator, *_args, **_kwargs): # somewhat wacky initialization of parent control apply(wxButton.__init__, (self,) + _args, _kwargs) Colleague.__init__(self, mediator) EVT_BUTTON(self, self.GetId(), self.OnClick) def OnClick(self, event): self.Changed(self, event) class myListBox(wxListBox, Colleague): """This is the overloaded wxListBox control""" def __init__(self, mediator, *_args, **_kwargs): # somewhat wacky initialization of parent control apply(wxListBox.__init__, (self,) + _args, _kwargs) Colleague.__init__(self, mediator) EVT_LISTBOX(self, self.GetId(), self.OnSelected) def OnSelected(self, event): self.Changed(self, event) class myRadioBox(wxRadioBox, Colleague): """This is the overloaded wxRadioBox control""" def __init__(self, mediator, *_args, **_kwargs): # somewhat wacky initialization of parent control apply(wxRadioBox.__init__, (self,) + _args, _kwargs) Colleague.__init__(self, mediator) EVT_RADIOBOX(self, self.GetId(), self.OnSelected) def OnSelected(self, event): self.Changed(self, event) # main frame of our application class MainFrame(wxFrame, Mediator): """The MainFrame of our application, essentially building the GUI and that's it""" # initialize the main window def __init__(self, parent, ID, title): wxFrame.__init__(self, parent, ID, title, wxDefaultPosition, wxSize(400, 300)) Mediator.__init__(self) # create the menu system self.SetMenuBar(self.initMenu()) # create the status bar self.CreateStatusBar() self.SetStatusText("Let's play with the Mediator!") # create the control panel self.createPanel() # prevent recursion on updates flag self.__inProcess = false # initialize the menubar for the main frame window def initMenu(self): """Initialize the main frame menu system""" # initialize the ID's [wxID_ABOUT, wxID_EXIT] = map(lambda init: wxNewId(), range(2)) # creat the menu bar self._menuBar = wxMenuBar() # initialize file menu _menu = wxMenu() _menu.Append(wxID_ABOUT, '&About', 'About this program') _menu.AppendSeparator() _menu.Append(wxID_EXIT, 'E&xit', 'Exit the program') self._menuBar.Append(_menu, 'Program') EVT_MENU(self, wxID_ABOUT, self.OnAbout) EVT_MENU(self, wxID_EXIT, self.OnExit) return self._menuBar def createPanel(self): """Create the windows panel containing the controls""" #self.__panel = wxPanel(self, -1) # create the child controls self.__selectText = myTextCtrl(self, self, -1, value = "", style = wxALIGN_RIGHT) radioList = ["&East", "&Midwest", "&West"] self.__radioBox = myRadioBox(self, self, -1, label = "Select Region", choices = radioList , majorDimension = 3, style = wxRA_SPECIFY_COLS, name = "Select Region") self.__buttonSelect = myButton(self, self, -1, "&Select") self.__buttonSelect.Enable(false) self.__buttonClear = myButton(self, self, -1, "&Clear") self.__buttonClear.Enable(false) # initialize the lists boxes with val self.__cityListBox = myListBox(self, self, -1, name = "Cities") self.__stateListBox = myListBox(self, self, -1, name = "States") self._InitializeLists(0) self.__buttonOkay = myButton(self, self, -1, "&Okay") self.__buttonOkay.Enable(false) self.__buttonCancel = myButton(self, self, -1, "Ca&ncel") # build mapping of controls into function all dictionary self.__colleagueMap = { self.__selectText : self._SelectTextChanged, self.__radioBox : self._RadioBoxChanged, self.__buttonSelect : self._ButtonSelectChanged, self.__buttonClear : self._ButtonClearChanged, self.__cityListBox : self._CityListBox, self.__stateListBox : self._StateListBox, self.__buttonOkay : self._ButtonOkay, self.__buttonCancel : self._ButtonCancel } # build selection sizer self.__selectionSizer = wxBoxSizer(wxHORIZONTAL) self.__selectionSizer.Add(wxStaticText(self, -1, "&Type City", style = wxALIGN_RIGHT), option = 0, flag = wxALL, border = 3) self.__selectionSizer.Add(self.__selectText, option = 0, flag = wxALL, border = 3) # build button sizer self.__buttonSizer = wxBoxSizer(wxHORIZONTAL) self.__buttonSizer.Add(self.__buttonSelect, option = 0, flag = wxALL, border = 3) self.__buttonSizer.Add(self.__buttonClear, option = 0, flag = wxALL, border = 3) # combine sizers self.__leftSizer = wxBoxSizer(wxVERTICAL) self.__leftSizer.Add(self.__selectionSizer, option = 0, flag = wxALL, border = 0) self.__leftSizer.Add(self.__radioBox, option = 0, flag = wxALL, border = 3) self.__leftSizer.Add(self.__buttonSizer, option = 0, flag = wxALL, border = 0) # list box sizer self.__rightSizer = wxBoxSizer(wxHORIZONTAL) self.__rightSizer.Add(self.__cityListBox, option = 1, flag = wxALL | wxEXPAND, border = 3) self.__rightSizer.Add(self.__stateListBox, option = 1, flag = wxALL | wxEXPAND, border = 3) # add sizers to top half sizer self.__tophalfSizer = wxBoxSizer(wxHORIZONTAL) self.__tophalfSizer.Add(self.__leftSizer, option = 0, flag = wxALL, border = 0) self.__tophalfSizer.Add(self.__rightSizer, option = 1, flag = wxEXPAND | wxALL, border = 0) # dialog button sizer self.__dialogButtonSizer = wxBoxSizer(wxHORIZONTAL) self.__dialogButtonSizer.Add(self.__buttonOkay, option = 0, flag = (wxALL | wxALIGN_RIGHT), border = 3) self.__dialogButtonSizer.Add(self.__buttonCancel, option = 0, flag = (wxALL | wxALIGN_RIGHT), border = 3) # add all the sizers to main self.__mainSizer = wxBoxSizer(wxVERTICAL) self.__mainSizer.Add(self.__tophalfSizer, option = 1, flag = wxEXPAND | wxALL, border = 0) #self.__mainSizer.Add(self.__selectionSizer, option = 0, flag = wxALL | wxEXPAND, border = 0) self.__mainSizer.Add(self.__dialogButtonSizer, option = 0, flag = (wxALL | wxALIGN_RIGHT), border = 0) # get the sizers going self.SetSizer(self.__mainSizer) self.SetAutoLayout(1) self.__mainSizer.Fit(self) self.__mainSizer.SetSizeHints(self) self.Show(1) def OnExit(self, event): self.Destroy() def OnAbout(self, event): """This is documentation for the OnAbout event""" dlg = wxMessageDialog(self, "This is just a little dialog box\nthat demonstrates the Mediator/Colleague pattern", "About Box", wxCANCEL | wxICON_INFORMATION) dlg.ShowModal() dlg.Destroy() def _ColleagueChanged(self, colleague, event): """This method gets called when when of the colleagues has changed. This is the central 'clearing' house for all changes and orchestrates these changes among the cooperating controls""" # don't get recursive on us if self.__inProcess != true: self.__inProcess = true # call the cooresponding method directly using a map lookup if self.__colleagueMap.has_key(colleague): self.__colleagueMap[colleague](event) self.__inProcess = false def _SelectTextChanged(self, event): self.__buttonSelect.Enable(true) self.__buttonClear.Enable(true) self.__buttonOkay.Enable(true) listBox = self.__cityListBox # search the list box for a matching string for index in range(listBox.GetCount()): string = listBox.GetString(index) if re.search("^" + chr(event.GetKeyCode()) + self.__selectText.GetValue(), string, re.IGNORECASE) != None: listBox.SetSelection(index) self.__stateListBox.SetSelection(index) break def _RadioBoxChanged(self, event): self._InitializeLists(event.GetInt()) self.__buttonSelect.Enable(false) self.__buttonClear.Enable(false) self.__selectText.Clear() self.__selectText.SetFocus() def _ButtonSelectChanged(self, event): self._ShowMessageBox() self.__selectText.SetFocus() def _ButtonClearChanged(self, event): self.__buttonClear.Enable(false) self.__selectText.Clear() self.__selectText.SetFocus() pass def _CityListBox(self, event): self.__stateListBox.SetSelection(self.__cityListBox.GetSelection()) self.__selectText.Clear() self.__buttonSelect.Enable(true) self.__buttonClear.Enable(false) self.__buttonOkay.Enable(true) def _StateListBox(self, event): self.__cityListBox.SetSelection(self.__stateListBox.GetSelection()) self.__selectText.Clear() self.__buttonSelect.Enable(true) self.__buttonClear.Enable(false) self.__buttonOkay.Enable(true) def _ButtonOkay(self, event): self._ShowMessageBox() self.Destroy() def _ButtonCancel(self, event): self.Destroy() def _InitializeLists(self, index): # clear out lists self.__cityListBox.Clear() self.__stateListBox.Clear() # rebuild lists based on index passed in if index == 0: self.__cityListBox.Set(["New York", "Hartford", "Miami"]) self.__stateListBox.Set(["New York", "Connecticut", "Florida"]) elif index == 1: self.__cityListBox.Set(["Springfield", "South Bend", "Chicago"]) self.__stateListBox.Set(["Ohio", "Indiana", "Illinois"]) elif index == 2: self.__cityListBox.Set(["San Francisco", "Seattle", "Portland"]) self.__stateListBox.Set(["California", "Washington", "Oregon"]) def _ShowMessageBox(self): dlg = wxMessageDialog(self, self.__cityListBox.GetStringSelection() + ", " + self.__stateListBox.GetStringSelection(), "Combined Text", wxCANCEL | wxICON_INFORMATION) dlg.ShowModal() dlg.Destroy() class MediatorApp(wxApp): """MediatorApp main application instance""" def OnInit(self): frame = MainFrame(NULL, -1, "Mediator/Colleague demo") frame.Show(true) self.SetTopWindow(frame) return true app = MediatorApp(0) app.MainLoop()