""" Dialog box: Display key-configuration. """ import wx import Keystroke import Config BUTTON_BASE_ID = 500 TEXT_BASE_ID = 600 class KeystrokeEater(wx.Window): """ Simple control for detecting keystrokes. """ def __init__(self, Index, KeyName, KeyCode, Parent): self.Index = Index self.ParentWindow = Parent self.KeyName = KeyName self.KeyCode = KeyCode self.HaveFocus = False wx.Window.__init__(self, Parent, -1, style = wx.WANTS_CHARS) self.SetBackgroundColour(wx.BLACK) self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) self.Bind(wx.EVT_PAINT, self.OnPaint) self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse) self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) try: self.Joystick = wx.Joystick() #self.Joystick.SetCapture(self) except: #traceback.print_exc() self.Joystick = None #self.Bind(wx.EVT_JOYSTICK_EVENTS, self.OnJoystick) self.OldJoystickButtonState = 0 def OnPaint(self, Event): DeviceContext = wx.PaintDC(self) Rectangle = self.GetClientRect() KeystrokeName = Keystroke.KeystrokeNames.get(self.KeyCode, "<%s>"%self.KeyCode) Label = "%s: %s"%(self.KeyName, KeystrokeName) if self.HaveFocus: DeviceContext.SetTextForeground(wx.RED) else: DeviceContext.SetTextForeground(wx.WHITE) DeviceContext.DrawLabel(Label, Rectangle, wx.ALIGN_CENTER | wx.ALIGN_TOP) def OnSetFocus(self, Event): self.HaveFocus = True self.ParentWindow.ActivePanel = self self.Refresh() def OnKillFocus(self, Event): self.HaveFocus = False self.Refresh() def OnMouse(self, Event): if Event.ButtonDown(): self.SetFocus() def OnKeyDown(self, Event): self.KeyCode = Event.GetKeyCode() self.ParentWindow.KeyConfig[self.Index] = self.KeyCode self.Refresh() if Event.GetKeyCode() == wx.WXK_ESCAPE: Log("PressedEscape!") else: Event.Skip() def CheckJoystick(self): OldKeyCode = self.KeyCode if not self.Joystick: return # Check for buttons which were not pressed, but now are: ButtonState = self.Joystick.GetButtonState() CodeChanged = 0 for ButtonIndex in range(8): Flag = 1 << ButtonIndex if (ButtonState & Flag) and not (self.OldJoystickButtonState & Flag): self.KeyCode = Keystroke.JoystickButtons.Button1 + ButtonIndex self.OldJoystickButtonState = ButtonState # Check for joystick directions: X = self.Joystick.GetPosition().x Y = self.Joystick.GetPosition().y if (X == 0): self.KeyCode = Keystroke.JoystickButtons.Left elif (Y == 0): self.KeyCode = Keystroke.JoystickButtons.Up elif (X == 65535): self.KeyCode = Keystroke.JoystickButtons.Right elif (Y == 65535): self.KeyCode = Keystroke.JoystickButtons.Down if self.KeyCode != OldKeyCode: self.ParentWindow.KeyConfig[self.Index] = self.KeyCode self.Refresh() class KeyConfigDialog(wx.Dialog): def __init__(self, KeyConfig, parent, ID, title, size = wx.DefaultSize, pos = wx.DefaultPosition, style = wx.DEFAULT_DIALOG_STYLE, useMetal = False): self.KeyConfig = KeyConfig[:] self.ActivePanel = None # Instead of calling wx.Dialog.__init__ we pre-create the dialog # so we can set an extra style that must be set before # creation, and then we create the GUI object using the Create # method. PreDialog = wx.PreDialog() PreDialog.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP) PreDialog.Create(parent, ID, title, pos, size, style) # This next step is the most important, it turns this Python # object into the real wrapper of the dialog (instead of pre) # as far as the wxPython extension is concerned. self.PostCreate(PreDialog) # This extra style can be set after the UI object has been created. if 'wxMac' in wx.PlatformInfo and useMetal: self.SetExtraStyle(wx.DIALOG_EX_METAL) # Now continue with the normal construction of the dialog # contents self.BuildWidgets() self.Timer = wx.CallLater(25, self.OnTimer) self.SetEscapeId(wx.ID_NONE) self.Bind(wx.EVT_BUTTON, self.OnClick, self.OKButton) self.Bind(wx.EVT_BUTTON, self.OnClick, self.CancelButton) def OnClick(self, Event): Button = Event.GetEventObject() if Button == self.OKButton: self.SetReturnCode(wx.ID_OK) self.Destroy() else: self.Destroy() def OnTimer(self, *args, **kw): if self.ActivePanel: self.ActivePanel.CheckJoystick() self.Timer.Restart() # make the timer get called again: def BuildWidgets(self): self.MasterSizer = wx.BoxSizer(wx.VERTICAL) Label = wx.StaticText(self, -1, "Key config: Click the button next to an input, then click the new key to use.") self.MasterSizer.Add(Label, 0, wx.ALIGN_CENTRE | wx.ALL, 5) self.KeyWidgets = [] for Index in range(Config.KeyConfig.KeyCount): self.AddKeyConfigWidgets(Index, Config.KeyConfig.Names[Index]) StaticLine = wx.StaticLine(self, -1, size = (20, -1), style = wx.LI_HORIZONTAL) self.MasterSizer.Add(StaticLine, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 5) ButtonSizer = wx.StdDialogButtonSizer() self.OKButton = wx.Button(self, wx.ID_OK) self.OKButton.SetDefault() ButtonSizer.AddButton(self.OKButton) self.CancelButton = wx.Button(self, wx.ID_CANCEL) ButtonSizer.AddButton(self.CancelButton) ButtonSizer.Realize() self.MasterSizer.Add(ButtonSizer, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5) self.SetSizer(self.MasterSizer) self.MasterSizer.Fit(self) self.Bind(wx.EVT_CHAR, self.HandleChar) self.Bind(wx.EVT_KEY_DOWN, self.HandleChar) def HandleChar(self, Event): KeyIndex = Event.GetId() - TEXT_BASE_ID KeyCode = Event.GetKeyCode() self.KeyConfig[KeyIndex] = KeyCode #self.Labels[KeyIndex].SetValue(self.GetKeyName(KeyCode)) Str = "%s: %s"%(Config.KeyConfig.Names[KeyIndex], self.GetKeyName(KeyCode)) self.Labels[KeyIndex].SetLabel(Str) Event.Skip() def GetKeyName(self, KeyConfig): return "%s"%KeyConfig def AddKeyConfigWidgets(self, Index, Name): """ Add label and button for one key-config item """ BoxSizer = wx.BoxSizer(wx.HORIZONTAL) KeyName = Config.KeyConfig.Names[Index] KeyCode = self.KeyConfig[Index] KeyWidget = KeystrokeEater(Index, KeyName, KeyCode, self) KeyWidget.SetMinSize((200, 20)) BoxSizer.Add(KeyWidget, 0, wx.ALIGN_CENTRE | wx.ALL, 5) self.MasterSizer.Add(BoxSizer, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 2) self.KeyWidgets.append(KeyWidget)