def __init__(self, overlayId, app): Overlay.__init__(self, OVERLAY_APP, overlayId) EventHandler.__init__(self) self.app = app # which app is this overlay tied to self.bounds.setAll(app.left, app.right, app.top, app.bottom) self.displayId = app.getDisplayId() self.aspectRatio = self.bounds.getWidth() / float(self.bounds.getHeight()) self.minAppSize = 300 # min app size in either direction self.z = self.app.getZvalue() self.__resetOverlay() self.capturedCorner = APP self.lastClickPos = (0,0) self.lastClickDeviceId = None self.overCorner = APP # register for the events that are fired when an app changes self.registerForEvent(EVT_APP_INFO, self.__onAppChanged) self.registerForEvent(EVT_Z_CHANGE, self.__onZChanged) # register for the events that are fired by devices self.registerForEvent(EVT_MOVE, self.__onOver) self.registerForEvent(EVT_CLICK, self.__onClick) self.registerForEvent(EVT_DRAG, self.__onDrag) self.registerForEvent(EVT_ROTATE, self.__onRotate) self.registerForEvent(EVT_ZOOM, self.__onZoom) self.registerForEvent(EVT_ARROW, self.__onArrow) self.registerForEvent(EVT_LEFT_WINDOW, self.__onLeftWindow) # register for the events from the special devices self.registerForEvent(EVT_MOVE_SPECIAL, self.__onSpecialMove) self.registerForEvent(EVT_ENTERED_WINDOW_SPECIAL, self.__onEnteredWindowSpecial) self.registerForEvent(EVT_LEFT_WINDOW_SPECIAL, self.__onLeftWindowSpecial)
def __init__(self, engine,localOptions): Mgr.__init__(self, engine) self.gameStarted = False self.winnerIndex = -1 self.lapsTillWin = localOptions.lapsTillWin self.textTint = (0.0,0.0,0.0) self.initialCountdownTime = 4 self.numRaces = 0 self.allPlayersReady = False # create all neccessary overlay panels self.mainMenu = Overlay(name = "MainMenu", pos = (0,150), size = (950,950), material = "MainMenu") self.finishPanel = Overlay(name = "ExitPanel", pos = (250,100), size = (500,500)) self.messagePanel = Overlay(name = "MessPanel", pos = (0,0), size = (1000,1000),material = None) # initialize values for finish panel self.finishPanel.addText("RACE OVER",130,30,30) self.finishPanel.addHorizontalDivider(60) self.finishPanel.addText("You Placed:",90,80,30) self.finalPlacement = self.finishPanel.addText(str(0),350,80,30) self.finishPanel.addText("Final Time:",70,120,30) self.finalTime = self.finishPanel.addText(str(0),320,120,30) self.finishPanel.addText("Press Enter to Play Again",50,380,20) self.finishPanel.addText("Press Escape or 'Q' to Exit",50,420,20) self.finishPanel.hideAll() #initialize values for message panel self.countdownText = self.messagePanel.addText(" ", 400,20,40) self.noServer = self.messagePanel.addText("No server found, looking...", 125,600,40,(1.0,1.0,1.0),(1.0,0.0,0.0)) self.waitingText = self.messagePanel.addText("Waiting for Players...", 200,400,40,(1.0,1.0,1.0),(1.0,0.0,0.0)) self.waitingText.hide() self.noServer.hide()
def __init__(self, app=None, direction=VERTICAL): Overlay.__init__(self, OVERLAY_SPLITTER) EventHandler.__init__(self, app) self.direction = direction self.__enlarged = False self.__scaleMultiplier = 4.0 self._canScale = False self.mouseOverScale = 1.0 self.setTransparency(255) self.z = BOTTOM_Z - 10 self.relPos = 0.5 # relative to the section it splits self._preCollapsedPos = self.relPos self.__buffer = int(20 * getGlobalScale()) self._collapsed = False self.registerForEvent(EVT_DRAG, self.__onDrag) self.registerForEvent(EVT_CLICK, self.__onClick) self.registerForEvent(EVT_MOVE, self.__onMove) self.registerForEvent(EVT_LEFT_WINDOW, self._onLeftWindow) self.registerForEvent(EVT_ENTERED_WINDOW, self._onEnteredWindow) if direction == VERTICAL: self.__image = opj("images", "vertical_divider.png") else: self.__image = opj("images", "horizontal_divider.png")
def __init__(self, app=None): Overlay.__init__(self, OVERLAY_BUTTON) EventHandler.__init__(self, app) # register for the events that are fired by devices self.registerForEvent(EVT_CLICK, self._onClick) self.registerForEvent(EVT_MOVE, self._onMove) self.registerForEvent(EVT_LEFT_WINDOW, self._onLeftWindow) self.registerForEvent(EVT_ENTERED_WINDOW, self._onEnteredWindow) # paths to images drawn for different button states self.__upImage = "images/default_button_up.png" self.__downImage = "" self.__overImage = "" self.__doPlaySound = True # button can be a toggle self._isToggle = False self.__radioFunc = True self.__clicked = False self._manual = False self._radio = False # current state of the button self.__state = UP_STATE # callbacks you can register self.__onDown = None self.__onUp = None self._lastDevice = None self.__minTimeBetweenClicks = 0.5 # by default, allow rapid successive clicks self.__lastUp = 0.0 self.__lastDown = 0.0
def __init__(self, app=None, label="", fontSize=NORMAL): """ If you pass in None for app, the widget will reside on the top layer above all apps but below pointers. """ Overlay.__init__(self, OVERLAY_LABEL) EventHandler.__init__(self, app) self.setLabel(label, fontSize) self.__drawBackground = True
def initialize(self, overlayId): Overlay.initialize(self, overlayId) # force a different initial state if self.__state != UP_STATE: newState = UP_STATE newState, self.__state = self.__state, newState self.setState(newState)
def __init__(self, parentItem, Z=1): Overlay.__init__(self, parentItem, Z) self.label = MetaItem(parent=self) self.label.setText('Empty') self.label.setFlags(QtGui.QGraphicsItem.ItemIsSelectable | QtGui.QGraphicsItem.ItemIsFocusable | QtGui.QGraphicsItem.ItemIsMovable | QtGui.QGraphicsItem.ItemIgnoresTransformations) self.menu = QtGui.QMenu() self.acts = {}
def __init__(self, app): Overlay.__init__(self, OVERLAY_APP) EventHandler.__init__(self, app) # must set size and pos first self._canScale = False self.setSize(1.0, 1.0) # same size as the app self.setPos(0.0, 0.0) # right over the app self._zOffset = APP_OVERLAY_Z self._allowSelection = True # some initial params self.minAppSize = 250 # min app size in either direction self.capturedCorner = APP self.lastClickPos = (0,0) self.lastClickDeviceId = None self.overCorner = APP self.bounds = self.getBounds() # from EventHandler base class self._clickDownTime = 0.0 self.__startedDrag = False # for accidental touches... # if less than X seconds has passed between two double clicks, # maximize to the whole display, otherwise, just within the section self._lastDoubleClick = 0.0 self.__maximizeThreshold = 1.3 # seconds between two double clicks... # for closing apps self.__multiTouchStartTime = -1 self.org = getLayoutOrganization() # get the filename from appLauncher if "imageviewer" in app.getName().lower() or \ "mplayer" in app.getName().lower() or \ "stereo3d" in app.getName().lower() or \ "pdf" in app.getName().lower(): # get the config info from the right appLauncher if app.getLauncherId() != "none": appLauncher = xmlrpclib.ServerProxy("http://" + app.getLauncherId()) try: res = appLauncher.getAppConfigInfo( app.getAppId() ) except: print "\nUnable to connect to appLauncher on", app.getLauncherId(), "so not saving this app: ", app.getName() else: print "appLauncher.getAppConfigInfo : ", res if res != -1: configName, optionalArgs = res if "imageviewer" in app.getName().lower(): # filename at the beginning of the command line for images self.fullpathname = optionalArgs.split()[0].strip('"') self.filename = os.path.basename( self.fullpathname ) else: # filename at the end of the command line for movies self.fullpathname = optionalArgs.split()[-1].strip('"') self.filename = os.path.basename( self.fullpathname ) if getShowWindowTitleBar(): self.setTooltip(self.filename, LARGER)
def __init__(self, app=None, direction=HORIZONTAL): """ If you pass in None for app, the widget will reside on the top layer above all apps but below pointers. """ Overlay.__init__(self, OVERLAY_SIZER) EventHandler.__init__(self, app) self.__direction = direction # let the events pass through since we are transparent self._eventTransparent = True
def __init__(self, parentItem, Z=1, startLine=True): Overlay.__init__(self, parentItem, Z=Z) self.opt = set( ['startLine', 'slope', 'const', 'domain', 'roi', 'crop']) # Create base and height lines self.line = QtGui.QGraphicsLineItem(parent=self) if not startLine: self.pen.setColor(QtGui.QColor('red')) self.line.setPen(self.pen) self.startLine = startLine
def __init__(self, overlayId): Overlay.__init__(self, OVERLAY_POINTER, overlayId) self.state = RESET self.lastOrientation = 0 self.inApp = False self.__savedState = [self.state, self.lastOrientation, self.inApp] # some devices only produce one analog event so set it here if so # (e.g. a zoom-only puck) # this is used when the device enters an application in order to show # the correct pointer shape describing what the device can do self.onlyAnalogEvent = None
def loadScorePanel(self): myMesh = self.engine.entMgr.entities[self.engine.entMgr.playerIndex].mesh self.scorePanel = Overlay(pos = (50,575), size = (950,100)) for i in range(1,5): self.scorePanel.addVerticalDivider(190* i) self.scorePanel.addHorizontalDivider(40) # establish partial text color based on color of ship model if myMesh.count("blue") > 0: self.textTint = (0.0,0.6,1.0) elif myMesh.count("purple") > 0: self.textTint = (0.25,0.0,0.5) elif myMesh.count("tan") > 0: self.textTint = (1.0,0.8,0.6) elif myMesh.count("green") > 0: self.textTint = (0.0,1.0,0.0) elif myMesh.count("gray") > 0: self.textTint = (0.25,0.25,0.25) elif myMesh.count("checkard") > 0: self.textTint = (0.0,0.0,0.0) # initialize all text in panel with the specified color self.scorePanel.addText("PLACE:",30,10,30) self.placeText = self.scorePanel.addText(str(0),85,50,30,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("LAP:",250,10,30) self.lapText = self.scorePanel.addText(str(0),255,50,30,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("SPEED:",410,10,30) self.speedText = self.scorePanel.addText(str(0),400,50,25,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("TIME:",620,10,30) self.timeText = self.scorePanel.addText(str(0),640,50,30,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("TIME/LAP:",790,15,20) self.timePerLapText = self.scorePanel.addText("--",840,50,30,(1.0,1.0,1.0),self.textTint)
def __init__(self, port=DEFAULT_MANAGER_PORT): signalutil.Runner.__init__(self) self.port = port self.overlay = Overlay() self.name_store = NameStore(self.overlay) self.type_store = TypeStore(self.overlay) self.migration_store = MigrationStore(self.overlay) self.script_store = ScriptStore(self.overlay) self.socket_store = SocketStore(self.overlay)
def __init__(self, app=None): """ If you pass in None for app, the widget will reside on the top layer above all apps but below pointers. """ Overlay.__init__(self, OVERLAY_PANEL) EventHandler.__init__(self, app) self.registerForEvent(EVT_DRAG, self.__onDrag) self.registerForEvent(EVT_CLICK, self._onClick) self._allowDrag = False # ONLY USE WITH ABSOLUTE POSITION!!! (wont work when aligned) self.__fitInWidth = True self.__fitInHeight = True self.__borderWidth = 0 self._zOffset -= 0.01 # just below the other widgets self.px = self.py = 0
def __init__(self, x=0, y=0): Overlay.__init__(self, OVERLAY_POINTER) EventHandler.__init__(self) self.setSize(50,75) self.setPos(x,y) self.setDrawOrder(POST_DRAW) self.state = RESET self.lastOrientation = 0 self.inApp = False self.__savedState = [self.state, self.lastOrientation, self.inApp] # some devices only produce one analog event so set it here if so # (e.g. a zoom-only puck) # this is used when the device enters an application in order to show # the correct pointer shape describing what the device can do self.onlyAnalogEvent = None self._eventTransparent = True # so that we dont receive our own clicks... self.__image = ""
def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.viewport_y = 0 # top visible line self.imagemode = False self.image = None self.scroll_height = 0 self.scroll_width = 0 self.timer = QTimer(self) self.backuptimer = QTimer(self) self.connect(self.timer, SIGNAL("timeout()"), self.analysis_timer) self.connect(self.backuptimer, SIGNAL("timeout()"), self.backup_timer) self.backuptimer.start(30000) self.undotimer = QTimer(self) self.connect(self.undotimer, SIGNAL("timeout()"), self.trigger_undotimer) self.blinktimer = QTimer(self) self.blinktimer.start(500) self.connect(self.blinktimer, SIGNAL("timeout()"), self.trigger_blinktimer) self.show_cursor = True self.boxcolors = [QColor("#DC322F"), QColor("#268BD2"), QColor("#D33682"), QColor("#B58900"), QColor("#2AA198"), QColor("#859900")] self.setCursor(Qt.IBeamCursor) # Semi-transparent overlay. # Used to display heat-map visualisation of profiler info, etc. self.overlay = Overlay(self) # Start hidden, make (in)visible with self.toggle_overlay(). self.overlay.hide() # Set to True if the user wants to see tool visualisations. self.show_tool_visualisations = True # Set True if Eco should be running profiler and other tools, # continuously in the background. self.run_background_tools = False
import rospy from math import pi, cos, sin from eqep import eQEP from std_msgs.msg import Float32 from nav_msgs.msg import Odometry from time import sleep from overlay import Overlay from tf import transformations # # this is probably fine for encoders for now but there are some # inherent granularity issues with using the eQEPs for velocity # control; probably want to switch to PRUs at some point # # overlay to device tree Overlay.apply("bone_eqep0") Overlay.apply("bone_eqep2b") # ros stuff rospy.init_node('odom_publisher') pub_left = rospy.Publisher('/wheel_left/state', Float32, queue_size=1) pub_right = rospy.Publisher('/wheel_right/state', Float32, queue_size=1) pub_odom = rospy.Publisher('/wheel_odom', Odometry, queue_size=3) # initialiaze eQEPs eqep_left = eQEP(eQEP.eQEP2, eQEP.MODE_ABSOLUTE) eqep_right = eQEP(eQEP.eQEP0, eQEP.MODE_ABSOLUTE) # set update frequency frequency = rospy.get_param('frequency', 30) period = 1000000000 / frequency
class GameMgr(Mgr): def __init__(self, engine,localOptions): Mgr.__init__(self, engine) self.gameStarted = False self.winnerIndex = -1 self.lapsTillWin = localOptions.lapsTillWin self.textTint = (0.0,0.0,0.0) self.initialCountdownTime = 4 self.numRaces = 0 self.allPlayersReady = False # create all neccessary overlay panels self.mainMenu = Overlay(name = "MainMenu", pos = (0,150), size = (950,950), material = "MainMenu") self.finishPanel = Overlay(name = "ExitPanel", pos = (250,100), size = (500,500)) self.messagePanel = Overlay(name = "MessPanel", pos = (0,0), size = (1000,1000),material = None) # initialize values for finish panel self.finishPanel.addText("RACE OVER",130,30,30) self.finishPanel.addHorizontalDivider(60) self.finishPanel.addText("You Placed:",90,80,30) self.finalPlacement = self.finishPanel.addText(str(0),350,80,30) self.finishPanel.addText("Final Time:",70,120,30) self.finalTime = self.finishPanel.addText(str(0),320,120,30) self.finishPanel.addText("Press Enter to Play Again",50,380,20) self.finishPanel.addText("Press Escape or 'Q' to Exit",50,420,20) self.finishPanel.hideAll() #initialize values for message panel self.countdownText = self.messagePanel.addText(" ", 400,20,40) self.noServer = self.messagePanel.addText("No server found, looking...", 125,600,40,(1.0,1.0,1.0),(1.0,0.0,0.0)) self.waitingText = self.messagePanel.addText("Waiting for Players...", 200,400,40,(1.0,1.0,1.0),(1.0,0.0,0.0)) self.waitingText.hide() self.noServer.hide() def loadScorePanel(self): myMesh = self.engine.entMgr.entities[self.engine.entMgr.playerIndex].mesh self.scorePanel = Overlay(pos = (50,575), size = (950,100)) for i in range(1,5): self.scorePanel.addVerticalDivider(190* i) self.scorePanel.addHorizontalDivider(40) # establish partial text color based on color of ship model if myMesh.count("blue") > 0: self.textTint = (0.0,0.6,1.0) elif myMesh.count("purple") > 0: self.textTint = (0.25,0.0,0.5) elif myMesh.count("tan") > 0: self.textTint = (1.0,0.8,0.6) elif myMesh.count("green") > 0: self.textTint = (0.0,1.0,0.0) elif myMesh.count("gray") > 0: self.textTint = (0.25,0.25,0.25) elif myMesh.count("checkard") > 0: self.textTint = (0.0,0.0,0.0) # initialize all text in panel with the specified color self.scorePanel.addText("PLACE:",30,10,30) self.placeText = self.scorePanel.addText(str(0),85,50,30,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("LAP:",250,10,30) self.lapText = self.scorePanel.addText(str(0),255,50,30,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("SPEED:",410,10,30) self.speedText = self.scorePanel.addText(str(0),400,50,25,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("TIME:",620,10,30) self.timeText = self.scorePanel.addText(str(0),640,50,30,(1.0,1.0,1.0),self.textTint) self.scorePanel.addText("TIME/LAP:",790,15,20) self.timePerLapText = self.scorePanel.addText("--",840,50,30,(1.0,1.0,1.0),self.textTint) def tick(self, dtime): # if networking is enabled, show text telling player that the game is still giving other players an oppertunnity to join. if self.engine.netMgr.networkingEnabled and not self.gameStarted and self.engine.gfxMgr.cameraMode != "Main Menu" and not self.allPlayersReady: if int(self.engine.netMgr.timeToWaitForPlayers) % 2 == 0: self.waitingText.hide() else: self.waitingText.show() # before the race starts show a countdown elif not self.gameStarted and self.engine.gfxMgr.cameraMode != "Main Menu" and self.allPlayersReady: self.waitingText.hide() if self.initialCountdownTime == 4 and self.numRaces == 0: self.loadScorePanel() self.initialCountdownTime -= dtime if self.initialCountdownTime <= 1: self.countdownText.setCaption(" GO!!! ") self.countdownText.setColourTop((0.0,0.0,1.0)) self.gameStarted = True elif self.initialCountdownTime <= 2: self.countdownText.setCaption("1 2 3") self.countdownText.setColourTop((0.0,1.0,0.0)) elif self.initialCountdownTime <= 3: self.countdownText.setCaption("1 2") self.countdownText.setColourTop((1.0,1.0,0.0)) elif self.initialCountdownTime <= 4: self.countdownText.setCaption("1") self.countdownText.setColourTop((1.0,0.0,0.0)) # once the countdown has finished, and as long as no one has won yet, keep performing game operations. elif self.gameStarted and self.winnerIndex == -1: placementArray = [] self.initialCountdownTime -= dtime if self.initialCountdownTime <= 0: self.countdownText.hide() for ent in self.engine.entMgr.entities: ent.totalTime += dtime ent.positionAngle = math.atan2(ent.pos.z,ent.pos.x) # if angle is less than 0, turn it in to it's positive representation if ent.positionAngle < 0: ent.positionAngle += math.pi *2 # check to see if this ship has passed first checkpoint if ent.positionAngle > (math.pi + math.pi/2) -.2 and ent.positionAngle < (math.pi + math.pi/2) and ent.checkpoint == 0: ent.checkpoint =1 # check to see if this ship has passed second checkpoint elif ent.positionAngle > math.pi -.2 and ent.positionAngle < math.pi and ent.checkpoint == 1: ent.checkpoint =2 # check to see if this ship has passed third checkpoint elif ent.positionAngle > (math.pi / 2) -.2 and ent.positionAngle < (math.pi / 2)and ent.checkpoint == 2: ent.checkpoint =3 # check to see if this ship has completed a lap elif ent.positionAngle > (math.pi*2) -.2 and ent.positionAngle < (math.pi*2)and ent.checkpoint == 3: ent.checkpoint = 0 ent.lap += 1 placementArray.append([ent.shipId, ent.lap * 4 + ent.checkpoint *1,ent.positionAngle]) # update score label information if ent.shipId == self.engine.entMgr.playerIndex: self.placeText.setCaption(str(ent.placement)) self.lapText.setCaption(str(ent.lap) + "/" + str(self.lapsTillWin)) # if speed is 500, print MAX if ent.speed < 500: self.speedText.setPosition(400,50) self.speedText.setCaption(str(ent.speed) + " mph") else: self.speedText.setPosition(445,50) self.speedText.setCaption("MAX") # print total time in format (m:ss) minutes = int(ent.totalTime / 60) seconds = int(ent.totalTime % 60) if seconds < 10: self.timeText.setCaption(str(minutes) + ":0" + str(seconds)) else: self.timeText.setCaption(str(minutes) + ":" + str(seconds)) # print time per lap in format (m:ss) if ent.lap >0: self.timePerLapText.setPosition(815,50) minutes = int(ent.totalTime /ent.lap / 60) seconds = int(ent.totalTime /ent.lap % 60) if seconds < 10: self.timePerLapText.setCaption(str(minutes) + ":0" + str(seconds)) else: self.timePerLapText.setCaption(str(minutes) + ":" + str(seconds)) #check to see if this player has finished there last lap and has won the game if ent.lap == self.lapsTillWin: self.engine.gfxMgr.cameraMode = "End View" self.scorePanel.hideAll() self.winnerIndex = ent.shipId # establish current placements for i in range(len(placementArray)): for j in range(len(placementArray) -1): if placementArray[j][1] < placementArray[j+1][1] or (placementArray[j][1] == placementArray[j+1][1] and placementArray[j][2] > placementArray[j+1][2]): temp = placementArray[j+1] placementArray[j+1] = placementArray[j] placementArray[j] = temp for i in range(len(placementArray)): self.engine.entMgr.entities[placementArray[i][0]].placement = i +1 # if the game has been won, print result panel to screen if self.winnerIndex != -1: myEnt = self.engine.entMgr.entities[self.engine.entMgr.playerIndex] myEnt.isReady = False # display medal if myEnt.placement == 1: self.finishPanel.panel.setMaterialName("Final-Gold") elif myEnt.placement == 2: self.finishPanel.panel.setMaterialName("Final-Silver") else: self.finishPanel.panel.setMaterialName("Final-Bronze") #display final placement and time self.finalPlacement.setCaption(str(myEnt.placement)) minutes = int(myEnt.totalTime / 60) seconds = int(myEnt.totalTime % 60) if seconds < 10: self.finalTime.setCaption(str(minutes) + ":0" + str(seconds)) else: self.finalTime.setCaption(str(minutes) + ":" + str(seconds)) self.finishPanel.showAll() def resetGame(self): # reset game variables self.numRaces += 1 self.winnerIndex = -1 self.timePerLapText.setCaption("--") self.timePerLapText.setPosition(840,50) self.initialCountdownTime = 4 self.gameStarted = False self.allPlayersReady = False self.countdownText.setCaption("") self.countdownText.show() self.engine.netMgr.timeToWaitForPlayers = 10 # reset all values for all entities for i in range(len(self.engine.entMgr.entities)): self.engine.entMgr.entities[i].pos = ogre.Vector3(const.INNER_RADIUS + 100 +(40*i),50,0) self.engine.entMgr.entities[i].dir = ogre.Vector3(0,0,-1) self.engine.entMgr.entities[i].speed = 0 self.engine.entMgr.entities[i].colVel = ogre.Vector3(0,0,0) self.engine.entMgr.entities[i].updateQueue = deque(maxlen = 1000) self.engine.entMgr.entities[i].placement = 0 self.engine.entMgr.entities[i].lap = 0 self.engine.entMgr.entities[i].checkpoint = 0 self.engine.entMgr.entities[i].positionAngle = 0 self.engine.entMgr.entities[i].totalTime = 0.0 self.engine.entMgr.entities[i].pitch = 0.0 self.engine.entMgr.entities[i].roll = 0.0
class Grid(object): def __init__(self, geometry, grid_update): self.x1 = 0 self.y1 = 0 self.x2 = geometry.width - 1 self.y2 = geometry.height - 1 self.click_type = 0 self.grid_update = grid_update self.overlay = Overlay(geometry, handler=self.key_event) self.update_overlay() def key_event(self, key, modifiers): if key == Qt.Key_Escape: self.exit() elif key == Qt.Key_Return: if Qt.ShiftModifier & modifiers: self.click_type = 3 else: self.click_type = 1 self.exit() elif key in KEY_MAP: self.resize(*KEY_MAP[key]) self.update_overlay() def exit(self): self.overlay.exit() def update_overlay(self): gridlines = self.make_gridlines() self.overlay.set_gridlines(gridlines) self.overlay.update() self.grid_update(self) def click_pos(self): xpos = int(round((self.x1 + self.x2) / 2)) ypos = int(round((self.y1 + self.y2) / 2)) return xpos, ypos def resize(self, xl, yl): dx = (self.x2 - self.x1) / 9 dy = (self.y2 - self.y1) / 9 xs = [int(round(self.x1 + i * dx)) for i in range(10)] ys = [int(round(self.y1 + i * dy)) for i in range(10)] if xl is not None: self.x1 = xs[xl + 4] self.x2 = xs[xl + 5] if yl is not None: self.y1 = ys[yl + 4] self.y2 = ys[yl + 5] def make_gridlines(self): dx = (self.x2 - self.x1) / 9 dy = (self.y2 - self.y1) / 9 for i in range(8): x = int(round(self.x1 + i * dx + dx)) y = int(round(self.y1 + i * dy + dy)) if i in (2, 5): yield MajorLine(x, self.y1, x, self.y2) yield MajorLine(self.x1, y, self.x2, y) else: yield MinorLine(x, self.y1, x, self.y2) yield MinorLine(self.x1, y, self.x2, y)
class DrawHandler(threading.Thread): def __init__(self, handler): threading.Thread.__init__(self) self.max_rate = 60 self.rate = Rate(self.max_rate) self.cursor_pos = (0, 0) self.image = cv2.imread('test2.jpg') self.width = self.image.shape[1] self.height = self.image.shape[0] self.screen = None self.overlay = Overlay() self.name = "Roundabout Map" cv2.namedWindow(self.name) cv2.setMouseCallback(self.name, self.mouse_event) self.event = 200 self.handler = handler handler.overlay = self.overlay def mouse_event(self, event, x, y, flags, param): self.event = 200 self.cursor_pos = (x, y) self.handler.mouse_event(event, x, y) def run(self): while True: key = cv2.waitKey(1) & 0xFF if key == 27: self.handler.shutdown() self.shutdown() break self.handler.keyboard_event(key) self.handler.overlay_event() if self.handler.update(): self.screen = copy.copy(self.image) for node in self.handler.graph.nodes: cv2.circle(self.screen, (node.pos[0], node.pos[1]), 2, (0, 0, 255), 2) for lane in node.lanes: cv_ext.draw_arrowed_polyline(self.screen, lane.points, (0, 255, 255)) for lane in self.handler.graph.lanes: cv2.polylines(self.screen, [np.array(lane.polygon)], False, (0, 255, 255)) if self.handler.mark is not None: cv2.circle(self.screen, (self.handler.mark[0], self.handler.mark[1]), 5, (0, 0, 255), 1) if self.handler.snapy is not None: cv2.circle(self.screen, (self.handler.snapy[0], self.handler.snapy[1]), 5, (0, 0, 0), 1) for border in self.handler.graph.borders: cv2.line(self.screen, (border.node_a.pos[0], border.node_a.pos[1]), (border.node_b.pos[0], border.node_b.pos[1]), (255, 0, 0), 2) vis = copy.copy(self.screen) self.overlay.setCursor(self.cursor_pos) self.overlay.draw(vis) self.overlay.clear() if self.event > 1: self.event -= 1 cv2.imshow(self.name, vis) self.rate.sleep_rate(self.event) def shutdown(self): cv2.destroyAllWindows()
from loader import Loader from overlay import Overlay from relocator import Relocator if __name__ == "__main__": loader = Loader("start.exe") loader.fetch_header() relocator = Relocator(loader) program = loader.load_program() overlay = Overlay("game.ovr", program) overlay.overlay_code() header = loader.header print(header) for instruction in program: print("%s %s" % (instruction.address, instruction))
def run(nsjail_bin, chroot, source_dir, command, android_target, dist_dir=None, build_id=None, max_cpus=None, user_id=None, group_id=None): """Run inside an NsJail sandbox. Args: nsjail_bin: A string with the path to the nsjail binary. chroot: A string with the path to the chroot. source_dir: A string with the path to the Android platform source. command: A list of strings with the command to run. android_target: A string with the name of the target to be prepared inside the container. dist_dir: A string with the path to the dist directory. build_id: A string with the build identifier. max_cpus: An integer with maximum number of CPUs. user_id: An integer with the user ID to run the build process under. group_id: An integer with the group ID to run the build process under. Returns: A list of commands that were executed. Each command is a list of strings. """ executed_commands = [] if user_id and group_id: commands = create_user(user_id, group_id) executed_commands.extend(commands) os.setgid(group_id) os.setuid(user_id) overlay = None # Apply the overlay for the selected Android target # to the source directory if overlays are present if os.path.exists(os.path.join(source_dir, 'overlays')): overlay = Overlay(android_target, source_dir) script_dir = os.path.dirname(os.path.abspath(__file__)) config_file = os.path.join(script_dir, 'nsjail.cfg') nsjail_command = [ nsjail_bin, '--bindmount', source_dir + ':/src', '--chroot', chroot, '--env', 'USER=android-build', '--config', config_file ] if dist_dir: nsjail_command.extend([ '--bindmount', dist_dir + ':/dist', '--env', 'DIST_DIR=/dist' ]) if build_id: nsjail_command.extend(['--env', 'BUILD_NUMBER=%s' % build_id]) if max_cpus: nsjail_command.append('--max_cpus=%i' % max_cpus) nsjail_command.append('--') nsjail_command.extend(command) print('NsJail command:') print(' '.join(nsjail_command)) subprocess.check_call(nsjail_command) executed_commands.append(nsjail_command) # Strip out overlay del overlay return executed_commands
def unscale(self, factor): Overlay.unscale(self, factor) self.line.setPen(self.pen)
def unscale(self, factor): Overlay.unscale(self, factor) self.up()
class Manager(signalutil.Runner): def __init__(self, port=DEFAULT_MANAGER_PORT): signalutil.Runner.__init__(self) self.port = port self.overlay = Overlay() self.name_store = NameStore(self.overlay) self.type_store = TypeStore(self.overlay) self.migration_store = MigrationStore(self.overlay) self.script_store = ScriptStore(self.overlay) self.socket_store = SocketStore(self.overlay) def begin(self): loc = ManagerExternalInterface( self.overlay, self.name_store, self.type_store, self.migration_store, self.script_store, self.socket_store ) port = self.port while port < self.port + 10: if self.takeport(port, loc): self.port = port break port = port + 1 log.debug(self, "listening on port %s" % port) here = socket.gethostbyname(socket.gethostname()) + ":%d" % self.port ipfinder.create_ip_server(DEFAULT_MANAGER_PORT - 1) self.overlay.here(here) self.overlay.populate(sys.argv) vis.add_manager(here) self.shell() def takeport(self, port, loc): try: self.__valve = rpc.RPCValve(port, loc, log) self.__valve.listen() return True except socket.error: return False def shutdown(self): log.debug(self, "shutting down") try: self.__valve.shutdown() print "closing port" except socket.error as e: print "ERROR:", e.args def __str__(self): return "Manager" def shell(self): print "Welcome to Stage#" execute = True while execute: if True: print (gethostname() + ":%d>" % self.port), command = sys.stdin.readline().strip() if command == "exit": execute = False else: try: exec (command) except: print "command not found" self.shutdown() sys.exit()
def main(): """ Sets up all the relevent object needed to run the game. This includes the game engine, player, and all enemies in the game. The player and enemies load thier sprites from a list of paths in a json file that is loaded and referenced in a dict at the start. Once initalization finishes the game loop is run until the user exits. """ engine = neon_engine.NeonEngine('Neon Souls') engine.init_pygame() with open('player_sprites.json', 'r') as p_file: player_sprites = json.load(p_file) with open('sentinal_sprites.json') as file: sentinal_sprites = json.load(file) player_static = player_sprites['static_sprites'] player_walking = player_sprites['walking_sprites'] player_running = player_sprites['running_sprites'] sentinal_sprites = sentinal_sprites['sprite_list'] player = Player(player_static, player_walking, player_running, (128, 128), 'default', 2, 300, 400) engine.player_instance = player sentinal1 = SentinalEnemy(sentinal_sprites, (100, 100), [(400, 500), (600, 500)], engine.kill_enemy, 2, 300, 475) sentinal2 = SentinalEnemy(sentinal_sprites, (100, 100), [(1100, 0), (1300, 0)], engine.kill_enemy, 2, 1200, 400) sentinal3 = SentinalEnemy(sentinal_sprites, (100, 100), [(1500, 0), (1700, 0)], engine.kill_enemy, 2, 1600, 450) engine.enemy_list.append(sentinal1) engine.enemy_list.append(sentinal2) engine.enemy_list.append(sentinal3) gravity_manager = GravityManager() gravity_manager.add_gravity('default', (0, 15)) gravity_manager.add_object(player) # create background and level init_map(engine, player, gravity_manager) overlay = Overlay(player) engine.objects.append(overlay) engine.drawables.add(overlay) pygame.time.set_timer(pygame.USEREVENT + 1, 1000 // league.Settings.gameTimeFactor) engine.movement_function = player.move_player engine.action_function = fire engine.physics_functions.append(player.process_gravity) engine.events[pygame.QUIT] = engine.stop engine.run()
def main(args=None): overlay = Overlay() overlay.setupProtocol() overlay.startOverlay()
from PyQt5.QtCore import QTimer from fbs_runtime.application_context.PyQt5 import ApplicationContext from overlay import Overlay if __name__ == '__main__': app_context = ApplicationContext() overlay = Overlay(app_context) gui_updater_timer = QTimer(overlay) gui_updater_timer.timeout.connect(overlay.gui_updater) gui_updater_timer.start(100) overlay.show() app_context.app.exec_()
class App(Configurable): # # CLASS VARIABLES # # data about this program PRG_NAME = 'Scrapless' PRG_VERS = '1.0.1.4' # path for config file SLF_PATH = './data/json/config/config.json' # path to manifest folder MNF_PATH = 'C:/ProgramData/Epic/EpicGamesLauncher/Data/Manifests/' # logging paths LOG_PATH = './logging/log/' ERR_PATH = './logging/err/' IMG_PATH = './logging/img/' # max exceptions before abandoning the reading MAX_EXC = 5 # time variables LOOP_INTER = 0.2 BNTY_INTER = 1.5 LBBY_INTER = 0.25 LOOT_INTER = 0.5 def __init__(self): # PREPARE LOGGING FIRST TO ENSURE # THE ABILITY TO OUTPUT ERROR LOGS # # create logging folders self._makeLogDirs() # initialise the logger self.logger = self._setLogger() # catch exceptions to log them try: # call parent class constructor Configurable.__init__(self, self.SLF_PATH) # initialise overlay self.overlay = Overlay(f'{self.PRG_NAME.upper()} {self.PRG_VERS}') # point pytesseract at tesseract installation self._setPyTesseract() # initialise a lobby reader self.lobby_reader = LobbyReader() # initialise a loot reader self.loot_reader = LootReader() # initialise a bounty reader self.bounty_reader = BountyReader() # initialise a data sender self.data_sender = DataSender() # read user from config file self.user = self._setUser() # read game patch self.patch = self._setGamePatch() # initialise screen capture as empty self.screen_capture = None # data holders self.bounty_data = {} self.lobby_data = {} self.loot_data = [] # exception counter for repeated issue handling self.exc_counter = 0 # welcome the user self.welcomeMessage() except Exception as e: # log the exception self.logger.error(str(e)) # shut down the app quit() ''' Capture new screenshot and store it within the instance of this class ''' def screenCap(self): # take the screencap screencap = pyautogui.screenshot(region=(0, 0, 1920, 1080)) # overwrite the capture with screencap converted to a numpy array self.screen_capture = np.array(screencap) ''' Main method of operation, calls associated readers to detect the screen and read it out if recognised. ''' def processScreen(self): # process the lobby if needed self._processLobby() # process the loot if needed self._processLoot() # process bounty draft if needed self._processBounty() # submit data if needed self._submitData() ''' Method for quickly clearing all data in the app ''' def clearData(self): # return data holders to base state self.bounty_data = {} self.lobby_data = {} self.loot_data = [] ''' Method for writing out a welcome message in the application ''' def welcomeMessage(self): self.logger.info(f'==== WELCOME TO SCRAPLESS {self.PRG_VERS} ====') self.logger.info(f'Dauntless ver {self.patch}') self.logger.info(f'Username set to {self.user}') print('\n') ''' Method for printing out an output to logs and to overlay This is a convenience function to reduce clutter and keep user information level high ''' def writeOutput(self, text, colour): # only call the overlay method if said overlay is enabled if self.overlay: self.overlay.writeLine(text.replace('\n', ''), colour) # write out to log self.logger.info(text) # in case of a success if colour == 'success': # reset exception counter self.exc_counter = 0 # in case of error if colour == 'error': # save current screen cv2.imwrite(f'{self.IMG_PATH}{uuid4()}.png', cv2.cvtColor(self.screen_capture, cv2.COLOR_RGB2BGR)) # clear data self.clearData() ''' Internal method for keeping track of repeating reading issues; clears all data after enough issues happened ''' def _incrementException(self): # increment exception counter self.exc_counter += 1 # check if exception count exceeded max if self.exc_counter >= self.MAX_EXC: # write out an error message self.writeOutput( f'Repeated issues detected. Screenshot saved, all data flushed', 'error') # reset exception counter self.exc_counter = 0 ''' Method for creating folders for logging In: nothing Out: nothing ''' def _makeLogDirs(self): # iterate over necessary paths for path in [self.LOG_PATH, self.ERR_PATH, self.IMG_PATH]: # create folder if it does not exist if not os.path.exists(path): os.makedirs(path) ''' Internal method for detecting and processing bounty draft Updates bounty data as a result, unless an exception happens ''' def _processBounty(self): # read only if both bounty and loot data is empty if len(self.bounty_data) <= 0 and len(self.loot_data) <= 0: # proceed if draft can be detected if self.bounty_reader.detectDraftStart(self.screen_capture): # inform the user about the fact self.writeOutput(f'Bounty draft detected, processing...', 'info') # wait out the initial animation time.sleep(self.BNTY_INTER) # enter a loop of attempting to read the bounty self._processBountyLoop() ''' Convenience function to keep attempting a bounty read until succeeding or detecting that user exited the screen ''' def _processBountyLoop(self): # keep looping until valid bounty was read, or the user left the draft screen while len(self.bounty_data ) <= 0 and not self.bounty_reader.detectDraftEnd( self.screen_capture): # capture a new screenshot self.screenCap() # attempt to read the bounty try: # store the data self.bounty_data = self.bounty_reader.readScreen( self.screen_capture) # inform the user self.writeOutput( f'{self.bounty_data["rarity"]} bounty detected. Awaiting draft end...', 'success') # in case illegal value was found except ValueError as e: self.writeOutput(str(e), 'warning') # wait briefly to get a better screen read time.sleep(self.LOOP_INTER) ''' Internal method for detecting and processing lobby screen more functional Updates lobby data as a result, unless an exception happens ''' def _processLobby(self): # try to read lobby only if no hunt data yet if len(self.lobby_data) <= 0: # detect if the screen is a lobby if self.lobby_reader.detectScreen(self.screen_capture): # inform about detection self.writeOutput(f'Lobby screen detected, processing...', 'info') # wait briefly to avoid unnecessary errors time.sleep(self.LBBY_INTER) # enter the lobby-reading loop self._processLobbyLoop() ''' Convenience function to keep attempting a lobby read until succeeding or detecting that user exited the screen ''' def _processLobbyLoop(self): # while we can still see the lobby and we have no lobby data while self.lobby_reader.detectScreen( self.screen_capture) and len(self.lobby_data) <= 0: # update screen grab self.screenCap() # attempt reading the screen try: # process lobby screen and save the data self.lobby_data = self.lobby_reader.readScreen( self.screen_capture) # write appropriate output self._processLobbyOutput() # handle an exception except ValueError as e: # communicate the exception to the user self.writeOutput(str(e), 'warning') # wait briefly to get a better screen read time.sleep(self.LOOP_INTER) ''' Convenience function encompassing all possible text output for when the program has read the lobby without any issues ''' def _processLobbyOutput(self): # get data to memory briefly, to simplify access data = self.lobby_data # if trial screen if 'Trial' in data['tier']: # report on trial tier self.writeOutput(f'{data["tier"]} detected', 'success') # otherwise, if escalation screen elif data['escalation'] != '': # report on escalation self.writeOutput( f'Valid hunt detected: {data["escalation"]}. ' + f'Loot data won\'t be recorded.', 'info') # otherwise, if actual behemoth elif data['behemoth'] != '': # report read data self.writeOutput( f'Valid hunt detected -- T{data["threat"]} ' + f'{data["behemoth"] if data["behemoth"] != data["tier"] else ""}' + f'{", " if data["behemoth"] != data["tier"] else ""}' + f'{data["tier"]} {data["type"]}. ' + f'Awaiting loot screen...', 'success') ''' Internal method for detecting and processing loot screen Updates loot data as a result, unless an exception happens In: none Out: none ''' def _processLoot(self): # try to read loot only if lobby data present if len(self.lobby_data) > 0 and len(self.loot_data) <= 0: # if trial, detect for trial end screen if 'Trial' in self.lobby_data['tier']: # check for trial end screen if self.loot_reader.detectTrialEnd(self.screen_capture): # inform the user, abandon processing self.writeOutput(f'{self.lobby_data["tier"]} has ended', 'success') self.clearData() # otherwise detect for loot screen else: # detect if screen is a loot screen if self.loot_reader.detectLootScreen(self.screen_capture): # check if the hunt was an Escalation if self.lobby_data['escalation'] != '': # inform the user, abandon processing self.writeOutput( f'Escalation run ended, no data will be submitted', 'success') self.clearData() # otherwise enter the loop of reading the screen else: # wait briefly to ensure animation end time.sleep(self.LOOT_INTER) # start the loop self._processLootLoop() ''' Convenience function for loot screen reading loop ''' def _processLootLoop(self): # only try reading until we have loot data or until we leave the screen while len(self.loot_data) <= 0 and self.loot_reader.detectLootScreen( self.screen_capture) and len(self.lobby_data) > 0: # take a new screencap self.screenCap() # process basic loot screen data data = self.loot_reader.readScreen(self.screen_capture) # check if the party was defeated if data['defeat']: # inform the user, abandon processing self.writeOutput(f'Party defeated, no data will be submitted', 'warning') self.clearData() # otherwise, check if valid hunt elif data['behemoth'] == self.lobby_data[ 'behemoth'] or self.lobby_data[ 'behemoth'] in self.lobby_reader.valid_hunts.keys(): # inform that more in-depth reading will now take place self.writeOutput(f'Loot screen detected, verifying...', 'info') # update lobby data self.lobby_data.update(data) # attempt to read the loot try: # store loot data in memory self.loot_data = self.loot_reader.readLoot( self.screen_capture, self.lobby_data['behemoth']) self.loot_data = self._processLootData() # inform that everything is okay self.writeOutput( f'Valid loot data read, you may now leave the screen', 'success') # in case OCR read anomalous stack of items, handle error internally except ValueError as e: self.writeOutput(str(e), 'error') # inform the reading will be attempted again else: self.writeOutput( f'Expected behemoth {self.lobby_data["behemoth"]} but found ' + f'{data["behemoth"]}, retrying...', 'warning') self._incrementException() # wait briefly to get a better screenshot time.sleep(self.LOOP_INTER) ''' Internal method for sampling the loot data into what will be submitted In: nothing Out: sampled data ''' def _processLootData(self): # determine slay roll count slay_rolls = 2 + (3 - self.lobby_data['deaths']) + ( 2 * self.lobby_data['elite']) # compensate for a bug with Elite loot display slay_rolls -= 2 * (self.lobby_data['tier'] == 'Heroic+' and self.lobby_data['behemoth'] not in ['Shrowd', 'Rezakiri'] and self.lobby_data['elite']) # calculate how many drops to sample out from the data # sampling is necessary because of numerous display bugs on loot screen sample_count = slay_rolls * 2 if len( self.loot_data) >= slay_rolls * 2 else slay_rolls # fill submission data with dyes and cells if present -- we always add them to submission data # because they can't drop from part break submit_data = [ drop for drop in self.loot_data if drop['rarity'] in ['Artifact (Dye)', 'Rare (Cell)', 'Uncommon (Cell)'] ] # data from which to draw samples source_data = [ drop for drop in self.loot_data if drop['rarity'] not in ['Artifact (Dye)', 'Rare (Cell)', 'Uncommon (Cell)'] ] # in the event of sample count being higher than valid loot, take number of items # in the loot - this is a safeguard against low-level hunts dropping part breaks on # slay rolls sample_count = min(sample_count, len(self.loot_data)) # draw the samples, reducing their number by dye drops present sample_data = random.sample(source_data, sample_count - len(submit_data)) # return sampled data return [*submit_data, *sample_data] ''' Method for initialising the logger and returning it In: nothing Out: logger object ''' def _setLogger(self): # compose file name containing date and name of the program file_name = f'{datetime.now().date()}_{self.PRG_NAME.lower()}' # set some basic information to work from going forward LOG_FRMT = '%(asctime)s %(message)s' DATE_FMT = '%d/%m/%Y %H:%M:%S' LOG_NAME = 'scrapless' INF_FILE = f'{self.LOG_PATH}{file_name}.log' ERR_FILE = f'{self.ERR_PATH}{file_name}.err' # create logger and configure its format logger = logging.getLogger(LOG_NAME) log_formatter = logging.Formatter(LOG_FRMT) # create a stream handler so logging goes to console stream_handler = logging.StreamHandler() stream_handler.setFormatter(log_formatter) logger.addHandler(stream_handler) # configure the logger for INFO logging # appending to files to support multiple sessions in one day file_handler_info = logging.FileHandler(INF_FILE, mode='a') file_handler_info.setFormatter(log_formatter) file_handler_info.setLevel(logging.INFO) logger.addHandler(file_handler_info) # configure the logger for ERROR logging # appending to files to support multiple sessions in one day file_handler_error = logging.FileHandler(ERR_FILE, mode='a') file_handler_error.setFormatter(log_formatter) file_handler_error.setLevel(logging.ERROR) logger.addHandler(file_handler_error) # set logger level to INFO and higher logger.setLevel(logging.INFO) return logger ''' Method for configuring PyTesseract from config file Reads the path and sets it to a global value Raises an exception if the path is missing or does not point to a file ''' def _setPyTesseract(self): # retrieve tesseract path from config tess_path = self.readKey('tesseract') # verify the path is a string if type(tess_path) == str: # verify path leads to a file if os.path.isfile(tess_path): # use the path read from config to setup pytesseract pytesseract.pytesseract.tesseract_cmd = tess_path # return the path return tess_path # otherwise raise an exception raise FileNotFoundError( f'file {tess_path} is not a file or could not be read') ''' Internal method to automatically accesses the manifest file created by Epic Games Store In: none Out: string number of game version ''' def _setGamePatch(self): # check if the manifest folder exists if os.path.isdir(self.MNF_PATH): # get the manifest items in the directory manifs = glob(self.MNF_PATH + '*.item') # check if there are any manifest items there if len(manifs) > 0: # iterate over file paths for item_path in manifs: # open a manifest file item_file = open(item_path, 'r') # parse file into JSON item = json.load(item_file) # check if the file contains Dauntless data if item['DisplayName'] == 'Dauntless': # get patch version patch_ver = '.'.join( item['AppVersionString'].split('.')[:3]) # return patch version return patch_ver # raise an exception if we iterated through all items without finding # a Dauntless manifest raise FileNotFoundError( f'Dauntless manifest file could not be found') # if not, raise an exception else: raise FileNotFoundError( f'no manifest files found in {self.MNF_PATH}') # if not, raise exception else: raise NotADirectoryError(f'{self.MNF_PATH} is not a directory') ''' Internal method for initialising the user and checking all necessary details about them In: none Out: string name of user ''' def _setUser(self): # read the user key from config file user = self.readKey('user') # check if the user value is empty if user == '': # replace empty name with random ID string user = str(uuid4()) # create an updated version of the config to over-write current one with new_conf = self.conf_file # overwrite user value new_conf['user'] = user # overwrite the file with open(self.conf_path, 'w') as write_file: json.dump(self.conf_file, write_file, indent=2, separators=(',', ':')) # return the user name return user ''' Internal method for submitting data, based on what data is filled at the moment In: none Out: none ''' def _submitData(self): # if loot data is not empty, submit loot data if len(self.loot_data) > 0: # iterate over drops for drop in self.loot_data: # add game and patch data drop['user'] = self.user drop['patch'] = self.patch drop['behemoth'] = self.lobby_data['behemoth'] drop['threat'] = self.lobby_data['threat'] drop['tier'] = self.lobby_data['tier'] # try submitting the drop try: # send POST request self.data_sender.submitData(drop, 'loot') # raise exception if encountered except HTTPError as e: self.writeOutput(str(e), 'error') # inform about data submission self.writeOutput(f'Loot data submitted', 'success') # clear the data self.clearData() # if bounty data is not empty if len(self.bounty_data) > 0: # check if draft screen was closed if self.bounty_reader.detectDraftEnd(self.screen_capture): # add game and patch data self.bounty_data['user'] = self.user self.bounty_data['patch'] = self.patch # try submitting the bounty try: # send a POST request self.data_sender.submitData(self.bounty_data, 'bounty') # inform about data submission self.writeOutput(f'Bounty data submitted', 'success') # raise exception if encountered except HTTPError as e: self.writeOutput(str(e), 'error') # empty the data self.clearData()
userFolder = str(sys.argv[2]) ownIP = str(sys.argv[3]) ownPort = int(sys.argv[4]) bootstrapIP = str(sys.argv[5]) bootstrapPort = int(sys.argv[6]) TCPPortStart = int(sys.argv[7]) TCPPortCount = int(sys.argv[8]) watcherIP = str(sys.argv[9]) else: userName = "******" #str(argv[1]) userFolder = "User1/" #str(argv[2]) ownIP = "localhost" #str(argv[3]) ownPort = 50001 #int(argv[4]) bootstrapIP = "localhost" #str(argv[5]) bootstrapPort = 50000 #int(argv[6]) TCPPortStart = 60010 #int(argv[7]) TCPPortCount = 10 #int(argv[8]) watcherIP = "localhost" #str(argv[9]) # initialize and start overlay layer overlay = Overlay(userName, ownIP, ownPort, bootstrapIP, bootstrapPort, n2o, o2n, a2o, o2a, watcherQ) application = Application(userFolder, o2a, a2o) network1 = Network(userFolder, ownIP, ownPort, TCPPortStart, TCPPortCount, n2o, o2n, watcherQ, watcherIP, 2) network1.run() while not raw_input() == 'e': pass application.terminate() overlay.terminate() network1.terminate()
class NodeEditor(QFrame): # ========================== init stuff ========================== # def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.viewport_y = 0 # top visible line self.imagemode = False self.image = None self.scroll_height = 0 self.scroll_width = 0 self.timer = QTimer(self) self.backuptimer = QTimer(self) self.connect(self.timer, SIGNAL("timeout()"), self.analysis_timer) self.connect(self.backuptimer, SIGNAL("timeout()"), self.backup_timer) self.backuptimer.start(30000) self.undotimer = QTimer(self) self.connect(self.undotimer, SIGNAL("timeout()"), self.trigger_undotimer) self.blinktimer = QTimer(self) self.blinktimer.start(500) self.connect(self.blinktimer, SIGNAL("timeout()"), self.trigger_blinktimer) self.show_cursor = True self.boxcolors = [ QColor("#DC322F"), QColor("#268BD2"), QColor("#2Ac598"), QColor("#D33682"), QColor("#B58900"), QColor("#859900") ] self.setCursor(Qt.IBeamCursor) # Semi-transparent overlay. # Used to display heat-map visualisation of profiler info, etc. self.overlay = Overlay(self) # Always show the overlay, users hide visualisations with the HUD. self.overlay.show() # Show / don't show HUD visualisations. self.hud_callgraph = False self.hud_eval = False self.hud_heat_map = False self.hud_types = False self.autolboxlines = {} def hud_show_callgraph(self): self.hud_callgraph = True self.hud_eval = False self.hud_heat_map = False self.hud_types = False def hud_show_eval(self): self.hud_callgraph = False self.hud_eval = True self.hud_heat_map = False self.hud_types = False def hud_show_types(self): self.hud_callgraph = False self.hud_eval = False self.hud_heat_map = False self.hud_types = True def hud_show_heat_map(self): self.hud_callgraph = False self.hud_eval = False self.hud_heat_map = True self.hud_types = False def hud_off(self): self.hud_callgraph = False self.hud_eval = False self.hud_heat_map = False self.hud_types = False def focusOutEvent(self, event): self.blinktimer.stop() self.show_cursor = True self.update() def focusInEvent(self, event): self.blinktimer.start() def resizeEvent(self, event): self.overlay.resize(event.size()) event.accept() def analysis_timer(self): if self.getWindow().show_namebinding(): if self.tm.analyse() is not False: self.update() self.getWindow().updateASTOutline() self.timer.stop() # save swap filename = self.getEditorTab().filename if filename: self.saveToJson(filename + ".swp", True) def backup_timer(self): filename = self.getEditorTab().filename if filename: self.saveToJson(filename + ".bak", True) def trigger_blinktimer(self): if self.timer.isActive(): self.show_cursor = True return self.show_cursor ^= True self.update() def trigger_undotimer(self): self.tm.undo_snapshot() self.undotimer.stop() def setImageMode(self, boolean): self.imagemode = boolean def reset(self): self.update() def set_mainlanguage(self, parser, lexer, lang_name): self.tm = TreeManager() self.tm.add_parser(parser, lexer, lang_name) def get_mainlanguage(self): return self.tm.parsers[0][2] def set_sublanguage(self, language): self.sublanguage = language def event(self, event): if event.type() == QEvent.ToolTip: pos = event.pos() temp_cursor = self.tm.cursor.copy() result = self.coordinate_to_cursor(pos.x(), pos.y()) node = self.tm.cursor.node self.tm.cursor.line = temp_cursor.line self.tm.cursor.node = temp_cursor.node self.tm.cursor.pos = temp_cursor.pos if not result: QToolTip.hideText() event.ignore() return True # Draw errors, if there are any. msg = self.tm.get_error(node) if not msg: msg = self.tm.get_error_presentation(node) if msg: QToolTip.showText(event.globalPos(), msg) return True # Draw tooltips if there are any. Tooltips can appear with any HUD # visualisation. elif (self.hud_callgraph or self.hud_eval or self.hud_types or self.hud_heat_map): strings = [] annotes = node.get_annotations_with_hint(ToolTip) if self.hud_callgraph: for annote in annotes: if annote.has_hint(HUDCallgraph): strings.append(annote.annotation) elif self.hud_eval: for annote in annotes: if annote.has_hint(HUDEval): strings.append(annote.annotation) elif self.hud_types: for annote in annotes: if annote.has_hint(HUDTypes): strings.append(annote.annotation) elif self.hud_heat_map: for annote in annotes: if annote.has_hint(HUDHeatmap): strings.append(annote.annotation) msg = "\n".join(strings) if msg.strip() != "": if self.tm.tool_data_is_dirty: msg += "\n[Warning: Information may be out of date.]" QToolTip.showText(event.globalPos(), msg) return True QToolTip.hideText() event.ignore() return True return QFrame.event(self, event) # ========================== GUI related stuff ========================== # def blink(self): if self.show_cursor: self.show_cursor = 0 else: self.show_cursor = 1 self.update() def sliderChanged(self, value): self.viewport_y = value self.overlay.start_line = self.viewport_y self.update() def sliderXChanged(self, value): self.move(-value * self.fontwt, 0) self.resize( self.parentWidget().geometry().width() + value * self.fontwt, self.geometry().height()) if self.x() == 0: self.updateGeometry() self.update() def getScrollSizes(self): total_lines = 0 max_width = 0 for l in self.lines: total_lines += l.height max_width = max(max_width, l.width) max_visible_lines = self.geometry().height() / self.fontht self.scroll_height = max(0, total_lines - max_visible_lines) current_width = self.parentWidget().geometry().width() / self.fontwt self.scroll_width = max(0, max_width - current_width) def paintEvent(self, event): # Clear data in the visualisation overlay self.overlay.clear_data() self.autolboxlines.clear() gfont = QApplication.instance().gfont self.font = gfont.font self.fontwt = gfont.fontwt self.fontht = gfont.fontht self.fontd = gfont.fontd QtGui.QFrame.paintEvent(self, event) paint = QtGui.QPainter() if self.imagemode: self.image = QImage() paint.begin(self.image) else: paint.begin(self) paint.setFont(self.font) self.longest_column = 0 # calculate how many lines we need to show self.init_height = self.geometry().height() self.paintLines(paint, self.viewport_y) paint.end() total_lines = 0 max_width = 0 for l in self.lines: total_lines += l.height max_width = max(max_width, l.width) max_visible_lines = self.geometry().height() / self.fontht self.scroll_height = max(0, total_lines - max_visible_lines) current_width = self.parentWidget().geometry().width() / self.fontwt self.scroll_width = max(0, max_width - current_width) railroad_annotations = self.tm.get_all_annotations_with_hint(Railroad) self.overlay.add_railroad_data(railroad_annotations) self.emit(SIGNAL("painted()")) # paint lines using new line manager def paintLines(self, paint, startline): # find internal line corresponding to visual line visual_line = 0 internal_line = 0 for l in self.tm.lines: if visual_line + l.height > startline: break visual_line += l.height internal_line += 1 x = 0 y = visual_line - startline # start drawing outside of viewport to display partial images self.paint_start = (internal_line, y) max_y = self.geometry().height() / self.fontht line = internal_line node = self.tm.lines[line].node _, _, self.end_line = self.paint_nodes(paint, node, x, y, line, max_y) #XXX if starting node is inside language box, init lbox with amount of language boxes def new_paint_nodes(self, paint, node, x, y, line, max_y, lbox=0): from nodepainter import NodePainter np = NodePainter(paint, node, x, y, line, max_y, lbox) np.cursor = self.tm.cursor np.repaint() self.lines = self.tm.lines self.cursor = self.tm.cursor return np.x, np.y, np.line def paint_nodes(self, paint, node, x, y, line, max_y, lbox=0): settings = QSettings("softdev", "Eco") colors = self.boxcolors if settings.value("app_theme", "Light").toString() in ["Dark"]: alpha = 100 self.highlight_line_color = QColor(250, 250, 250, 20) elif settings.value("app_theme", "Light").toString() in ["Gruvbox"]: alpha = 100 self.highlight_line_color = QColor(250, 250, 250, 20) else: alpha = 60 self.highlight_line_color = QColor(0, 0, 0, 10) self.show_highlight_line = settings.value("highlight_line", False).toBool() first_node = node selected_language = self.tm.mainroot highlighter = self.get_highlighter(node) selection_start = min(self.tm.selection_start, self.tm.selection_end) selection_end = max(self.tm.selection_start, self.tm.selection_end) if selection_start.node is not selection_end.node: if type(selection_start.node.symbol) is MagicTerminal: selection_start = selection_start.copy() selection_start.node = selection_start.node.symbol.ast.children[ 0] selection_start.pos = 0 if type(selection_end.node.symbol) is MagicTerminal: selection_end = selection_end.copy() selection_end.node = selection_end.node.symbol.ast.children[-1] selection_end.pos = 0 selection_end.jump_left() draw_selection_start = (0, 0, 0) draw_selection_end = (0, 0, 0) start_lbox = self.get_languagebox(node) renderer = self.get_renderer(node) self.selected_lbox = self.tm.get_languagebox(self.tm.cursor.node) #XXX get initial x for langbox if start_lbox: lbox += 1 if start_lbox and self.selected_lbox is start_lbox: draw_lbox = True else: draw_lbox = False draw_all_boxes = self.getWindow().show_languageboxes() self.lines = self.tm.lines self.cursor = self.tm.cursor self.lines[line].height = 1 # reset height draw_cursor = True show_namebinding = self.getWindow().show_namebinding() while y < max_y: # check if node is connected to auto lbox if node.autobox: if self.autolboxlines.has_key(line): for box in node.autobox: # Avoid duplicate suggestions by comparing the # identities of language box candidates exists = False for b in self.autolboxlines[line]: if b is box: exists = True break if not exists: self.autolboxlines[line].append(box) else: self.autolboxlines[line] = list(node.autobox) # if we found a language box, continue drawing inside of it if isinstance(node.symbol, MagicTerminal): if self.tm.is_syntaxerror(node): self.draw_vertical_squiggly_line(paint, x, y) lbox += 1 lbnode = node.symbol.ast if self.selected_lbox is node: color = colors[(lbox - 1) % len(colors)] if not self.tm.is_syntaxerror(node): self.draw_lbox_bracket(paint, '[', node, x, y, color) draw_lbox = True selected_language = lbnode else: draw_lbox = False node = lbnode.children[0] highlighter = self.get_highlighter(node) renderer = self.get_renderer(node) continue if isinstance(node, EOS): lbnode = self.get_languagebox(node) if self.cursor.node is lbnode and self.show_cursor: self.draw_cursor(paint, x, 4 + y * self.fontht) if lbnode: color = colors[(lbox - 1) % len(colors)] if lbox > 0: lbox -= 1 node = lbnode.next_terminal() highlighter = self.get_highlighter(node) renderer = self.get_renderer(node) if self.selected_lbox is lbnode: # draw bracket self.draw_lbox_bracket(paint, ']', node, x, y, color) draw_lbox = False lbnode = self.get_languagebox(node) if lbnode and self.selected_lbox is lbnode: draw_lbox = True continue else: self.lines[line].width = x / self.fontwt break if isinstance(node.symbol.name, list): node = node.symbol.name[0] continue # draw language boxes if lbox > 0 and (draw_lbox or draw_all_boxes): if draw_all_boxes: color = colors[(lbox - 1) % len(colors)] color.setAlpha(alpha) else: color = colors[0] color.setAlpha(alpha) if draw_lbox and draw_all_boxes: # we are drawing the currently selected language box color.setAlpha(20) renderer.update_image(node) if node.symbol.name != "\r" and not isinstance( node.symbol, IndentationTerminal): if not node.image or node.plain_mode: if isinstance(node, BOS) and isinstance( node.next_term, EOS): self.draw_lbox_hints(paint, node, x, y, color) else: paint.fillRect( QRectF(x, 3 + y * self.fontht, len(node.symbol.name) * self.fontwt, self.fontht), color) # prepare selection drawing if node is selection_start.node: if node.lookup == "<return>": sel_x = x else: sel_x = x + selection_start.pos * self.fontwt draw_selection_start = (sel_x, y, line) if node is selection_end.node: draw_selection_end = (x + selection_end.pos * self.fontwt, y, line) # draw node dx, dy = renderer.paint_node(paint, node, x, y, highlighter) x += dx self.lines[line].height = max(self.lines[line].height, dy) # Draw footnotes and add heatmap data to overlay. annotes = [ annote.annotation for annote in node.get_annotations_with_hint(Heatmap) ] # Heatmap data can always be sent to the overlay, it won't be # rendered unless the user selects the Heatmap HUD radio button. for annote in annotes: self.overlay.add_heatmap_datum(line + 1, annote) if self.hud_eval or self.hud_types: infofont = QApplication.instance().tool_info_font annotes = [] annotes_ = node.get_annotations_with_hint(Footnote) if self.hud_eval: for annote in annotes_: if annote.has_hint(HUDEval): annotes.append(annote) elif self.hud_types: for annote in annotes_: if annote.has_hint(HUDTypes): annotes.append(annote) footnote = " ".join([annote.annotation for annote in annotes]) if footnote.strip() != "": if not self.tm.tool_data_is_dirty: infofont.font.setBold(True) else: infofont.font.setBold(False) paint.setFont(infofont.font) paint.setPen( QPen(QColor((highlighter.get_default_color())))) start_y = self.fontht + ((y + 1) * self.fontht) paint.drawText(QtCore.QPointF(x - dx, start_y), footnote) self.lines[line].height = max(self.lines[line].height, 2) paint.setFont(self.font) # after we drew a return, update line information if (node.lookup == "<return>" or node.symbol.name == "\r") and not node is first_node: # draw lbox to end of line if draw_lbox or (draw_all_boxes and lbox > 0): paint.fillRect( QRectF(x, 3 + y * self.fontht, self.geometry().width() - x, self.fontht), color) self.lines[line].width = x / self.fontwt x = 0 y += self.lines[line].height line += 1 self.lines[line].height = 1 # reset height if self.show_highlight_line: if node.lookup == "<return>" or isinstance(node, BOS): if self.cursor.line == line: self.highlight_line(paint, y) # draw cursor if node is self.cursor.node and self.show_cursor: draw_x = max(0, x - dx) cursor_pos = self.cursor.pos if node.symbol.name == "\r": cursor_pos = 0 if node.image and not node.plain_mode: draw_x = x cursor_pos = 0 self.draw_cursor(paint, draw_x + cursor_pos * self.fontwt, 4 + y * self.fontht) if False and line == self.cursor.y and x / self.fontwt >= self.cursor.x and draw_cursor: draw_cursor_at = QRect(0 + self.cursor.x * self.fontwt, 5 + y * self.fontht, 0, self.fontht - 3) paint.drawRect(draw_cursor_at) # set lbox info coordinates infobox_coordinates = (self.cursor.x * self.fontwt, (y + 1) * self.fontht) draw_cursor = False # draw errors using squiggly lines if show_namebinding and self.tm.is_typeerror(node): length = len(node.symbol.name) * self.fontwt self.draw_squiggly_line(paint, x - length, y, length, "orange") if self.tm.has_error_presentation(node): length = len(node.symbol.name) * self.fontwt self.draw_squiggly_line(paint, x - length, y, length, "blue") elif self.tm.is_syntaxerror(node): if isinstance(node, EOS): length = self.fontwt else: length = len(node.symbol.name) * self.fontwt self.draw_squiggly_line(paint, x - length, y, length, "red") node = node.next_terminal() if selection_start != selection_end: self.draw_selection(paint, draw_selection_start, draw_selection_end, max_y) # paint infobox if False: lang_name = self.tm.parsers[selected_language] lang_status = self.tm.get_parser[selected_language][0].last_status if lang_status is True: color = QColor(100, 255, 100) else: color = QColor(255, 100, 100) paint.setFont(infofont) paint.fillRect( QRect(infobox_coordinates[0], 5 + infobox_coordinates[1], len(lang_name) * infofontwt, infofontht), color) paint.drawText( QtCore.QPointF(infobox_coordinates[0], -3 + self.fontht + infobox_coordinates[1]), lang_name) paint.setFont(self.font) return x, y, line def highlight_line(self, paint, y): width = self.parentWidget().geometry().width() paint.fillRect(QRect(-5, y * self.fontht + 3, width, self.fontht), self.highlight_line_color) def draw_lbox_hints(self, paint, node, x, y, color): if node is self.cursor.node: return alpha = color.alpha() color.setAlpha(255) path = QPainterPath() x = x - 2 y = y * self.fontht + 4 path.moveTo(x, y) path.lineTo(x + 6, y) path.lineTo(x + 3, y + 3) path.lineTo(x, y) paint.fillPath(path, QBrush(color)) color.setAlpha(alpha) def draw_lbox_bracket(self, paint, bracket, node, x, y, color): assert bracket in ['[', ']'] oldpen = paint.pen() newpen = QPen() color.setAlpha(255) newpen.setColor(color) newpen.setWidth(1) paint.setPen(newpen) # paint brackets path = QPainterPath() if bracket == '[': if x == 0: tmpx = x + 2 else: tmpx = x + 1 # adjust bracket position path.moveTo(tmpx, 3 + y * self.fontht) path.lineTo(tmpx - 2, 3 + y * self.fontht) path.moveTo(tmpx - 2, 3 + y * self.fontht) path.lineTo(tmpx - 2, 3 + y * self.fontht + self.fontht - 1) else: tmpx = x - 1 path.moveTo(tmpx, 3 + y * self.fontht) path.lineTo(tmpx + 2, 3 + y * self.fontht) path.moveTo(tmpx + 2, 3 + y * self.fontht) path.lineTo(tmpx + 2, 3 + y * self.fontht + self.fontht - 1) path.lineTo(tmpx, 3 + y * self.fontht + self.fontht - 1) paint.drawPath(path) paint.setPen(oldpen) def draw_cursor(self, paint, x, y): pen = paint.pen() colorhex = self.palette().color(QPalette.Text) pen.setColor(QColor(colorhex)) paint.setPen(pen) draw_cursor_at = QRect(x, y, 0, self.fontht - 3) paint.drawRect(draw_cursor_at) def draw_vertical_squiggly_line(self, paint, x, y): paint.setPen(Qt.CustomDashLine) pen = paint.pen() pen.setColor(QColor("red")) y = 3 + y * self.fontht pen.setDashPattern([4, 4]) paint.setPen(pen) paint.drawLine(x - 2, y, x - 2, y + self.fontht) pen.setDashPattern([2, 2]) paint.setPen(pen) paint.drawLine(x - 3, y + 3, x - 3, y + self.fontht) pen.setDashPattern([4, 4]) paint.setPen(pen) paint.drawLine(x - 4, y + 4, x - 4, y + self.fontht) paint.setPen(Qt.SolidLine) def draw_squiggly_line(self, paint, x, y, length, color): paint.setPen(Qt.CustomDashLine) pen = paint.pen() pen.setColor(QColor(color)) paint.setPen(pen) y = (y + 1) * self.fontht + 1 pen.setDashPattern([4, 4]) paint.setPen(pen) paint.drawLine(x, y + 2, x + length, y + 2) pen.setDashPattern([2, 2]) paint.setPen(pen) paint.drawLine(x + 3, y + 1, x + length, y + 1) pen.setDashPattern([4, 4]) paint.setPen(pen) paint.drawLine(x + 4, y, x + length, y) paint.setPen(Qt.SolidLine) def draw_selection(self, paint, draw_selection_start, draw_selection_end, max_y): x1, y1, line1 = draw_selection_start x2, y2, line2 = draw_selection_end start = min(self.tm.selection_start, self.tm.selection_end) end = max(self.tm.selection_start, self.tm.selection_end) if x1 + y1 + line1 + x2 + y2 + line2 == 0: # everything out of viewport, draw nothing # unless start and end are on opposite sides of the viewport if not (start.line <= self.paint_start[0] and end.line >= self.paint_start[0] + max_y): return if x1 + y1 + line1 == 0: # start outside of viewport line1 = self.paint_start[0] if x2 + y2 + line2 == 0: # end outside of viewport line2 = self.paint_start[0] + max_y y2 = max_y if y1 == y2: paint.fillRect( QRectF(x1, 3 + y1 * self.fontht, x2 - x1, self.fontht), QColor(0, 0, 255, 100)) else: width = max(self.fontwt, self.tm.lines[line1].width * self.fontwt) paint.fillRect( QRectF(x1, 3 + y1 * self.fontht, width - x1, self.fontht), QColor(0, 0, 255, 100)) y = y1 + self.tm.lines[line1].height for i in range(line1 + 1, line2): width = self.tm.lines[i].width * self.fontwt if width == 0: width = self.fontwt paint.fillRect( QRectF(0, 3 + y * self.fontht, width, self.fontht), QColor(0, 0, 255, 100)) y = y + self.tm.lines[i].height paint.fillRect(QRectF(0, 3 + y2 * self.fontht, x2, self.fontht), QColor(0, 0, 255, 100)) def get_highlighter(self, node): root = node.get_root() base = lang_dict[self.tm.get_language(root)].base s = syntaxhighlighter.get_highlighter(base, self.palette()) return s def get_languagebox(self, node): root = node.get_root() lbox = root.get_magicterminal() return lbox def get_renderer(self, node): root = node.get_root() base = lang_dict[self.tm.get_language(root)].base return renderers.get_renderer(base, self.fontwt, self.fontht, self.fontd) def focusNextPrevChild(self, b): # don't switch to next widget on TAB return False def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self.tm.input_log.append("# mousePressEvent") self.coordinate_to_cursor(e.x(), e.y()) self.tm.selection_start = self.tm.cursor.copy() self.tm.selection_end = self.tm.cursor.copy() self.tm.input_log.append( "self.selection_start = self.cursor.copy()") self.tm.input_log.append("self.selection_end = self.cursor.copy()") self.getWindow().showLookahead() self.show_cursor = True self.blinktimer.start() self.update() def mouseDoubleClickEvent(self, e): if e.button() == Qt.LeftButton: self.coordinate_to_cursor(e.x(), e.y()) node = self.tm.get_node_from_cursor() lbox = self.get_languagebox(node) if lbox and lbox.symbol.name == "<IPython>": if lbox.plain_mode is False: lbox.plain_mode = True else: lbox.plain_mode = False self.update() return elif node.image is None: self.tm.doubleclick_select() self.update() return if node.plain_mode is False: node.plain_mode = True self.tm.cursor.pos = len(node.symbol.name) else: node.plain_mode = False self.update() def cursor_to_coordinate(self): y = 0 for l in self.tm.lines[:self.cursor.line]: y += l.height * self.fontht x = self.tm.cursor.get_x() * self.fontwt y = y - self.getScrollArea().verticalScrollBar().value() * self.fontht return (x, y) def coordinate_to_cursor(self, x, y): mouse_y = y / self.fontht first_line = self.paint_start[0] y_offset = self.paint_start[1] y = y_offset line = first_line if mouse_y < 0: while line > 0: y -= self.tm.lines[line].height if y < mouse_y: break line -= 1 else: while line < len(self.tm.lines) - 1: y += self.tm.lines[line].height if y > mouse_y: break line += 1 self.tm.cursor.line = line cursor_x = int(round(float(x) / self.fontwt)) self.tm.cursor.move_to_x(cursor_x) self.tm.input_log.append("self.cursor.line = %s" % str(line)) self.tm.log_input("cursor.move_to_x", str(cursor_x)) if mouse_y > y or self.tm.cursor.get_x() != cursor_x: return False return True def mouseMoveEvent(self, e): # apparently this is only called when a mouse button is clicked while # the mouse is moving if self.tm.input_log[-2].startswith("self.cursor.move_to_x"): # only log the last move event self.tm.input_log.pop() self.tm.input_log.pop() self.tm.input_log.pop() self.coordinate_to_cursor(e.x(), e.y()) self.tm.selection_end = self.tm.cursor.copy() self.tm.input_log.append("self.selection_end = self.cursor.copy()") self.update() self.getEditorTab().keypress() def keyPressEvent(self, e): self.timer.start(500) self.show_cursor = True startundotimer = False key = KeyPress(e) # key presses to ignore if key.is_modifier or key.page_up or key.page_down: return # has been processes in get_nodes_at_pos -> reset self.edit_rightnode = False reparse = True if key.escape: self.tm.key_escape() elif key.backspace: startundotimer = True self.tm.key_backspace() elif key.home: self.tm.key_home(shift=key.m_shift) elif key.end: self.tm.key_end(shift=key.m_shift) elif key.is_arrow: if key.jump_word: self.tm.ctrl_cursor(key, shift=key.m_shift) else: self.tm.key_cursors(key, shift=key.m_shift) reparse = False elif key.delete: startundotimer = True self.tm.key_delete() elif e.key() == Qt.Key_F3: self.tm.find_next() # User pressed Ctrl- Or Alt- (etc.) i.e. a character we can't # sensibly insert into the text. elif key.has_action_modifier: pass # every other normal key press else: startundotimer = True if e.key() == Qt.Key_Tab: text = " " else: # text is a char array, so we need the first letter # to match it against the set text = e.text() if text.isEmpty() or text.toUtf8()[0] not in whitelist: logging.debug("Key %s not supported" % text) return self.tm.key_normal(text) if reparse: self.getWindow().btReparse([]) self.update() self.emit(SIGNAL("keypress(QKeyEvent)"), e) self.getWindow().showLookahead() if startundotimer: self.undotimer.start(500) def showLanguageBoxMenu(self): self.showSubgrammarMenu() self.create_languagebox() def create_languagebox(self): if self.sublanguage: if self.tm.hasSelection(): self.tm.surround_with_languagebox(self.sublanguage) self.tm.reparse(self.tm.selection_start.node) else: self.tm.add_languagebox(self.sublanguage) self.getWindow().btReparse([]) self.update() def change_languagebox(self): if self.sublanguage: self.tm.change_languagebox(self.sublanguage) def showCodeCompletion(self): l = self.tm.getCompletion() if l: self.showCodeCompletionMenu(l) def println(self, prestring, y): node = self.lines[y].node.next_term x = [] while node is not None and node.symbol.name != "\r": x.append(node.symbol.name) node = node.next_term print(prestring, "".join(x)) def print_line(self, y): current = self.lines[y].node while True: print(current) current = current.next_term if current is None: return # ========================== AST modification stuff ========================== # def insertTextNoSim(self, text): self.viewport_y = 0 self.tm.import_file(text) return def getTL(self): return self.getWindow().tl def getPL(self): return self.getWindow().pl def getLRP(self): return self.getWindow().lrp def getWindow(self): return self.window() def getEditorTab(self): return self.parent().parent().parent() def getScrollArea(self): return self.parent().parent() def createSubgrammarMenu(self, menu, change=False): self.sublanguage = None tmp = None if change: # try and find lbox and set cursor to previous node before getting # lookahead list root = self.tm.cursor.node.get_root() lbox = root.get_magicterminal() if lbox: tmp = self.tm.cursor.node self.tm.cursor.node = lbox.prev_term lalist = self.tm.getLookaheadList() if tmp: # undo cursor change self.tm.cursor.node = tmp # Filter out languages that are part of this composition. todo = [self.get_mainlanguage()] comp_langs = [] while todo: l = todo.pop() for sl in lang_dict[l].included_langs: if lang_dict[sl] not in comp_langs: comp_langs.append(lang_dict[sl]) todo.append(sl) # Generate list of languages valid at current position valid_langs = [] for l in comp_langs: if "<%s>" % l in lalist: valid_langs.append(l) for l in valid_langs: # Don't show languages twice comp_langs.remove(l) def create_entry(l, menu): pass bf = QFont() bf.setBold(True) # Show valid languages first if len(valid_langs) > 0: for l in sorted(valid_langs, key=lambda x: x.name): item = QAction(str(l), menu) item.setData(l) self._set_icon(item, l) item.setFont(bf) menu.addAction(item) menu.addSeparator() # Then show languages that are part of this composition for l in sorted(comp_langs, key=lambda x: x.name): item = QAction(str(l), menu) item.setData(l) self._set_icon(item, l) menu.addAction(item) # Finally add another submenu with all remaining languages other_langs = QtGui.QMenu("Other", self) for l in sorted(languages, key=lambda x: x.name): if l not in comp_langs and l not in valid_langs: item = QAction(str(l), other_langs) item.setData(l) self._set_icon(item, l) other_langs.addAction(item) menu.addSeparator() menu.addMenu(other_langs) return menu def showSubgrammarMenu(self): menu = QtGui.QMenu("Language", self) self.createSubgrammarMenu(menu) x, y = self.cursor_to_coordinate() action = menu.exec_( self.mapToGlobal(QPoint(0, 0)) + QPoint(3 + x, y + self.fontht)) if action: self.sublanguage = action.data().toPyObject() self.edit_rightnode = True def _set_icon(self, mitem, lang): if lang.base.lower() == "html": icon = QIcon.fromTheme("text-xhtml+xml") else: icon = QIcon.fromTheme("text-x-" + lang.base.lower()) if icon.isNull(): icon = QIcon.fromTheme("application-x-" + lang.base.lower()) if icon.isNull(): icon = QIcon.fromTheme("text-x-generic") mitem.setIcon(icon) def showCodeCompletionMenu(self, l): menu = QtGui.QMenu(self) # Create actions toolbar = QtGui.QToolBar() for n in l: path = [] for p in n.path: if p and p.name: path.append(p.name) if n.vartype: vartype = n.vartype while vartype.children != []: try: vartype = vartype.children[0] except KeyError: vartype = vartype.children["name"] text = "%s : %s - %s (%s)" % (n.name, vartype.symbol.name, ".".join(path), n.kind) elif n.kind == "method": text = self.cc_method(n) + " - %s" % (".".join(path)) else: text = "%s - %s (%s)" % (n.name, ".".join(path), n.kind) item = toolbar.addAction(text, self.createCCFunc(n.name)) item.setIcon(QIcon("gui/" + n.kind + ".png")) menu.addAction(item) x, y = self.cursor_to_coordinate() menu.exec_( self.mapToGlobal(QPoint(0, 0)) + QPoint(3 + x, y + self.fontht)) def cc_method(self, n): s = [n.name, "("] param_ln = n.astnode.children["params"] if isinstance(param_ln, ListNode): for p in param_ln.children: tmp = p.children["type"] if isinstance(tmp, AstNode): s.append(tmp.children["name"].symbol.name) else: s.append(tmp.symbol.name) s.append(" ") s.append(p.children["name"].symbol.name) if p != param_ln.children[-1]: s.append(", ") s.append(")") return "".join(s) def createMenuFunction(self, l): def action(): self.sublanguage = l self.edit_rightnode = True return action def createCCFunc(self, text): def action(): self.tm.pasteCompletion(text) self.update() return action def selectSubgrammar(self, item): pass def saveToJson(self, filename, swap=False): whitespaces = self.tm.get_mainparser().whitespaces root = self.tm.parsers[0][0].previous_version.parent language = self.tm.parsers[0][2] manager = JsonManager() manager.save(root, language, whitespaces, filename) if not swap: self.tm.changed = False self.emit(SIGNAL("painted()")) def loadFromJson(self, filename): manager = JsonManager() language_boxes = manager.load(filename) self.tm = TreeManager() self.tm.load_file(language_boxes) self.reset() def export(self, run=False, profile=False, source=None, debug=False): return self.tm.export(None, run, profile, source=source, debug=debug)
class NodeEditor(QFrame): # ========================== init stuff ========================== # def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.viewport_y = 0 # top visible line self.imagemode = False self.image = None self.scroll_height = 0 self.scroll_width = 0 self.timer = QTimer(self) self.backuptimer = QTimer(self) self.connect(self.timer, SIGNAL("timeout()"), self.analysis_timer) self.connect(self.backuptimer, SIGNAL("timeout()"), self.backup_timer) self.backuptimer.start(30000) self.undotimer = QTimer(self) self.connect(self.undotimer, SIGNAL("timeout()"), self.trigger_undotimer) self.blinktimer = QTimer(self) self.blinktimer.start(500) self.connect(self.blinktimer, SIGNAL("timeout()"), self.trigger_blinktimer) self.show_cursor = True self.boxcolors = [QColor("#DC322F"), QColor("#268BD2"), QColor("#D33682"), QColor("#B58900"), QColor("#2AA198"), QColor("#859900")] self.setCursor(Qt.IBeamCursor) # Semi-transparent overlay. # Used to display heat-map visualisation of profiler info, etc. self.overlay = Overlay(self) # Start hidden, make (in)visible with self.toggle_overlay(). self.overlay.hide() # Set to True if the user wants to see tool visualisations. self.show_tool_visualisations = True # Set True if Eco should be running profiler and other tools, # continuously in the background. self.run_background_tools = False def toggle_overlay(self): self.hide_overlay() if self.overlay.isVisible() else self.show_overlay() def show_overlay(self): self.overlay.show() def hide_overlay(self): self.overlay.hide() def is_overlay_visible(self): return self.overlay.isVisible() def resizeEvent(self, event): self.overlay.resize(event.size()) event.accept() def analysis_timer(self): if self.getWindow().show_namebinding(): self.tm.analyse() self.update() self.timer.stop() # save swap filename = self.getEditorTab().filename if filename: self.saveToJson(filename + ".swp", True) def backup_timer(self): filename = self.getEditorTab().filename if filename: self.saveToJson(filename + ".bak", True) def trigger_blinktimer(self): if self.timer.isActive(): self.show_cursor = True return self.show_cursor ^= True self.update() def trigger_undotimer(self): self.tm.save_current_version() self.undotimer.stop() def setImageMode(self, boolean): self.imagemode = boolean def reset(self): #self.getWindow().ui.scrollArea.horizontalScrollBar().setValue(0) #self.getWindow().ui.scrollArea.verticalScrollBar().setValue(0) self.update() def set_mainlanguage(self, parser, lexer, lang_name): self.tm = TreeManager() self.tm.add_parser(parser, lexer, lang_name) def set_sublanguage(self, language): self.sublanguage = language def event(self, event): if event.type() == QEvent.ToolTip: if QToolTip.isVisible(): QToolTip.hideText() event.ignore() return True pos = event.pos() temp_cursor = self.tm.cursor.copy() result = self.coordinate_to_cursor(pos.x(), pos.y()) node = self.tm.cursor.node self.tm.cursor.line = temp_cursor.line self.tm.cursor.node = temp_cursor.node self.tm.cursor.pos = temp_cursor.pos if not result: event.ignore() return True # Draw errors, if there are any. msg = self.tm.get_error(node) if msg: QToolTip.showText(event.globalPos(), msg) # Draw annotations if there are any. elif self.show_tool_visualisations: annotes = [annote.annotation for annote in node.get_annotations_with_hint(ToolTip)] msg = "\n".join(annotes) if msg.strip() != "": if self.tm.tool_data_is_dirty: msg += "\n[Warning: Information may be out of date.]" QToolTip.showText(event.globalPos(), msg) return True return QFrame.event(self, event) # ========================== GUI related stuff ========================== # def blink(self): if self.show_cursor: self.show_cursor = 0 else: self.show_cursor = 1 self.update() def sliderChanged(self, value): change = self.viewport_y - value self.viewport_y = value self.overlay.start_line = self.viewport_y self.update() def sliderXChanged(self, value): self.move(-value*self.fontwt,0) self.resize(self.parentWidget().geometry().width() + value*self.fontwt, self.geometry().height()) if self.x() == 0: self.updateGeometry() self.update() def getScrollSizes(self): total_lines = 0 max_width = 0 for l in self.lines: total_lines += l.height max_width = max(max_width, l.width) max_visible_lines = self.geometry().height() / self.fontht self.scroll_height = max(0, total_lines - max_visible_lines) current_width = self.parentWidget().geometry().width() / self.fontwt self.scroll_width = max(0, max_width - current_width) def paintEvent(self, event): # Clear data in the heatmap overlay self.overlay.clear_data() gfont = QApplication.instance().gfont self.font = gfont.font self.fontwt = gfont.fontwt self.fontht = gfont.fontht QtGui.QFrame.paintEvent(self, event) paint = QtGui.QPainter() if self.imagemode: self.image = QImage() paint.begin(self.image) else: paint.begin(self) paint.setFont(self.font) y = 0 x = 0 self.longest_column = 0 # calculate how many lines we need to show self.init_height = self.geometry().height() self.paintLines(paint, self.viewport_y) paint.end() total_lines = 0 max_width = 0 for l in self.lines: total_lines += l.height max_width = max(max_width, l.width) max_visible_lines = self.geometry().height() / self.fontht self.scroll_height = max(0, total_lines - max_visible_lines) current_width = self.parentWidget().geometry().width() / self.fontwt self.scroll_width = max(0, max_width - current_width) self.emit(SIGNAL("painted()")) # paint lines using new line manager def paintLines(self, paint, startline): # find internal line corresponding to visual line visual_line = 0 internal_line = 0 for l in self.tm.lines: if visual_line + l.height > startline: break visual_line += l.height internal_line += 1 x = 0 y = visual_line - startline # start drawing outside of viewport to display partial images self.paint_start = (internal_line, y) max_y = self.geometry().height() / self.fontht line = internal_line node = self.tm.lines[line].node self.paint_nodes(paint, node, x, y, line, max_y) #XXX if starting node is inside language box, init lbox with amout of languge boxes def paint_nodes(self, paint, node, x, y, line, max_y, lbox=0): settings = QSettings("softdev", "Eco") colors = self.boxcolors if settings.value("app_theme", "Light").toString() in ["Dark"]: alpha = 100 elif settings.value("app_theme", "Light").toString() in ["Gruvbox"]: alpha = 100 else: alpha = 40 first_node = node selected_language = self.tm.mainroot error_node = self.tm.get_mainparser().error_node error_node = self.fix_errornode(error_node) highlighter = self.get_highlighter(node) selection_start = min(self.tm.selection_start, self.tm.selection_end) selection_end = max(self.tm.selection_start, self.tm.selection_end) draw_selection_start = (0,0,0) draw_selection_end = (0,0,0) start_lbox = self.get_languagebox(node) editor = self.get_editor(node) self.selected_lbox = self.tm.get_languagebox(self.tm.cursor.node) #XXX get initial x for langbox if start_lbox: lbox += 1 if start_lbox and self.selected_lbox is start_lbox: draw_lbox = True else: draw_lbox = False draw_all_boxes = self.getWindow().show_languageboxes() self.lines = self.tm.lines self.cursor = self.tm.cursor self.lines[line].height = 1 # reset height draw_cursor = True #l_x = [0] while y < max_y: # if we found a language box, continue drawing inside of it if isinstance(node.symbol, MagicTerminal): #l_x.append(x) #node.pos = x lbox += 1 lbnode = node.symbol.ast if self.selected_lbox is node: self.draw_lbox_bracket(paint, '[', node, x, y) draw_lbox = True selected_language = lbnode else: draw_lbox = False node = lbnode.children[0] highlighter = self.get_highlighter(node) editor = self.get_editor(node) error_node = self.tm.get_parser(lbnode).error_node error_node = self.fix_errornode(error_node) continue if isinstance(node, EOS): lbnode = self.get_languagebox(node) if self.cursor.node is lbnode: self.draw_cursor(paint, x, 5 + y * self.fontht) if lbnode: #l_x.pop() if lbox > 0: lbox -= 1 node = lbnode.next_term highlighter = self.get_highlighter(node) editor = self.get_editor(node) if self.selected_lbox is lbnode: # draw bracket self.draw_lbox_bracket(paint, ']', node, x, y) draw_lbox = False lbnode = self.get_languagebox(node) if lbnode and self.selected_lbox is lbnode: draw_lbox = True error_node = self.tm.get_parser(lbnode.symbol.ast).error_node error_node = self.fix_errornode(error_node) else: error_node = self.tm.get_mainparser().error_node error_node = self.fix_errornode(error_node) continue else: self.lines[line].width = x / self.fontwt break # draw language boxes if lbox > 0 and (draw_lbox or draw_all_boxes): #color = self.nesting_colors[lbox % 5] if draw_all_boxes: color = colors[(lbox-1) % len(colors)] color.setAlpha(alpha) else: color = colors[0] color.setAlpha(alpha) if draw_lbox and draw_all_boxes: # we are drawing the currently selected language box color.setAlpha(20) editor.update_image(node) if node.symbol.name != "\r" and not isinstance(node.symbol, IndentationTerminal): if not node.image or node.plain_mode: paint.fillRect(QRectF(x,3 + y*self.fontht, len(node.symbol.name)*self.fontwt, self.fontht), color) # prepare selection drawing if node is selection_start.node: if node.lookup == "<return>": sel_x = x else: sel_x = x + selection_start.pos * self.fontwt draw_selection_start = (sel_x, y, line) if node is selection_end.node: draw_selection_end = (x + selection_end.pos * self.fontwt, y, line) # draw node dx, dy = editor.paint_node(paint, node, x, y, highlighter) x += dx #y += dy self.lines[line].height = max(self.lines[line].height, dy) # Draw footnotes and add data to heatmap. annotes = [annote.annotation for annote in node.get_annotations_with_hint(Heatmap)] for annote in annotes: self.overlay.add_datum(line + 1, annote) if self.show_tool_visualisations: # Draw footnotes. infofont = QApplication.instance().tool_info_font annotes = [annote.annotation for annote in node.get_annotations_with_hint(Footnote)] footnote = " ".join(annotes) if footnote.strip() != "": if not self.tm.tool_data_is_dirty: infofont.font.setBold(True) else: infofont.font.setBold(False) paint.setFont(infofont.font) paint.setPen(QPen(QColor((highlighter.get_default_color())))) start_x = (0 if (x - len(footnote) * infofont.fontwt) < 0 else x - len(footnote) * infofont.fontwt) start_y = self.fontht + ((y + 1) * self.fontht) paint.drawText(QtCore.QPointF(x-dx, start_y), footnote) self.lines[line].height = max(self.lines[line].height, 2) paint.setFont(self.font) # after we drew a return, update line information if node.lookup == "<return>" and not node is first_node: # draw lbox to end of line if draw_lbox or (draw_all_boxes and lbox > 0): paint.fillRect(QRectF(x,3+y*self.fontht, self.geometry().width()-x, self.fontht), color) self.lines[line].width = x / self.fontwt x = 0#l_x[-1] y += self.lines[line].height line += 1 self.lines[line].height = 1 # reset height # draw cursor if node is self.cursor.node and self.show_cursor: draw_x = max(0, x-dx) cursor_pos = self.cursor.pos if node.symbol.name == "\r": cursor_pos = 0 if node.image and not node.plain_mode: draw_x = x cursor_pos = 0 self.draw_cursor(paint, draw_x + cursor_pos * self.fontwt, 5 + y * self.fontht) if False and line == self.cursor.y and x/self.fontwt >= self.cursor.x and draw_cursor: draw_cursor_at = QRect(0 + self.cursor.x * self.fontwt, 5 + y * self.fontht, 0, self.fontht - 3) paint.drawRect(draw_cursor_at) # set lbox info coordinates infobox_coordinates = (self.cursor.x * self.fontwt, (y+1) * self.fontht) draw_cursor = False # draw squiggly line if node is error_node or (self.getWindow().show_namebinding() and self.tm.has_error(node)): if isinstance(node, EOS): length = self.fontwt else: length = len(node.symbol.name)*self.fontwt if isinstance(node.symbol, MagicTerminal): self.draw_vertical_squiggly_line(paint,x,y) else: if self.tm.has_error(node): color = "orange" else: color = "red" self.draw_squiggly_line(paint,x-length,y,length, color) node = node.next_term if selection_start != selection_end: self.draw_selection(paint, draw_selection_start, draw_selection_end, max_y) # paint infobox if False: lang_name = self.tm.parsers[selected_language] parser = self.tmselected_language lang_status = self.tm.get_parser[selected_language][0].last_status if lang_status is True: color = QColor(100,255,100) else: color = QColor(255,100,100) paint.setFont(infofont) paint.fillRect(QRect(infobox_coordinates[0], 5 + infobox_coordinates[1], len(lang_name)*infofontwt, infofontht), color) paint.drawText(QtCore.QPointF(infobox_coordinates[0], -3 + self.fontht + infobox_coordinates[1]), lang_name) paint.setFont(self.font) return x, y, line def draw_lbox_bracket(self, paint, bracket, node, x, y): assert bracket in ['[',']'] oldpen = paint.pen() newpen = QPen() color = self.get_highlighter(node).get_default_color() newpen.setColor(color) newpen.setWidth(2) paint.setPen(newpen) # paint brackets tmpy = y path = QPainterPath() if bracket == '[': tmpx = x + 1 # adjust bracket position path.moveTo(tmpx, 3+y*self.fontht) path.lineTo(tmpx-2, 3+y*self.fontht) path.moveTo(tmpx-2, 3+y*self.fontht) path.lineTo(tmpx-2, 3+y*self.fontht + self.fontht) else: tmpx = x - 1 path.moveTo(tmpx, 3+y*self.fontht) path.lineTo(tmpx+2, 3+y*self.fontht) path.moveTo(tmpx+2, 3+y*self.fontht) path.lineTo(tmpx+2, 3+y*self.fontht + self.fontht) path.lineTo(tmpx, 3+y*self.fontht + self.fontht) paint.drawPath(path) paint.setPen(oldpen) def fix_errornode(self, error_node): if not error_node: return while isinstance(error_node.symbol, IndentationTerminal): error_node = error_node.next_term return error_node def draw_cursor(self, paint, x, y): pen = paint.pen() colorhex = self.palette().color(QPalette.Text) pen.setColor(QColor(colorhex)) paint.setPen(pen) draw_cursor_at = QRect(x, y, 0, self.fontht - 3) paint.drawRect(draw_cursor_at) def draw_vertical_squiggly_line(self, paint, x, y): paint.setPen(Qt.CustomDashLine) pen = paint.pen() pen.setDashPattern([2,2]) pen.setColor(QColor("red")) paint.setPen(pen) y = 3+y*self.fontht paint.drawLine(x-1, y, x-1, y+self.fontht) paint.drawLine(x, y+2, x, y+self.fontht) paint.setPen(Qt.SolidLine) def draw_squiggly_line(self, paint, x, y, length, color): paint.setPen(Qt.CustomDashLine) pen = paint.pen() pen.setDashPattern([2,2]) pen.setColor(QColor(color)) paint.setPen(pen) #x -= length y = (y+1)*self.fontht+1 paint.drawLine(x, y, x+length, y) paint.drawLine(x+2, y+1, x+2+length, y+1) paint.setPen(Qt.SolidLine) def draw_selection(self, paint, draw_selection_start, draw_selection_end, max_y): x1, y1, line1 = draw_selection_start x2, y2, line2 = draw_selection_end if x1 + y1 + line1 == 0: # start outside of viewport line1 = self.paint_start[0] if line2 == 0: # end outside of viewport line2 = self.paint_start[0] + max_y if y1 + y2 == 0: # start and end outside of viewport y2 = max_y if y1 == y2: paint.fillRect(QRectF(x1, 3 + y1 * self.fontht, x2-x1, self.fontht), QColor(0,0,255,100)) else: paint.fillRect(QRectF(x1, 3 + y1 * self.fontht, self.tm.lines[line1].width*self.fontwt - x1, self.fontht), QColor(0,0,255,100)) y = y1 + self.tm.lines[line1].height for i in range(line1+1, line2): width = self.tm.lines[i].width*self.fontwt if width == 0: width = self.fontwt paint.fillRect(QRectF(0, 3 + y * self.fontht, width, self.fontht), QColor(0,0,255,100)) y = y + self.tm.lines[i].height paint.fillRect(QRectF(0, 3 + y2 * self.fontht, x2, self.fontht), QColor(0,0,255,100)) def get_highlighter(self, node): root = node.get_root() base = lang_dict[self.tm.get_language(root)].base s = syntaxhighlighter.get_highlighter(base, self.palette()) return s def get_languagebox(self, node): root = node.get_root() lbox = root.get_magicterminal() return lbox def get_editor(self, node): root = node.get_root() base = lang_dict[self.tm.get_language(root)].base return editor.get_editor(base, self.fontwt, self.fontht) def focusNextPrevChild(self, b): # don't switch to next widget on TAB return False def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self.tm.input_log.append("# mousePressEvent") self.coordinate_to_cursor(e.x(), e.y()) # self.tm.cursor = cursor self.tm.selection_start = self.tm.cursor.copy() self.tm.selection_end = self.tm.cursor.copy() self.tm.input_log.append("self.selection_start = self.cursor.copy()") self.tm.input_log.append("self.selection_end = self.cursor.copy()") #self.tm.fix_cursor_on_image() self.getWindow().showLookahead() self.update() def mouseDoubleClickEvent(self, e): if e.button() == Qt.LeftButton: self.coordinate_to_cursor(e.x(), e.y()) node = self.tm.get_node_from_cursor() lbox = self.get_languagebox(node) if lbox and lbox.symbol.name == "<IPython>": if lbox.plain_mode is False: lbox.plain_mode = True else: lbox.plain_mode = False self.update() return elif node.image is None: self.tm.selection_start = self.tm.cursor.copy() self.tm.selection_start.node = self.tm.cursor.find_previous_visible(self.tm.cursor.node) self.tm.selection_start.pos = len(self.tm.selection_start.node.symbol.name) self.tm.selection_end = self.tm.cursor.copy() self.tm.selection_end.pos = len(self.tm.selection_end.node.symbol.name) self.tm.cursor.pos = self.tm.selection_end.pos self.tm.cursor.node = self.tm.selection_end.node self.update() return if node.plain_mode is False: node.plain_mode = True self.tm.cursor.pos = len(node.symbol.name) else: node.plain_mode = False self.update() def cursor_to_coordinate(self): y = 0 for l in self.tm.lines[:self.cursor.line]: y += l.height * self.fontht x = self.tm.cursor.get_x() * self.fontwt y = y - self.getScrollArea().verticalScrollBar().value() * self.fontht return (x,y) def coordinate_to_cursor(self, x, y): mouse_y = y / self.fontht first_line = self.paint_start[0] y_offset = self.paint_start[1] y = y_offset line = first_line if mouse_y < 0: while line > 0: y -= self.tm.lines[line].height if y < mouse_y: break line -= 1 else: while line < len(self.tm.lines) - 1: y += self.tm.lines[line].height if y > mouse_y: break line += 1 self.tm.cursor.line = line cursor_x = int(round(float(x) / self.fontwt)) self.tm.cursor.move_to_x(cursor_x, self.tm.lines) self.tm.input_log.append("self.cursor.line = %s" % str(line)) self.tm.log_input("cursor.move_to_x", str(cursor_x), "self.lines") if mouse_y > y or self.tm.cursor.get_x() != cursor_x: return False return True def mouseMoveEvent(self, e): # apparaently this is only called when a mouse button is clicked while # the mouse is moving if self.tm.input_log[-2].startswith("self.cursor.move_to_x"): # only log the last move event self.tm.input_log.pop() self.tm.input_log.pop() self.tm.input_log.pop() self.coordinate_to_cursor(e.x(), e.y()) self.tm.selection_end = self.tm.cursor.copy() self.tm.input_log.append("self.selection_end = self.cursor.copy()") self.update() self.getEditorTab().keypress() def key_to_string(self, key): if key == Qt.Key_Up: return "up" if key == Qt.Key_Down: return "down" if key == Qt.Key_Left: return "left" if key == Qt.Key_Right: return "right" def keyPressEvent(self, e): startundotimer = False self.timer.start(500) self.show_cursor = True if e.key() in [Qt.Key_Shift, Qt.Key_Alt, Qt.Key_Control, Qt.Key_Meta, Qt.Key_AltGr]: if e.key() == Qt.Key_Shift: self.tm.key_shift() return text = e.text() self.edit_rightnode = False # has been processes in get_nodes_at_pos -> reset if e.key() == Qt.Key_Escape: self.tm.key_escape() elif e.key() == Qt.Key_Backspace: startundotimer = True self.tm.key_backspace() elif e.key() in [Qt.Key_Up, Qt.Key_Down, Qt.Key_Left, Qt.Key_Right]: if e.modifiers() == Qt.ShiftModifier: self.tm.key_cursors(self.key_to_string(e.key()), True) elif e.modifiers() == Qt.ControlModifier: self.tm.ctrl_cursor(self.key_to_string(e.key())) else: self.tm.key_cursors(self.key_to_string(e.key()), False) elif e.key() == Qt.Key_Home: self.tm.key_home(e.modifiers() == Qt.ShiftModifier) elif e.key() == Qt.Key_End: self.tm.key_end(e.modifiers() == Qt.ShiftModifier) elif e.key() == Qt.Key_Delete: startundotimer = True self.tm.key_delete() elif e.key() == Qt.Key_F3: self.tm.find_next() elif e.key() in [Qt.Key_PageUp, Qt.Key_PageDown]: pass # ignore those keys elif e.modifiers() in [Qt.ControlModifier, Qt.AltModifier]: # User pressed Ctrl- Or Alt- (etc.) i.e. a character we can't # sensibly insert into the text. pass else: startundotimer = True if e.key() == Qt.Key_Tab: text = " " else: text = e.text() if text.toUtf8() not in whitelist: logging.debug("Key %s not supported" % text) return self.tm.key_normal(text) self.getWindow().btReparse([]) self.update() self.emit(SIGNAL("keypress(QKeyEvent)"), e) self.getWindow().showLookahead() if startundotimer: self.undotimer.start(500) def showLanguageBoxMenu(self): self.showSubgrammarMenu() self.create_languagebox() def create_languagebox(self): if self.sublanguage: if self.tm.hasSelection(): self.tm.surround_with_languagebox(self.sublanguage) else: self.tm.add_languagebox(self.sublanguage) def change_languagebox(self): if self.sublanguage: self.tm.change_languagebox(self.sublanguage) def showCodeCompletion(self): l = self.tm.getCompletion() if l: self.showCodeCompletionMenu(l) def println(self, prestring, y): node = self.lines[y].node.next_term x = [] while node is not None and node.symbol.name != "\r": x.append(node.symbol.name) node = node.next_term print(prestring, "".join(x)) def print_line(self, y): current = self.lines[y].node while True: print(current) current = current.next_term if current is None: return # ========================== AST modification stuff ========================== # def insertTextNoSim(self, text): self.viewport_y = 0 self.tm.import_file(text) return def getTL(self): return self.getWindow().tl def getPL(self): return self.getWindow().pl def getLRP(self): return self.getWindow().lrp def getWindow(self): return self.window() def getEditorTab(self): return self.parent().parent().parent() def getScrollArea(self): return self.parent().parent() def createSubgrammarMenu(self, menu, change=False): self.sublanguage = None tmp = None if change: # try and find lbox and set cursor to previous node before getting # lookahead list root = self.tm.cursor.node.get_root() lbox = root.get_magicterminal() if lbox: tmp = self.tm.cursor.node self.tm.cursor.node = lbox.prev_term # Create actions bf = QFont() bf.setBold(True) valid_langs = [] for l in languages: if "<%s>" % l in self.tm.getLookaheadList(): valid_langs.append(l) if tmp: # undo cursor change self.tm.cursor.node = tmp if len(valid_langs) > 0: for l in valid_langs: item = QAction(str(l), menu) item.setData(l) self._set_icon(item, l) item.setFont(bf) menu.addAction(item) menu.addSeparator() for l in languages: item = QAction(str(l), menu) item.setData(l) self._set_icon(item, l) menu.addAction(item) return menu def showSubgrammarMenu(self): menu = QtGui.QMenu("Language", self) self.createSubgrammarMenu(menu) x,y = self.cursor_to_coordinate() action = menu.exec_(self.mapToGlobal(QPoint(0,0)) + QPoint(3 + x, y + self.fontht)) if action: self.sublanguage = action.data().toPyObject() self.edit_rightnode = True def _set_icon(self, mitem, lang): if lang.base.lower() == "html": icon = QIcon.fromTheme("text-xhtml+xml") else: icon = QIcon.fromTheme("text-x-" + lang.base.lower()) if icon.isNull(): icon = QIcon.fromTheme("application-x-" + lang.base.lower()) if icon.isNull(): icon = QIcon.fromTheme("text-x-generic") mitem.setIcon(icon) def showCodeCompletionMenu(self, l): menu = QtGui.QMenu( self ) # Create actions toolbar = QtGui.QToolBar() for n in l: path = [] for p in n.path: if p and p.name: path.append(p.name) if n.vartype: vartype = n.vartype while vartype.children != []: try: vartype = vartype.children[0] except KeyError: vartype = vartype.children["name"] text = "%s : %s - %s (%s)" % (n.name, vartype.symbol.name, ".".join(path), n.kind) elif n.kind == "method": text = self.cc_method(n) + " - %s" % (".".join(path)) else: text = "%s - %s (%s)" % (n.name, ".".join(path), n.kind) item = toolbar.addAction(text, self.createCCFunc(n.name)) item.setIcon(QIcon("gui/" + n.kind + ".png")) menu.addAction(item) x,y = self.cursor_to_coordinate() menu.exec_(self.mapToGlobal(QPoint(0,0)) + QPoint(3 + x, y + self.fontht)) def cc_method(self, n): s = [n.name, "("] param_ln = n.astnode.children["params"] if isinstance(param_ln, ListNode): for p in param_ln.children: tmp = p.children["type"] if isinstance(tmp, AstNode): s.append(tmp.children["name"].symbol.name) else: s.append(tmp.symbol.name) s.append(" ") s.append(p.children["name"].symbol.name) if p != param_ln.children[-1]: s.append(", ") s.append(")") return "".join(s) def createMenuFunction(self, l): def action(): self.sublanguage = l self.edit_rightnode = True return action def createCCFunc(self, text): def action(): self.tm.pasteCompletion(text) return action def selectSubgrammar(self, item): pass def saveToJson(self, filename, swap=False): whitespaces = self.tm.get_mainparser().whitespaces root = self.tm.parsers[0][0].previous_version.parent language = self.tm.parsers[0][2] manager = JsonManager() manager.save(root, language, whitespaces, filename) if not swap: self.tm.changed = False self.emit(SIGNAL("painted()")) def loadFromJson(self, filename): manager = JsonManager() language_boxes = manager.load(filename) self.tm = TreeManager() self.tm.load_file(language_boxes) self.reset() def export(self, run=False, profile=False): return self.tm.export(None, run, profile)
def __init__(self): # PREPARE LOGGING FIRST TO ENSURE # THE ABILITY TO OUTPUT ERROR LOGS # # create logging folders self._makeLogDirs() # initialise the logger self.logger = self._setLogger() # catch exceptions to log them try: # call parent class constructor Configurable.__init__(self, self.SLF_PATH) # initialise overlay self.overlay = Overlay(f'{self.PRG_NAME.upper()} {self.PRG_VERS}') # point pytesseract at tesseract installation self._setPyTesseract() # initialise a lobby reader self.lobby_reader = LobbyReader() # initialise a loot reader self.loot_reader = LootReader() # initialise a bounty reader self.bounty_reader = BountyReader() # initialise a data sender self.data_sender = DataSender() # read user from config file self.user = self._setUser() # read game patch self.patch = self._setGamePatch() # initialise screen capture as empty self.screen_capture = None # data holders self.bounty_data = {} self.lobby_data = {} self.loot_data = [] # exception counter for repeated issue handling self.exc_counter = 0 # welcome the user self.welcomeMessage() except Exception as e: # log the exception self.logger.error(str(e)) # shut down the app quit()