def new(self): self.all_sprites = pg.sprite.Group() self.walls = pg.sprite.Group() self.enemies = pg.sprite.Group() self.inters = pg.sprite.Group() self.spells = pg.sprite.Group() self.playerg = pg.sprite.Group() self.screens = pg.sprite.Group() self.player = Player(self, 8, 8) self.log = LogWindow(self, 3, 15) self.inventory = Inventory(self, 0, 0) # first floor (TODO start screen) self.current_floor = Floor(self, 1) self.current_floor.populate_floor() # put the player in a random place gx, gy = self.current_floor.get_valid_pos() self.player.update_global_position(gx, gy) # start the engines self.tick = True # TODO remove self.save_map()
def createDockWindows(self): """ Create the dock windows: dropbar, log, properties, interfaces, routes. """ self.log = LogWindow(self.tr("Log"), self) self.log.append("Welcome to %s %s!\n" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION)) self.log.append( "To open an existing topology, please click the 'Open' icon from the tray above canvas!" ) self.log.setGeometry(QtCore.QRect(0, 0, 800, 114)) mainWidgets["log"] = self.log self.dropbar = DropBar(self.tr("Components"), self) self.dropbar.setGeometry(QtCore.QRect(0, 0, 129, 390)) mainWidgets["drop"] = self.dropbar self.properties = PropertiesWindow(self) self.properties.setWindowTitle("Properties") mainWidgets["properties"] = self.properties self.interfaces = InterfacesWindow(self) self.interfaces.setWindowTitle("Interfaces") mainWidgets["interfaces"] = self.interfaces self.routes = RoutesWindow(self.interfaces, self) self.routes.setWindowTitle("Routes") mainWidgets["routes"] = self.routes self.tm = TaskManagerWindow(self) self.tm.setWindowTitle("Task Manager") mainWidgets["tm"] = self.tm self.debugWindow = QtGui.QDockWidget(self.tr("Debug Window")) self.debugWindow.setWidget(DebugWindow(self)) self.docks = { "Components": self.dropbar, "Log": self.log, "Properties": self.properties, "Interfaces": self.interfaces, "Routes": self.routes, "Task Manager": self.tm } self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dropbar) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.properties) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.interfaces) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.routes) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tm) self.tm.setFloating(True) self.routes.setFloating(True) self.debugWindow.setFloating(True)
def create_database(): try: cursor.execute("CREATE DATABASE {} DEFAULT CHARACTER SET 'utf8'".format(db_name)) cursor.execute("USE {}".format(db_name)) cursor.execute("""CREATE TABLE IF NOT EXISTS `users` (id INT(2) AUTO_INCREMENT, name VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(20) NOT NULL, role TINYINT NOT NULL, PRIMARY KEY(id))""") cursor.execute("""INSERT INTO users (name, password,role) values('Ivan', '1234',1), ('Anna', 'qwert', 2), ('Jane', '123qwe',2)""") con.commit() LogWindow.logwin() except mysql.connector.Error as err: if err.errno == errorcode.ER_DB_CREATE_EXISTS: LogWindow.logwin() else: print("Failed creating database: {}".format(err))
def createDockWindows(self): """ Create the dock windows: dropbar, log, properties, interfaces, routes. """ self.log = LogWindow(self.tr("Log"), self) self.log.append("Welcome to %s %s!\n" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION)) self.log.setGeometry(QtCore.QRect(0, 0, 800, 114)) mainWidgets["log"] = self.log self.dropbar = DropBar(self.tr("Components"), self) self.dropbar.setGeometry(QtCore.QRect(0, 0, 129, 390)) mainWidgets["drop"] = self.dropbar self.properties = PropertiesWindow(self) self.properties.setWindowTitle("Properties") mainWidgets["properties"] = self.properties self.interfaces = InterfacesWindow(self) self.interfaces.setWindowTitle("Interfaces") mainWidgets["interfaces"] = self.interfaces self.routes = RoutesWindow(self.interfaces, self) self.routes.setWindowTitle("Routes") mainWidgets["routes"] = self.routes self.tm = TaskManagerWindow(self) self.tm.setWindowTitle("Task Manager") mainWidgets["tm"] = self.tm self.debugWindow = QtGui.QDockWidget(self.tr("Debug Window")) self.debugWindow.setWidget(DebugWindow(self)) self.docks = { "Components": self.dropbar, "Log": self.log, "Properties": self.properties, "Interfaces": self.interfaces, "Routes": self.routes, "Task Manager": self.tm, } self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dropbar) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.properties) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.interfaces) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.routes) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tm) self.tm.setFloating(True) self.routes.setFloating(True) self.debugWindow.setFloating(True)
def initWechat(self): self.LogWin = LogWindow.LogWindow() self.MainWin = MainWindow.mainWindow() self.MainWin.sendMessage.connect(self.sendMsg) # 发送输入消息 self.MainWin.selectFriend.connect( self.changeChattingFriend) # 鼠标点击左侧朋友 self.MainWin.imgHeadRequest.connect(self.userHeadRespond) # 相应头像请求 self.MainWin.friendAutoReply.connect(self.setFriendAutoReply) self.LogWin.mainButton.clicked.connect(self.slotButtonGetQR) self.LogWin.show() self.LogWin.setWindowIcon(QIcon('0qrc/icon.png')) self.MainWin.hide() self.rTime = None
class MainWindow(Systray): def __init__(self, app): """ Create a main window for the given application. """ defaultOptions["palette"] = app.palette() Systray.__init__(self) self.expansions = 0 self.client = None self.server = None self.running = False self.recovery = False mainWidgets["main"] = self mainWidgets["app"] = app self.canvas = Canvas(self) mainWidgets["canvas"] = self.canvas self.tabWidget = TabWidget(self) mainWidgets["tab"] = self.tabWidget self.setCentralWidget(self.tabWidget) #self.setCentralWidget(self.canvas) self.createActions() self.createMenus() self.createToolBars() self.createStatusBar() self.createDockWindows() self.createConfigWindows() self.createPopupWindows() self.createProgressBar() self.newScene() self.debugWindow.hide() self.tm.hide() self.routes.hide() self.setVisible(True) self.center() self.saveLayout(environ["config"] + "defaultLayout") self.defaultLayout = True if options["restore"]: self.loadLayout() self.defaultLayout = False self.loadProject() def center(self): """ Center the window. """ screen = QtGui.QDesktopWidget().screenGeometry() rect = self.geometry() self.move((screen.width()-rect.width())/2, (screen.height()-rect.height())/2) self.show() def getProject(self): """ Return the project. """ return self.project def startTutorial(self): """ Start the interactive tutorial. """ if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You are already doing the tutorial! If you would like to stop or restart, select 'Close' from the File menu now.") return if not self.closeTopology(): return self.project = "Tutorial" self.filename = "" self.canvas = Tutorial(self) mainWidgets["canvas"] = self.canvas self.tabWidget.removeTab(0) self.tabWidget.addTab(self.canvas, "Tutorial") self.canvas.start() for nodeType in nodeTypes.keys(): itemTypes = nodeTypes[nodeType] itemTypes[nodeType] = 0 self.properties.clear() self.interfaces.clear() self.routes.clear() self.resetLayout(True) self.lockDocks() def lockDocks(self): """ Lock the dock windows so they cannot be moved, closed or resized. """ self.tm.hide() for dock in self.docks.values(): dock.setFeatures(dock.NoDockWidgetFeatures) def unlockDocks(self): """ Unlock the dock windows. """ self.tm.show() for dock in self.docks.values(): dock.setFeatures(dock.DockWidgetClosable | dock.DockWidgetMovable | dock.DockWidgetFloatable) def faq(self): """ Open the FAQ in the default browser. """ olddir = os.getcwd() os.chdir(environ["doc"]) loadpath = os.getcwd() os.chdir(olddir) if environ["os"] == "Windows": url = QtCore.QUrl("file:///" + loadpath + "/FAQ.html") else: url = QtCore.QUrl("file://" + loadpath + "/FAQ.html") QtGui.QDesktopServices.openUrl(url) def closeTopology(self): """ Close the current topology. """ if self.running: self.log.append("You cannot close a topology when one is still running!") return False scene = self.canvas.scene() if scene and scene.items(): reply = QtGui.QMessageBox.warning(self, self.tr(Core.globals.PROG_NAME), self.tr("Save before closing?"), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Yes: if not self.saveTopology(): return False elif reply == QtGui.QMessageBox.No: pass else: return False if isinstance(mainWidgets["canvas"], Tutorial): self.canvas = Canvas(self) mainWidgets["canvas"] = self.canvas self.tabWidget.removeTab(0) self.tabWidget.addTab(self.canvas, "Default Project") self.project = "" self.unlockDocks() self.filename = "" scene = Scene(self.canvas) scene.setItemIndexMethod(QtGui.QGraphicsScene.NoIndex) self.canvas.setScene(scene) self.expansions = 0 for nodeType in nodeTypes.keys(): itemTypes = nodeTypes[nodeType] itemTypes[nodeType] = 0 self.properties.clear() self.interfaces.clear() self.routes.clear() return True def sendFile(self): """ Start a process to select and send a file to the server. """ if not self.server or self.server.poll() != None: self.log.append("Please start the server first!") return if not self.client or not self.client.isConnected(): self.startClient() filename = self.loadFile("All Files (*.*)") if not filename: return self.sendWindow.setFilename(filename) self.sendWindow.show() def newScene(self): """ Close the current topology and create a new one. """ if self.running: self.log.append("You cannot create a new topology when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot create a new topology during the tutorial!") return if not self.closeTopology(): return self.expandScene() def expandScene(self): """ Expand the scene based on number of expansions. """ x = 175 + self.expansions * 30 y = 160 + self.expansions * 20 scene = self.canvas.scene() item = QtGui.QGraphicsLineItem(-x, -y, x, y) scene.addItem(item) scene.removeItem(item) self.expansions += 1 def newProject(self): """ Create a new project for device sharing. """ if self.running: self.log.append("You cannot create a new project when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot create a new project during the tutorial!") return filename = self.saveFile("gproj") if filename.isEmpty(): return projectname = str(filename).split("/")[-1].strip(".gproj") from Core.Item import nodeTypes for nodeType in nodeTypes: if projectname.startswith(nodeType + "_"): self.popup.setWindowTitle("Invalid Project Name") self.popup.setText("You cannot name a project starting with the name of a device and underscore!") self.popup.show() return self.project = str(filename) file = QtCore.QFile(filename) if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning(self, self.tr("Save Error"), self.tr("Cannot write file %1:\n%2.") .arg(self.filename) .arg(file.errorString())) return out = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) if options["username"]: out << "username="******"username"] + "\n" else: self.log.append("Warning, no username is specified!") if options["session"]: out << "session=" + options["session"] + "\n" elif options["server"]: out << "server=" + options["server"] + "\n" else: self.log.append("Warning, no server or session name is specified!") QtGui.QApplication.restoreOverrideCursor() self.tabWidget.addTab(self.canvas, projectname) def openProject(self): """ Load an existing project for device sharing. """ if self.running: self.log.append("You cannot open a project when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot open a project during the tutorial!") return filename = self.loadFile("GPROJ (*.gproj)") if filename.isEmpty(): return self.project = str(filename) self.loadProject() def loadProject(self): """ Load project file data into options. """ if not self.project: self.tabWidget.addTab(self.canvas, "Default Project") return file = QtCore.QFile(self.project) if not file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning(self, self.tr("Load Error"), self.tr("Cannot read file %1:\n%2.") .arg(self.project) .arg(file.errorString())) self.tabWidget.addTab(self.canvas, "Default Project") return _in = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) while not _in.atEnd(): line = str(_in.readLine()) option, value = line.split("=", 1) options[option] = value self.configWindow.updateSettings() QtGui.QApplication.restoreOverrideCursor() projectname = self.project.split("/")[-1].strip(".gproj") self.tabWidget.addTab(self.canvas, projectname) def closeProject(self): """ Close the current project. """ if self.running: self.log.append("You cannot close a project when it is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot close a project during the tutorial!") return if self.tabWidget.count() == 1: self.tabWidget.addTab(self.canvas, "Default Project") self.project = "" else: self.tabWidget.removeTab(0) def export(self): """ Open an export window to generate an image from the canvas. """ self.exportWindow.show() def startBackend(self): """ Start the backend server. """ self.startServer() #self.startClient() def setRecovery(self, recovery): """ Set the recovering state of the topology. """ self.recovery = recovery def isRunning(self): """ Returns whether a topology is running or not. """ return self.running def startServer(self): """ Start the server backend of gbuilder, which controls running topologies. """ if self.server and self.server.poll() == None: self.log.append("A server is already running!") return base = "ssh -t " if options["username"] : base += options['username'] + "@" base += options["server"] tunnel = " -L " + options["localPort"] + ":localhost:" + options["remotePort"] server = "bash -c -i 'gserver " + options["remotePort"] + "' || sleep 5" command = "" if environ["os"] == "Windows": startpath = environ["tmp"] + "gserver.start" try: startFile = open(startpath, "w") startFile.write("echo -ne \"\\033]0;gserver\\007\"\n") startFile.write(server) startFile.close() except: self.log.append("Failed to write to start file!") return command += "putty -" if options["session"]: command += "load " + options["session"] + " -l " + options["username"] + " -t" else: command += base command += tunnel + " -m \"" + startpath + "\"" else: command += "xterm -T gserver -e " + base + tunnel + " \" " + server + "\"" self.server = subprocess.Popen(str(command), shell=True) def startClient(self): """ Start the client of gbuilder, which communicates with the server. """ self.client = Client(self) self.client.connectTo("localhost", int(options["localPort"]), 10) #self.client.start() mainWidgets["client"] = self.client def compile(self): """ Compile the current topology. """ if self.running: self.log.append("You cannot compile a topology when one is still running!") return False if self.saveTopology() == False: return False scene = self.canvas.scene() compiler = Compiler(scene.items(), self.filename) xmlFile = compiler.compile() self.properties.display() self.interfaces.display() self.routes.display() if xmlFile: self.statusBar().showMessage(self.tr("Compiled '%1'").arg(xmlFile), 2000) return True else: self.statusBar().showMessage(self.tr("Compile failed"), 2000) return False def run(self): """ Run the current topology. """ if not self.server or self.server.poll() != None: self.log.append("Please start the server first!") return if not self.client or not self.client.isConnected(): self.startClient() if self.isRunning() and not self.recovery: self.log.append("A topology is already running, please stop it first!") return scene = self.canvas.scene() items = scene.items() if items: if self.recovery: self.recovery = False elif options["autocompile"] and not self.compile(): return else: self.log.append("Please create or load a topology first!") return options["elasticMode"] = False xmlFile = self.filename.replace(".gsav", ".xml") if not os.access(xmlFile, os.F_OK): self.log.append("Please compile the topology first!") return self.tm.show() #self.progressBar.setValue(0) self.client.process("file . " + xmlFile) self.client.send("init " + self.project.split("/")[-1].strip(".gproj")) self.client.send("canvas %d,%d" % (scene.width(), scene.height())) for item in items: if item.type == "Mobile" or item.type == "Wireless_access_point": x = item.pos().x() y = item.pos().y() self.client.send("mobile %s %d,%d" % (item.getName(), x, y)) self.client.process("start " + xmlFile) self.running = True self.canvas.setAcceptDrops(False) scene = self.canvas.scene() scene.startRefresh() scene.clearSelection() self.properties.clear() self.interfaces.clear() self.routes.clear() def stop(self): """ Stop the current running topology. """ if not self.server or self.server.poll() != None: self.log.append("Please start the server first!") return if not self.client or not self.client.isConnected(): self.startClient() if self.recovery: self.recovery = False scene = self.canvas.scene() activeDevices = False from Core.Device import Device for item in scene.items(): if not isinstance(item, Device): continue if item.type == "Router": item.stop() if item.status: activeDevices = True if not activeDevices: self.stopped() elif not scene.isRefreshing(): scene.startRefresh() self.client.process("stop") def stopped(self): """ Handle a fully stopped topology. """ self.running = False self.canvas.scene().stopRefresh() self.tm.hide() self.canvas.setAcceptDrops(True) olddir = os.getcwd() os.chdir(environ["tmp"]) for tmpfile in os.listdir("."): if tmpfile.startswith("."): continue try: os.remove(tmpfile) except: continue os.chdir(olddir) def loadFile(self, filetype): """ Load a file through a file dialog. """ # Qt is very picky in the filename structure but python is not, so we use python # to form the correct path which will work for both Windows and Linux olddir = os.getcwd() os.chdir(environ["sav"]) loadpath = os.getcwd() os.chdir(olddir) filename = QtGui.QFileDialog.getOpenFileName(self, self.tr("Choose a file name"), loadpath, self.tr(filetype)) return filename def loadTopology(self): """ Load a topology. """ if self.running: self.log.append("You cannot load a topology when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot load a topology during the tutorial!") return def loadIntoScene(line): scene = self.canvas.scene() itemType,arg = line.split(":") args = str(arg).strip("()").split(",") if itemType == "edge": source = scene.findItem(args[0]) dest = scene.findItem(args[1]) if source.type == "Mobile" or dest.type == "Mobile": item = Wireless_Connection(source, dest) else: item = Connection(source, dest) scene.addItem(item) else: devType, index = str(itemType).rsplit("_", 1) item = deviceTypes[devType]() item.setIndex(int(index)) scene.addItem(item) item.setPos(float(args[0]), float(args[1])) item.nudge() return item def loadProperties(itemDict): currentInterfaceTarget = None currentRouteSubnet = None for item, properties in itemDict.iteritems(): for line in properties: count = 0 while line.find("\t") == 0: line = line[1:] count += 1 prop, value = line.split(":", 1) if count == 1: item.setProperty(prop, value) elif count == 2: currentInterfaceTarget = self.canvas.scene().findItem(value) elif count == 3: item.setInterfaceProperty(prop, value, currentInterfaceTarget) elif count == 4: currentRouteSubnet = value item.addEntry("", "", value, currentInterfaceTarget) elif count == 5: item.setEntryProperty(prop, value, currentRouteSubnet, currentInterfaceTarget) filename = self.loadFile("GSAV (*.gsav)") if filename.isEmpty(): return file = QtCore.QFile(filename) if not file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning(self, self.tr("Load Error"), self.tr("Cannot read file %1:\n%2.") .arg(filename) .arg(file.errorString())) return self.newScene() self.filename = str(filename) _in = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) itemDict = {} line = str(_in.readLine()) lines = [] while not _in.atEnd(): item = loadIntoScene(line) line = str(_in.readLine()) while line.find("\t") == 0: lines.append(line) line = str(_in.readLine()) itemDict[item] = lines lines = [] loadProperties(itemDict) QtGui.QApplication.restoreOverrideCursor() self.statusBar().showMessage(self.tr("Loaded '%1'").arg(filename), 2000) def saveFile(self, filetype): """ Save a file through a file dialog. """ olddir = os.getcwd() os.chdir(environ["sav"]) savepath = os.getcwd() os.chdir(olddir) filename = QtGui.QFileDialog.getSaveFileName(self, self.tr("Choose a file name"), savepath, self.tr(filetype.upper() + " (*.%s)" % filetype)) if filename.isEmpty(): return filename if not filename.toLower().endsWith("." + filetype): filename += "." + filetype return filename def saveTopologyAs(self): """ Save a topology under a given filename. """ if not self.canvas.scene().items(): self.log.append("There is nothing to save!") return False filename = self.saveFile("gsav") if filename.isEmpty(): return False self.filename = str(filename) return self.saveTopology() def saveTopology(self): """ Save a topology. """ if not self.canvas.scene().items(): self.log.append("There is nothing to save!") return False # for first time use if not self.filename: return self.saveTopologyAs() file = QtCore.QFile(self.filename) if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning(self, self.tr("Save Error"), self.tr("Cannot write file %1:\n%2.") .arg(self.filename) .arg(file.errorString())) return False out = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) scene = self.canvas.scene() outstring = "" for item in scene.items(): if isinstance(item, Node): outstring += item.toString() for item in scene.items(): if isinstance(item, Edge): outstring += item.toString() out << outstring QtGui.QApplication.restoreOverrideCursor() self.statusBar().showMessage(self.tr("Saved '%1'").arg(self.filename), 2000) return True def copy(self): """ Copy selected text from the log into the paste buffer. """ self.log.copy() def config(self): """ Open the options window. """ self.configWindow.show() def arrange(self): """ Rearrange the topology based on the distance between nodes. """ if self.isRunning(): self.log.append("Cannot arrange while running!") return if isinstance(mainWidgets["canvas"], Tutorial): mainWidgets["log"].append("Cannot arrange during the tutorial!") return options["elasticMode"] = not options["elasticMode"] def about(self): """ Show the about window. """ QtGui.QMessageBox.about(self, self.tr("About %s %s" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION)), self.tr("<b>%s %s</b><br>Written by Daniel Ng<br>under the supervision of Muthucumaru Maheswaran" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION))) def createActions(self): """ Create the actions used in the menus and toolbars. """ self.newSceneAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "new.png"), self.tr("&New"), self) self.newSceneAct.setShortcut(self.tr("Ctrl+N")) self.newSceneAct.setStatusTip(self.tr("Create a new topology")) self.connect(self.newSceneAct, QtCore.SIGNAL("triggered()"), self.newScene) self.closeAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "close.png"), self.tr("&Close"), self) self.closeAct.setShortcut(self.tr("Ctrl+W")) self.closeAct.setStatusTip(self.tr("Close the current topology")) self.connect(self.closeAct, QtCore.SIGNAL("triggered()"), self.closeTopology) self.loadAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "open.png"), self.tr("&Open..."), self) self.loadAct.setShortcut(self.tr("Ctrl+O")) self.loadAct.setStatusTip(self.tr("Load a topology")) self.connect(self.loadAct, QtCore.SIGNAL("triggered()"), self.loadTopology) self.saveAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "save.png"), self.tr("&Save..."), self) self.saveAct.setShortcut(self.tr("Ctrl+S")) self.saveAct.setStatusTip(self.tr("Save the current topology")) self.connect(self.saveAct, QtCore.SIGNAL("triggered()"), self.saveTopology) self.saveAsAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "save.png"), self.tr("&Save As..."), self) self.saveAsAct.setShortcut(self.tr("Ctrl+Shift+S")) self.saveAsAct.setStatusTip(self.tr("Save the current topology under a given filename")) self.connect(self.saveAsAct, QtCore.SIGNAL("triggered()"), self.saveTopologyAs) self.sendFileAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "send.png"), self.tr("&Send File..."), self) self.sendFileAct.setShortcut(self.tr("Ctrl+F")) self.sendFileAct.setStatusTip(self.tr("Choose a file to send to the server")) self.connect(self.sendFileAct, QtCore.SIGNAL("triggered()"), self.sendFile) self.exportAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "export.png"), self.tr("&Export..."), self) self.exportAct.setShortcut(self.tr("Ctrl+P")) self.exportAct.setStatusTip(self.tr("Export the current topology as an image")) self.connect(self.exportAct, QtCore.SIGNAL("triggered()"), self.export) self.copyAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "copy.png"), self.tr("&Copy"), self) self.copyAct.setShortcut(self.tr("Ctrl+C")) self.copyAct.setStatusTip(self.tr("Copy the selected text")) self.connect(self.copyAct, QtCore.SIGNAL("triggered()"), self.copy) self.compileAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "compile.png"), self.tr("&Compile"), self) self.compileAct.setShortcut(self.tr("Ctrl+E")) self.compileAct.setStatusTip(self.tr("Compile the current topology")) self.connect(self.compileAct, QtCore.SIGNAL("triggered()"), self.compile) self.runAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "run.png"), self.tr("&Run"), self) self.runAct.setShortcut(self.tr("Ctrl+R")) self.runAct.setStatusTip(self.tr("Run the current topology")) self.connect(self.runAct, QtCore.SIGNAL("triggered()"), self.run) self.stopAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "stop.png"), self.tr("&Stop"), self) self.stopAct.setShortcut(self.tr("Ctrl+D")) self.stopAct.setStatusTip(self.tr("Stop the current topology")) self.connect(self.stopAct, QtCore.SIGNAL("triggered()"), self.stop) self.startServerAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "startServer.png"), self.tr("&Start Server"), self) self.startServerAct.setShortcut(self.tr("Ctrl+T")) self.startServerAct.setStatusTip(self.tr("Start the server")) self.connect(self.startServerAct, QtCore.SIGNAL("triggered()"), self.startBackend) self.optionsAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "options.png"), self.tr("&Options"), self) self.optionsAct.setShortcut(self.tr("F2")) self.optionsAct.setStatusTip(self.tr("Show the options window")) self.connect(self.optionsAct, QtCore.SIGNAL("triggered()"), self.config) self.arrangeAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "arrange.png"), self.tr("&Arrange"), self) self.arrangeAct.setShortcut(self.tr("Ctrl+A")) self.arrangeAct.setStatusTip(self.tr("Arranges the current topology")) self.connect(self.arrangeAct, QtCore.SIGNAL("triggered()"), self.arrange) self.resetLayoutAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "layout.png"), self.tr("Reset Layout"), self) self.resetLayoutAct.setStatusTip(self.tr("Reset dock windows to the saved layout")) self.connect(self.resetLayoutAct, QtCore.SIGNAL("triggered()"), self.resetLayout) self.expandSceneAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "expand.png"), self.tr("Expand Scene"), self) self.expandSceneAct.setStatusTip(self.tr("Expand the scene for more space")) self.connect(self.expandSceneAct, QtCore.SIGNAL("triggered()"), self.expandScene) self.quitAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "exit.png"), self.tr("&Quit"), self) self.quitAct.setShortcut(self.tr("Ctrl+Q")) self.quitAct.setStatusTip(self.tr("Quit the application")) self.connect(self.quitAct, QtCore.SIGNAL("triggered()"), self.quit) self.newProjectAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "new.png"), self.tr("&New"), self) self.newProjectAct.setShortcut(self.tr("Ctrl+Shift+N")) self.newProjectAct.setStatusTip(self.tr("Create a new project")) self.connect(self.newProjectAct, QtCore.SIGNAL("triggered()"), self.newProject) self.openProjectAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "open.png"), self.tr("&Open"), self) self.openProjectAct.setShortcut(self.tr("Ctrl+Shift+O")) self.openProjectAct.setStatusTip(self.tr("Open an existing project")) self.connect(self.openProjectAct, QtCore.SIGNAL("triggered()"), self.openProject) self.closeProjectAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "close.png"), self.tr("&Close"), self) self.closeProjectAct.setShortcut(self.tr("Ctrl+Shift+W")) self.closeProjectAct.setStatusTip(self.tr("Close the current project")) self.connect(self.closeProjectAct, QtCore.SIGNAL("triggered()"), self.closeProject) self.tutorialAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "tutorial.png"), self.tr("&Tutorial"), self) self.connect(self.tutorialAct, QtCore.SIGNAL("triggered()"), self.startTutorial) self.faqAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "help.png"), self.tr("&FAQ"), self) self.connect(self.faqAct, QtCore.SIGNAL("triggered()"), self.faq) self.aboutAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "giniLogo.png"), self.tr("&About"), self) self.aboutAct.setStatusTip(self.tr("Show the application's About box")) self.connect(self.aboutAct, QtCore.SIGNAL("triggered()"), self.about) self.aboutQtAct = QtGui.QAction(self.tr("About &Qt"), self) self.aboutQtAct.setStatusTip(self.tr("Show the Qt library's About box")) self.connect(self.aboutQtAct, QtCore.SIGNAL("triggered()"), QtGui.qApp, QtCore.SLOT("aboutQt()")) def createMenus(self): """ Create the menus with actions. """ self.fileMenu = self.menuBar().addMenu(self.tr("&File")) self.fileMenu.setPalette(defaultOptions["palette"]) self.fileMenu.addAction(self.newSceneAct) self.fileMenu.addAction(self.loadAct) self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.sendFileAct) self.fileMenu.addAction(self.exportAct) self.fileMenu.addAction(self.closeAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.quitAct) self.projectMenu = self.menuBar().addMenu(self.tr("&Project")) self.projectMenu.setPalette(defaultOptions["palette"]) self.projectMenu.addAction(self.newProjectAct) self.projectMenu.addAction(self.openProjectAct) self.projectMenu.addAction(self.closeProjectAct) self.editMenu = self.menuBar().addMenu(self.tr("&Edit")) self.editMenu.setPalette(defaultOptions["palette"]) self.editMenu.addAction(self.copyAct) self.editMenu.addAction(self.arrangeAct) self.editMenu.addAction(self.resetLayoutAct) self.editMenu.addAction(self.expandSceneAct) self.runMenu = self.menuBar().addMenu(self.tr("&Run")) self.runMenu.setPalette(defaultOptions["palette"]) self.runMenu.addAction(self.compileAct) self.runMenu.addAction(self.runAct) self.runMenu.addAction(self.stopAct) self.runMenu.addAction(self.startServerAct) self.configMenu = self.menuBar().addMenu(self.tr("&Config")) self.configMenu.setPalette(defaultOptions["palette"]) self.configMenu.addAction(self.optionsAct) self.menuBar().addSeparator() self.helpMenu = self.menuBar().addMenu(self.tr("&Help")) self.helpMenu.setPalette(defaultOptions["palette"]) self.helpMenu.addAction(self.tutorialAct) self.helpMenu.addAction(self.faqAct) self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) def createPopupMenu(self): """ Customize the popup menu so that it is visible. """ popupMenu = QtGui.QMainWindow.createPopupMenu(self) popupMenu.setPalette(defaultOptions["palette"]) return popupMenu def createToolBars(self): """ Create the toolbars with actions. """ self.fileToolBar = self.addToolBar(self.tr("File")) self.fileToolBar.addAction(self.newSceneAct) self.fileToolBar.addAction(self.loadAct) self.fileToolBar.addAction(self.saveAct) self.fileToolBar.addAction(self.sendFileAct) self.fileToolBar.addAction(self.exportAct) self.fileToolBar.addAction(self.closeAct) self.editToolBar = self.addToolBar(self.tr("Edit")) self.editToolBar.addAction(self.copyAct) self.editToolBar.addAction(self.resetLayoutAct) self.editToolBar.addAction(self.expandSceneAct) self.runToolBar = self.addToolBar(self.tr("Run")) self.runToolBar.addAction(self.compileAct) self.runToolBar.addAction(self.runAct) self.runToolBar.addAction(self.stopAct) self.runToolBar.addAction(self.startServerAct) def createStatusBar(self): """ Create the status bar. """ self.statusBar().showMessage(self.tr("Ready")) def createProgressBar(self): """ Create the progress bar. """ self.progressBar = QtGui.QProgressBar() self.progressBar.setRange(0, 10000) self.progressBar.setValue(0) self.statusBar().addPermanentWidget(self.progressBar) self.progressBar.show() def getDeviceCount(self, alive=False): """ Return the interfaceable device count, or the alive ones if alive=True. """ from Core.Interfaceable import Interfaceable count = 0.0 for item in self.canvas.scene().items(): if isinstance(item, Interfaceable): if alive and item.status in ("", "dead"): continue count += 1.0 return count def updateProgressBar(self): """ Update the progress bar. """ maxVal = self.progressBar.maximum() finalVal = (self.getDeviceCount(True) / self.getDeviceCount()) * maxVal if finalVal < 0: finalVal = 0 self.progressBar.setValue(finalVal) if finalVal == 0: return True return False def createConfigWindows(self): """ Create the options window. """ self.configWindow = ConfigDialog(self) def createDockWindows(self): """ Create the dock windows: dropbar, log, properties, interfaces, routes. """ self.log = LogWindow(self.tr("Log"), self) self.log.append("Welcome to %s %s!\n" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION)) self.log.setGeometry(QtCore.QRect(0, 0, 800, 114)) mainWidgets["log"] = self.log self.dropbar = DropBar(self.tr("Components"), self) self.dropbar.setGeometry(QtCore.QRect(0, 0, 129, 390)) mainWidgets["drop"] = self.dropbar self.properties = PropertiesWindow(self) self.properties.setWindowTitle("Properties") mainWidgets["properties"] = self.properties self.interfaces = InterfacesWindow(self) self.interfaces.setWindowTitle("Interfaces") mainWidgets["interfaces"] = self.interfaces self.routes = RoutesWindow(self.interfaces, self) self.routes.setWindowTitle("Routes") mainWidgets["routes"] = self.routes self.tm = TaskManagerWindow(self) self.tm.setWindowTitle("Task Manager") mainWidgets["tm"] = self.tm self.debugWindow = QtGui.QDockWidget(self.tr("Debug Window")) self.debugWindow.setWidget(DebugWindow(self)) self.docks = {"Components":self.dropbar, "Log":self.log, "Properties":self.properties, "Interfaces":self.interfaces, "Routes":self.routes, "Task Manager":self.tm} self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dropbar) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.properties) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.interfaces) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.routes) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tm) self.tm.setFloating(True) self.routes.setFloating(True) self.debugWindow.setFloating(True) def createPopupWindows(self): """ Create the different popup windows. """ self.exportWindow = ExportWindow(self) self.sendWindow = SendDirectoryWindow(self) self.popup = QtGui.QMessageBox(self) self.popup.setIcon(QtGui.QMessageBox.Warning) self.popup.setWindowIcon(QtGui.QIcon(environ["images"]+"giniLogo.png")) mainWidgets["popup"] = self.popup def keyPressEvent(self, event): """ Handle specific shortcut keys. """ key = event.key() scene = self.canvas.scene() if key == QtCore.Qt.Key_Escape: scene.clearSelection() elif key == QtCore.Qt.Key_Delete: for item in scene.selectedItems(): item.delete() elif key == QtCore.Qt.Key_C: items = scene.items() if not items: return selected = scene.selectedItems() scene.clearSelection() if selected: index = items.index(selected[0]) items[index - 1].setSelected(True) else: items[0].setSelected(True) elif key == QtCore.Qt.Key_H: for dock in self.docks.values(): dock.setFloating(not dock.isFloating()) elif key == QtCore.Qt.Key_F10: self.debugWindow.show()
class MainWindow(Systray): def __init__(self, app): """ Create a main window for the given application. """ defaultOptions["palette"] = app.palette() Systray.__init__(self) self.expansions = 0 self.client = None self.server = None self.running = False self.recovery = False mainWidgets["main"] = self mainWidgets["app"] = app self.canvas = Canvas(self) mainWidgets["canvas"] = self.canvas self.tabWidget = TabWidget(self) mainWidgets["tab"] = self.tabWidget self.setCentralWidget(self.tabWidget) #self.setCentralWidget(self.canvas) self.createActions() self.createMenus() self.createToolBars() self.createStatusBar() self.createDockWindows() self.createConfigWindows() self.createPopupWindows() self.createProgressBar() self.newScene() self.debugWindow.hide() self.tm.hide() self.routes.hide() self.setVisible(True) self.center() self.saveLayout(environ["config"] + "defaultLayout") self.defaultLayout = True if options["restore"]: self.loadLayout() self.defaultLayout = False self.loadProject() atexit.register(self.cleanup) def center(self): """ Center the window. """ screen = QtGui.QDesktopWidget().screenGeometry() rect = self.geometry() self.move((screen.width() - rect.width()) / 2, (screen.height() - rect.height()) / 2) self.show() def getProject(self): """ Return the project. """ return self.project def startTutorial(self): """ Start the interactive tutorial. """ if isinstance(mainWidgets["canvas"], Tutorial): self.log.append( "You are already doing the tutorial! If you would like to stop or restart, select 'Close' from the File menu now." ) return if not self.closeTopology(): return self.project = "Tutorial" self.filename = "" self.canvas = Tutorial(self) mainWidgets["canvas"] = self.canvas self.tabWidget.removeTab(0) self.tabWidget.addTab(self.canvas, "Tutorial") self.canvas.start() for nodeType in nodeTypes.keys(): itemTypes = nodeTypes[nodeType] itemTypes[nodeType] = 0 self.properties.clear() self.interfaces.clear() self.routes.clear() self.resetLayout(True) self.lockDocks() def lockDocks(self): """ Lock the dock windows so they cannot be moved, closed or resized. """ self.tm.hide() for dock in self.docks.values(): dock.setFeatures(dock.NoDockWidgetFeatures) def unlockDocks(self): """ Unlock the dock windows. """ self.tm.show() for dock in self.docks.values(): dock.setFeatures(dock.DockWidgetClosable | dock.DockWidgetMovable | dock.DockWidgetFloatable) def faq(self): """ Open the FAQ in the default browser. """ olddir = os.getcwd() os.chdir(environ["doc"]) loadpath = os.getcwd() os.chdir(olddir) if environ["os"] == "Windows": url = QtCore.QUrl("file:///" + loadpath + "/FAQ.html") else: url = QtCore.QUrl("file://" + loadpath + "/FAQ.html") QtGui.QDesktopServices.openUrl(url) def closeTopology(self): """ Close the current topology. """ if self.running: self.log.append( "You cannot close a topology when one is still running!") return False scene = self.canvas.scene() if scene and scene.items(): reply = QtGui.QMessageBox.warning( self, self.tr(Core.globals.PROG_NAME), self.tr("Save before closing?"), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel) if reply == QtGui.QMessageBox.Yes: if not self.saveTopology(): return False elif reply == QtGui.QMessageBox.No: pass else: return False if isinstance(mainWidgets["canvas"], Tutorial): self.canvas = Canvas(self) mainWidgets["canvas"] = self.canvas self.tabWidget.removeTab(0) self.tabWidget.addTab(self.canvas, "Default Project") self.project = "" self.unlockDocks() self.filename = "" scene = Scene(self.canvas) scene.setItemIndexMethod(QtGui.QGraphicsScene.NoIndex) self.canvas.setScene(scene) self.expansions = 0 for nodeType in nodeTypes.keys(): itemTypes = nodeTypes[nodeType] itemTypes[nodeType] = 0 self.properties.clear() self.interfaces.clear() self.routes.clear() return True def sendFile(self): """ Start a process to select and send a file to the server. """ if not self.server or self.server.poll() != None: self.log.append("Please start the server first!") return if not self.client or not self.client.isConnected(): self.startClient() filename = self.loadFile("All Files (*.*)") if not filename: return self.sendWindow.setFilename(filename) self.sendWindow.show() def newScene(self): """ Close the current topology and create a new one. """ if self.running: self.log.append( "You cannot create a new topology when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append( "You cannot create a new topology during the tutorial!") return if not self.closeTopology(): return self.expandScene() def expandScene(self): """ Expand the scene based on number of expansions. """ x = 175 + self.expansions * 30 y = 160 + self.expansions * 20 scene = self.canvas.scene() item = QtGui.QGraphicsLineItem(-x, -y, x, y) scene.addItem(item) scene.removeItem(item) self.expansions += 1 def newProject(self): """ Create a new project for device sharing. """ if self.running: self.log.append( "You cannot create a new project when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append( "You cannot create a new project during the tutorial!") return filename = self.saveFile("gproj") if filename.isEmpty(): return projectname = str(filename).split("/")[-1].strip(".gproj") from Core.Item import nodeTypes for nodeType in nodeTypes: if projectname.startswith(nodeType + "_"): self.popup.setWindowTitle("Invalid Project Name") self.popup.setText( "You cannot name a project starting with the name of a device and underscore!" ) self.popup.show() return self.project = str(filename) file = QtCore.QFile(filename) if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning( self, self.tr("Save Error"), self.tr("Cannot write file %1:\n%2.").arg(self.filename).arg( file.errorString())) return out = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) if options["username"]: out << "username="******"username"] + "\n" else: self.log.append("Warning, no username is specified!") if options["session"]: out << "session=" + options["session"] + "\n" elif options["server"]: out << "server=" + options["server"] + "\n" else: self.log.append("Warning, no server or session name is specified!") QtGui.QApplication.restoreOverrideCursor() self.tabWidget.addTab(self.canvas, projectname) def openProject(self): """ Load an existing project for device sharing. """ if self.running: self.log.append( "You cannot open a project when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot open a project during the tutorial!") return filename = self.loadFile("GPROJ (*.gproj)") if filename.isEmpty(): return self.project = str(filename) self.loadProject() def loadProject(self): """ Load project file data into options. """ if not self.project: self.tabWidget.addTab(self.canvas, "Default Project") return file = QtCore.QFile(self.project) if not file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning( self, self.tr("Load Error"), self.tr("Cannot read file %1:\n%2.").arg(self.project).arg( file.errorString())) self.tabWidget.addTab(self.canvas, "Default Project") return _in = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) while not _in.atEnd(): line = str(_in.readLine()) option, value = line.split("=", 1) options[option] = value self.configWindow.updateSettings() QtGui.QApplication.restoreOverrideCursor() projectname = self.project.split("/")[-1].strip(".gproj") self.tabWidget.addTab(self.canvas, projectname) def closeProject(self): """ Close the current project. """ if self.running: self.log.append( "You cannot close a project when it is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot close a project during the tutorial!") return if self.tabWidget.count() == 1: self.tabWidget.addTab(self.canvas, "Default Project") self.project = "" else: self.tabWidget.removeTab(0) def export(self): """ Open an export window to generate an image from the canvas. """ self.exportWindow.show() def startBackend(self): """ Start the backend server. """ self.startServer() #self.startClient() def setRecovery(self, recovery): """ Set the recovering state of the topology. """ self.recovery = recovery def isRunning(self): """ Returns whether a topology is running or not. """ return self.running def startServer(self): """ Start the server backend of gbuilder, which controls running topologies. """ if self.server and self.server.poll() == None: self.log.append("A server is already running!") return base = "ssh -t " + options["username"] + "@" + options["server"] tunnel = " -L " + options["localPort"] + ":localhost:" + options[ "remotePort"] server = "bash -c -i 'gserver " + options["remotePort"] + "' || sleep 5" command = "" gserver = "gserver" if environ["os"] == "Windows": startpath = environ["tmp"] + "gserver.start" try: startFile = open(startpath, "w") startFile.write("echo -ne \"\\033]0;" + gserver + "\\007\"\n") startFile.write(server) startFile.close() except: self.log.append("Failed to write to start file!") return command += "putty -" if options["session"]: command += "load " + options["session"] + " -l " + options[ "username"] + " -t" else: command += base command += tunnel + " -m \"" + startpath + "\"" else: command += "rxvt -T \"" + gserver + "\" -e " + base + tunnel + " \" " + server + "\"" self.server = subprocess.Popen(str(command), shell=True, preexec_fn=os.setpgrp) def startClient(self): """ Start the client of gbuilder, which communicates with the server. """ self.client = Client(self) self.client.connectTo("localhost", int(options["localPort"]), 10) #self.client.start() mainWidgets["client"] = self.client def compile(self): """ Compile the current topology. """ if self.running: self.log.append( "You cannot compile a topology when one is still running!") return False if self.saveTopology() == False: return False scene = self.canvas.scene() compiler = Compiler(scene.items(), self.filename) xmlFile = compiler.compile() self.properties.display() self.interfaces.display() self.routes.display() if xmlFile: self.statusBar().showMessage( self.tr("Compiled '%1'").arg(xmlFile), 2000) return True else: self.statusBar().showMessage(self.tr("Compile failed"), 2000) return False def run(self): """ Run the current topology. """ if not self.server or self.server.poll() != None: self.log.append("Please start the server first!") return if not self.client or not self.client.isConnected(): self.startClient() if self.isRunning() and not self.recovery: self.log.append( "A topology is already running, please stop it first!") return scene = self.canvas.scene() items = scene.items() if items: if self.recovery: self.recovery = False elif options["autocompile"] and not self.compile(): return else: self.log.append("Please create or load a topology first!") return options["elasticMode"] = False xmlFile = self.filename.replace(".gsav", ".xml") if not os.access(xmlFile, os.F_OK): self.log.append("Please compile the topology first!") return self.tm.show() #self.progressBar.setValue(0) self.client.process("file . " + xmlFile) self.client.send("init " + self.project.split("/")[-1].strip(".gproj")) self.client.send("canvas %d,%d" % (scene.width(), scene.height())) for item in items: if item.device_type == "Mobile" or item.device_type == "Wireless_access_point": x = item.pos().x() y = item.pos().y() self.client.send("mobile %s %d,%d" % (item.getName(), x, y)) self.client.process("start " + xmlFile) self.running = True self.canvas.setAcceptDrops(False) scene = self.canvas.scene() scene.startRefresh() scene.clearSelection() self.properties.clear() self.interfaces.clear() self.routes.clear() def stop(self): """ Stop the current running topology. """ if not self.server or self.server.poll() != None: self.log.append("Please start the server first!") return if not self.client or not self.client.isConnected(): self.startClient() if self.recovery: self.recovery = False scene = self.canvas.scene() activeDevices = False from Core.Device import Device for item in scene.items(): if not isinstance(item, Device): continue if item.device_type == "Router": item.stop() if item.status: activeDevices = True if not activeDevices: self.stopped() elif not scene.isRefreshing(): scene.startRefresh() self.client.process("stop") def stopped(self): """ Handle a fully stopped topology. """ self.running = False self.canvas.scene().stopRefresh() self.tm.hide() self.canvas.setAcceptDrops(True) olddir = os.getcwd() os.chdir(environ["tmp"]) for tmpfile in os.listdir("."): if tmpfile.startswith("."): continue try: os.remove(tmpfile) except: continue os.chdir(olddir) def loadFile(self, filetype): """ Load a file through a file dialog. """ # Qt is very picky in the filename structure but python is not, so we use python # to form the correct path which will work for both Windows and Linux olddir = os.getcwd() os.chdir(environ["sav"]) loadpath = os.getcwd() os.chdir(olddir) filename = QtGui.QFileDialog.getOpenFileName( self, self.tr("Choose a file name"), loadpath, self.tr(filetype)) return filename def loadTopology(self): """ Load a topology. """ if self.running: self.log.append( "You cannot load a topology when one is still running!") return if isinstance(mainWidgets["canvas"], Tutorial): self.log.append("You cannot load a topology during the tutorial!") return def loadIntoScene(line): scene = self.canvas.scene() itemType, arg = line.split(":") args = str(arg).strip("()").split(",") if itemType == "edge": source = scene.findItem(args[0]) dest = scene.findItem(args[1]) if source.device_type == "Mobile" or dest.device_type == "Mobile": item = Wireless_Connection(source, dest) else: item = Connection(source, dest) scene.addItem(item) else: devType, index = str(itemType).rsplit("_", 1) item = deviceTypes[devType]() item.setIndex(int(index)) scene.addItem(item) item.setPos(float(args[0]), float(args[1])) item.nudge() return item def loadProperties(itemDict): currentInterfaceTarget = None currentRouteSubnet = None for item, properties in itemDict.iteritems(): for line in properties: count = 0 while line.find("\t") == 0: line = line[1:] count += 1 prop, value = line.split(":", 1) if count == 1: item.setProperty(prop, value) elif count == 2: currentInterfaceTarget = self.canvas.scene().findItem( value) elif count == 3: item.setInterfaceProperty(prop, value, currentInterfaceTarget) elif count == 4: currentRouteSubnet = value item.addEntry("", "", value, currentInterfaceTarget) elif count == 5: item.setEntryProperty(prop, value, currentRouteSubnet, currentInterfaceTarget) filename = self.loadFile("GSAV (*.gsav)") if filename.isEmpty(): return file = QtCore.QFile(filename) if not file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning( self, self.tr("Load Error"), self.tr("Cannot read file %1:\n%2.").arg(filename).arg( file.errorString())) return self.newScene() self.filename = str(filename) _in = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) itemDict = {} line = str(_in.readLine()) lines = [] while not _in.atEnd(): item = loadIntoScene(line) line = str(_in.readLine()) while line.find("\t") == 0: lines.append(line) line = str(_in.readLine()) itemDict[item] = lines lines = [] loadProperties(itemDict) QtGui.QApplication.restoreOverrideCursor() self.statusBar().showMessage( self.tr("Loaded '%1'").arg(filename), 2000) def saveFile(self, filetype): """ Save a file through a file dialog. """ olddir = os.getcwd() os.chdir(environ["sav"]) savepath = os.getcwd() os.chdir(olddir) filename = QtGui.QFileDialog.getSaveFileName( self, self.tr("Choose a file name"), savepath, self.tr(filetype.upper() + " (*.%s)" % filetype)) if filename.isEmpty(): return filename if not filename.toLower().endsWith("." + filetype): filename += "." + filetype return filename def saveTopologyAs(self): """ Save a topology under a given filename. """ if not self.canvas.scene().items(): self.log.append("There is nothing to save!") return False filename = self.saveFile("gsav") if filename.isEmpty(): return False self.filename = str(filename) return self.saveTopology() def saveTopology(self): """ Save a topology. """ if not self.canvas.scene().items(): self.log.append("There is nothing to save!") return False # for first time use if not self.filename: return self.saveTopologyAs() file = QtCore.QFile(self.filename) if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): QtGui.QMessageBox.warning( self, self.tr("Save Error"), self.tr("Cannot write file %1:\n%2.").arg(self.filename).arg( file.errorString())) return False out = QtCore.QTextStream(file) QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) scene = self.canvas.scene() outstring = "" for item in scene.items(): if isinstance(item, Node): outstring += item.toString() for item in scene.items(): if isinstance(item, Edge): outstring += item.toString() out << outstring QtGui.QApplication.restoreOverrideCursor() self.statusBar().showMessage( self.tr("Saved '%1'").arg(self.filename), 2000) return True def copy(self): """ Copy selected text from the log into the paste buffer. """ self.log.copy() def config(self): """ Open the options window. """ self.configWindow.show() def arrange(self): """ Rearrange the topology based on the distance between nodes. """ if self.isRunning(): self.log.append("Cannot arrange while running!") return if isinstance(mainWidgets["canvas"], Tutorial): mainWidgets["log"].append("Cannot arrange during the tutorial!") return options["elasticMode"] = not options["elasticMode"] def about(self): """ Show the about window. """ QtGui.QMessageBox.about( self, self.tr("About %s %s" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION)), self. tr("<b>%s %s</b><br>Written by Daniel Ng<br>under the supervision of Muthucumaru Maheswaran" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION))) def createActions(self): """ Create the actions used in the menus and toolbars. """ self.newSceneAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "new.png"), self.tr("&New"), self) self.newSceneAct.setShortcut(self.tr("Ctrl+N")) self.newSceneAct.setStatusTip(self.tr("Create a new topology")) self.connect(self.newSceneAct, QtCore.SIGNAL("triggered()"), self.newScene) self.closeAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "close.png"), self.tr("&Close"), self) self.closeAct.setShortcut(self.tr("Ctrl+W")) self.closeAct.setStatusTip(self.tr("Close the current topology")) self.connect(self.closeAct, QtCore.SIGNAL("triggered()"), self.closeTopology) self.loadAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "open.png"), self.tr("&Open..."), self) self.loadAct.setShortcut(self.tr("Ctrl+O")) self.loadAct.setStatusTip(self.tr("Load a topology")) self.connect(self.loadAct, QtCore.SIGNAL("triggered()"), self.loadTopology) self.saveAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "save.png"), self.tr("&Save..."), self) self.saveAct.setShortcut(self.tr("Ctrl+S")) self.saveAct.setStatusTip(self.tr("Save the current topology")) self.connect(self.saveAct, QtCore.SIGNAL("triggered()"), self.saveTopology) self.saveAsAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "save.png"), self.tr("&Save As..."), self) self.saveAsAct.setShortcut(self.tr("Ctrl+Shift+S")) self.saveAsAct.setStatusTip( self.tr("Save the current topology under a given filename")) self.connect(self.saveAsAct, QtCore.SIGNAL("triggered()"), self.saveTopologyAs) self.sendFileAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "send.png"), self.tr("&Send File..."), self) self.sendFileAct.setShortcut(self.tr("Ctrl+F")) self.sendFileAct.setStatusTip( self.tr("Choose a file to send to the server")) self.connect(self.sendFileAct, QtCore.SIGNAL("triggered()"), self.sendFile) self.exportAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "export.png"), self.tr("&Export..."), self) self.exportAct.setShortcut(self.tr("Ctrl+P")) self.exportAct.setStatusTip( self.tr("Export the current topology as an image")) self.connect(self.exportAct, QtCore.SIGNAL("triggered()"), self.export) self.copyAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "copy.png"), self.tr("&Copy"), self) self.copyAct.setShortcut(self.tr("Ctrl+C")) self.copyAct.setStatusTip(self.tr("Copy the selected text")) self.connect(self.copyAct, QtCore.SIGNAL("triggered()"), self.copy) self.compileAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "compile.png"), self.tr("&Compile"), self) self.compileAct.setShortcut(self.tr("Ctrl+E")) self.compileAct.setStatusTip(self.tr("Compile the current topology")) self.connect(self.compileAct, QtCore.SIGNAL("triggered()"), self.compile) self.runAct = QtGui.QAction(QtGui.QIcon(environ["images"] + "run.png"), self.tr("&Run"), self) self.runAct.setShortcut(self.tr("Ctrl+R")) self.runAct.setStatusTip(self.tr("Run the current topology")) self.connect(self.runAct, QtCore.SIGNAL("triggered()"), self.run) self.stopAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "stop.png"), self.tr("&Stop"), self) self.stopAct.setShortcut(self.tr("Ctrl+D")) self.stopAct.setStatusTip(self.tr("Stop the current topology")) self.connect(self.stopAct, QtCore.SIGNAL("triggered()"), self.stop) self.startServerAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "startServer.png"), self.tr("&Start Server"), self) self.startServerAct.setShortcut(self.tr("Ctrl+T")) self.startServerAct.setStatusTip(self.tr("Start the server")) self.connect(self.startServerAct, QtCore.SIGNAL("triggered()"), self.startBackend) self.optionsAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "options.png"), self.tr("&Options"), self) self.optionsAct.setShortcut(self.tr("F2")) self.optionsAct.setStatusTip(self.tr("Show the options window")) self.connect(self.optionsAct, QtCore.SIGNAL("triggered()"), self.config) self.arrangeAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "arrange.png"), self.tr("&Arrange"), self) self.arrangeAct.setShortcut(self.tr("Ctrl+A")) self.arrangeAct.setStatusTip(self.tr("Arranges the current topology")) self.connect(self.arrangeAct, QtCore.SIGNAL("triggered()"), self.arrange) self.resetLayoutAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "layout.png"), self.tr("Reset Layout"), self) self.resetLayoutAct.setStatusTip( self.tr("Reset dock windows to the saved layout")) self.connect(self.resetLayoutAct, QtCore.SIGNAL("triggered()"), self.resetLayout) self.expandSceneAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "expand.png"), self.tr("Expand Scene"), self) self.expandSceneAct.setStatusTip( self.tr("Expand the scene for more space")) self.connect(self.expandSceneAct, QtCore.SIGNAL("triggered()"), self.expandScene) self.quitAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "exit.png"), self.tr("&Quit"), self) self.quitAct.setShortcut(self.tr("Ctrl+Q")) self.quitAct.setStatusTip(self.tr("Quit the application")) self.connect(self.quitAct, QtCore.SIGNAL("triggered()"), self.quit) self.newProjectAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "new.png"), self.tr("&New"), self) self.newProjectAct.setShortcut(self.tr("Ctrl+Shift+N")) self.newProjectAct.setStatusTip(self.tr("Create a new project")) self.connect(self.newProjectAct, QtCore.SIGNAL("triggered()"), self.newProject) self.openProjectAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "open.png"), self.tr("&Open"), self) self.openProjectAct.setShortcut(self.tr("Ctrl+Shift+O")) self.openProjectAct.setStatusTip(self.tr("Open an existing project")) self.connect(self.openProjectAct, QtCore.SIGNAL("triggered()"), self.openProject) self.closeProjectAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "close.png"), self.tr("&Close"), self) self.closeProjectAct.setShortcut(self.tr("Ctrl+Shift+W")) self.closeProjectAct.setStatusTip(self.tr("Close the current project")) self.connect(self.closeProjectAct, QtCore.SIGNAL("triggered()"), self.closeProject) self.tutorialAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "tutorial.png"), self.tr("&Tutorial"), self) self.connect(self.tutorialAct, QtCore.SIGNAL("triggered()"), self.startTutorial) self.faqAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "help.png"), self.tr("&FAQ"), self) self.connect(self.faqAct, QtCore.SIGNAL("triggered()"), self.faq) self.aboutAct = QtGui.QAction( QtGui.QIcon(environ["images"] + "giniLogo.png"), self.tr("&About"), self) self.aboutAct.setStatusTip(self.tr("Show the application's About box")) self.connect(self.aboutAct, QtCore.SIGNAL("triggered()"), self.about) self.aboutQtAct = QtGui.QAction(self.tr("About &Qt"), self) self.aboutQtAct.setStatusTip( self.tr("Show the Qt library's About box")) self.connect(self.aboutQtAct, QtCore.SIGNAL("triggered()"), QtGui.qApp, QtCore.SLOT("aboutQt()")) def createMenus(self): """ Create the menus with actions. """ self.fileMenu = self.menuBar().addMenu(self.tr("&File")) self.fileMenu.setPalette(defaultOptions["palette"]) self.fileMenu.addAction(self.newSceneAct) self.fileMenu.addAction(self.loadAct) self.fileMenu.addAction(self.saveAct) self.fileMenu.addAction(self.saveAsAct) self.fileMenu.addAction(self.sendFileAct) self.fileMenu.addAction(self.exportAct) self.fileMenu.addAction(self.closeAct) self.fileMenu.addSeparator() self.fileMenu.addAction(self.quitAct) self.projectMenu = self.menuBar().addMenu(self.tr("&Project")) self.projectMenu.setPalette(defaultOptions["palette"]) self.projectMenu.addAction(self.newProjectAct) self.projectMenu.addAction(self.openProjectAct) self.projectMenu.addAction(self.closeProjectAct) self.editMenu = self.menuBar().addMenu(self.tr("&Edit")) self.editMenu.setPalette(defaultOptions["palette"]) self.editMenu.addAction(self.copyAct) self.editMenu.addAction(self.arrangeAct) self.editMenu.addAction(self.resetLayoutAct) self.editMenu.addAction(self.expandSceneAct) self.runMenu = self.menuBar().addMenu(self.tr("&Run")) self.runMenu.setPalette(defaultOptions["palette"]) self.runMenu.addAction(self.compileAct) self.runMenu.addAction(self.runAct) self.runMenu.addAction(self.stopAct) self.runMenu.addAction(self.startServerAct) self.configMenu = self.menuBar().addMenu(self.tr("&Config")) self.configMenu.setPalette(defaultOptions["palette"]) self.configMenu.addAction(self.optionsAct) self.menuBar().addSeparator() self.helpMenu = self.menuBar().addMenu(self.tr("&Help")) self.helpMenu.setPalette(defaultOptions["palette"]) self.helpMenu.addAction(self.tutorialAct) self.helpMenu.addAction(self.faqAct) self.helpMenu.addAction(self.aboutAct) self.helpMenu.addAction(self.aboutQtAct) def createPopupMenu(self): """ Customize the popup menu so that it is visible. """ popupMenu = QtGui.QMainWindow.createPopupMenu(self) popupMenu.setPalette(defaultOptions["palette"]) return popupMenu def createToolBars(self): """ Create the toolbars with actions. """ self.fileToolBar = self.addToolBar(self.tr("File")) self.fileToolBar.addAction(self.newSceneAct) self.fileToolBar.addAction(self.loadAct) self.fileToolBar.addAction(self.saveAct) self.fileToolBar.addAction(self.sendFileAct) self.fileToolBar.addAction(self.exportAct) self.fileToolBar.addAction(self.closeAct) self.editToolBar = self.addToolBar(self.tr("Edit")) self.editToolBar.addAction(self.copyAct) self.editToolBar.addAction(self.resetLayoutAct) self.editToolBar.addAction(self.expandSceneAct) self.runToolBar = self.addToolBar(self.tr("Run")) self.runToolBar.addAction(self.compileAct) self.runToolBar.addAction(self.runAct) self.runToolBar.addAction(self.stopAct) self.runToolBar.addAction(self.startServerAct) def createStatusBar(self): """ Create the status bar. """ self.statusBar().showMessage(self.tr("Ready")) def createProgressBar(self): """ Create the progress bar. """ self.progressBar = QtGui.QProgressBar() self.progressBar.setRange(0, 10000) self.progressBar.setValue(0) self.statusBar().addPermanentWidget(self.progressBar) self.progressBar.show() def getDeviceCount(self, alive=False): """ Return the interfaceable device count, or the alive ones if alive=True. """ from Core.Interfaceable import Interfaceable count = 0.0 for item in self.canvas.scene().items(): if isinstance(item, Interfaceable): if item.device_type != "REALM": if alive and item.status in ("", "dead"): continue count += 1.0 return count def updateProgressBar(self): """ Update the progress bar. """ maxVal = self.progressBar.maximum() finalVal = (self.getDeviceCount(True) / self.getDeviceCount()) * maxVal if finalVal < 0: finalVal = 0 self.progressBar.setValue(finalVal) if finalVal == 0: return True return False def createConfigWindows(self): """ Create the options window. """ self.configWindow = ConfigDialog(self) def createDockWindows(self): """ Create the dock windows: dropbar, log, properties, interfaces, routes. """ self.log = LogWindow(self.tr("Log"), self) self.log.append("Welcome to %s %s!\n" % (Core.globals.PROG_NAME, Core.globals.PROG_VERSION)) self.log.setGeometry(QtCore.QRect(0, 0, 800, 114)) mainWidgets["log"] = self.log self.dropbar = DropBar(self.tr("Components"), self) self.dropbar.setGeometry(QtCore.QRect(0, 0, 129, 390)) mainWidgets["drop"] = self.dropbar self.properties = PropertiesWindow(self) self.properties.setWindowTitle("Properties") mainWidgets["properties"] = self.properties self.interfaces = InterfacesWindow(self) self.interfaces.setWindowTitle("Interfaces") mainWidgets["interfaces"] = self.interfaces self.routes = RoutesWindow(self.interfaces, self) self.routes.setWindowTitle("Routes") mainWidgets["routes"] = self.routes self.tm = TaskManagerWindow(self) self.tm.setWindowTitle("Task Manager") mainWidgets["tm"] = self.tm self.debugWindow = QtGui.QDockWidget(self.tr("Debug Window")) self.debugWindow.setWidget(DebugWindow(self)) self.docks = { "Components": self.dropbar, "Log": self.log, "Properties": self.properties, "Interfaces": self.interfaces, "Routes": self.routes, "Task Manager": self.tm } self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dropbar) self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.properties) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.interfaces) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.routes) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.tm) self.tm.setFloating(True) self.routes.setFloating(True) self.debugWindow.setFloating(True) def createPopupWindows(self): """ Create the different popup windows. """ self.exportWindow = ExportWindow(self) self.sendWindow = SendDirectoryWindow(self) self.popup = QtGui.QMessageBox(self) self.popup.setIcon(QtGui.QMessageBox.Warning) self.popup.setWindowIcon( QtGui.QIcon(environ["images"] + "giniLogo.png")) mainWidgets["popup"] = self.popup def keyPressEvent(self, event): """ Handle specific shortcut keys. """ key = event.key() scene = self.canvas.scene() if key == QtCore.Qt.Key_Escape: scene.clearSelection() elif key == QtCore.Qt.Key_Delete: for item in scene.selectedItems(): item.delete() elif key == QtCore.Qt.Key_C: items = scene.items() if not items: return selected = scene.selectedItems() scene.clearSelection() if selected: index = items.index(selected[0]) items[index - 1].setSelected(True) else: items[0].setSelected(True) elif key == QtCore.Qt.Key_H: for dock in self.docks.values(): dock.setFloating(not dock.isFloating()) elif key == QtCore.Qt.Key_F10: self.debugWindow.show() def cleanup(self): if self.server != None: self.server.kill()
class Game: def __init__(self): pg.init() self.screen = pg.display.set_mode((WIDTH, HEIGHT), flags=DOUBLEBUF) self.screen.set_alpha(None) pg.display.set_caption(TITLE) self.clock = pg.time.Clock() pg.key.set_repeat(SPRINT_DELAY, SPRINT_SPEED) self.current_floor = None self.view = None self.load_data() self.show_grid = True self.log = None self.tick = False self.show_inventory = False self.godmode = GODMODE pg.event.set_allowed([QUIT, KEYDOWN, KEYUP]) def load_data(self): pass def new(self): self.all_sprites = pg.sprite.Group() self.walls = pg.sprite.Group() self.enemies = pg.sprite.Group() self.inters = pg.sprite.Group() self.spells = pg.sprite.Group() self.playerg = pg.sprite.Group() self.screens = pg.sprite.Group() self.player = Player(self, 8, 8) self.log = LogWindow(self, 3, 15) self.inventory = Inventory(self, 0, 0) # first floor (TODO start screen) self.current_floor = Floor(self, 1) self.current_floor.populate_floor() # put the player in a random place gx, gy = self.current_floor.get_valid_pos() self.player.update_global_position(gx, gy) # start the engines self.tick = True # TODO remove self.save_map() def run(self): # game loop - set self.playing = False to end the game self.playing = True self.log.init() while self.playing: self.dt = self.clock.tick(FPS) / 1000 self.events() self.update() self.draw() return self.playing def save_map(self): map_string = "" fl = self.current_floor.layout px = self.player.gx py = self.player.gy for y in range(0, MAP_HEIGHT): for x in range(0, MAP_WIDTH): if x == px and y == py: map_string += "@" elif fl[x][y] == 9: map_string += "^" elif fl[x][y] == 0: map_string += "." else: map_string += str(fl[x][y]) map_string += '\n' if not os.path.exists("scraps"): os.makedirs("scraps") with open("scraps/last_map.txt", 'w') as f: f.write(map_string) print("level map saved in scraps/last_map.txt!") def quit(self, save_map=False): if save_map: self.save_map() pg.quit() sys.exit() def update(self): # only update on tick # (currently just player movement) if not self.player.still: self.tick = True if self.show_inventory: self.inventory.update() elif self.tick: # NOTE: might be able to toggle turn based here... # use the global position of the player to decide what to draw cur_g_x = self.player.gx cur_g_y = self.player.gy self.playerg.update() self.walls.update() self.spells.update() self.enemies.update() self.inters.update() self.current_floor.update_viewport(cur_g_x, cur_g_y) self.player.still = True self.tick = False self.player.dx = 0 self.player.dy = 0 self.log.update() if not self.player.state.alive: self.playing = False def draw_grid(self): for x in range(0, WIDTH, TILESIZE): pg.draw.line(self.screen, DARKGREY, (x, 0), (x, HEIGHT)) for y in range(0, HEIGHT, TILESIZE): pg.draw.line(self.screen, DARKGREY, (0, y), (WIDTH, y)) def draw(self): if self.show_inventory: self.inventory.drawt(self.screen) else: self.screen.fill(BGCOLOR) for wall in self.walls: wall.drawt(self.screen) for enemy in self.enemies: enemy.drawt(self.screen) for inter in self.inters: inter.drawt(self.screen) for spell in self.spells: spell.drawt(self.screen) if self.show_grid: self.draw_grid() self.player.drawt(self.screen) self.log.draw(self.screen) pg.display.flip() def events(self): # catch all events here for event in pg.event.get(): if event.type == pg.QUIT: self.quit() if self.show_inventory: if event.type == pg.KEYDOWN: if event.key == pg.K_i: self.show_inventory = False elif event.type == pg.MOUSEBUTTONUP and event.button == 1: mouse_pos = pg.mouse.get_pos() self.inventory.check(mouse_pos) else: if event.type == pg.KEYDOWN: if event.key == pg.K_ESCAPE: self.quit() if event.key == pg.K_m: self.quit(save_map=True) if event.key == pg.K_a: self.player.move(dx=-1) if event.key == pg.K_d: self.player.move(dx=1) if event.key == pg.K_w: self.player.move(dy=-1) if event.key == pg.K_s: self.player.move(dy=1) if event.key == pg.K_SPACE: # if not self.player.is_firing: TODO maybe limit this? self.tick = True mouse_pos = pg.mouse.get_pos() self.player.fire_spell(mouse_pos) if event.key == pg.K_RETURN: self.tick = True if event.key == pg.K_RSHIFT or event.key == pg.K_LSHIFT: self.player.use_item() if event.key == pg.K_g: self.show_grid = not self.show_grid if event.key == pg.K_l: self.godmode = not self.godmode self.log.info(f"GODMODE ON: {self.godmode}") if event.key == pg.K_i: self.show_inventory = True if event.key == pg.K_o: print(f"group num walls = {len(self.walls)}") if event.key == pg.K_DOWN: self.log.update_place(change=1) if event.key == pg.K_UP: self.log.update_place(change=-1) elif event.type == pg.MOUSEBUTTONUP and event.button == 1: mouse_pos = pg.mouse.get_pos() self.player.inspect_space(mouse_pos) self.tick = True elif event.type == pg.MOUSEBUTTONUP and event.button == 3: mouse_pos = pg.mouse.get_pos() self.player.interact_space(mouse_pos) def get_sprite_at(self, x, y): for sprite in self.all_sprites: try: if sprite.x == x and sprite.y == y: return sprite except: pass return None def object_in_view(self, gx, gy): """ gx and gy are global quards """ # use the global position of the player to decide what to draw cur_g_x = self.player.gx cur_g_y = self.player.gy # need to massage the indexes so that (xmin, ymin) is (0, 0) on the view xmin = cur_g_x - 6 xmax = cur_g_x + 10 ymin = cur_g_y - 6 ymax = cur_g_y + 10 # if we are out of sight, despawn if gx < xmin or gx > xmax or gy < ymin or gy > ymax: return False return True def show_start_screen(self): pass def show_go_screen(self): pass