def __init__(self): wx.App.__init__(self, False) # resource manager self.resourceManager = ResourceManager # settings self.defaultSettings = { 'rows': 3, 'buttonsPerRow': 9, 'buttonSize': 48, 'offset': (24, 16), 'opacity': 255, 'scope': "Darkfall Online" } savedSettings = self.resourceManager.loadDict(self.DATAPATH+self.SETTINGS_FILENAME) self.settings = copy.deepcopy(savedSettings if savedSettings is not None else self.defaultSettings) del savedSettings # global keyboard manager self.keyManager = KeyManager() self.keyManager.monitor.KeyDown = self.keyPressed self.keyManager.monitor.KeyUp = self.keyReleased self.keybinds = {} self.keybindStates = {} # initial calculations self.mainFrameWidth = self.settings['buttonsPerRow']*self.settings['buttonSize'] self.mainFrameHeight = self.settings['rows']*self.settings['buttonSize'] # ui self.lastButtonID = self.settings['rows']*self.settings['buttonsPerRow'] - 1; self.mainFrame = wx.Frame(None, wx.ID_ANY, size=(self.mainFrameWidth, self.mainFrameHeight), style=wx.STAY_ON_TOP | wx.NO_BORDER) self.menu = Menu(self.mainFrame) self.buttons = {} # images self.bitmaps = { 'available': self.DATAPATH+'icons/iconWhite.png', 'running': self.DATAPATH+'icons/iconGreen.png', 'down': self.DATAPATH+'icons/iconRed.png', 'menu': self.DATAPATH+'icons/iconMenu.png', } # scripts self.scripts = {} self.activeScript = None self.keybinds = {}
class Controller(wx.App): DATAPATH = 'data/' SETTINGS_FILENAME = 'settings.xdf' SCRIPTDATA_FILENAME = 'scripts.xdf' # constructor def __init__(self): wx.App.__init__(self, False) # resource manager self.resourceManager = ResourceManager # settings self.defaultSettings = { 'rows': 3, 'buttonsPerRow': 9, 'buttonSize': 48, 'offset': (24, 16), 'opacity': 255, 'scope': "Darkfall Online" } savedSettings = self.resourceManager.loadDict(self.DATAPATH+self.SETTINGS_FILENAME) self.settings = copy.deepcopy(savedSettings if savedSettings is not None else self.defaultSettings) del savedSettings # global keyboard manager self.keyManager = KeyManager() self.keyManager.monitor.KeyDown = self.keyPressed self.keyManager.monitor.KeyUp = self.keyReleased self.keybinds = {} self.keybindStates = {} # initial calculations self.mainFrameWidth = self.settings['buttonsPerRow']*self.settings['buttonSize'] self.mainFrameHeight = self.settings['rows']*self.settings['buttonSize'] # ui self.lastButtonID = self.settings['rows']*self.settings['buttonsPerRow'] - 1; self.mainFrame = wx.Frame(None, wx.ID_ANY, size=(self.mainFrameWidth, self.mainFrameHeight), style=wx.STAY_ON_TOP | wx.NO_BORDER) self.menu = Menu(self.mainFrame) self.buttons = {} # images self.bitmaps = { 'available': self.DATAPATH+'icons/iconWhite.png', 'running': self.DATAPATH+'icons/iconGreen.png', 'down': self.DATAPATH+'icons/iconRed.png', 'menu': self.DATAPATH+'icons/iconMenu.png', } # scripts self.scripts = {} self.activeScript = None self.keybinds = {} def getIcon(self, key): return self.resourceManager.loadBitmap(self.bitmaps[key]) # boot def boot(self): # ui config self.resourceManager.loadFonts(self.DATAPATH+'fonts') self.mainFrame.SetBackgroundColour('Black') self.menu.spnOpacity.SetRange(15, 255) self.menu.update(self.settings) # buttons and scripts savedScripts = self.resourceManager.loadDict(self.DATAPATH+self.SCRIPTDATA_FILENAME) if savedScripts is None: savedScripts = {} self.btnMenu = Button(self.mainFrame, self.lastButtonID) self.btnMenu.SetPosition(((self.settings['buttonsPerRow']-1)*self.settings['buttonSize'], (self.settings['rows']-1)*self.settings['buttonSize'])) self.btnMenu.setIcon(self.getIcon('menu')) for y in range(self.settings['rows']): for x in range(self.settings['buttonsPerRow']): id = (y*self.settings['buttonsPerRow']+x) if id<self.lastButtonID: self.buttons[id] = Button(self.mainFrame, id) self.buttons[id].SetPosition((x*self.settings['buttonSize'], y*self.settings['buttonSize'])) self.buttons[id].setIcon(self.getIcon('available')) self.buttons[id].onClick = self.btnClicked self.scripts[id] = Script(id) if id in savedScripts.keys(): self.scripts[id].loadFields(savedScripts[id]) self.scriptEdited(id) # bindings self.btnMenu.onClick = self.btnClicked self.menu.btnQuit.Bind(wx.EVT_BUTTON, lambda(e): self.quit()) self.menu.btnReset.Bind(wx.EVT_BUTTON, lambda(e): self.resetSettings()) self.menu.btnApply.Bind(wx.EVT_BUTTON, lambda(e): self.applyMenu()) # start listening to global keyboard events self.keyManager.startListening() # update then show ui self.update() self.mainFrame.Show(True) self.MainLoop() # exit gracefully def quit(self): # stop listening to global keyboard events self.keyManager.stopListening() # save data and settings self.resourceManager.saveDict(self.settings, self.DATAPATH+self.SETTINGS_FILENAME) savedScripts = {} for id in self.scripts.keys(): savedScripts[id] = self.scripts[id].getFields() self.resourceManager.saveDict(savedScripts, self.DATAPATH+self.SCRIPTDATA_FILENAME) # kill the active script gracefully if self.activeScript is not None: self.activeScript.interrupt() self.mainFrame.Close() # reset settings def resetSettings(self): self.settings = copy.deepcopy(self.defaultSettings) self.update() # apply changes in the menu def applyMenu(self): if len(self.menu.txtScope.GetValue())>0: self.settings['scope'] = self.menu.txtScope.GetValue() self.settings['opacity'] = int(self.menu.spnOpacity.GetValue()) self.settings['offset'] = (int(self.menu.txtOffsetX.GetValue()), int(self.menu.txtOffsetY.GetValue())) self.update() # update the UI according to settings def update(self): self.mainFrame.Freeze() self.mainFrame.Disable() self.mainFrame.SetTransparent(self.settings['opacity']) dw, dh = wx.DisplaySize() w, h = self.mainFrame.GetSize() x = dw - w - self.settings['offset'][0] y = dh - h - self.settings['offset'][1] self.mainFrame.SetPosition((x, y)) self.menu.update(self.settings) self.mainFrame.Enable() self.mainFrame.Thaw() def triggerScript(self, id): wasRunning = False if self.activeScript is not None and self.activeScript.isAlive(): wasRunning = True self.activeScript.interrupt() if self.activeScript is None or id != self.activeScript.script.id or (self.activeScript.script.id == id and not wasRunning): self.activeScript = ScriptThread(self.scripts[id]) self.activeScript.onStatusChanged = self.activeScriptStatusChanged self.activeScript.onKeyEventFired = self.activeScriptKeyFired self.activeScript.start() # # event listeners # # global key down def keyPressed(self, event): if event.WindowName==self.settings['scope'] and not event.IsInjected(): # IsInjected = generated by XDF key = self.keyManager.resolveKeybindFromEvent(event) if key in self.keybinds.keys(): if key not in self.keybindStates or not self.keybindStates[key]: self.keybindStates[key] = True thread.start_new_thread(self.triggerScript, (self.keybinds[key],)) return False return True # global key up def keyReleased(self, event): if event.WindowName==self.settings['scope'] and not event.IsInjected(): # IsInjected = generated by XDF key = self.keyManager.resolveKeybindFromEvent(event) if key in self.keybinds.keys(): self.keybindStates[key] = False if self.activeScript is not None: self.activeScript.keyReleasedFlag = True return True # current script status has changed def activeScriptStatusChanged(self, id, state): if state==ScriptThread.STATE_RUNNING: self.buttons[id].setIcon(self.getIcon('running')) else: self.buttons[id].setIcon(self.getIcon('available')) # handle simulated key events def activeScriptKeyFired(self, key): self.keyManager.send(key, self.settings['scope']) # the user changed a script trough the editor def scriptEdited(self, id): self.buttons[id].setName(self.scripts[id].name if len(self.scripts[id].name) > 0 else str(id+1)) # deletes old key bind index = None for key in self.keybinds.keys(): if self.keybinds[key]==id: index = key if index is not None: del self.keybinds[index] # new keybind keybind = self.scripts[id].key if keybind is not None: modifier = self.scripts[id].modifier if modifier is not None: keybind = modifier+"+"+keybind bound = keybind in self.keybinds.keys() if bound and self.keybinds[keybind]!=id: # another script is bound to this key old_id = self.keybinds[keybind] self.scripts[old_id].key = None self.scripts[old_id].modifier = None self.scriptUpdated(old_id) self.keybinds[keybind] = id txt_keybind = keybind.upper().replace("CONTROL", "CTRL").replace('NUMPADMULT', '*').replace('NUMPADADD','+').replace('NUMPADSUB','-').replace('NUMPADDIV','/') self.buttons[id].setKeybind(txt_keybind.upper()) self.scripts[id].parseTasks() # btn clicked on the mainFrame def btnClicked(self, id, btn): if id==self.lastButtonID: self.menu.Show(True) else: if btn=='right': ScriptEditor(self.mainFrame, self.scripts[id], self.scriptEdited) else: self.triggerScript(id)