def cw_btn_clicked(self, *args):
        def cleanup(arg):
            del self.cw
            self.cw = None

        if not self.cw:
            home = expanduser("~")
            self.cw = CoverWindow(self.source.plugin, self.cw_btn.get_toplevel(), home)
            self.cw.connect('close-window', cleanup)

        self.cw.show_all(' ', self.pixbuf)
Ejemplo n.º 2
0
    def cw_btn_clicked(self, *args):
        def cleanup(arg):
            del self.cw
            self.cw = None

        if not self.cw:
            home = expanduser("~")
            self.cw = CoverWindow(self.source.plugin, self.cw_btn.get_toplevel(), home)
            self.cw.connect('close-window', cleanup)

        self.cw.show_all(' ', self.pixbuf)
Ejemplo n.º 3
0
class ResultsGrid(Gtk.Grid):
    # signals
    __gsignals__ = {
        'update-cover':
        (GObject.SIGNAL_RUN_LAST, None, (GObject.Object, RB.RhythmDBEntry)),
        'whats-playing': (GObject.SIGNAL_RUN_LAST, None, (bool, ))
    }
    image_width = 0

    def __init__(self, *args, **kwargs):
        super(ResultsGrid, self).__init__(*args, **kwargs)

    def initialise(self, entry_view_grid, source):
        self.pixbuf = None

        self.entry_view_grid = entry_view_grid
        self.source = source

        self.oldval = 0
        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self.stack.set_transition_duration(350)

        self.image1 = Gtk.Image()
        self.image1.props.hexpand = True
        self.image1.props.vexpand = True
        self.stack.add_named(self.image1, "image1")

        self.image2 = Gtk.Image()
        self.image2.props.hexpand = True
        self.image2.props.vexpand = True
        self.stack.add_named(self.image2, "image2")

        self.frame = Gtk.Frame.new()  # "", 0.5, 0.5, 1, False)
        try:
            # correct from Gtk 3.12 onwards
            self.frame.set_margin_end(5)
        except:
            self.frame.set_margin_right(5)

        self.update_cover(None, None, None)
        self.scroll = Gtk.ScrolledWindow()
        self.scroll.add(self.stack)
        self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC,
                               Gtk.PolicyType.AUTOMATIC)

        self.scroll.set_resize_mode(Gtk.ResizeMode.QUEUE)

        self.frame.add(self.scroll)
        self._signal_connected = None
        '''
          when we hover over the coverart then a zoom icon is overlayed with the coverart
          when we move the mouse pointer from the coverart then the zoom icon is hidden

          this is achieved by a GtkOverlay - the stack doesnt normally have a mouse over event so
          we need to understand when a mouse pointer enters or leaves the stack.

          Also a peculiarity is that moving the pointer over the overlay zoom icon causes
          enter and leave events ... so we need to monitor the mouse over for the icon as well
        '''
        self.overlay = Gtk.Overlay()
        self.overlay.add(self.frame)

        image = Gtk.Image.new_from_icon_name(Gtk.STOCK_ZOOM_FIT,
                                             Gtk.IconSize.SMALL_TOOLBAR)
        self.cw_btn = Gtk.Button(label=None, image=image)

        self.cw_btn.set_valign(Gtk.Align.END)
        self.cw_btn.set_halign(Gtk.Align.CENTER)
        self.cw_btn_state = False
        self.hover = False
        self.overlay.add_overlay(self.cw_btn)

        self.attach(self.overlay, 6, 0, 1, 1)

        self.stack.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK)
        self.stack.add_events(Gdk.EventMask.LEAVE_NOTIFY_MASK)
        self.stack.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
        self.cw_btn.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
        self.stack.connect('enter-notify-event', self.stack_notify_event)
        self.stack.connect('leave-notify-event', self.stack_notify_event)
        self.stack.connect('motion-notify-event', self.motion_notify_event)
        self.cw_btn.connect('clicked', self.cw_btn_clicked)
        self.cw_btn.connect('motion-notify-event', self.motion_notify_event)
        self.cw_btn.connect('show', self.cw_btn_show_event)
        self.cw = None
        self.hover_time_out = None
        self.connect('update-cover', self.update_cover)
        self.connect('whats-playing', self.display_whats_playing)

        # lets fix the situation where some-themes background colour is incorrectly defined
        # in these cases the background colour is black
        context = self.get_style_context()
        bg_colour = context.get_background_color(Gtk.StateFlags.NORMAL)
        if bg_colour == Gdk.RGBA(0, 0, 0, 0):
            color = context.get_color(Gtk.StateFlags.NORMAL)
            self.override_background_color(Gtk.StateType.NORMAL, color)

    '''
      when a show, show_all is used lets make sure we set the icon visibility correctly
    '''

    def cw_btn_show_event(self, *args):
        self.cw_btn.set_visible(self.hover)

    '''
      when mousing over the stack/icon we need to remember that we are hovering ... so the visibility
      is set correctly - in the stack notify event
    '''

    def motion_notify_event(self, *args):
        self.hover = True

    def cw_btn_clicked(self, *args):
        def cleanup(arg):
            del self.cw
            self.cw = None

        if not self.cw:
            home = expanduser("~")
            self.cw = CoverWindow(self.source.plugin,
                                  self.cw_btn.get_toplevel(), home)
            self.cw.connect('close-window', cleanup)

        self.cw.show_all(' ', self.pixbuf)

    '''
      when entering and leaving the stack (also the icon) then we assume the icon is to be invisible
      Use a short delay to allow the motion events to kick in - if we are still in the stack/icon
      then the hover visibility will be changed
    '''

    def stack_notify_event(self, widget, event_crossing):

        if self.hover_time_out:
            GLib.source_remove(self.hover_time_out)
            self.hover_time_out = None

        def set_hover():
            if self.pixbuf:
                self.cw_btn.set_visible(self.hover)
            else:
                self.cw_btn.set_visible(False)

            self.hover_time_out = None
            return False

        self.hover = False

        self.hover_time_out = GLib.timeout_add(350, set_hover)

        return False

    def update_cover(self, widget, source, entry):

        print('update_cover')
        self.oldval = 0  # force a redraw
        if entry:
            print('entry')
            album = source.album_manager.model.get_from_dbentry(entry)
            self.pixbuf = GdkPixbuf.Pixbuf().new_from_file(
                album.cover.original)
            self.window_resize(None)
            self.frame.set_shadow_type(Gtk.ShadowType.NONE)
        else:
            print('no pixbuf')
            self.pixbuf = None
            self.frame.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)

        if self.stack.get_visible_child_name() == "image1":
            self.image1.queue_draw()
        else:
            self.image2.queue_draw()

    def display_whats_playing(self, show_playing):
        view = self.get_child_at(0, 0)

        view.display_playing_tracks(show_playing)

    def window_resize(self, widget):
        alloc = self.get_allocation()
        if alloc.height < 10:
            return

        entry_grid_alloc = self.entry_view_grid.get_allocation()

        if (alloc.width / 4) <= (MIN_IMAGE_SIZE + 30) or \
                        (entry_grid_alloc.height) <= (MIN_IMAGE_SIZE + 30):
            self.overlay.set_visible(False)
            return
        else:
            self.overlay.set_visible(True)
            vbar = self.scroll.get_vscrollbar()
            if vbar:
                vbar.set_visible(False)
            hbar = self.scroll.get_hscrollbar()
            if hbar:
                hbar.set_visible(False)

        minval = min((alloc.width / 4), (alloc.height))
        if self.oldval == minval:
            return
        self.oldval = minval
        if minval < MIN_IMAGE_SIZE:
            minval = MIN_IMAGE_SIZE

        if self.pixbuf:
            p = self.pixbuf.scale_simple(minval - 15, minval - 15,
                                         GdkPixbuf.InterpType.BILINEAR)
        else:
            p = None

        if self.stack.get_visible_child_name() == "image1":
            self.image2.set_from_pixbuf(p)
            self.stack.set_visible_child_name("image2")
        else:
            self.image1.set_from_pixbuf(p)
            self.stack.set_visible_child_name("image1")

    def change_view(self, entry_view, show_coverart):
        print("debug - change_view")
        widget = self.get_child_at(0, 0)
        if widget:
            self.remove(widget)

        if not show_coverart:
            widget = self.get_child_at(6, 0)
            if widget:
                self.remove(widget)

        entry_view.props.hexpand = True
        entry_view.props.vexpand = True
        self.attach(entry_view, 0, 0, 3, 1)

        if show_coverart:
            self.attach(self.overlay, 6, 0, 1, 1)

        self.show_all()
        self.cw_btn.set_visible(self.hover)
Ejemplo n.º 4
0
class ResultsGrid(Gtk.Grid):
    # signals
    __gsignals__ = {
        'update-cover': (GObject.SIGNAL_RUN_LAST, None, (GObject.Object, RB.RhythmDBEntry)),
        'whats-playing': (GObject.SIGNAL_RUN_LAST, None, (bool,))
    }
    image_width = 0

    def __init__(self, *args, **kwargs):
        super(ResultsGrid, self).__init__(*args, **kwargs)

    def initialise(self, entry_view_grid, source):
        self.pixbuf = None

        self.entry_view_grid = entry_view_grid
        self.source = source

        self.oldval = 0
        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.CROSSFADE)
        self.stack.set_transition_duration(350)

        self.image1 = Gtk.Image()
        self.image1.props.hexpand = True
        self.image1.props.vexpand = True
        self.stack.add_named(self.image1, "image1")

        self.image2 = Gtk.Image()
        self.image2.props.hexpand = True
        self.image2.props.vexpand = True
        self.stack.add_named(self.image2, "image2")

        self.frame = Gtk.Frame.new()  # "", 0.5, 0.5, 1, False)
        try:
            # correct from Gtk 3.12 onwards
            self.frame.set_margin_end(5)
        except:
            self.frame.set_margin_right(5)

        self.update_cover(None, None, None)
        self.scroll = Gtk.ScrolledWindow()
        self.scroll.add(self.stack)
        self.scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)

        self.scroll.set_resize_mode(Gtk.ResizeMode.QUEUE)

        self.frame.add(self.scroll)
        self._signal_connected = None

        '''
          when we hover over the coverart then a zoom icon is overlayed with the coverart
          when we move the mouse pointer from the coverart then the zoom icon is hidden

          this is achieved by a GtkOverlay - the stack doesnt normally have a mouse over event so
          we need to understand when a mouse pointer enters or leaves the stack.

          Also a peculiarity is that moving the pointer over the overlay zoom icon causes
          enter and leave events ... so we need to monitor the mouse over for the icon as well
        '''
        self.overlay = Gtk.Overlay()
        self.overlay.add(self.frame)

        image = Gtk.Image.new_from_icon_name(Gtk.STOCK_ZOOM_FIT, Gtk.IconSize.SMALL_TOOLBAR)
        self.cw_btn = Gtk.Button(label=None, image=image)

        self.cw_btn.set_valign(Gtk.Align.END)
        self.cw_btn.set_halign(Gtk.Align.CENTER)
        self.cw_btn_state = False
        self.hover = False
        self.overlay.add_overlay(self.cw_btn)

        self.attach(self.overlay, 6, 0, 1, 1)

        self.stack.add_events(Gdk.EventMask.ENTER_NOTIFY_MASK)
        self.stack.add_events(Gdk.EventMask.LEAVE_NOTIFY_MASK)
        self.stack.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
        self.cw_btn.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
        self.stack.connect('enter-notify-event', self.stack_notify_event)
        self.stack.connect('leave-notify-event', self.stack_notify_event)
        self.stack.connect('motion-notify-event', self.motion_notify_event)
        self.cw_btn.connect('clicked', self.cw_btn_clicked)
        self.cw_btn.connect('motion-notify-event', self.motion_notify_event)
        self.cw_btn.connect('show', self.cw_btn_show_event)
        self.cw = None
        self.hover_time_out = None
        self.connect('update-cover', self.update_cover)
        self.connect('whats-playing', self.display_whats_playing)

        # lets fix the situation where some-themes background colour is incorrectly defined
        # in these cases the background colour is black
        context = self.get_style_context()
        bg_colour = context.get_background_color(Gtk.StateFlags.NORMAL)
        if bg_colour == Gdk.RGBA(0, 0, 0, 0):
            color = context.get_color(Gtk.StateFlags.NORMAL)
            self.override_background_color(Gtk.StateType.NORMAL, color)

    '''
      when a show, show_all is used lets make sure we set the icon visibility correctly
    '''

    def cw_btn_show_event(self, *args):
        self.cw_btn.set_visible(self.hover)

    '''
      when mousing over the stack/icon we need to remember that we are hovering ... so the visibility
      is set correctly - in the stack notify event
    '''

    def motion_notify_event(self, *args):
        self.hover = True

    def cw_btn_clicked(self, *args):
        def cleanup(arg):
            del self.cw
            self.cw = None

        if not self.cw:
            home = expanduser("~")
            self.cw = CoverWindow(self.source.plugin, self.cw_btn.get_toplevel(), home)
            self.cw.connect('close-window', cleanup)

        self.cw.show_all(' ', self.pixbuf)

    '''
      when entering and leaving the stack (also the icon) then we assume the icon is to be invisible
      Use a short delay to allow the motion events to kick in - if we are still in the stack/icon
      then the hover visibility will be changed
    '''

    def stack_notify_event(self, widget, event_crossing):

        if self.hover_time_out:
            GLib.source_remove(self.hover_time_out)
            self.hover_time_out = None

        def set_hover():
            if self.pixbuf:
                self.cw_btn.set_visible(self.hover)
            else:
                self.cw_btn.set_visible(False)

            self.hover_time_out = None
            return False

        self.hover = False

        self.hover_time_out = GLib.timeout_add(350, set_hover)

        return False

    def update_cover(self, widget, source, entry):

        print('update_cover')
        self.oldval = 0  # force a redraw
        if entry:
            print('entry')
            album = source.album_manager.model.get_from_dbentry(entry)
            self.pixbuf = GdkPixbuf.Pixbuf().new_from_file(album.cover.original)
            self.window_resize(None)
            self.frame.set_shadow_type(Gtk.ShadowType.NONE)
        else:
            print('no pixbuf')
            self.pixbuf = None
            self.frame.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)

        if self.stack.get_visible_child_name() == "image1":
            self.image1.queue_draw()
        else:
            self.image2.queue_draw()

    def display_whats_playing(self, show_playing):
        view = self.get_child_at(0, 0)

        view.display_playing_tracks(show_playing)

    def window_resize(self, widget):
        alloc = self.get_allocation()
        if alloc.height < 10:
            return

        entry_grid_alloc = self.entry_view_grid.get_allocation()

        if (alloc.width / 4) <= (MIN_IMAGE_SIZE + 30) or \
                        (entry_grid_alloc.height) <= (MIN_IMAGE_SIZE + 30):
            self.overlay.set_visible(False)
            return
        else:
            self.overlay.set_visible(True)
            vbar = self.scroll.get_vscrollbar()
            if vbar:
                vbar.set_visible(False)
            hbar = self.scroll.get_hscrollbar()
            if hbar:
                hbar.set_visible(False)

        minval = min((alloc.width / 4), (alloc.height))
        if self.oldval == minval:
            return
        self.oldval = minval
        if minval < MIN_IMAGE_SIZE:
            minval = MIN_IMAGE_SIZE

        if self.pixbuf:
            p = self.pixbuf.scale_simple(minval - 15, minval - 15, GdkPixbuf.InterpType.BILINEAR)
        else:
            p = None

        if self.stack.get_visible_child_name() == "image1":
            self.image2.set_from_pixbuf(p)
            self.stack.set_visible_child_name("image2")
        else:
            self.image1.set_from_pixbuf(p)
            self.stack.set_visible_child_name("image1")

    def change_view(self, entry_view, show_coverart):
        print("debug - change_view")
        widget = self.get_child_at(0, 0)
        if widget:
            self.remove(widget)

        if not show_coverart:
            widget = self.get_child_at(6, 0)
            if widget:
                self.remove(widget)

        entry_view.props.hexpand = True
        entry_view.props.vexpand = True
        self.attach(entry_view, 0, 0, 3, 1)

        if show_coverart:
            self.attach(self.overlay, 6, 0, 1, 1)

        self.show_all()
        self.cw_btn.set_visible(self.hover)