def blink(blinking_element, timeout_start, overall_duration, freq): """ Make the given element blinking. :param blinking_element: any :class:`Scannable` instance. :param timeout_start: current timestamp, helps calculating when the animation should be over. :param overall_duration: total duration of the blinking animation. :param freq: frequency of blinking. """ hilitten = False def switch_hilite(): nonlocal hilitten when_to_exit = timeout_start + (overall_duration - 2 * freq) / 1000 if time.time() > when_to_exit: if hasattr(blinking_element, "disable_lag_hilite"): blinking_element.disable_lag_hilite() return False else: if hilitten: if hasattr(blinking_element, "disable_lag_hilite"): blinking_element.disable_lag_hilite() hilitten = False else: if hasattr(blinking_element, "enable_lag_hilite"): blinking_element.enable_lag_hilite() hilitten = True return True Clutter.threads_add_timeout(0, freq, switch_hilite)
def clutter(self): if self.actor is None: if self._tag == 'img': self.actor = Clutter.Texture() self.actor.set_from_file(self._src) elif self._tag == 'video': self.actor = ClutterGst.VideoTexture() self.actor.set_seek_flags(ClutterGst.SeekFlags(1)) self.actor.set_uri(self._src) self.actor.connect("eos", self._after) if self._region in region_names: parent = False for region in region_names[self._region]: if not parent: region.stage.add_actor(self.actor) parent = True else: clone = Clutter.Clone.new(self.actor) region.stage.add_actor(clone) self.clone.append(clone) elif self._region in region_ids: region_ids[self._region].stage.add_actor(self.actor) else: stage.add_actor(self.actor) if self._tag == 'img': Clutter.threads_add_timeout(0, self._dur, self._after, None) elif self._tag == 'video': self.actor.set_progress(0.0) self.actor.set_playing(True) self.actor.show()
def run(self): """ Run automatic slideshow. Turn on the fullscreen mode if the corresponding property is setted to True. """ if self.slideshow_on_fullscreen: self.fullscreen_on = True self.stage = self.get_stage() self.cover_frame = Clutter.Actor() self.cover_frame.set_size(unit.size_pix[0], unit.size_pix[1]) self.slide.remove_transition("x") self.remove_child(self.slide) self.cover_frame.add_child(self.slide) self.slide.set_x(0) cover_frame_color = Clutter.Color.new(0, 0, 0, 255) self.cover_frame.set_background_color(cover_frame_color) if (self.cached_slide_width is None and self.cached_slide_height is None): self.cached_slide_width, self.cached_slide_height = \ self.slide.get_size() self.slide.set_size(unit.size_pix[0], unit.size_pix[1]) self.stage.add_child(self.cover_frame) self.slideshow_on = True Clutter.threads_add_timeout(0, self.idle_duration, lambda _: self.slideshow_timeout(), None)
def load_popup(self, message, unwind=None, unwind_data=None, container=None, timeout=5000): """ Load a pop-up view with some message displayed and then, after a given amount of time automatically load some another view or perform some operation. :param message: message to be displayed on the screen. :param unwind: name of a view that should be loaded after the `timeout` expires or callable that should be called then or None. :param unwind_data: data to be passed to an unwind handler or None. :param container: container that popup should be added to or None, if None then it will be displayed as a standard standalone view. :param timeout: time after which the `unwind` will be executed automatically, in miliseconds, default is 1 second, if -1 then the `unwind` to will not be executed at all. :return: None. """ if timeout >= 0 and unwind is not None: if callable(unwind): handler = (lambda *_: unwind(unwind_data)) if \ unwind_data is not None else lambda *_: unwind() else: handler = lambda *_: self.load_view(unwind, unwind_data) Clutter.threads_add_timeout(0, timeout, handler) if container: self._display_popup_widget(container, message) else: self.load_view("popup", {"message": message})
def blink(blinking_element, timeout_start, overall_duration, freq): """ Make the given element blinking. :param blinking_element: any :class:`Scannable` instance. :param timeout_start: current timestamp, helps calculating when the animation should be over. :param overall_duration: total duration of the blinking animation. :param freq: frequency of blinking. """ hilitten = False def switch_hilite(): nonlocal hilitten when_to_exit = timeout_start + (overall_duration - 2*freq)/1000 if time.time() > when_to_exit: if hasattr(blinking_element, "disable_lag_hilite"): blinking_element.disable_lag_hilite() return False else: if hilitten: if hasattr(blinking_element, "disable_lag_hilite"): blinking_element.disable_lag_hilite() hilitten = False else: if hasattr(blinking_element, "enable_lag_hilite"): blinking_element.enable_lag_hilite() hilitten = True return True Clutter.threads_add_timeout(0, freq, switch_hilite)
def run(self, block): self.idx = 0 self.items = block.get_children() self.limit = len(self.items) Clutter.threads_add_timeout(0, self.pace, self._on_timeout, None) self.is_running = True self._on_timeout(None)
def on_click_activate(self, source): if self.on_select_hilite_duration: self.style_pseudo_class_add("active") self.timeout_token = object() Clutter.threads_add_timeout(0, self.on_select_hilite_duration, self.on_select_hilite_off, self.timeout_token)
def _on_lag(self, lag_type, element_to_hilite, lag_duration): """ Stops ('lags') the scanning proccess for the given amount of time and performes all the previously ordered actions, i.e. highlights the current element. In the end schedules an adequate closure. :param lag_type: type of lag to be performed. Currently there are only two of them: 'start_up' that can happen before the scanning proccess starts and 'select', after selection of an element. :param element_to_hilite: element that has scanning focus during the lag and that should be highlighted. :param lag_duration: duration of the lag in miliseconds. """ if self.lag_hilite_mode == "blink": timeout_start = time.time() self.blink(element_to_hilite, timeout_start, lag_duration, self.blinking_freq) elif self.lag_hilite_mode == "still": if hasattr(element_to_hilite, "enable_lag_hilite"): element_to_hilite.enable_lag_hilite() if lag_type == "start_up": closure = self._do_start param = None elif lag_type == "select": closure = self._do_select param = element_to_hilite Clutter.threads_add_timeout(0, lag_duration, closure, param)
def run_automatic(self): """ Start automatic page flipping. """ self.is_running = True Clutter.threads_add_timeout(0, self.idle_duration, self._automatic_timeout, None)
def _on_lag(self, lag_type, element_to_hilite, lag_duration): """ Stops ('lags') the scanning proccess for the given amount of time and performs all the previously ordered actions, i.e. highlights the current element. In the end schedules an adequate closure. :param lag_type: type of lag to be performed. Currently there are only two of them: 'start_up' that can happen before the scanning process starts and 'select', after selection of an element. :param element_to_hilite: element that has scanning focus during the lag and that should be highlighted. :param lag_duration: duration of the lag in miliseconds. """ if self.lag_hilite_mode == "blink": timeout_start = time.time() self.blink(element_to_hilite, timeout_start, lag_duration, self.blinking_freq) elif self.lag_hilite_mode == "still": if hasattr(element_to_hilite, "enable_lag_hilite"): element_to_hilite.enable_lag_hilite() if lag_type == "start_up": closure = self._do_start param = None elif lag_type == "select": closure = self._do_select param = element_to_hilite Clutter.threads_add_timeout(0, lag_duration, closure, param)
def run_automatic(self): """ Start automatic page flipping. """ if self._page_count > 1: self.is_running = True Clutter.threads_add_timeout(0, self.idle_duration, self._automatic_timeout, None)
def on_new_data(self, data): """ Receives new raw data, parses them and schedules calling the main thread callback. :param data: raw data. """ x, y = self.parse_coords(data) Clutter.threads_add_timeout(-100, 20, self.on_new_coords, x, y)
def _do_start(self, *_source): self.index = None self._cycle_count = 0 self._expose_next(enforced=True) self.timeout_token = object() if hasattr(self.group, "disable_lag_hilite"): self.group.disable_lag_hilite() Clutter.threads_add_timeout(0, self.interval, self.cycle_timeout, self.timeout_token)
def _schedule_sending_data(self, direction): """ Schedule sending the data as soon as it is available. Data should be loaded in a background. :param direction: -1 or 1, that is whether data should be sent from backward or forward. """ Clutter.threads_add_timeout(0, 0.1, self._send_data, direction)
def _do_start(self, source=None): self.index = None self._cycle_count = 0 self._expose_next(enforced=True) self.timeout_token = object() if hasattr(self.group, "disable_lag_hilite"): self.group.disable_lag_hilite() Clutter.threads_add_timeout(0, self.interval, self.cycle_timeout, self.timeout_token)
def __init__(self): super().__init__() self.dynamic_canvas = DynamicCanvas() self.dynamic_canvas.set_x_expand(True) self.dynamic_canvas.set_y_expand(True) self.add_child(self.dynamic_canvas) self.layout = Clutter.BoxLayout() self.set_layout_manager(self.layout) Clutter.threads_add_timeout(0, 33, self._render, None)
def run_automatic(self): """ Start automatic page flipping. :deprecated: Use scanning instead """ if self._page_count > 1: self.is_running = True Clutter.threads_add_timeout(0, self.idle_duration, self._automatic_timeout, None)
def start(self): self.compute_sequence() if len(self._subgroups) == 0: # stop immediately self.index = None Clutter.threads_add_timeout(0, self.interval, self.cycle_timeout, self.timeout_token) else: self.index = None self._cycle_count = 0 self._expose_next() self.timeout_token = object() Clutter.threads_add_timeout(0, self.interval, self.cycle_timeout, self.timeout_token)
def start_cycle(self): """ Reimplementation of the generic scanning group method. Flips the target pager page and schedules the start of the page scanning cycle. """ if self._target is not None: self._target.next_page() Clutter.threads_add_timeout(0, self._target.transition_duration, lambda *_: self._target.scan_page(), None) else: _LOG.warning("PageFlip without target: " + self.get_id())
def __init__(self): # initialize Clutter Clutter.init([]) self.colors = { 'white': Clutter.Color.new(0, 0, 0, 255), 'blue': Clutter.Color.new(16, 16, 32, 255), 'black': Clutter.Color.new(255, 255, 255, 128), 'hand': Clutter.Color.new(16, 32, 16, 196) } # create a resizable stage stage = Clutter.Stage.new() stage.set_title("2D Clock") stage.set_user_resizable(True) stage.set_background_color(self.colors['blue']) stage.set_size(300, 300) stage.show() # our 2D canvas, courtesy of Cairo canvas = Clutter.Canvas.new() canvas.set_size(300, 300) actor = Clutter.Actor.new() actor.set_content(canvas) actor.set_content_scaling_filters(Clutter.ScalingFilter.TRILINEAR, Clutter.ScalingFilter.LINEAR) stage.add_child(actor) # bind the size of the actor to that of the stage actor.add_constraint( Clutter.BindConstraint.new(stage, Clutter.BindCoordinate.SIZE, 0)) # resize the canvas whenever the actor changes size actor.connect("allocation-changed", self.on_actor_resize) # quit on destroy stage.connect("destroy", self.on_destroy) # connect our drawing code canvas.connect("draw", self.draw_clock) # invalidate the canvas, so that we can draw before the main loop starts Clutter.Content.invalidate(canvas) # set up a timer that invalidates the canvas every second Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, 1000, self.invalidate_clock, canvas) Clutter.main()
def __init__ (self): # initialize Clutter Clutter.init([]) self.colors = { 'white' : Clutter.Color.new(0, 0, 0, 255), 'blue' : Clutter.Color.new(16, 16, 32, 255), 'black' : Clutter.Color.new(255, 255, 255, 128), 'hand' : Clutter.Color.new(16, 32, 16, 196) } # create a resizable stage stage = Clutter.Stage.new () stage.set_title ("2D Clock") stage.set_user_resizable (True) stage.set_background_color (self.colors['blue']) stage.set_size (300, 300) stage.show () # our 2D canvas, courtesy of Cairo canvas = Clutter.Canvas.new () canvas.set_size (300, 300) actor = Clutter.Actor.new () actor.set_content (canvas) actor.set_content_scaling_filters (Clutter.ScalingFilter.TRILINEAR, Clutter.ScalingFilter.LINEAR) stage.add_child (actor) # bind the size of the actor to that of the stage actor.add_constraint(Clutter.BindConstraint.new(stage, Clutter.BindCoordinate.SIZE, 0)) # resize the canvas whenever the actor changes size actor.connect ("allocation-changed", self.on_actor_resize) # quit on destroy stage.connect ("destroy", self.on_destroy) # connect our drawing code canvas.connect ("draw", self.draw_clock) # invalidate the canvas, so that we can draw before the main loop starts Clutter.Content.invalidate (canvas) # set up a timer that invalidates the canvas every second Clutter.threads_add_timeout (GLib.PRIORITY_DEFAULT, 1000, self.invalidate_clock, canvas) Clutter.main ()
def start(self): """ Method invoked by a group which wants its scanning cycle to be started. """ self.compute_sequence() if len(self._subgroups) == 0: # stop immediately self.index = None Clutter.threads_add_timeout(0, self.interval, self.cycle_timeout, self.timeout_token) else: if self.start_up_lag > 0: self._on_lag("start_up", self.group, self.start_up_lag) else: self._do_start()
def create_ui(self): self.record_control = RecordControl() self.video_view = ClutterView() self.video_view.show() self.add_pipeline_actor() self.warp_control = WarpControl(self.warp_actor) for slave in (self.record_control, self.warp_control, self.video_view): slave.show() self.add_slave(slave) self.record_control.on_changed = self.on_options_changed for slave in (self.record_control, self.warp_control): # Do not expand record or warp rows. self.widget.set_child_packing(slave.widget, False, False, 0, Gtk.PackType.START) Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, 1000, self.refresh_config)
def load_popup(self, message, unwind=None, unwind_data=None, container=None, timeout=5000, icon=True): """ Load a pop-up view with some message displayed and then, after a given amount of time automatically load some another view or perform some operation. :param message: message to be displayed on the screen. :param unwind: name of a view that should be loaded after the `timeout` expires or callable that should be called then or None. :param unwind_data: data to be passed to an unwind handler or None. :param container: container that popup should be added to or None, if None then it will be displayed as a standard standalone view. :param timeout: time after which the `unwind` will be executed automatically, in miliseconds, default is 1 second, if -1 then the `unwind` to will not be executed at all. :param icon: boolean, if icon should be displayed. :return: None. """ if timeout >= 0 and unwind is not None: if callable(unwind): handler = (lambda *_: unwind(unwind_data)) if \ unwind_data is not None else lambda *_: unwind() else: if unwind.split('/')[ 0] == 'main_panel' and self.app_name != 'main_panel': handler = lambda *_: self.application.main_quit() else: handler = lambda *_: self.load_view(unwind, unwind_data) Clutter.threads_add_timeout(0, timeout, handler) if container: self._display_popup_widget(container, message) else: self.load_view("popup", {"message": message, 'icon': icon})
def blink(blinking_element, timeout_start, overall_duration, freq): hilitten = False def switch_hilite(): nonlocal hilitten when_to_exit = timeout_start + (overall_duration - 2*freq)/1000 if time.time() > when_to_exit: if hasattr(blinking_element, "disable_lag_hilite"): blinking_element.disable_lag_hilite() return False else: if hilitten: if hasattr(blinking_element, "disable_lag_hilite"): blinking_element.disable_lag_hilite() hilitten = False else: if hasattr(blinking_element, "enable_lag_hilite"): blinking_element.enable_lag_hilite() hilitten = True return True Clutter.threads_add_timeout(0, freq, switch_hilite)
stage.set_color(Clutter.Color.get_static(Clutter.StaticColor.SKY_BLUE_LIGHT)) stage.set_user_resizable(True) stage.set_size(SIZE_WIDTH, SIZE_HEIGHT) stage.connect("destroy", Clutter.main_quit) stage.show() # This is one way of setting up a constraint manually; we could also use # BindConstraint.new(), and do it in one (LONG) line. constraint = Clutter.BindConstraint() constraint.set_source(stage) constraint.set_coordinate(Clutter.BindCoordinate.SIZE) constraint.set_offset(0) # This is our Cairo drawing texture. We will eventually be passed a # rendering context for this texture when responding to the "draw" # event... canvas = Clutter.CairoTexture(SIZE_WIDTH, SIZE_HEIGHT) canvas.add_constraint(constraint) canvas.set_auto_resize(True) canvas.connect("draw", cairo_draw) canvas.invalidate() # Finally, add the canvas and turn it loose. stage.add_actor(canvas) # This appears to actually call add_timeout_full() Clutter.threads_add_timeout(1, 1000, invalidate_clock, canvas) Clutter.main()
def on_actor_resize (self, actor, allocation, flags): # throttle multiple actor allocations to one canvas resize we use a guard # variable to avoid queueing multiple resize operations if self.idle_resize_id == 0: self.idle_resize_id = Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, 1000, self.idle_resize, actor)
def _add_timeout(self, duration): Clutter.threads_add_timeout(0, self._calculate_new_timeout(), self._on_cycle_timeout, duration)
def on_new_data(self, data): x, y = self.parse_coords(data) Clutter.threads_add_timeout(-100, 20, self.on_new_coords, x, y)
def on_allocation(self, *_): if self.idle_resize_id == 0: self.idle_resize_id = Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, self.refresh_millis, self.idle_resize)
def on_actor_resize(self, actor, allocation, flags): # throttle multiple actor allocations to one canvas resize we use a guard # variable to avoid queueing multiple resize operations if self.idle_resize_id == 0: self.idle_resize_id = Clutter.threads_add_timeout( GLib.PRIORITY_DEFAULT, 1000, self.idle_resize, actor)
def _on_obci_feedback(self, msg): msg = str(msg) Clutter.threads_add_timeout(0, 5, lambda *_: self._parse_obci_feedback(msg))
def _schedule_set_preview(self, tile, preview_path): Clutter.threads_add_timeout(0, 1000, self._do_set_preview, tile, preview_path)
Clutter.Color.get_static(Clutter.StaticColor.SKY_BLUE_LIGHT)) stage.set_user_resizable(True) stage.set_size(SIZE_WIDTH, SIZE_HEIGHT) stage.connect("destroy", Clutter.main_quit) stage.show() # This is one way of setting up a constraint manually; we could also use # BindConstraint.new(), and do it in one (LONG) line. constraint = Clutter.BindConstraint() constraint.set_source(stage) constraint.set_coordinate(Clutter.BindCoordinate.SIZE) constraint.set_offset(0) # This is our Cairo drawing texture. We will eventually be passed a # rendering context for this texture when responding to the "draw" # event... canvas = Clutter.CairoTexture(SIZE_WIDTH, SIZE_HEIGHT) canvas.add_constraint(constraint) canvas.set_auto_resize(True) canvas.connect("draw", cairo_draw) canvas.invalidate() # Finally, add the canvas and turn it loose. stage.add_actor(canvas) # This appears to actually call add_timeout_full() Clutter.threads_add_timeout(1, 1000, invalidate_clock, canvas) Clutter.main()
def _handle_lb_mouse(actor, event): global gLBMMCnt #print("INFO:LbMouse:{}:{}:{},{}:{}".format(event.time, actor, event.x, event.y, event.type)) aID = actor.get_id() orientation = actor.get_layout_manager().get_orientation() if event.type == Clutter.EventType.BUTTON_PRESS: dprint(DEBUG_LBM, "DBUG:LBMouse:BtnPress", aID, gLBMMCnt, gActors[aID]['posX'], gActors[aID]['posY']) gActors[aID]['prevPos'] = (event.x, event.y) gActors[aID]['prevTime'] = event.time gActors[aID]['startTime'] = event.time return Clutter.EVENT_PROPAGATE elif event.type == Clutter.EventType.MOTION: gLBMMCnt += 1 prevPos = gActors[aID]['prevPos'] prevTime = gActors[aID]['prevTime'] x = gActors[aID]['posX'] y = gActors[aID]['posY'] if prevTime != None: timeDelta = event.time - prevTime else: timeDelta = 54321 if (timeDelta < LB_GESTURE_DELTATIME_MS): xD = event.x - prevPos[0] yD = event.y - prevPos[1] if abs(xD) > abs(yD): x -= xD bHorizScroll = True bVertiScroll = False else: y -= yD bVertiScroll = True bHorizScroll = False if (x >= 0) and (y >= 0): if ((orientation == Clutter.Orientation.HORIZONTAL) and (x > 0) and bHorizScroll) or ( (orientation == Clutter.Orientation.VERTICAL) and (y > 0) and bVertiScroll): dprint(DEBUG_LBM_EXTRA, "DBUG:LBMouse:Motion: Will Scroll", aID, gLBMMCnt, x, y) actor.save_easing_state() point = Clutter.Point() point.x = x point.y = y actor.scroll_to_point(point) gActors[aID]['posX'] = x gActors[aID]['posY'] = y actor.restore_easing_state() else: dprint(DEBUG_LBM_NEGPATH, "DBUG:LBMouse:Motion: Not my scroll", aID, gLBMMCnt) return False else: if ((orientation == Clutter.Orientation.HORIZONTAL) and (x < 0)) or ((orientation == Clutter.Orientation.VERTICAL) and (y < 0)): dprint(DEBUG_LBM, "DBUG:LBMouse:Motion: Scroll already at boundry", aID, gLBMMCnt, x, y) if gActors[aID]['blur'] == False: actor.add_effect(blurEffect) gActors[aID]['blur'] = True Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, LB_CLEANUP_TIMEOUT, _lb_scroll_cleanup, actor) else: dprint( DEBUG_LBM_NEGPATH, "DBUG:LBMouse:Motion: Scroll Pos -ve, Not mine, just passing up", aID, gLBMMCnt, x, y, xD, yD) return False gActors[aID]['prevPos'] = (event.x, event.y) gActors[aID]['prevTime'] = event.time return True else: dprint(DEBUG_LBM_NEGPATH, "DBUG:LBMouse:Motion: Stray or Delayed", aID, gLBMMCnt, timeDelta) return False elif event.type == Clutter.EventType.BUTTON_RELEASE: dprint(DEBUG_LBM, "DBUG:LBMouse:BtnRelease", aID, gLBMMCnt, gActors[aID]['posX'], gActors[aID]['posY']) gActors[aID]['startTime'] = None gActors[aID]['prevPos'] = None gActors[aID]['prevTime'] = None if gActors[aID]['blur']: actor.remove_effect(blurEffect) gActors[aID]['blur'] = False return Clutter.EVENT_PROPAGATE
def clutter_quit(*args): Clutter.main_quit() if __name__ == '__main__': Clutter.init([]) stage = Clutter.Stage() stage.set_size(800, 500) stage.set_title('Clutter - custom layout managers') stage.set_user_resizable(True) # quit when the window gets closed stage.connect('destroy', clutter_quit) # close window on escape stage.connect('key-press-event', stage_key) vbox = VBox() stage.add_child(vbox) # bind the size of vbox to the size of the stage vbox.add_constraint(Clutter.BindConstraint.new(stage, Clutter.BindCoordinate.SIZE, 0.0)) # update the content of vbox every 4 seconds Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, 4000, vbox.content.update) stage.show() Clutter.main()
def clutter_quit(*args): Clutter.main_quit() if __name__ == '__main__': Clutter.init([]) stage = Clutter.Stage() stage.set_size(800, 500) stage.set_title('Clutter - custom layout managers') stage.set_user_resizable(True) # quit when the window gets closed stage.connect('destroy', clutter_quit) # close window on escape stage.connect('key-press-event', stage_key) vbox = VBox() stage.add_child(vbox) # bind the size of vbox to the size of the stage vbox.add_constraint( Clutter.BindConstraint.new(stage, Clutter.BindCoordinate.SIZE, 0.0)) # update the content of vbox every 4 seconds Clutter.threads_add_timeout(GLib.PRIORITY_DEFAULT, 4000, vbox.content.update) stage.show() Clutter.main()