def loadCFG(self): cfg = Config("apps/python/prunn/", "config.ini") if cfg.get("SETTINGS", "lap_can_be_invalidated", "int") == 1: self.lapCanBeInvalidated = True else: self.lapCanBeInvalidated = False self.ui_row_height.setValue(cfg.get("SETTINGS", "ui_row_height", "int")) if self.ui_row_height.hasChanged(): self.reDrawSize()
def __init__(self): self.window = Window(name="ACTV Delta", icon=False, width=240, height=184, texture="") self.cursor = Value(False) self.session = Value(-1) self.performance = Value(0) self.spline = Value(0) self.laptime = Value(0) self.TimeLeftUpdate = Value(0) self.referenceLap = [] self.referenceLapTime = Value(0) self.lastLapTime = Value(0) self.lapCount = 0 self.lastLapIsValid = True self.currentLap = [] self.deltaLoaded = False self.thread_save = False self.highlight_end = 0 self.rowHeight = Value(-1) self.lbl_delta = ( Label(self.window.app, "+0.000") .setSize(150, 36) .setPos(0, 60) .setFontSize(26) .setAlign("right") .setVisible(1) ) self.lbl_lap = ( Label(self.window.app, "0.000") .setSize(150, 32) .setPos(0, 86) .setFontSize(17) .setAlign("right") .setVisible(1) ) self.btn_reset = ( Button(self.window.app, self.onResetPress) .setPos(90, 68) .setSize(60, 20) .setText("Reset") .setAlign("center") .setBgColor(rgb([255, 12, 12], bg=True)) .setVisible(0) ) self.spin_row_height = ac.addSpinner(self.window.app, "") ac.setRange(self.spin_row_height, 20, 48) ac.setPosition(self.spin_row_height, 20, 28) ac.setValue(self.spin_row_height, self.__class__.ui_row_height) ac.addOnValueChangeListener(self.spin_row_height, self.onSpinRowHeightChanged) ac.setVisible(self.spin_row_height, 0) fontName = "Segoe UI" if ac.initFont(0, fontName, 0, 0) > 0: self.lbl_delta.setFont(fontName, 0, 1) self.cfg = Config("apps/python/prunn/", "config.ini") self.loadCFG()
def checkMPH(self,cfg_path): conf = Config(cfg_path, "/gameplay.ini") opt_mph = conf.get("OPTIONS", "USE_MPH",type = "int") if opt_mph == 1: self.useMPH = True
class Configuration: configChanged = False race_mode = 0 qual_mode = 0 lapCanBeInvalidated = 1 max_num_cars = 18 max_num_laps_stint = 8 ui_row_height = 36 # INITIALIZATION def __init__(self): self.session = Value(-1) self.listen_active = True self.window = Window(name="ACTV Config", icon=True, width=251, height=480, texture="").setBgOpacity(0.6) y = 60 self.spin_race_mode = ac.addSpinner(self.window.app, "Race tower mode :") ac.setRange(self.spin_race_mode, 0, 2) ac.setPosition(self.spin_race_mode, 20, y) ac.setValue(self.spin_race_mode, self.__class__.race_mode) ac.addOnValueChangeListener(self.spin_race_mode, self.onSpinRaceModeChanged) self.lbl_race_mode = ( Label(self.window.app, "Auto") .setSize(120, 26) .setPos(186, y - 28) .setFontSize(12) .setAlign("left") .setVisible(1) ) y += 80 self.spin_qual_mode = ac.addSpinner(self.window.app, "Qual tower mode :") ac.setRange(self.spin_qual_mode, 0, 1) ac.setPosition(self.spin_qual_mode, 20, y) ac.setValue(self.spin_qual_mode, self.__class__.qual_mode) ac.addOnValueChangeListener(self.spin_qual_mode, self.onSpinQualModeChanged) self.lbl_qual_mode = ( Label(self.window.app, "Gaps") .setSize(120, 26) .setPos(186, y - 28) .setFontSize(12) .setAlign("left") .setVisible(1) ) y += 80 self.spin_num_cars = ac.addSpinner(self.window.app, "Number cars tower") ac.setRange(self.spin_num_cars, 6, 28) ac.setPosition(self.spin_num_cars, 20, y) ac.setValue(self.spin_num_cars, self.__class__.max_num_cars) ac.addOnValueChangeListener(self.spin_num_cars, self.onSpinNumCarsChanged) y += 80 self.spin_num_laps = ac.addSpinner(self.window.app, "Number laps stint mode") ac.setRange(self.spin_num_laps, 2, 28) ac.setPosition(self.spin_num_laps, 20, y) ac.setValue(self.spin_num_laps, self.__class__.max_num_laps_stint) ac.addOnValueChangeListener(self.spin_num_laps, self.onSpinNumLapsChanged) y += 80 self.spin_row_height = ac.addSpinner(self.window.app, "Row height") ac.setRange(self.spin_row_height, 20, 48) ac.setPosition(self.spin_row_height, 20, y) ac.setValue(self.spin_row_height, self.__class__.ui_row_height) ac.addOnValueChangeListener(self.spin_row_height, self.onSpinRowHeightChanged) y += 60 self.chk_invalidated = ac.addCheckBox(self.window.app, "") ac.setPosition(self.chk_invalidated, 20, y) ac.addOnCheckBoxChanged(self.chk_invalidated, self.onCheckInvalidatedChanged) self.lbl_title_invalidated = ( Label(self.window.app, "Lap can be invalidated") .setSize(200, 26) .setPos(65, y + 1) .setFontSize(16) .setAlign("left") .setVisible(1) ) self.cfg_loaded = False self.cfg = Config("apps/python/prunn/", "config.ini") self.loadCFG() # thread self.key_listener = threading.Thread(target=self.listen_key) self.key_listener.daemon = True self.key_listener.start() def __del__(self): self.listen_active = False def loadCFG(self): self.__class__.lapCanBeInvalidated = self.cfg.get("SETTINGS", "lap_can_be_invalidated", "int") if self.__class__.lapCanBeInvalidated == -1: self.__class__.lapCanBeInvalidated = 1 self.__class__.max_num_cars = self.cfg.get("SETTINGS", "num_cars_tower", "int") if self.__class__.max_num_cars == -1: self.__class__.max_num_cars = 18 self.__class__.max_num_laps_stint = self.cfg.get("SETTINGS", "num_laps_stint", "int") if self.__class__.max_num_laps_stint == -1: self.__class__.max_num_laps_stint = 8 self.__class__.ui_row_height = self.cfg.get("SETTINGS", "ui_row_height", "int") if self.__class__.ui_row_height == -1: self.__class__.ui_row_height = 36 self.__class__.race_mode = self.cfg.get("SETTINGS", "race_mode", "int") if self.__class__.race_mode == -1: self.__class__.race_mode = 0 self.__class__.qual_mode = self.cfg.get("SETTINGS", "qual_mode", "int") if self.__class__.qual_mode == -1: self.__class__.qual_mode = 0 ac.setValue(self.spin_race_mode, self.__class__.race_mode) ac.setValue(self.spin_qual_mode, self.__class__.qual_mode) ac.setValue(self.spin_num_cars, self.__class__.max_num_cars) ac.setValue(self.spin_num_laps, self.__class__.max_num_laps_stint) ac.setValue(self.spin_row_height, self.__class__.ui_row_height) ac.setValue(self.chk_invalidated, self.__class__.lapCanBeInvalidated) self.setLabelQual() self.setLabelRace() self.cfg_loaded = True def saveCFG(self): self.setLabelRace() self.setLabelQual() self.cfg.set("SETTINGS", "race_mode", self.__class__.race_mode) self.cfg.set("SETTINGS", "qual_mode", self.__class__.qual_mode) self.cfg.set("SETTINGS", "lap_can_be_invalidated", self.__class__.lapCanBeInvalidated) self.cfg.set("SETTINGS", "num_cars_tower", self.__class__.max_num_cars) self.cfg.set("SETTINGS", "num_laps_stint", self.__class__.max_num_laps_stint) self.cfg.set("SETTINGS", "ui_row_height", self.__class__.ui_row_height) def setLabelQual(self): if self.__class__.qual_mode == 0: self.lbl_qual_mode.setText("Gaps") else: self.lbl_qual_mode.setText("Times") def setLabelRace(self): if self.__class__.race_mode == 0: self.lbl_race_mode.setText("Auto") elif self.__class__.race_mode == 1: self.lbl_race_mode.setText("Full-Gaps") else: self.lbl_race_mode.setText("Full") def onUpdate(self, sim_info): self.window.setBgOpacity(0.6).border(0) self.session.setValue(sim_info.graphics.session) if self.__class__.configChanged and self.cfg_loaded: self.saveCFG() self.__class__.configChanged = False return True elif self.__class__.configChanged and not self.cfg_loaded: self.__class__.configChanged = False return False def listen_key(self): try: # ctypes.windll.user32.RegisterHotKey(None, 1, 0, apps.util.win32con.VK_F7) ctypes.windll.user32.RegisterHotKey(None, 1, apps.util.win32con.MOD_CONTROL, 0x44) # CTRL+D msg = ctypes.wintypes.MSG() while self.listen_active: if ctypes.windll.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0: # ac.console("loopmess."+ str(msg.message)) if msg.message == apps.util.win32con.WM_HOTKEY: self.hotkey_pressed() ctypes.windll.user32.TranslateMessage(ctypes.byref(msg)) ctypes.windll.user32.DispatchMessageA(ctypes.byref(msg)) except: Log.w("Error") finally: ctypes.windll.user32.UnregisterHotKey(None, 1) def hotkey_pressed(self): if self.session.value == 2: if self.__class__.race_mode >= 2: self.__class__.race_mode = 0 else: self.__class__.race_mode += 1 ac.setValue(self.spin_race_mode, self.__class__.race_mode) else: if self.__class__.qual_mode >= 1: self.__class__.qual_mode = 0 else: self.__class__.qual_mode += 1 ac.setValue(self.spin_qual_mode, self.__class__.qual_mode) self.__class__.configChanged = True @staticmethod def onCheckInvalidatedChanged(name, state): Configuration.lapCanBeInvalidated = state Configuration.configChanged = True @staticmethod def onSpinNumCarsChanged(value): Configuration.max_num_cars = value Configuration.configChanged = True @staticmethod def onSpinNumLapsChanged(value): Configuration.max_num_laps_stint = value Configuration.configChanged = True @staticmethod def onSpinRowHeightChanged(value): Configuration.ui_row_height = value Configuration.configChanged = True @staticmethod def onSpinRaceModeChanged(value): Configuration.race_mode = value Configuration.configChanged = True @staticmethod def onSpinQualModeChanged(value): Configuration.qual_mode = value Configuration.configChanged = True
def __init__(self): self.session = Value(-1) self.listen_active = True self.window = Window(name="ACTV Config", icon=True, width=251, height=480, texture="").setBgOpacity(0.6) y = 60 self.spin_race_mode = ac.addSpinner(self.window.app, "Race tower mode :") ac.setRange(self.spin_race_mode, 0, 2) ac.setPosition(self.spin_race_mode, 20, y) ac.setValue(self.spin_race_mode, self.__class__.race_mode) ac.addOnValueChangeListener(self.spin_race_mode, self.onSpinRaceModeChanged) self.lbl_race_mode = ( Label(self.window.app, "Auto") .setSize(120, 26) .setPos(186, y - 28) .setFontSize(12) .setAlign("left") .setVisible(1) ) y += 80 self.spin_qual_mode = ac.addSpinner(self.window.app, "Qual tower mode :") ac.setRange(self.spin_qual_mode, 0, 1) ac.setPosition(self.spin_qual_mode, 20, y) ac.setValue(self.spin_qual_mode, self.__class__.qual_mode) ac.addOnValueChangeListener(self.spin_qual_mode, self.onSpinQualModeChanged) self.lbl_qual_mode = ( Label(self.window.app, "Gaps") .setSize(120, 26) .setPos(186, y - 28) .setFontSize(12) .setAlign("left") .setVisible(1) ) y += 80 self.spin_num_cars = ac.addSpinner(self.window.app, "Number cars tower") ac.setRange(self.spin_num_cars, 6, 28) ac.setPosition(self.spin_num_cars, 20, y) ac.setValue(self.spin_num_cars, self.__class__.max_num_cars) ac.addOnValueChangeListener(self.spin_num_cars, self.onSpinNumCarsChanged) y += 80 self.spin_num_laps = ac.addSpinner(self.window.app, "Number laps stint mode") ac.setRange(self.spin_num_laps, 2, 28) ac.setPosition(self.spin_num_laps, 20, y) ac.setValue(self.spin_num_laps, self.__class__.max_num_laps_stint) ac.addOnValueChangeListener(self.spin_num_laps, self.onSpinNumLapsChanged) y += 80 self.spin_row_height = ac.addSpinner(self.window.app, "Row height") ac.setRange(self.spin_row_height, 20, 48) ac.setPosition(self.spin_row_height, 20, y) ac.setValue(self.spin_row_height, self.__class__.ui_row_height) ac.addOnValueChangeListener(self.spin_row_height, self.onSpinRowHeightChanged) y += 60 self.chk_invalidated = ac.addCheckBox(self.window.app, "") ac.setPosition(self.chk_invalidated, 20, y) ac.addOnCheckBoxChanged(self.chk_invalidated, self.onCheckInvalidatedChanged) self.lbl_title_invalidated = ( Label(self.window.app, "Lap can be invalidated") .setSize(200, 26) .setPos(65, y + 1) .setFontSize(16) .setAlign("left") .setVisible(1) ) self.cfg_loaded = False self.cfg = Config("apps/python/prunn/", "config.ini") self.loadCFG() # thread self.key_listener = threading.Thread(target=self.listen_key) self.key_listener.daemon = True self.key_listener.start()
def loadCFG(self): cfg = Config("apps/python/prunn/", "config.ini") self.ui_row_height.setValue(cfg.get("SETTINGS", "ui_row_height", "int")) if self.ui_row_height.hasChanged(): self.reDrawSize()
class ACDelta: resetPressed = False configChanged = False ui_row_height = 38 # INITIALIZATION def __init__(self): self.window = Window(name="ACTV Delta", icon=False, width=240, height=184, texture="") self.cursor = Value(False) self.session = Value(-1) self.performance = Value(0) self.spline = Value(0) self.laptime = Value(0) self.TimeLeftUpdate = Value(0) self.referenceLap = [] self.referenceLapTime = Value(0) self.lastLapTime = Value(0) self.lapCount = 0 self.lastLapIsValid = True self.currentLap = [] self.deltaLoaded = False self.thread_save = False self.highlight_end = 0 self.rowHeight = Value(-1) self.lbl_delta = ( Label(self.window.app, "+0.000") .setSize(150, 36) .setPos(0, 60) .setFontSize(26) .setAlign("right") .setVisible(1) ) self.lbl_lap = ( Label(self.window.app, "0.000") .setSize(150, 32) .setPos(0, 86) .setFontSize(17) .setAlign("right") .setVisible(1) ) self.btn_reset = ( Button(self.window.app, self.onResetPress) .setPos(90, 68) .setSize(60, 20) .setText("Reset") .setAlign("center") .setBgColor(rgb([255, 12, 12], bg=True)) .setVisible(0) ) self.spin_row_height = ac.addSpinner(self.window.app, "") ac.setRange(self.spin_row_height, 20, 48) ac.setPosition(self.spin_row_height, 20, 28) ac.setValue(self.spin_row_height, self.__class__.ui_row_height) ac.addOnValueChangeListener(self.spin_row_height, self.onSpinRowHeightChanged) ac.setVisible(self.spin_row_height, 0) fontName = "Segoe UI" if ac.initFont(0, fontName, 0, 0) > 0: self.lbl_delta.setFont(fontName, 0, 1) self.cfg = Config("apps/python/prunn/", "config.ini") self.loadCFG() @staticmethod def onSpinRowHeightChanged(value): ACDelta.ui_row_height = value ACDelta.configChanged = True @staticmethod def onResetPress(a, b): ACDelta.resetPressed = True # PUBLIC METHODS def loadCFG(self): self.__class__.ui_row_height = self.cfg.get("DELTA", "delta_row_height", "int") ac.setValue(self.spin_row_height, self.__class__.ui_row_height) self.reDrawSize() def saveCFG(self): self.reDrawSize() self.cfg.set("DELTA", "delta_row_height", self.__class__.ui_row_height) def reDrawSize(self): if self.__class__.ui_row_height > 0: self.rowHeight.setValue(self.__class__.ui_row_height) else: self.rowHeight.setValue(38) if self.rowHeight.hasChanged(): fontSize = getFontSize(self.rowHeight.value) fontSize2 = getFontSize(self.rowHeight.value - 16) rowHeight2 = self.rowHeight.value - 16 # width=self.rowHeight*5 self.lbl_delta.setSize(rowHeight2 / 24 * 32 + 120, self.rowHeight.value).setFontSize(fontSize) self.lbl_lap.setSize(rowHeight2 / 24 * 32 + 120, rowHeight2).setPos( 0, self.rowHeight.value + 54 ).setFontSize(fontSize2) self.btn_reset.setSize(self.rowHeight.value + 26, rowHeight2).setPos( 90, self.rowHeight.value * 2 + 48 ).setFontSize(fontSize2) def getDeltaFilePath(self): trackFilePath = os.path.join( os.path.expanduser("~"), "Documents", "Assetto Corsa", "plugins", "actv_deltas", "default" ) if not os.path.exists(trackFilePath): os.makedirs(trackFilePath) trackFilePath += "/" + ac.getTrackName(0) if ac.getTrackConfiguration(0) != "": trackFilePath += "_" + ac.getTrackConfiguration(0) trackFilePath += "_" + ac.getCarName(0) + ".delta" return trackFilePath def saveDelta(self): # ac.log(str(time.time())+" saveDelta start:") referenceLap = list(self.referenceLap) # referenceLap=self.referenceLap referenceLapTime = self.referenceLapTime.value if len(referenceLap) > 0: try: times = [] for l in referenceLap: times.append((l.sector, l.time)) data_file = { "lap": referenceLapTime, "times": times, "track": ac.getTrackName(0), "config": ac.getTrackConfiguration(0), "car": ac.getCarName(0), "user": ac.getDriverName(0), } file = self.getDeltaFilePath() with gzip.open(file, "wt") as outfile: json.dump(data_file, outfile) except: Log.w("Error tower") # ac.console("lap saved:" + str(referenceLapTime) + ","+str(len(referenceLap))) # ac.log(str(time.time())+" lap saved:" + str(referenceLapTime) + ","+str(len(referenceLap))) def loadDelta(self): self.deltaLoaded = True file = self.getDeltaFilePath() if os.path.exists(file): try: with gzip.open(file, "rt") as data_file: data = json.load(data_file) self.referenceLapTime.setValue(data["lap"]) times = data["times"] self.referenceLap = [] for t in times: self.referenceLap.append(raceGaps(t[0], t[1])) ac.console("AC Delta: File loaded") except: Log.w("Error tower") def getPerformanceGap(self, sector, time): if len(self.referenceLap) < 10: return round(ac.getCarState(0, acsys.CS.PerformanceMeter) * 1000) # if self.referenceLap[sector*100] if sector > 0.5: referenceLap = reversed(self.referenceLap) else: referenceLap = self.referenceLap for l in referenceLap: if l.sector == sector: return time - l.time # do not update return False def time_splitting(self, ms, full="no"): s = ms / 1000 m, s = divmod(s, 60) h, m = divmod(m, 60) # d,h=divmod(h,24) if full == "yes": d = ms % 1000 if h > 0: return "{0}:{1}:{2}.{3}".format( int(h), str(int(m)).zfill(2), str(int(s)).zfill(2), str(int(d)).zfill(3) ) elif m > 0: return "{0}:{1}.{2}".format(int(m), str(int(s)).zfill(2), str(int(d)).zfill(3)) else: return "{0}.{1}".format(int(s), str(int(d)).zfill(3)) else: d = ms / 100 % 10 if h > 0: return "{0}:{1}:{2}.{3}".format(int(h), str(int(m)).zfill(2), str(int(s)).zfill(2), int(d)) elif m > 0: return "{0}:{1}.{2}".format(int(m), str(int(s)).zfill(2), int(d)) else: return "{0}.{1}".format(int(s), int(d)) def manageWindow(self): pt = POINT() result = ctypes.windll.user32.GetCursorPos(ctypes.byref(pt)) win_x = self.window.getPos().x win_y = self.window.getPos().y if win_x > 0: self.window.last_x = win_x self.window.last_y = win_y else: self.window.setLastPos() win_x = self.window.getPos().x win_y = self.window.getPos().y if ( result and pt.x > win_x and pt.x < win_x + self.window.width and pt.y > win_y and pt.y < win_y + self.window.height ): self.cursor.setValue(True) else: self.cursor.setValue(False) sessionChanged = self.session.hasChanged() if sessionChanged: self.resetData() if self.cursor.hasChanged() or sessionChanged: if self.cursor.value: self.window.setBgOpacity(0.4).border(0) self.window.showTitle(True) self.btn_reset.setVisible(1) ac.setVisible(self.spin_row_height, 1) else: self.window.setBgOpacity(0).border(0) self.window.showTitle(False) self.btn_reset.setVisible(0) ac.setVisible(self.spin_row_height, 0) def resetData(self): self.currentLap = [] self.lastLapIsValid = True self.lapCount = 0 self.highlight_end = 0 def onUpdate(self, sim_info): if self.__class__.configChanged: self.saveCFG() self.__class__.configChanged = False if not self.deltaLoaded: thread_load = threading.Thread(target=self.loadDelta) thread_load.daemon = True thread_load.start() if self.__class__.resetPressed: self.referenceLapTime.setValue(0) self.referenceLap = [] self.__class__.resetPressed = False self.session.setValue(sim_info.graphics.session) self.manageWindow() self.lbl_delta.animate() self.lbl_lap.animate() sim_info_status = sim_info.graphics.status if sim_info_status == 2: # LIVE sessionTimeLeft = sim_info.graphics.sessionTimeLeft if math.isinf( sessionTimeLeft ): # or (sim_info.graphics.iCurrentTime == 0 and sim_info.graphics.completedLaps == 0): self.resetData() elif self.session.value == 2 and sessionTimeLeft > 1800000: self.resetData() elif bool(ac.isCarInPitline(0)) or bool(ac.isCarInPit(0)): self.resetData() self.spline.setValue(round(ac.getCarState(0, acsys.CS.NormalizedSplinePosition), 3)) if self.lastLapIsValid and sim_info.physics.numberOfTyresOut >= 4: self.lastLapIsValid = False if self.spline.hasChanged(): self.laptime.setValue(round(ac.getCarState(0, acsys.CS.LapTime), 3)) self.lastLapTime.setValue(ac.getCarState(0, acsys.CS.LastLap)) gap = self.getPerformanceGap(self.spline.value, self.laptime.value) if gap != False: self.performance.setValue(gap) # new lap if self.lastLapTime.hasChanged(): # ac.console("newlap----")(self.laptime.old > self.laptime.value) or # ac.console("lastLap=currentLap---waiting " + str(self.laptime.old) + ":" + str(self.laptime.value)) # ac.log(str(time.time()) +" lastLap=currentLap---waiting " + str(self.laptime.old) + ":" + str(self.laptime.value)) if ( (self.referenceLapTime.value == 0 or self.lastLapTime.value < self.referenceLapTime.value) and self.lastLapIsValid and self.lastLapTime.value > 0 and self.lapCount < ac.getCarState(0, acsys.CS.LapCount) ): self.referenceLapTime.setValue(self.lastLapTime.value) # self.referenceLap=list(self.lastLap) self.referenceLap = list(self.currentLap) if len(self.referenceLap) > 2000: # 2laps in ac.console("too many laps in reference----") ac.log("too many laps in reference----") how_much = math.floor(len(self.referenceLap) / 1000) del self.referenceLap[0 : math.floor(len(self.referenceLap) / how_much)] # self.referenceLap=self.lastLap#self.lastLap=list(self.currentLap) # ac.log(str(time.time()) +" referenceLap=lastlap --- lets save") # ac.console("referenceLap=lastlap --- lets save") thread_save = threading.Thread(target=self.saveDelta) thread_save.daemon = True thread_save.start() # make it green for 5 sec self.highlight_end = sim_info.graphics.sessionTimeLeft - 6000 self.lbl_lap.setColor(Colors.green(), True) # else: # ac.log(str(time.time()) +" dismissed") # self.lastLap=self.currentLap self.currentLap = [] self.lapCount = ac.getCarState(0, acsys.CS.LapCount) self.lastLapIsValid = True self.currentLap.append(raceGaps(self.spline.value, self.laptime.value)) # ac.console("--currentLap : " + str(len(self.currentLap)) + " --lastLap : " + str(len(self.lastLap)) + " --referenceLap : " + str(len(self.referenceLap))) # update graphics if not math.isinf(sessionTimeLeft): self.TimeLeftUpdate.setValue(int(sessionTimeLeft / 500)) if self.TimeLeftUpdate.hasChanged(): if self.performance.hasChanged(): time_prefix = "" color = Colors.white() if self.performance.value > 0: time_prefix = "+" if self.lastLapIsValid: color = Colors.yellow() else: color = Colors.red() elif self.performance.value < 0: time_prefix = "-" if self.lastLapIsValid: color = Colors.green() else: color = Colors.orange() else: if not self.lastLapIsValid: color = Colors.red() self.lbl_delta.setText( time_prefix + self.time_splitting(abs(self.performance.value), "yes") ).setColor(color, True) if self.referenceLapTime.hasChanged(): self.lbl_lap.setText(self.time_splitting(self.referenceLapTime.value, "yes")) if self.highlight_end == 0 or sessionTimeLeft < self.highlight_end: self.lbl_lap.setColor(Colors.white(), True)