def set_track_time(self, name, time, bb, layer_num): """ Set track time :param name: button state :param time: track time :param bb: bounding box :param layer_num: layer number """ font_size = int((bb.h * 45)/100.0) font = self.util.get_font(font_size) size = font.size(time) label = font.render(time, 1, self.config[COLORS][COLOR_BRIGHT]) c = Component(self.util, label) c.bgr = (255, 0, 0) c.name = name c.text = time c.text_size = font_size c.text_color_current = self.config[COLORS][COLOR_BRIGHT] c.content_x = bb.x + (bb.width - size[0])/2 c.content_y = bb.y + (bb.height - size[1])/2 self.components[layer_num] = c if self.visible: self.draw() self.update()
def draw_tile_header(self, x, y, w, h, fcast): """ Draw tile header :param x: tile x coordinate :param y: tile y coordinate :param w: tile width :param h: tile height :param fcast: one day forecast """ height = (h / 100) * TILE_HEADER_HEIGHT comp = Component(self.util) comp.name = "tile.header." + str(x) + "." + str(y) comp.content_x = x comp.content_y = y rect = pygame.Rect(x, y, w, height) comp.content = rect comp.fgr = self.semi_transparent_color comp.bgr = self.semi_transparent_color comp.bounding_box = rect self.add_component(comp) text_color = self.util.weather_config[COLOR_BRIGHT] font_size = int((height / 100) * DAY_HEIGHT) if fcast[DAY] == UNKNOWN: d = UNKNOWN else: d = self.weather_config[fcast[DAY].lower()] c = self.util.get_text_component(d, text_color, font_size) c.name = "th." + str(x) + "." + str(y) c.content_x = x + (w - c.content.get_size()[0]) / 2 c.content_y = y + font_size / 8 self.add_component(c)
def add_bgr(self): """ Add background rectangle """ comp = Component(self.util, self.bounding_box) comp.name = self.name + ".bgr" comp.bgr = self.bgr self.add_component(comp)
def __init__(self, util, name, bgr, slider_color, img_knob, img_knob_on, key_incr, key_decr, key_knob, bb): """ Initializer :param util: utility object :param name: slider name :param bgr: slider background color :param slider_color: slider center line color :param img_knob: knob image :param img_knob_on: knob image in on state :param key_incr: keyboard key associated with slider increment action :param key_decr: keyboard key associated with slider decrement action :param key_knob: keyboard key associated with single click on knob :param bb: slider bounding box """ Container.__init__(self, util, background=bgr, bounding_box=bb) self.util = util self.config = util.config self.lock = RLock() self.CURRENT_TIME_LAYER = 3 self.TOTAL_TIME_LAYER = 2 # don't increase the following number too much as it affects UV Meter screen-saver performance self.LOOP_CYCLES_PER_SECOND = 5 self.CYCLE_TIME = 1 / self.LOOP_CYCLES_PER_SECOND self.active = True comp = Component(self.util, bb) comp.name = name + "bgr" comp.bgr = bgr self.add_component(comp) layout = BorderLayout(bb) layout.set_percent_constraints(0.0, 0.0, 20.0, 20.0) self.current_time_name = name + "current" self.total_time_name = name + "total" self.current_time_layout = layout.LEFT self.total_time_layout = layout.RIGHT self.slider = Slider(util, name + "slider", bgr, slider_color, img_knob, img_knob_on, None, key_incr, key_decr, key_knob, layout.CENTER, False) self.slider.add_slide_listener(self.slider_action_handler) self.total_track_time = 0 self.seek_time = 0 self.add_component(self.slider) c = Component(self.util, None) # init total time layer self.add_component(c) c = Component(self.util, None) # init current time layer self.add_component(c) self.seek_listeners = [] self.start_timer_listeners = [] self.stop_timer_listeners = [] self.update_seek_listeners = True self.use_web = self.config[USAGE][USE_WEB] self.stop_timer() thread = Thread(target = self.start_loop) thread.start()
def add_bgr(self): """ Add background rectangle """ if not self.full_width: self.bounding_box.x += 1 self.bounding_box.y += 1 self.bounding_box.w -= 2 self.bounding_box.h -= 1 comp = Component(self.util, self.bounding_box) comp.name = self.name + ".bgr" comp.bgr = self.bgr self.add_component(comp)
def draw_background(self, x, y, w, h): """ Draw background defined by input parameters :param x: x coordinate :param y: y coordinate :param w: width :param h: height """ c = Component(self.util) c.name = "today.bgr" c.content = pygame.Rect(x, y, w, h) c.content_x = x c.content_y = y c.bounding_box = c.content c.bgr = self.semi_transparent_color self.add_component(c)
def draw_separator(self, x, y, w, h): """ Draw tile separator :param x: tile x coordinate :param y: tile y coordinate :param w: tile width :param h: tile height """ height = (h / 100) * TILE_HEADER_HEIGHT comp = Component(self.util) comp.name = "sep." + str(x) + "." + str(y) rect = pygame.Rect(x + w, y + height, 1, h - height + 2) comp.content = rect comp.fgr = self.util.weather_config[COLOR_DARK_LIGHT] comp.bgr = self.util.weather_config[COLOR_DARK_LIGHT] comp.bounding_box = rect self.add_component(comp)
def add_selection(self, state, bb): if not self.selected: return border = 2 c = Component(self.util, t=border) c.name = state.name + ".selection" x = state.bounding_box.x + border / 2 y = state.bounding_box.y + border / 2 w = state.bounding_box.w - border h = state.bounding_box.h - border c.content = pygame.Rect(x, y, w, h) c.bgr = state.text_color_selected c.fgr = (0, 0, 0, 0) c.content_x = state.bounding_box.x c.content_y = state.bounding_box.y self.add_component(c)
def draw_tile_body(self, x, y, w, h, fcast): """ Draw center part of the tile :param x: tile x coordinate :param y: tile y coordinate :param w: tile width :param h: tile height :param fcast: one day forecast """ top_height = (h / 100) * TILE_HEADER_HEIGHT y += top_height h = h - top_height + 1 comp = Component(self.util) comp.name = "tile.body" + str(x) + "." + str(y) comp.content_x = x comp.content_y = y rect = pygame.Rect(x, y, w, h) comp.content = rect comp.fgr = self.util.weather_config[COLOR_BRIGHT] comp.bgr = self.util.weather_config[COLOR_BRIGHT] comp.bounding_box = rect self.add_component(comp)
def draw_high_low(self): """ Draw high/low today's temperatures """ bb_x = self.temp_right_edge bb_y = int((self.rect.h / 100) * TOP_HEIGHT) bb_w = self.rect.w - bb_x bb_h = self.rect.h - bb_y - int((self.rect.h / 100) * BOTTOM_HEIGHT) text_color = self.util.weather_config[COLOR_CONTRAST] font_size = int((bb_w / 100) * HIGH_LOW_TEXT_SIZE) c = self.util.get_text_component(self.high, text_color, font_size) c.name = "high" w = c.content.get_size()[0] h = c.content.get_size()[1] c.content_x = bb_x + int((bb_w - w) / 2) c.content_y = bb_y + int((bb_h - h) / 2) - (font_size / 2) self.add_component(c) c = self.util.get_text_component(self.low, text_color, font_size) c.name = "low" w = c.content.get_size()[0] h = c.content.get_size()[1] c.content_x = bb_x + int((bb_w - w) / 2) c.content_y = bb_y + int((bb_h - h) / 2) + (font_size / 1.4) self.add_component(c) x = c.content_x y = bb_y + int(bb_h / 2) w = c.content.get_size()[0] h = 2 r = pygame.Rect(x, y, w, h) c = Component(self.util, r) c.name = "sep" + ".text" c.content_x = 0 c.content_y = 0 c.fgr = text_color c.bgr = text_color self.add_component(c)
def set_labels(self, name, v, bb, layer_num): font_size = int((bb.h * 45) / 100.0) font = self.util.get_font(font_size) size = font.size(v) label = font.render(v, 1, self.config[COLORS][COLOR_BRIGHT]) c = Component(self.util, label) c.bgr = (255, 0, 0) c.name = name c.text = v c.text_size = font_size c.text_color_current = self.config[COLORS][COLOR_BRIGHT] c.content_x = bb.x + (bb.width - size[0]) / 2 c.content_y = bb.y + (bb.height - size[1]) / 2 self.components[layer_num] = c if self.visible: self.draw() self.update() if self.use_web and getattr(self, "web_seek_listener", None): s = State() s.event_origin = self s.seek_time_label = v self.web_seek_listener(s)
def __init__(self, id, util, name, bgr, slider_color, img_knob, img_knob_on, key_incr, key_decr, key_knob, bb, listener, label): """ Initializer :param id: band ID :param util: utility object :param name: slider name :param bgr: slider background color :param slider_color: slider center line color :param img_knob: knob image :param img_knob_on: knob image in on state :param key_incr: keyboard key associated with slider increment action :param key_decr: keyboard key associated with slider decrement action :param key_knob: keyboard key associated with single click on knob :param bb: slider bounding box """ Container.__init__(self, util, background=bgr, bounding_box=bb) self.util = util self.config = util.config self.VALUE_LAYER = 3 self.LABEL_LAYER = 2 comp = Component(self.util, bb) comp.name = name + ".bgr." + str(id) comp.bgr = bgr self.add_component(comp) layout = BorderLayout(bb) layout.set_percent_constraints(10.0, 10.0, 0.0, 0.0) self.value_name = name + ".value." + str(id) self.label_name = name + ".label." + str(id) self.value_layout = layout.TOP self.label_layout = layout.BOTTOM k = 1.75 w = self.label_layout.w h = self.label_layout.h self.label_layout.w *= k self.label_layout.h *= k self.label_layout.x -= (self.label_layout.w - w) / 2 self.label_layout.y -= (self.label_layout.h - h) / 2 k = 1.6 w = self.value_layout.w h = self.value_layout.h self.value_layout.w *= k self.value_layout.h *= k self.value_layout.x -= (self.value_layout.w - w) / 2 self.value_layout.y -= (self.value_layout.h - h) / 2 - 2 self.slider = Slider(util, "slider." + str(id), bgr, slider_color, img_knob, img_knob_on, None, key_incr, key_decr, key_knob, layout.CENTER) self.slider.add_slide_listener(listener) self.value = "0" self.add_component(self.slider) c = Component(self.util, None) # init total time layer self.add_component(c) c = Component(self.util, None) # init current time layer self.add_component(c) self.seek_listeners = [] self.update_seek_listeners = True self.use_web = self.config[USAGE][USE_WEB] self.set_labels(self.label_name, label, self.label_layout, self.LABEL_LAYER) self.set_labels(self.value_name, self.value, self.value_layout, self.VALUE_LAYER) self.use_web = self.config[USAGE][USE_WEB]
def __init__(self, util, name, bgr, slider_color, img_knob, img_knob_on, img_selected, key_incr, key_decr, key_knob, bb): """ Initializer :param util: utility object :param name: slider name :param bgr: slider background color :param slider_color: slider center line color :param img_knob: knob image :param img_knob_on: knob image in on state :param img_selected: knob image in selected state :param key_incr: keyboard key associated with slider increment action :param key_decr: keyboard key associated with slider decrement action :param key_knob: keyboard key associated with single click on knob :param bb: slider bounding box """ Container.__init__(self, util, background=bgr, bounding_box=bb) self.util = util self.name = name self.img_knob = img_knob[1] self.img_knob_on = img_knob_on[1] self.img_selected = img_selected self.knob_width = self.img_knob.get_size()[0] self.knob_height = self.img_knob.get_size()[1] self.knob_filename = img_knob[0] self.knob_on_filename = img_knob_on[0] self.selected = False self.dragging = False self.initial_level = 0 self.current_img = self.img_knob self.current_filename = self.knob_filename self.clicked = False self.press_listeners = list() self.slide_listeners = list() self.knob_listeners = list() self.motion_listeners = list() pygame.key.set_repeat(50, 10) self.step = 10 self.key_incr = key_incr self.key_decr = key_decr self.key_knob = key_knob slider_x = self.knob_width/2 self.bounding_box.h += 1 slider_y = self.bounding_box.y + self.bounding_box.height - self.bounding_box.height/2 slider_width = self.bounding_box.width - self.knob_width slider_height = 2 self.slider = pygame.Rect(slider_x, slider_y, slider_width, slider_height) self.slider_max_x = self.bounding_box.width - self.knob_width/2 self.slider_min_x = self.knob_width/2 self.slide_increment = (self.slider_max_x - self.slider_min_x)/100.0 self.last_knob_position = (int)(self.initial_level * self.slide_increment) self.knob_y = self.bounding_box.y + self.bounding_box.height/2 - self.knob_height/2 self.event_source_local = True comp = Component(self.util, self.bounding_box) comp.name = self.name + ".bgr" comp.bgr = bgr self.add_component(comp) comp = Component(self.util, self.slider) comp.name = self.name + ".slider" comp.thickness = 1 comp.content_x = slider_x comp.content_y = slider_y comp.bgr = slider_color self.add_component(comp) comp = Component(self.util, self.current_img) comp.name = self.name + ".knob" h = self.current_img.get_size()[1] comp.content_y = bb.y + (bb.h - h)/2 comp.image_filename = self.knob_filename self.add_component(comp)
def __init__(self, items, util, bounding_box, update_parent, callback, default_selection=None): """ Initializer :param items: list of item names :param util: utility object :param bounding_box: bounding box :param update_parent: redraw parent function :param callback: menu selection callback """ Container.__init__(self, util, bounding_box, (0, 0, 0)) self.util = util self.factory = Factory(util) self.config = util.config self.update_parent = update_parent self.callback = callback self.popup = True c = Component(self.util) w = self.config[SCREEN_INFO][WIDTH] h = self.config[SCREEN_INFO][HEIGHT] c.content = pygame.Rect(0, 0, w, h) c.content_x = 0 c.content_y = 0 c.bounding_box = c.content c.bgr = (0, 0, 0, 0) c.name = "popup.overlay.bgr" c.handle_event = self.handle_outside_event self.add_component(c) c = Component(self.util) c.content = pygame.Rect(bounding_box.x, bounding_box.y, bounding_box.w, bounding_box.h - 1) c.content_x = 0 c.content_y = 0 c.bounding_box = c.content c.bgr = self.config[COLORS][COLOR_BRIGHT] c.name = "popup.bgr" self.add_component(c) self.cols = 1 self.rows = len(items) m = self.create_popup_menu_button b = pygame.Rect(bounding_box.x, bounding_box.y, bounding_box.w, bounding_box.h - 2) self.menu = Menu(util, None, b, self.rows, self.cols, create_item_method=m) layout = GridLayout(self.menu.bb) layout.set_pixel_constraints(self.rows, self.cols, 1, 1) bounding_box = layout.get_next_constraints() self.modes = self.util.load_menu(items, NAME, [], V_ALIGN_TOP, bb=bounding_box, scale=IMAGE_SCALE) if not default_selection: selection = self.modes[items[0]] else: selection = self.modes[default_selection] self.menu.set_items(self.modes, 0, self.select_item, False) self.menu.visible = False self.menu.item_selected(selection) self.add_component(self.menu) self.redraw_observer = None self.clicked = False self.visible = False
def __init__(self, util, name, time_key, digits, bb, timer_lock, clock_change_callback, change_codes): """ Initializer :param util: utility object :param name: component name :param time_key: key of the clock time in configuration :param digits: images of the clock digits 0-9 :param bb: clock bounding box :param gap: gap between hours and minutes :param icon_size: size of the button icon size :param timer_lock: lock object :param clock_change_callback: callback function :param change_codes: codes for increment and decrement for hours and minutes """ self.util = util self.name = name self.timer_lock = timer_lock self.clock_change_callback = clock_change_callback self.config = self.util.config Container.__init__(self, util) self.content = None self.clock_bb = bb self.bounding_box = bb.LEFT size = digits[0][1].get_size() self.digit_w = size[0] self.digit_h = size[1] separator = util.image_util.get_flipclock_separator(self.digit_h / 3) self.shift_x = 2 border_x = bb.RIGHT.x self.change_codes = change_codes self.change_listeners = [] r = pygame.Rect(bb.x, bb.y + 1, border_x, bb.h - 1) c = Component(self.util, r, bb=bb) c.name = name + ".bgr" c.bgr = self.config[BACKGROUND][MENU_BGR_COLOR] self.add_component(c) size = separator[1].get_size() w = size[0] h = size[1] c = Component(self.util) c.name = name + ".separator" c.content = separator separator_x = (border_x / 2) - (w / 2) separator_y = bb.y + (bb.h / 2) - (h / 2) c.content_x = separator_x c.content_y = separator_y self.add_component(c) self.time_key = time_key current_time = datetime.now().strftime("%H%M") try: self.time = self.config[TIMER][time_key] except: self.time = current_time if len(self.time.strip()) == 0: self.time = current_time with self.timer_lock: self.config[TIMER][self.time_key] = self.time h1_x = separator_x - (self.digit_w * 2) - w h1_n = name + ".h1" self.h1 = self.add_digit(digits, int(self.time[0]), h1_x, self.increment_hours, self.decrement_hours, h1_n) h2_x = separator_x - self.digit_w - w h2_n = name + ".h2" self.h2 = self.add_digit(digits, int(self.time[1]), h2_x, self.increment_hours, self.decrement_hours, h2_n) m1_x = separator_x + w * 2 m1_n = name + ".m1" self.m1 = self.add_digit(digits, int(self.time[2]), m1_x, self.increment_minutes, self.decrement_minutes, m1_n) m2_x = separator_x + self.digit_w + w * 2 m2_n = name + ".m2" self.m2 = self.add_digit(digits, int(self.time[3]), m2_x, self.increment_minutes, self.decrement_minutes, m2_n) key_height = self.digit_h self.top_image = util.image_util.get_flipclock_key( "key-top.png", key_height) self.bottom_image = util.image_util.get_flipclock_key( "key-bottom.png", key_height) self.top_image_on = util.image_util.get_flipclock_key( "key-top-on.png", key_height) self.bottom_image_on = util.image_util.get_flipclock_key( "key-bottom-on.png", key_height) y = self.clock_bb.y + (self.clock_bb.h / 2) - (self.digit_h / 2) self.h_top = self.add_key(h2_x, y, h2_n + ".top.key", self.top_image) self.m_top = self.add_key(m2_x, y, m2_n + ".top.key", self.top_image) y = self.clock_bb.y + (self.clock_bb.h / 2) - ( self.digit_h / 2) + self.digit_h - self.bottom_image[1].get_size()[1] self.h_bottom = self.add_key(h2_x, y, h2_n + ".bottom.key", self.bottom_image) self.m_bottom = self.add_key(m2_x, y, m2_n + ".bottom.key", self.bottom_image) self.selected_key = None
def __init__(self, util, name, bgr, slider_color, img_knob, img_knob_on, img_selected, key_incr, key_decr, key_knob, bb, knob_selected=False, rest_commands=[]): """ Initializer :param util: utility object :param name: slider name :param bgr: slider background color :param slider_color: slider center line color :param img_knob: knob image :param img_knob_on: knob image in on state :param img_selected: knob image in selected state :param key_incr: keyboard key associated with slider increment action :param key_decr: keyboard key associated with slider decrement action :param key_knob: keyboard key associated with single click on knob :param bb: slider bounding box """ Container.__init__(self, util, background=bgr, bounding_box=bb) self.content = None if bb.h > bb.w: self.orientation = VERTICAL else: self.orientation = HORIZONTAL self.util = util self.name = name self.img_knob = img_knob[1] self.img_knob_on = img_knob_on[1] self.img_selected = img_selected self.rest_commands = rest_commands self.knob_width = self.img_knob.get_size()[0] self.knob_height = self.img_knob.get_size()[1] self.knob_filename = img_knob[0] self.knob_on_filename = img_knob_on[0] self.dragging = False self.initial_level = 0 self.check_pause = True self.handle_knob_events = True self.selected = False if knob_selected: self.selected = knob_selected self.current_img = self.img_selected[1] else: self.current_img = self.img_knob self.current_filename = self.knob_filename self.clicked = False self.press_listeners = list() self.slide_listeners = list() self.knob_listeners = list() self.motion_listeners = list() pygame.key.set_repeat(50, 10) self.step = 10 self.key_incr = key_incr self.key_decr = key_decr self.key_knob = key_knob h = self.current_img.get_size()[1] if self.orientation == HORIZONTAL: slider_x = self.bounding_box.x + self.knob_width / 2 slider_y = self.bounding_box.y + self.bounding_box.height / 2 slider_width = self.bounding_box.width - self.knob_width slider_height = 1 self.slider = pygame.Rect(slider_x, slider_y, slider_width, slider_height) self.slider_max_x = self.bounding_box.x + self.bounding_box.width - self.knob_width / 2 self.slider_min_x = self.bounding_box.x + self.knob_width / 2 self.slide_increment = (self.slider_max_x - self.slider_min_x) / 100.0 self.last_knob_position = bb.x self.knob_y = self.bounding_box.y + self.bounding_box.height / 2 - self.knob_height / 2 else: slider_x = self.bounding_box.x + self.bounding_box.width / 2 - 1 slider_y = self.bounding_box.y + self.knob_height / 2 slider_width = 1 slider_height = self.bounding_box.height - self.knob_height self.slider = pygame.Rect(slider_x, slider_y, slider_width, slider_height) self.slider_max_y = self.bounding_box.y + self.bounding_box.height - self.knob_height / 2 self.slider_min_y = self.bounding_box.y + self.knob_height / 2 self.slide_increment = (self.slider_max_y - self.slider_min_y) / 100.0 self.last_knob_position = bb.y + bb.h - self.knob_height self.knob_x = self.bounding_box.x + self.bounding_box.width / 2 - self.knob_width / 2 comp = Component(self.util, self.bounding_box) comp.name = self.name + ".bgr" comp.bgr = bgr self.add_component(comp) comp = Component(self.util, self.slider) comp.name = self.name + ".slider" comp.thickness = 1 comp.content_x = slider_x comp.content_y = slider_y comp.bgr = slider_color self.add_component(comp) comp = Component(self.util, self.current_img) comp.name = self.name + ".knob" if self.orientation == HORIZONTAL: comp.content_x = bb.x comp.content_y = bb.y + (bb.h - h) / 2 + 1 else: comp.content_x = self.knob_x comp.content_y = self.last_knob_position comp.image_filename = self.knob_filename self.add_component(comp)