def do_activate(self): # Basic Activation Procedure self.shell = self.object self.main_window = self.shell.props.window # Prepare internal variables self.song_duration = 0 self.cover_pixbuf = None self.entry = None # Prepare Album Art Displaying self.album_art_db = GObject.new(RB.ExtDB, name="album-art") # Build up actions. self.action_group = ActionGroup(self.shell, 'small window actions') action = self.action_group.add_action(func=self.small_window_action, action_name='SmallWindow', label='Small Window', action_type='app') self._appshell = ApplicationShell(self.shell) self._appshell.insert_action_group(self.action_group) self._appshell.add_app_menuitems(ui_string, 'small window actions') # Build up small window interface builder = Gtk.Builder() if is_rb3(): builder.add_from_file(rb.find_plugin_file(self, "interface_rb3.ui")) else: builder.add_from_file(rb.find_plugin_file(self, "interface_rb2.ui")) self.load_builder_content(builder) self.connect_builder_content(builder) restore = builder.get_object('restore button') restore.connect('clicked', self.main_window_action) # Prepare windows for sub_widget in self.small_window: sub_widget.show_all() geometry = Gdk.Geometry() geometry.min_width = 300 geometry.max_width = 5120 geometry.min_height = -1 geometry.max_height = -1 self.small_window.set_geometry_hints( self.small_window, geometry, Gdk.WindowHints.MIN_SIZE | Gdk.WindowHints.MAX_SIZE) if is_rb3(): self.shell.props.application.add_window(self.small_window) # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "play"), (self.prev_button, "play-previous"), (self.next_button, "play-next"), (self.repeat_toggle, "play-repeat"), (self.shuffle_toggle, "play-shuffle")): a.set_action_name("app." + b) #if b == "play-repeat" or b == "play-shuffle": # a.set_action_target_value(GLib.Variant("b", True)) else: # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "ControlPlay"), (self.prev_button, "ControlPrevious"), (self.next_button, "ControlNext"), (self.repeat_toggle, "ControlRepeat"), (self.shuffle_toggle, "ControlShuffle")): a.set_related_action( self._appshell.lookup_action("MainActions", b).action) # Bind needed properites. self.bind_title = GObject.Binding(source=self.main_window, source_property="title", target=self.small_window, target_property="title", flags=GObject.BindingFlags.DEFAULT) # Connect signal handlers to rhythmbox self.shell_player = self.shell.props.shell_player self.sh_psc = self.shell_player.connect("playing-song-changed", self._sh_on_song_change) self.sh_op = self.shell_player.connect("elapsed-changed", self._sh_on_playing)
def do_activate(self): # Basic Activation Procedure self.shell = self.object self.main_window = self.shell.props.window # Prepare internal variables self.song_duration = 0 self.cover_pixbuf = None self.entry = None # Prepare Album Art Displaying self.album_art_db = GObject.new(RB.ExtDB, name="album-art") # Build up actions. self.action_group = ActionGroup(self.shell, 'small window actions') action = self.action_group.add_action( func=self.small_window_action, action_name='SmallWindow', label='Small Window', action_type='app') self._appshell = ApplicationShell(self.shell) self._appshell.insert_action_group(self.action_group) self._appshell.add_app_menuitems(ui_string, 'small window actions') # Build up small window interface builder = Gtk.Builder() if is_rb3(): builder.add_from_file(rb.find_plugin_file(self, "interface_rb3.ui")) else: builder.add_from_file(rb.find_plugin_file(self, "interface_rb2.ui")) self.load_builder_content(builder) self.connect_builder_content(builder) restore = builder.get_object('restore button') restore.connect('clicked', self.main_window_action) # Prepare windows for sub_widget in self.small_window: sub_widget.show_all() geometry = Gdk.Geometry() geometry.min_width = 300 geometry.max_width = 5120 geometry.min_height = -1 geometry.max_height = -1 self.small_window.set_geometry_hints(self.small_window, geometry, Gdk.WindowHints.MIN_SIZE | Gdk.WindowHints.MAX_SIZE) if is_rb3(): self.shell.props.application.add_window(self.small_window) # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "play"), (self.prev_button, "play-previous"), (self.next_button, "play-next"), (self.repeat_toggle, "play-repeat"), (self.shuffle_toggle, "play-shuffle")): a.set_action_name("app." + b) #if b == "play-repeat" or b == "play-shuffle": # a.set_action_target_value(GLib.Variant("b", True)) else: # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "ControlPlay"), (self.prev_button, "ControlPrevious"), (self.next_button, "ControlNext"), (self.repeat_toggle, "ControlRepeat"), (self.shuffle_toggle, "ControlShuffle")): a.set_related_action(self._appshell.lookup_action("MainActions", b).action) # Bind needed properites. self.bind_title = GObject.Binding(source=self.main_window, source_property="title", target=self.small_window, target_property="title", flags=GObject.BindingFlags.DEFAULT) # Connect signal handlers to rhythmbox self.shell_player = self.shell.props.shell_player self.sh_psc = self.shell_player.connect("playing-song-changed", self._sh_on_song_change) self.sh_op = self.shell_player.connect("elapsed-changed", self._sh_on_playing)
class SmallWindow(GObject.Object, Peas.Activatable): object = GObject.Property(type=GObject.Object) # Builder releated utility functions... #################################### def load_builder_content(self, builder): if (not hasattr(self, "__builder_obj_names")): self.__builder_obj_names = list() for obj in builder.get_objects(): if (isinstance(obj, Gtk.Buildable)): name = Gtk.Buildable.get_name(obj).replace(' ', '_') self.__dict__[name] = obj self.__builder_obj_names.append(name) def connect_builder_content(self, builder): builder.connect_signals_full(self.connect_builder_content_func, self) def connect_builder_content_func(self, builder, object, sig_name, handler_name, conn_object, flags, target): handler = None h_name_internal = "_sh_" + handler_name.replace(" ", "_") if (hasattr(target, h_name_internal)): handler = getattr(target, h_name_internal) else: handler = eval(handler_name) object.connect(sig_name, handler) def purge_builder_content(self): for name in self.__builder_obj_names: o = self.__dict__[name] if (isinstance(o, Gtk.Widget)): o.destroy() del self.__dict__[name] del self.__builder_obj_names # Plugins Methods... ####################################################### def __init__(self): super(SmallWindow, self).__init__() def do_activate(self): # Basic Activation Procedure self.shell = self.object self.main_window = self.shell.props.window # Prepare internal variables self.song_duration = 0 self.cover_pixbuf = None self.entry = None # Prepare Album Art Displaying self.album_art_db = GObject.new(RB.ExtDB, name="album-art") # Build up actions. self.action_group = ActionGroup(self.shell, 'small window actions') action = self.action_group.add_action(func=self.small_window_action, action_name='SmallWindow', label='Small Window', action_type='app') self._appshell = ApplicationShell(self.shell) self._appshell.insert_action_group(self.action_group) self._appshell.add_app_menuitems(ui_string, 'small window actions') # Build up small window interface builder = Gtk.Builder() if is_rb3(): builder.add_from_file(rb.find_plugin_file(self, "interface_rb3.ui")) else: builder.add_from_file(rb.find_plugin_file(self, "interface_rb2.ui")) self.load_builder_content(builder) self.connect_builder_content(builder) restore = builder.get_object('restore button') restore.connect('clicked', self.main_window_action) # Prepare windows for sub_widget in self.small_window: sub_widget.show_all() geometry = Gdk.Geometry() geometry.min_width = 300 geometry.max_width = 5120 geometry.min_height = -1 geometry.max_height = -1 self.small_window.set_geometry_hints( self.small_window, geometry, Gdk.WindowHints.MIN_SIZE | Gdk.WindowHints.MAX_SIZE) if is_rb3(): self.shell.props.application.add_window(self.small_window) # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "play"), (self.prev_button, "play-previous"), (self.next_button, "play-next"), (self.repeat_toggle, "play-repeat"), (self.shuffle_toggle, "play-shuffle")): a.set_action_name("app." + b) #if b == "play-repeat" or b == "play-shuffle": # a.set_action_target_value(GLib.Variant("b", True)) else: # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "ControlPlay"), (self.prev_button, "ControlPrevious"), (self.next_button, "ControlNext"), (self.repeat_toggle, "ControlRepeat"), (self.shuffle_toggle, "ControlShuffle")): a.set_related_action( self._appshell.lookup_action("MainActions", b).action) # Bind needed properites. self.bind_title = GObject.Binding(source=self.main_window, source_property="title", target=self.small_window, target_property="title", flags=GObject.BindingFlags.DEFAULT) # Connect signal handlers to rhythmbox self.shell_player = self.shell.props.shell_player self.sh_psc = self.shell_player.connect("playing-song-changed", self._sh_on_song_change) self.sh_op = self.shell_player.connect("elapsed-changed", self._sh_on_playing) def do_deactivate(self): self.shell_player.disconnect(self.sh_op) self.shell_player.disconnect(self.sh_psc) del self.shell_player del self.bind_title self._appshell.cleanup() del self.album_art_db self.purge_builder_content() del self.main_window del self.shell # Controlling Functions #################################################### def display_song(self, entry): self.entry = entry self.cover_pixbuf = None self.album_cover.clear() if (entry is None): self.song_button_label.set_text("") else: self.song_button_label.set_markup( "<b>{title}</b> <small>{album} - {artist}</small>".format( title=entry.get_string(RB.RhythmDBPropType.TITLE), album=entry.get_string(RB.RhythmDBPropType.ALBUM), artist=entry.get_string(RB.RhythmDBPropType.ARTIST))) key = entry.create_ext_db_key(RB.RhythmDBPropType.ALBUM) self.album_art_db.request(key, self.display_song_album_art_callback, entry) def display_song_album_art_callback(self, key, filename, data, entry): if ((data is not None) and (isinstance(data, GdkPixbuf.Pixbuf))): self.cover_pixbuf = data scale_cover = self.cover_pixbuf.scale_simple( 24, 24, GdkPixbuf.InterpType.HYPER) self.album_cover.set_from_pixbuf(scale_cover) else: self.cover_pixbuf = None self.album_cover.clear() # Signal Handlers ########################################################## def small_window_action(self, *args): self.main_window.hide() self.small_window.show() def main_window_action(self, *args): self.small_window.hide() self.main_window.show() def _sh_small_window_on_close(self, window, asdf): self.shell.quit() def _sh_on_song_change(self, player, entry): if (entry is not None): self.song_duration = entry.get_ulong(RB.RhythmDBPropType.DURATION) else: self.song_duration = 0 self.display_song(entry) def _sh_on_playing(self, player, second): if (self.song_duration != 0): self.song_progress.progress = float(second) / self.song_duration def _sh_progress_control(self, progress, fraction): if (self.song_duration != 0): self.shell_player.set_playing_time(self.song_duration * fraction) def _sh_bigger_cover(self, cover, x, y, key, tooltip): if (self.cover_pixbuf is not None): tooltip.set_icon( self.cover_pixbuf.scale_simple(300, 300, GdkPixbuf.InterpType.HYPER)) return True else: return False
class SmallWindow(GObject.Object, Peas.Activatable): object = GObject.Property(type=GObject.Object) # Builder releated utility functions... #################################### def load_builder_content(self, builder): if ( not hasattr(self, "__builder_obj_names") ): self.__builder_obj_names = list() for obj in builder.get_objects(): if ( isinstance(obj, Gtk.Buildable) ): name = Gtk.Buildable.get_name(obj).replace(' ', '_') self.__dict__[name] = obj self.__builder_obj_names.append(name) def connect_builder_content(self, builder): builder.connect_signals_full(self.connect_builder_content_func, self) def connect_builder_content_func(self, builder, object, sig_name, handler_name, conn_object, flags, target): handler = None h_name_internal = "_sh_" + handler_name.replace(" ", "_") if ( hasattr(target, h_name_internal) ): handler = getattr(target, h_name_internal) else: handler = eval(handler_name) object.connect(sig_name, handler) def purge_builder_content(self): for name in self.__builder_obj_names: o = self.__dict__[name] if ( isinstance(o, Gtk.Widget) ): o.destroy() del self.__dict__[name] del self.__builder_obj_names # Plugins Methods... ####################################################### def __init__(self): super(SmallWindow, self).__init__() def do_activate(self): # Basic Activation Procedure self.shell = self.object self.main_window = self.shell.props.window # Prepare internal variables self.song_duration = 0 self.cover_pixbuf = None self.entry = None # Prepare Album Art Displaying self.album_art_db = GObject.new(RB.ExtDB, name="album-art") # Build up actions. self.action_group = ActionGroup(self.shell, 'small window actions') action = self.action_group.add_action( func=self.small_window_action, action_name='SmallWindow', label='Small Window', action_type='app') self._appshell = ApplicationShell(self.shell) self._appshell.insert_action_group(self.action_group) self._appshell.add_app_menuitems(ui_string, 'small window actions') # Build up small window interface builder = Gtk.Builder() if is_rb3(): builder.add_from_file(rb.find_plugin_file(self, "interface_rb3.ui")) else: builder.add_from_file(rb.find_plugin_file(self, "interface_rb2.ui")) self.load_builder_content(builder) self.connect_builder_content(builder) restore = builder.get_object('restore button') restore.connect('clicked', self.main_window_action) # Prepare windows for sub_widget in self.small_window: sub_widget.show_all() geometry = Gdk.Geometry() geometry.min_width = 300 geometry.max_width = 5120 geometry.min_height = -1 geometry.max_height = -1 self.small_window.set_geometry_hints(self.small_window, geometry, Gdk.WindowHints.MIN_SIZE | Gdk.WindowHints.MAX_SIZE) if is_rb3(): self.shell.props.application.add_window(self.small_window) # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "play"), (self.prev_button, "play-previous"), (self.next_button, "play-next"), (self.repeat_toggle, "play-repeat"), (self.shuffle_toggle, "play-shuffle")): a.set_action_name("app." + b) #if b == "play-repeat" or b == "play-shuffle": # a.set_action_target_value(GLib.Variant("b", True)) else: # Bring Builtin Actions to plugin for (a, b) in ((self.play_button, "ControlPlay"), (self.prev_button, "ControlPrevious"), (self.next_button, "ControlNext"), (self.repeat_toggle, "ControlRepeat"), (self.shuffle_toggle, "ControlShuffle")): a.set_related_action(self._appshell.lookup_action("MainActions", b).action) # Bind needed properites. self.bind_title = GObject.Binding(source=self.main_window, source_property="title", target=self.small_window, target_property="title", flags=GObject.BindingFlags.DEFAULT) # Connect signal handlers to rhythmbox self.shell_player = self.shell.props.shell_player self.sh_psc = self.shell_player.connect("playing-song-changed", self._sh_on_song_change) self.sh_op = self.shell_player.connect("elapsed-changed", self._sh_on_playing) def do_deactivate(self): self.shell_player.disconnect(self.sh_op) self.shell_player.disconnect(self.sh_psc) del self.shell_player del self.bind_title self._appshell.cleanup() del self.album_art_db self.purge_builder_content() del self.main_window del self.shell # Controlling Functions #################################################### def display_song(self, entry): self.entry = entry self.cover_pixbuf = None self.album_cover.clear() if ( entry is None ): self.song_button_label.set_text("") else: self.song_button_label.set_markup( "<b>{title}</b> <small>{album} - {artist}</small>".format( title=entry.get_string(RB.RhythmDBPropType.TITLE), album=entry.get_string(RB.RhythmDBPropType.ALBUM), artist=entry.get_string(RB.RhythmDBPropType.ARTIST))) key = entry.create_ext_db_key(RB.RhythmDBPropType.ALBUM) self.album_art_db.request(key, self.display_song_album_art_callback, entry) def display_song_album_art_callback(self, key, filename, data, entry): if ( ( data is not None ) and ( isinstance(data, GdkPixbuf.Pixbuf) ) ): self.cover_pixbuf = data scale_cover = self.cover_pixbuf.scale_simple(24, 24, GdkPixbuf.InterpType.HYPER) self.album_cover.set_from_pixbuf(scale_cover) else: self.cover_pixbuf = None self.album_cover.clear() # Signal Handlers ########################################################## def small_window_action(self, *args): self.main_window.hide() self.small_window.show() def main_window_action(self, *args): self.small_window.hide() self.main_window.show() def _sh_small_window_on_close(self, window, asdf): self.shell.quit() def _sh_on_song_change(self, player, entry): if ( entry is not None ): self.song_duration = entry.get_ulong(RB.RhythmDBPropType.DURATION) else: self.song_duration = 0 self.display_song(entry) def _sh_on_playing(self, player, second): if ( self.song_duration != 0 ): self.song_progress.progress = float(second) / self.song_duration def _sh_progress_control(self, progress, fraction): if ( self.song_duration != 0 ): self.shell_player.set_playing_time(self.song_duration * fraction) def _sh_bigger_cover(self, cover, x, y, key, tooltip): if ( self.cover_pixbuf is not None ): tooltip.set_icon(self.cover_pixbuf.scale_simple(300, 300, GdkPixbuf.InterpType.HYPER)) return True else: return False