def __init__(self, parent, message, name, move_func, value, inc_amt, precision, min_val=None, max_val=None, additional_formatting=False): self.parent = parent self.message = message self.name = name self.precision = precision self.inc_amt = inc_amt self.additional_formatting = additional_formatting self.fmt = "%%.%df" % precision self.default_str = str(value) self.set_value(value) self.default_value = self.value self.cursor = len(self.valstr) self.cursoff = colors.get_line_width( self.message) + 4 # + 4 for the " [ " in the rendered string self.move_func = move_func self.min_val = min_val self.max_val = max_val self.need_update = False
def __init__(self, parent, message, name, move_func, value, min_val=None, max_val=None, additional_formatting=False): self.parent = parent self.message = message self.name = name self.additional_formatting = additional_formatting self.default_str = str(value) self.set_value( value) self.default_value = self.value self.cursor = len(self.valstr) self.cursoff = colors.get_line_width(self.message)+4 # + 4 for the " [ " in the rendered string self.move_func = move_func self.min_val = min_val self.max_val = max_val self.need_update = False
def render(self, screen, row, width, active, col=1, cursor_offset=0): if not active and self.need_update: if not self.valstr or self.valstr == '-': self.value = self.default_value self.valstr = self.default_str try: float(self.value) except: self.real_value = False else: self.set_value(self.valstr) self.__limit_value() self.valstr = self.fmt % self.value self.cursor = len(self.valstr) self.cursor = colors.get_line_width(self.valstr) self.need_update = False elif self.need_update and self.valstr != '-': self.real_value = True try: self.value = round(float(self.valstr), self.precision) except: self.value = self.default_value try: float(self.value) except: self.real_value = False if not self.valstr: self.parent.add_string(row, "%s {!input!}[ ]" % self.message, screen, col, False, True) elif active: self.parent.add_string( row, "%s {!input!}[ {!black,white,bold!}%s{!white,black!} ]" % (self.message, self.valstr), screen, col, False, True) elif self.additional_formatting and self.valstr == self.default_str: self.parent.add_string( row, "%s {!input!}[ {!magenta,black!}%s{!input!} ]" % (self.message, self.valstr), screen, col, False, True) else: self.parent.add_string( row, "%s {!input!}[ %s ]" % (self.message, self.valstr), screen, col, False, True) if active: self.move_func(row, self.cursor + self.cursoff + cursor_offset) return 1
def render(self, screen, row, width, active, col=1, cursor_offset=0): if not active and self.need_update: if not self.valstr or self.valstr == '-': self.value = self.default_value self.valstr = self.default_str try: float(self.value) except: self.real_value = False else: self.set_value(self.valstr) self.__limit_value() self.valstr = self.fmt % self.value self.cursor = len(self.valstr) self.cursor = colors.get_line_width(self.valstr) self.need_update = False elif self.need_update and self.valstr != '-': self.real_value = True try: self.value = round(float(self.valstr), self.precision) except: self.value = self.default_value try: float(self.value) except: self.real_value = False if not self.valstr: self.parent.add_string(row,"%s {!input!}[ ]"%self.message,screen,col,False,True) elif active: self.parent.add_string(row,"%s {!input!}[ {!black,white,bold!}%s{!white,black!} ]"%(self.message,self.valstr),screen,col,False,True) elif self.additional_formatting and self.valstr == self.default_str: self.parent.add_string(row,"%s {!input!}[ {!magenta,black!}%s{!input!} ]"%(self.message,self.valstr),screen,col,False,True) else: self.parent.add_string(row,"%s {!input!}[ %s ]"%(self.message,self.valstr),screen,col,False,True) if active: self.move_func(row,self.cursor+self.cursoff+cursor_offset) return 1
def add_line(self, text, refresh=True): """ Add a line to the screen. This will be showed between the two bars. The text can be formatted with color using the following format: "{!fg, bg, attributes, ...!}" See: http://docs.python.org/library/curses.html#constants for attributes. Alternatively, it can use some built-in scheme for coloring. See colors.py for built-in schemes. "{!scheme!}" Examples: "{!blue, black, bold!}My Text is {!white, black!}cool" "{!info!}I am some info text!" "{!error!}Uh oh!" :param text: the text to show :type text: string :param refresh: if True, the screen will refresh after the line is added :type refresh: bool """ if self.console_config["save_legacy_history"]: #Determine which file is the active one #If both are under maximum, it's first, otherwise it's the one not full if self._hf_lines[0] < MAX_HISTFILE_SIZE and self._hf_lines[1] < MAX_HISTFILE_SIZE: active_file = 0 elif self._hf_lines[0] == MAX_HISTFILE_SIZE: active_file = 1 else: active_file = 0 #Write the line f = open(self.history_file[active_file], 'a') if isinstance(text, unicode): text = text.encode(self.encoding) f.write(text) f.write( os.linesep ) #And increment line counter self._hf_lines[active_file] += 1 #If the active file reaches max size, we truncate it # therefore swapping the currently active file if self._hf_lines[active_file] == MAX_HISTFILE_SIZE: self._hf_lines[1 - active_file] = 0 f = open(self.history_file[1 - active_file], 'w') f.truncate(0) def get_line_chunks(line): """ Returns a list of 2-tuples (color string, text) """ if not line or line.count("{!") != line.count("!}"): return [] chunks = [] if not line.startswith('{!'): begin = line.find('{!') if begin == -1: begin = len(line) chunks.append( ('', line[:begin]) ) line = line[begin:] while line: # We know the line starts with '{!' here end_color = line.find('!}') next_color = line.find('{!', end_color) if next_color == -1: next_color = len(line) chunks.append( (line[:end_color+2], line[end_color+2:next_color]) ) line = line[next_color:] return chunks for line in text.splitlines(): # We need to check for line lengths here and split as necessary try: line_length = colors.get_line_width(line) except colors.BadColorString: log.error("Passed a bad colored line: %s", line) continue if line_length >= (self.cols - 1): s = "" # The length of the text without the color tags s_len = 0 # We need to split this over multiple lines for chunk in get_line_chunks(line): if (strwidth(chunk[1]) + s_len) < (self.cols - 1): # This chunk plus the current string in 's' isn't over # the maximum width, so just append the color tag and text s += chunk[0] + chunk[1] s_len += strwidth(chunk[1]) else: # The chunk plus the current string in 's' is too long. # We need to take as much of the chunk and put it into 's' # with the color tag. remain = (self.cols - 1) - s_len s += chunk[0] + chunk[1][:remain] # We append the line since it's full self.lines.append(s) # Start a new 's' with the remainder chunk s = chunk[0] + chunk[1][remain:] s_len = strwidth(chunk[1][remain:]) # Append the final string which may or may not be the full width if s: self.lines.append(s) else: self.lines.append(line) while len(self.lines) > LINES_BUFFER_SIZE: # Remove the oldest line if the max buffer size has been reached del self.lines[0] if refresh: self.refresh()
def add_line(self, text, refresh=True): """ Add a line to the screen. This will be showed between the two bars. The text can be formatted with color using the following format: "{!fg, bg, attributes, ...!}" See: http://docs.python.org/library/curses.html#constants for attributes. Alternatively, it can use some built-in scheme for coloring. See colors.py for built-in schemes. "{!scheme!}" Examples: "{!blue, black, bold!}My Text is {!white, black!}cool" "{!info!}I am some info text!" "{!error!}Uh oh!" :param text: the text to show :type text: string :param refresh: if True, the screen will refresh after the line is added :type refresh: bool """ if self.console_config["save_legacy_history"]: #Determine which file is the active one #If both are under maximum, it's first, otherwise it's the one not full if self._hf_lines[0] < MAX_HISTFILE_SIZE and self._hf_lines[ 1] < MAX_HISTFILE_SIZE: active_file = 0 elif self._hf_lines[0] == MAX_HISTFILE_SIZE: active_file = 1 else: active_file = 0 #Write the line f = open(self.history_file[active_file], 'a') if isinstance(text, unicode): text = text.encode(self.encoding) f.write(text) f.write(os.linesep) #And increment line counter self._hf_lines[active_file] += 1 #If the active file reaches max size, we truncate it # therefore swapping the currently active file if self._hf_lines[active_file] == MAX_HISTFILE_SIZE: self._hf_lines[1 - active_file] = 0 f = open(self.history_file[1 - active_file], 'w') f.truncate(0) def get_line_chunks(line): """ Returns a list of 2-tuples (color string, text) """ if not line or line.count("{!") != line.count("!}"): return [] chunks = [] if not line.startswith('{!'): begin = line.find('{!') if begin == -1: begin = len(line) chunks.append(('', line[:begin])) line = line[begin:] while line: # We know the line starts with '{!' here end_color = line.find('!}') next_color = line.find('{!', end_color) if next_color == -1: next_color = len(line) chunks.append( (line[:end_color + 2], line[end_color + 2:next_color])) line = line[next_color:] return chunks for line in text.splitlines(): # We need to check for line lengths here and split as necessary try: line_length = colors.get_line_width(line) except colors.BadColorString: log.error("Passed a bad colored line: %s", line) continue if line_length >= (self.cols - 1): s = "" # The length of the text without the color tags s_len = 0 # We need to split this over multiple lines for chunk in get_line_chunks(line): if (strwidth(chunk[1]) + s_len) < (self.cols - 1): # This chunk plus the current string in 's' isn't over # the maximum width, so just append the color tag and text s += chunk[0] + chunk[1] s_len += strwidth(chunk[1]) else: # The chunk plus the current string in 's' is too long. # We need to take as much of the chunk and put it into 's' # with the color tag. remain = (self.cols - 1) - s_len s += chunk[0] + chunk[1][:remain] # We append the line since it's full self.lines.append(s) # Start a new 's' with the remainder chunk s = chunk[0] + chunk[1][remain:] s_len = strwidth(chunk[1][remain:]) # Append the final string which may or may not be the full width if s: self.lines.append(s) else: self.lines.append(line) while len(self.lines) > LINES_BUFFER_SIZE: # Remove the oldest line if the max buffer size has been reached del self.lines[0] if refresh: self.refresh()