class PlayListButton(object):
    def __init__(self):
        self.button = ToggleButton(
            app_theme.get_pixbuf("bottom_buttons/play_list_button.png"),
            app_theme.get_pixbuf("bottom_buttons/list_button_background.png"),
            )
        self.button.set_active(False)
        tooltip_text(self.button, _("Playlist"))
class PlayListButton(object):
    def __init__(self):
        self.button = ToggleButton(
            app_theme.get_pixbuf("bottom_buttons/play_list_button.png"),
            app_theme.get_pixbuf("bottom_buttons/list_button_background.png"),
        )
        self.button.set_active(False)
        tooltip_text(self.button, _("Playlist"))
Ejemplo n.º 3
0
 def __setup_toggle(self):
     toggle_button = ToggleButton(
         app_theme.get_pixbuf("toggle_button/inactive_normal.png"),
         app_theme.get_pixbuf("toggle_button/active_normal.png"),
         inactive_disable_dpixbuf=app_theme.get_pixbuf(
             "toggle_button/inactive_normal.png"))
     toggle_button.set_active(self.my_bluetooth.adapter.get_powered())
     return toggle_button
 def __setup_toggle(self):
     toggle_button = ToggleButton(app_theme.get_pixbuf("toggle_button/inactive_normal.png"),
                                  app_theme.get_pixbuf("toggle_button/active_normal.png"),
                                  inactive_disable_dpixbuf = app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
     toggle_button.set_active(self.my_bluetooth.adapter.get_powered())
     return toggle_button
Ejemplo n.º 5
0
class VolumeButton(gtk.HBox):
    
    def __init__(self, init_value=100, min_value=0, max_value=100):
        
        super(VolumeButton, self).__init__()
        self.set_spacing(2)
        self.volume_progressbar = HScalebar(
            app_theme.get_pixbuf("volume/fg.png"),
            app_theme.get_pixbuf("volume/bg.png"),
            app_theme.get_pixbuf("volume/point_normal.png"),
            )
        
        self.volume_button = ToggleButton(
            app_theme.get_pixbuf("volume/high_normal.png"),
            app_theme.get_pixbuf("volume/mute_normal.png"),
            app_theme.get_pixbuf("volume/high_hover.png"),
            app_theme.get_pixbuf("volume/mute_hover.png"),
            app_theme.get_pixbuf("volume/high_press.png"),
            app_theme.get_pixbuf("volume/mute_press.png"),
            )
        
        # Init widget.
        self.volume_progressbar.set_size_request(58, 11)
        self.volume_progressbar.set_range(min_value, max_value)
        self.volume_progressbar.set_value(init_value)
        self.volume_progressbar.connect("button-release-event", self.release_event)
        
        # Signals.
        self.volume_progressbar.get_adjustment().connect("value-changed", self.moniter_volume_change)
        
        # Pack.
        volume_align = gtk.Alignment()
        volume_align.set(0.5, 0.5, 0, 0)
        volume_align.add(self.volume_progressbar)
        
        button_align = gtk.Alignment()
        # button_align.set(0.5, 0.5, 0, 0)
        button_align.add(self.volume_button)

        self.pack_start(button_align, False, False)
        self.pack_start(volume_align, False, False)
            
    def release_event(self, widget, event):    
        pass
        
    def update_volume_button_pixbuf(self, name):
        group = (
            app_theme.get_pixbuf("volume/%s_normal.png" % name),
            app_theme.get_pixbuf("volume/%s_hover.png" % name),
            app_theme.get_pixbuf("volume/%s_press.png" % name),
            app_theme.get_pixbuf("volume/%s_press.png" % name)
            )
        self.volume_button.set_inactive_pixbuf_group(group)
        self.queue_draw()
        
    
    def moniter_volume_change(self, adjustment):
        high_value = adjustment.get_upper()
        lower_value = adjustment.get_lower()
        total_value = high_value - lower_value
        current_value = adjustment.get_value() - lower_value
        
        if current_value > 0:
            if self.volume_button.get_active():
                self.volume_button.set_active(False)
        if current_value == 0:
            self.update_volume_button_pixbuf("zero")
        elif 0 < current_value  <= total_value * 0.3: 
            self.update_volume_button_pixbuf("lower")
        elif total_value * 0.3 < current_value <= total_value * 0.6:
            self.update_volume_button_pixbuf("middle")
        elif total_value * 0.6 < current_value <= total_value:
            self.update_volume_button_pixbuf("high")
class LyricsModule(object):
    def __init__(self):
        self.desktop_lyrics_win = DesktopLyrics()
        self.desktop_lyrics_win.connect("moved", self.adjust_toolbar_rect)
        self.desktop_lyrics_win.connect("resized", self.adjust_toolbar_rect)
        self.desktop_lyrics_win.connect("hide-bg", self.hide_toolbar)
        self.desktop_lyrics_win.connect("show-bg", self.show_toolbar)
        self.desktop_lyrics_win.connect("button-press-event", self.popup_desktop_right_menu)

        self.desktop_lyrics_win.connect("configure-event", self.lyrics_desktop_configure_event)
        
        self.scroll_lyrics = ScrollLyrics()
        self.scroll_lyrics.connect("configure-event", self.lyrcis_scroll_configure_event)
        self.scroll_lyrics.revert_button.connect("clicked", lambda w: self.switch_to_desktop_lyrics())        
        self.scroll_lyrics.connect("seek", self.seek_cb)
        self.scroll_lyrics.connect("right-press", self.scroll_right_press_cb)
        
        Player.connect("instant-new-song", self.instant_update_lrc)
        Player.connect("played", self.play_time_source)
        Player.connect("paused", self.pause_time_source)
        Player.connect("play-end", self.pause_time_source)
        Dispatcher.connect("reload-lrc", self.update_lrc)
        Dispatcher.connect("unlock-lyrics", self.__unlock_lyrics)
        Dispatcher.connect("lock-lyrics", self.__lock_lyrics)
        Dispatcher.connect("show-lyrics", lambda w : self.run())
        Dispatcher.connect("close-lyrics", lambda w: self.hide_all())
        Dispatcher.connect("search-lyrics", lambda w: self.open_search_window(w))
        Dispatcher.connect("dialog-run", self.on_dialog_run)
        Dispatcher.connect("dialog-close", self.on_dialog_close)
        
        self.lrc_manager = LrcManager()
        self.lrc = LrcParser()
        
        self.search_ui = SearchUI()
        self.lrc_id = -1
        self.lrc_next_id = -1
        self.current_line = 0
        self.message_source = None
        self.time_source = None
        self.song_duration = 0
        self.__find_flag = False
        self.__lyrics_mode = config.getint("lyrics", "mode")
        self.__dialog_locked_flag = False        
        
        self.init_toolbar()
        
        self.current_song = None
        self.next_lrc_to_download = None
        self.condition = threading.Condition()
        self.thread = threading.Thread(target=self.func_thread)
        self.thread.setDaemon(True)
        self.thread.start()
        
    def init_toolbar(self):    
        self.toolbar = Window(window_type=gtk.WINDOW_POPUP) 
        self.toolbar.set_size_request(-1, 41)
        padding_x, padding_y = 10, 5
        play_box = gtk.HBox(spacing=2)
        play_box.connect("expose-event", self.expose_toolbar_mask)
        
        # swap played status handler
        Player.connect("played", self.__swap_play_status, True)
        Player.connect("paused", self.__swap_play_status, False)
        Player.connect("stopped", self.__swap_play_status, False)
        Player.connect("play-end", self.__swap_play_status, False)
        self.playpause_button = ToggleButton(
            app_theme.get_pixbuf("lyric/play_normal.png"),
            app_theme.get_pixbuf("lyric/pause_normal.png"),
            app_theme.get_pixbuf("lyric/play_hover.png"),
            app_theme.get_pixbuf("lyric/pause_hover.png"),
            app_theme.get_pixbuf("lyric/play_press.png"),
            app_theme.get_pixbuf("lyric/pause_press.png"),
            )
        self.__id_signal_play = self.playpause_button.connect("toggled", lambda w: Player.playpause())
        prev = self.__create_button("previous")
        next = self.__create_button("next")
        
        prev_align = gtk.Alignment()
        prev_align.set(0.5, 0.5, 0, 0)
        prev_align.add(prev)
        next_align = gtk.Alignment()
        next_align.set(0.5, 0.5, 0, 0)
        next_align.add(next)
        
        play_align = gtk.Alignment()
        play_align.set_padding(2, 0, 0, 0)
        play_align.set(0.5, 0.5, 0, 0)
        play_align.add(self.playpause_button)
        
        # separte line
        separate_line = ImageBox(app_theme.get_pixbuf("lyric/separate.png"))
        sep_align = gtk.Alignment()
        sep_align.set(0.5, 0.5, 0, 0)
        sep_align.add(separate_line)
        
        zoom_in_align = self.__create_zoom_button("zoom_in", _("increase the lyrics size"))
        zoom_out_align = self.__create_zoom_button("zoom_out", _("decrease the lyrics size"))
        predefine_align = self.__create_simple_button("predefine_color", self.popup_predefine_menu, 
                                                      _("Select color theme"), True)
        lock_align = self.__create_simple_button("lock", self.__lock_lyrics, _("Lock lyrics"))
        karaoke_align, self.karaoke_button = self.__create_single_toggle_button("karaoke", 
                                                                                self.change_karaoke_status,
                                                                                _("karaoke on/off"))
        line_align, self.line_button = self.__create_simple_toggle_button("double_line", "single_line",
                                                                          self.change_line_status,
                                                                          _("Switch lines"))
        setting_align = self.__create_simple_button("setting", self.open_setting_window, _("Open settings panel"))
        search_align = self.__create_simple_button("search", self.open_search_window, _("search lrc file for current track"))
        close_align = self.__create_simple_button("close", self.close_lyric_window, _("Close lyrics"))
        before_align = self.__create_simple_button("before", self.before_offset, _("Lyrics rewind"))
        after_align = self.__create_simple_button("after", self.after_offset, _("Lyrics forward"))
        lrc_align = self.__create_simple_button("lrc", self.switch_to_scroll_lyrics, _("Switch to window mode"))

        play_box.pack_start(prev_align, False, False)
        play_box.pack_start(play_align, False, False)
        play_box.pack_start(next_align, False, False)
        play_box.pack_start(sep_align, False, False)
        play_box.pack_start(zoom_in_align, False, False)
        play_box.pack_start(zoom_out_align, False, False)
        play_box.pack_start(before_align, False, False)
        play_box.pack_start(after_align, False, False)
        play_box.pack_start(predefine_align, False, False)
        play_box.pack_start(karaoke_align, False, False)
        play_box.pack_start(line_align, False, False)
        play_box.pack_start(lock_align, False, False)        
        play_box.pack_start(setting_align, False, False)
        play_box.pack_start(lrc_align, False, False)
        play_box.pack_start(search_align, False, False)
        play_box.pack_start(close_align, False, False)
        
        main_align = gtk.Alignment()
        main_align.set_padding(0, 0, padding_x, padding_x)
        main_align.set(0.5, 0.5, 0, 0)
        main_align.add(play_box)
        self.toolbar.window_frame.pack_start(main_align)
        
        self.load_button_status()
        
    def expose_toolbar_mask(self, widget, event):    
        cr = widget.window.cairo_create()
        rect = widget.allocation
        draw_alpha_mask(cr, rect.x - 9, rect.y, rect.width + 18, rect.height, "lyricsMask")
        return False
        
    def scroll_right_press_cb(self, widget, event):    
        menu_items = [
            (self.get_scroll_menu_pixbufs("lrc"), _("Switch to desktop mode"), self.switch_to_desktop_lyrics),
            None,
            (self.get_scroll_menu_pixbufs("before"), _("Lyrics rewind"), lambda : self.before_offset(None)),
            (self.get_scroll_menu_pixbufs("after"), _("Lyrics forward"), lambda : self.after_offset(None)),
            None,
            (self.get_scroll_menu_pixbufs("search"), _("Search"), lambda :self.open_search_window(None)),
            (self.get_scroll_menu_pixbufs("setting"), _("Settings"), lambda : Dispatcher.show_scroll_page()),
                      ]
        Menu(menu_items, True).show((int(event.x_root), int(event.y_root)))
        
    def popup_desktop_right_menu(self, widget, event):    
        if event.button == 3 and Player.song:
            adjust_menu_item = [(None, _("Forward 0.5 seconds"), lambda : self.after_offset(None)), 
                                (None, _("Rewind 0.5 seconds"), lambda : self.before_offset(None))]
            menu_items = [
                (None, _("Search"), lambda : self.open_search_window(None)),
                (None, _("Adjust lyrics"), Menu(adjust_menu_item)),
                None,
                (None, _("Choose local lrc"), self.allocation_lrc),
                (None, _("Open directory"), self.open_lrc_dir),
                None,
                (None, _("Settings"), lambda : self.open_setting_window(None)),
                (None, _("Switch to window mode"), lambda : self.switch_to_scroll_lyrics(None))
                ]
            Menu(menu_items, True).show((int(event.x_root), int(event.y_root)))
            
    def allocation_lrc(self):        
        lrc_path = WinFile(False).run()
        if lrc_path:
            self.lrc_manager.allocation_lrc_file(Player.song, lrc_path)
            
    def open_lrc_dir(self):        
        save_dir = os.path.expanduser(config.get("lyrics", "save_lrc_path", "~/.lyrics"))
        utils.run_command("xdg-open %s" % save_dir)
        
    def get_scroll_menu_pixbufs(self, name):    
        return (
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            None, None)
        
    def switch_to_scroll_lyrics(self, widget):    
        config.set("lyrics", "mode", str(LRC_WINDOW_MODE))
        self.__lyrics_mode = LRC_WINDOW_MODE
        self.hide_desktop_lyrics()
        self.show_scroll_lyrics()
        self.play_time_source()
        
    def switch_to_desktop_lyrics(self):    
        config.set("lyrics", "mode", str(LRC_DESKTOP_MODE))
        self.__lyrics_mode = LRC_DESKTOP_MODE
        self.hide_scroll_lyrics()
        self.show_desktop_lyrics()
        self.play_time_source()
    
    def seek_cb(self, widget, lyric_id, percentage):
        item_time = self.lrc.get_item_time(lyric_id)
        new_time = item_time / 1000
        if Player.song.get_type() == "cue":
            new_time += Player.song.get("seek", 0)
        Player.seek(new_time)        
        self.scroll_lyrics.set_progress(lyric_id, percentage)
        time.sleep(0.1)
        
        
    def load_button_status(self):    
        if not config.getboolean("lyrics","karaoke_mode"):
            self.karaoke_button.set_active(True)
        if config.getint("lyrics", "line_count") == 1:
            self.line_button.set_active(True)
        
    def __create_simple_button(self, name, callback, tip_msg=None, has_event=False):    
        button = ImageButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % name),
            app_theme.get_pixbuf("lyric/%s_press.png" % name)
            )
        if has_event:
            button.connect("button-press-event", callback)
        else:    
            button.connect("clicked", callback)
            
        if tip_msg:    
            Tooltip.text(button, tip_msg)
            
        button_align = gtk.Alignment()
        button_align.set(0.5, 0.5, 0, 0)
        button_align.add(button)
        return button_align
        
    def __create_simple_toggle_button(self, normal_name, active_name, callback, tip_msg=None):
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % normal_name),
            app_theme.get_pixbuf("lyric/%s_normal.png" % active_name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % normal_name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % active_name),
            app_theme.get_pixbuf("lyric/%s_press.png" % normal_name),
            app_theme.get_pixbuf("lyric/%s_press.png" % active_name),
            )
        toggle_button.connect("toggled", callback)
        toggle_align = gtk.Alignment()
        toggle_align.set(0.5, 0.5, 0, 0)
        toggle_align.add(toggle_button)
        
        if tip_msg:
            Tooltip.text(toggle_button, tip_msg)
        return toggle_align, toggle_button
    
    def __create_single_toggle_button(self, normal_name, callback, tip_msg=None):
        if normal_name == "karaoke":
            toggle_button = ToggleButton(
                app_theme.get_pixbuf("lyric/%s_press.png" % normal_name),
                app_theme.get_pixbuf("lyric/%s_normal.png" % normal_name),            
                app_theme.get_pixbuf("lyric/%s_hover.png" % normal_name),
                )
        else:    
            toggle_button = ToggleButton(
                app_theme.get_pixbuf("lyric/%s_normal.png" % normal_name),
                app_theme.get_pixbuf("lyric/%s_press.png" % normal_name),            
                app_theme.get_pixbuf("lyric/%s_hover.png" % normal_name),
                )
            
        toggle_button.connect("toggled", callback)
        toggle_align = gtk.Alignment()
        toggle_align.set(0.5, 0.5, 0, 0)
        toggle_align.add(toggle_button)
        
        if tip_msg:
            Tooltip.text(toggle_button, tip_msg)
        return toggle_align, toggle_button
    
    def __create_button(self, name, tip_msg=None):   
        button = ImageButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % name),
            app_theme.get_pixbuf("lyric/%s_press.png" % name)
            )
        button.connect("clicked", self.player_control, name)
        return button
    
    def __swap_play_status(self, obj, active):    
        self.playpause_button.handler_block(self.__id_signal_play)
        self.playpause_button.set_active(active)
        self.playpause_button.handler_unblock(self.__id_signal_play)
        
    def __create_zoom_button(self, name, msg=None):    
        button = ImageButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % name),
            app_theme.get_pixbuf("lyric/%s_press.png" % name)
            )
        button.connect("clicked", self.change_font_size, name)
        if msg:
            Tooltip.text(button, msg)
        align = gtk.Alignment()
        align.set(0.5, 0.5, 0, 0)
        align.add(button)
        return align
    
    def change_font_size(self, widget, name):    
        old_size= self.desktop_lyrics_win.get_font_size()
        if name == "zoom_in":
            new_size = old_size + 2
            if new_size > 70:
                new_size = 70
            config.set("lyrics", "font_size", str(new_size))
        elif name == "zoom_out":    
            new_size = old_size - 2
            if new_size < 16:
                new_size = 16
            config.set("lyrics", "font_size", str(new_size))
        
    def player_control(self, button, name):   
        if name == "next":
            getattr(Player, name)(True)
        else:    
            getattr(Player, name)()
    
    def before_offset(self, widget):        
        self.lrc.set_offset(-500)
        
    def after_offset(self, widget):    
        self.lrc.set_offset(500)
        
    def open_search_window(self, widget):
        try:
            self.search_ui.result_view.clear()
            self.search_ui.artist_entry.entry.set_text(Player.song.get_str("artist"))
            self.search_ui.title_entry.entry.set_text(Player.song.get_str("title"))
            self.search_ui.search_lyric_cb(None)
        except:    
            pass
        self.search_ui.show_window()
    
    def close_lyric_window(self, widget):
        Dispatcher.close_lyrics()
        
    def open_setting_window(self, widget):
        Dispatcher.show_desktop_page()
        
    def on_dialog_close(self, sender):    
        if self.__dialog_locked_flag:
            self.desktop_lyrics_win.set_locked(False)
    
    def on_dialog_run(self, sender):
        if config.getboolean("lyrics", "status"):
            if not self.desktop_lyrics_win.get_locked():
                self.__dialog_locked_flag = True
                self.desktop_lyrics_win.set_locked()
        
    def __unlock_lyrics(self, *args):
        self.desktop_lyrics_win.set_locked(False)
        
    def __lock_lyrics(self, *args):        
        self.desktop_lyrics_win.set_locked()
    
    def change_karaoke_status(self, widget):
        self.desktop_lyrics_win.set_karaoke_mode()
    
    def change_line_status(self, widget):
        if widget.get_active():
            self.desktop_lyrics_win.set_line_count(1)
        else:    
            self.desktop_lyrics_win.set_line_count(2)
        
    def popup_predefine_menu(self, widget, event):    
        menu_dict = OrderedDict()
        menu_dict["vitality_yellow"] = _("Vitality yellow")
        menu_dict["fresh_green"]  = _("Fresh green")
        menu_dict["playful_pink"] = _("Playful pink")
        menu_dict["cool_blue"] = _("Cool blue")
        
        menu_items = []
        save_predefine_color = config.get("lyrics", "predefine_color", "vitality_yellow")
        for key, value in menu_dict.iteritems():
            item_pixbuf = None
            if key == save_predefine_color:
                item_pixbuf = (app_theme.get_pixbuf("menu/tick.png"),
                               app_theme.get_pixbuf("menu/tick_press.png"),
                               app_theme.get_pixbuf("menu/tick_disable.png"))
                
            if item_pixbuf is None:    
                menu_items.append((None, value, self.set_predefine_color, key))    
            else:    
                menu_items.append((item_pixbuf, value, self.set_predefine_color, key))    
        predefine_menu = Menu(menu_items, True)
        predefine_menu.show((int(event.x_root), int(event.y_root)))
        
    def set_predefine_color(self, key):    
        if key in PREDEFINE_COLORS.keys():
            values = PREDEFINE_COLORS[key]
            config.set("lyrics", "predefine_color", key)
            config.set("lyrics", "inactive_color_upper", values[0])
            config.set("lyrics", "inactive_color_middle", values[1])
            config.set("lyrics", "inactive_color_bottom", values[2])
            config.set("lyrics", "active_color_upper", values[3])
            config.set("lyrics", "active_color_middle", values[4])
            config.set("lyrics", "active_color_bottom", values[5])
        
        
    def func_thread(self):    
        while True:
            self.condition.acquire()
            while not self.next_lrc_to_download:
                self.condition.wait()
            next_lrc_to_download = self.next_lrc_to_download    
            self.next_lrc_to_download = None
            self.condition.release()
            self.set_current_lrc(True, next_lrc_to_download)
        
    def set_duration(self, duration):    
        if not duration:
            return 
        self.song_duration = duration
        
    def set_lrc_file(self, filename):    
        if filename and self.message_source != None:
            self.clear_message()
        # self.clear_lyrics()    
        self.lrc.set_filename(filename)
        self.scroll_lyrics.set_whole_lyrics(self.lrc.scroll_lyrics)
        
    def set_scroll_played_time(self, played_time):    
        info = self.lrc.get_lyric_by_time(played_time, self.song_duration)
        if not info:
            return
        text, percentage, lyric_id = info
        self.scroll_lyrics.set_progress(lyric_id, percentage)

    def set_played_time(self, played_time):    
        info = self.lrc.get_lyric_by_time(played_time, self.song_duration)
        if not info:
            return
        text, percentage, lyric_id = info
        real_id, real_lyric = self.get_real_lyric(lyric_id)
        if real_lyric == None:
            nid = -1
        else: 
            nid = real_id
            
        if self.lrc_id != nid:    
            if nid == -1:
                self.clear_lyrics()
                return
            if nid != self.lrc_next_id:
                self.current_line = 0
                if real_lyric:
                    self.desktop_lyrics_win.set_lyric(self.current_line, real_lyric)
                if nid != lyric_id:
                    self.desktop_lyrics_win.set_current_percentage(0.0)
                self.update_next_lyric(real_id)    
            else:    
                self.desktop_lyrics_win.set_line_percentage(self.current_line, 1.0)
                self.current_line = 1 - self.current_line
                
            self.lrc_id = nid    
            self.desktop_lyrics_win.set_current_line(self.current_line)
            
        if nid == lyric_id and percentage > 0.5:    
            self.update_next_lyric(real_id)
            
        if nid == lyric_id:    
            self.desktop_lyrics_win.set_current_percentage(percentage)
                
    def update_next_lyric(self, item_id):            
        if self.desktop_lyrics_win.get_line_count() == 1:
            self.lrc_next_id = -1
            return
        item_id += 1
        real_id, real_lyric = self.get_real_lyric(item_id)
        if real_lyric == None:
            if self.lrc_next_id == -1:
                return
            else:
                self.lrc_next_id = -1
                self.desktop_lyrics_win.set_lyric(1 - self.current_line, "")
        else:        
            if self.lrc_next_id == real_id:
                return
            if real_lyric:
                self.lrc_next_id = real_id
                self.desktop_lyrics_win.set_lyric(1 - self.current_line, real_lyric)
        self.desktop_lyrics_win.set_line_percentage(1 - self.current_line, 0.0)        
        
        
    def get_real_lyric(self, item_id):             
        while True:
            if self.lrc.get_item_lyric(item_id) != "":
                break
            item_id += 1
        return item_id, self.lrc.get_item_lyric(item_id)
    
    def clear_lyrics(self):
        self.desktop_lyrics_win.set_lyric(0, "")
        self.desktop_lyrics_win.set_lyric(1, "")
        self.current_line = 0
        self.lrc_id = -1
        self.lrc_next_id = -1
        
    def set_message(self, message, duration_ms=None):    
        if not message:
            return
        self.desktop_lyrics_win.set_current_line(0)
        self.desktop_lyrics_win.set_current_percentage(0.0)
        self.desktop_lyrics_win.set_lyric(0, message)
        self.desktop_lyrics_win.set_lyric(1, "")
        
        if self.message_source != None:
            gobject.source_remove(self.message_source)
            
        if duration_ms:    
            self.message_source = gobject.timeout_add(duration_ms, self.hide_message)
            
    def hide_message(self):    
        self.desktop_lyrics_win.set_lyric(0, "")
        self.message_source = None
        return False
    
    def clear_message(self):
        if self.message_source != None:
            gobject.source_remove(self.message_source)
            self.hide_message()
    
    def set_search_message(self, message):
        self.set_message(message, -1)
        
    def set_search_fail_message(self, message):
        self.set_message(message, MESSAGE_DURATION_MS)
        
    def set_download_fail_message(self, message):
        self.set_message(message, MESSAGE_DURATION_MS)
        
    def run(self):
        config.set("lyrics", "status", "true")                    
        self.play_time_source()
        if self.__lyrics_mode == LRC_WINDOW_MODE:
            self.show_scroll_lyrics()
        else:    
            self.show_desktop_lyrics()

    def hide_toolbar(self, widget):    
        self.toolbar.hide_all()
        
    def show_toolbar(self, widget):    
        self.toolbar.show_all()
        self.toolbar.hide_all()
        l_x, l_y = self.desktop_lyrics_win.get_position()
        l_w, l_h = self.desktop_lyrics_win.get_size()
        rect = gtk.gdk.Rectangle(int(l_x), int(l_y), int(l_w), int(l_h))
        self.adjust_toolbar_rect(None, rect)
        self.toolbar.show_all()
        
    def hide_all(self):    
        config.set("lyrics", "status", "false")
        self.hide_scroll_lyrics()
        self.hide_desktop_lyrics()
        self.pause_time_source()
        
    def hide_without_config(self):    
        self.hide_scroll_lyrics()
        self.hide_desktop_lyrics()
        self.pause_time_source()
        
    def hide_scroll_lyrics(self):    
        self.scroll_lyrics.hide_all()
        
    def lyrcis_scroll_configure_event(self, widget, event):    
        if widget.get_property("visible"):
            if widget.get_resizable():
                config.set("lyrics","scroll_w","%d"%event.width)
                config.set("lyrics","scroll_h","%d"%event.height)
            config.set("lyrics","scroll_x","%d"%event.x)
            config.set("lyrics","scroll_y","%d"%event.y)
            
    def show_scroll_lyrics(self):    
        if config.get("lyrics", "scroll_x") != "-1":
            x = config.getint("lyrics", "scroll_x")
            y = config.getint("lyrics", "scroll_y")
            self.scroll_lyrics.move(int(x), int(y))
        try:    
            w = config.getint("lyrics", "scroll_w")
            h = config.getint("lyrics", "scroll_h")
            self.scroll_lyrics.resize(int(w), int(h))
        except: pass    

        if not self.__find_flag:
            self.update_lrc(None, Player.song)
        self.scroll_lyrics.show_all()        
        
    def hide_desktop_lyrics(self):    
        self.desktop_lyrics_win.hide_all()
        self.toolbar.hide_all()
        
    def lyrics_desktop_configure_event(self, widget, event):    
        if widget.get_property("visible"):
            if widget.get_resizable():
                config.set("lyrics","desktop_h","%d"%event.height)
                config.set("lyrics","desktop_w","%d"%event.width)
            config.set("lyrics","desktop_y","%d"%event.y)
            config.set("lyrics","desktop_x","%d"%event.x)
            widget.update_lyric_rects()
            
    def show_desktop_lyrics(self):    
        if config.get("lyrics", "desktop_x") == "-1":
            screen_w, screen_h = gtk.gdk.get_default_root_window().get_size()
            w , h = self.desktop_lyrics_win.get_size()
            x = screen_w / 2 - w / 2
            y = screen_h - h
        else:    
            x = config.getint("lyrics", "desktop_x")
            y = config.getint("lyrics", "desktop_y")
            
        self.desktop_lyrics_win.move(x, y)    
        try:
            d_w = config.getint("lyrics", "desktop_w")
            d_h = config.getint("lyrics", "desktop_h")
            self.desktop_lyrics_win.resize(d_w, d_h)          
        except: pass    

        if not self.__find_flag:
            self.update_lrc(None, Player.song)            
        self.desktop_lyrics_win.show_all()           

        
    def adjust_toolbar_rect(self, widget, rect):    
        screen_w, screen_h = gtk.gdk.get_default_root_window().get_size()
        centre_x = rect.x + rect.width / 2
        l_w, l_h = self.toolbar.get_size()
        l_x = centre_x - l_w / 2
        if rect.y <  l_h:
            l_y = rect.y + rect.height
        elif rect.y > screen_h - rect.height:    
            l_y = rect.y - l_h
        else:    
            l_y = rect.y - l_h
        self.toolbar.move(l_x, l_y)    
        
    def update_lrc(self, widget, songs):
        if not config.getboolean("lyrics", "status"):
            return 
        if isinstance(songs, list):
            if self.current_song in songs:
                self.current_song = songs[songs.index(self.current_song)]
        else:        
            self.current_song = songs
            
        if self.current_song is not None:    
            if not self.set_current_lrc(False):
                self.condition.acquire()
                self.next_lrc_to_download = self.current_song
                self.condition.notify()
                self.condition.release()
                
    def real_show_lyrics(self):            
        played_timed = Player.get_lyrics_position()
        if self.__lyrics_mode == LRC_WINDOW_MODE:
            self.set_scroll_played_time(played_timed)
        else:
            self.set_played_time(played_timed)
        return True
    
    def pause_time_source(self, *args):
        if self.time_source != None:
            gobject.source_remove(self.time_source)
            self.time_source = None
            
    def play_time_source(self, *args):        
        self.pause_time_source()
        if not self.__find_flag:
            return 
        if not config.getboolean("lyrics", "status"):
            return 
        
        if self.__lyrics_mode == LRC_WINDOW_MODE:
            self.time_source = gobject.timeout_add(200, self.real_show_lyrics)
        else:    
            self.time_source = gobject.timeout_add(100, self.real_show_lyrics)
                
    def set_current_lrc(self, try_web=True, force_song=None):        
        ret = False
        if not force_song:
            force_song = self.current_song
        filename = self.lrc_manager.get_lrc(force_song, try_web)    
        if filename and os.path.exists(filename):
            if self.time_source != None:
                gobject.source_remove(self.time_source)
                self.time_source = None
                self.clear_lyrics()
            if try_web:
                gobject.idle_add(self.set_lrc_file, filename)
            else:    
                self.set_lrc_file(filename)
                ret = True
            self.set_duration(force_song.get("#duration"))    
            self.__find_flag = True
            if config.getboolean("lyrics", "status"):
                self.play_time_source()
        else:    
            if self.current_song != force_song:
                return 
            if self.time_source != None:
                gobject.source_remove(self.time_source)
                self.time_source = None
                self.clear_lyrics()
            if try_web:    
                self.set_message(self.get_default_message(force_song) + " "+ _("No lyrics found!"))
                self.scroll_lyrics.set_message(self.get_default_message(force_song) + " " +  _("No lyrics found!"))
            else:    
                self.set_search_fail_message(_("Searching for lyrics..."))
                self.scroll_lyrics.set_message(_("Searching for lyrics..."))
            self.__find_flag = False    
        return ret    
        
    def instant_update_lrc(self, widget, song):    
        if song.get_type() in ('webcast', 'cue'):
            return 
        self.scroll_lyrics.set_whole_lyrics([])
        self.set_message(self.get_default_message(song))
        self.update_lrc(widget, song)
        
    def get_default_message(self, song):    
        artist = song.get_str("artist")
        title = song.get_str("title")
        if artist:
            return "%s-%s" % (artist, title)
        else:
            return "%s" % title
Ejemplo n.º 7
0
class LyricsModule(object):
    def __init__(self):
        self.desktop_lyrics_win = DesktopLyrics()
        self.desktop_lyrics_win.connect("moved", self.adjust_toolbar_rect)
        self.desktop_lyrics_win.connect("resized", self.adjust_toolbar_rect)
        self.desktop_lyrics_win.connect("hide-bg", self.hide_toolbar)
        self.desktop_lyrics_win.connect("show-bg", self.show_toolbar)
        self.desktop_lyrics_win.connect("button-press-event",
                                        self.popup_desktop_right_menu)

        self.desktop_lyrics_win.connect("configure-event",
                                        self.lyrics_desktop_configure_event)

        self.scroll_lyrics = ScrollLyrics()
        self.scroll_lyrics.connect("configure-event",
                                   self.lyrcis_scroll_configure_event)
        self.scroll_lyrics.revert_button.connect(
            "clicked", lambda w: self.switch_to_desktop_lyrics())
        self.scroll_lyrics.connect("seek", self.seek_cb)
        self.scroll_lyrics.connect("right-press", self.scroll_right_press_cb)

        Player.connect("instant-new-song", self.instant_update_lrc)
        Player.connect("played", self.play_time_source)
        Player.connect("paused", self.pause_time_source)
        Player.connect("play-end", self.pause_time_source)
        Dispatcher.connect("reload-lrc", self.update_lrc)
        Dispatcher.connect("unlock-lyrics", self.__unlock_lyrics)
        Dispatcher.connect("lock-lyrics", self.__lock_lyrics)
        Dispatcher.connect("show-lyrics", lambda w: self.run())
        Dispatcher.connect("close-lyrics", lambda w: self.hide_all())
        Dispatcher.connect("search-lyrics",
                           lambda w: self.open_search_window(w))
        Dispatcher.connect("dialog-run", self.on_dialog_run)
        Dispatcher.connect("dialog-close", self.on_dialog_close)

        config.connect("config-changed", self.on_config_changed)

        self.lrc_manager = LrcManager()
        self.lrc = LrcParser()

        self.search_ui = SearchUI()
        self.lrc_id = -1
        self.lrc_next_id = -1
        self.current_line = 0
        self.message_source = None
        self.time_source = None
        self.song_duration = 0
        self.__find_flag = False
        self.__lyrics_mode = config.getint("lyrics", "mode")
        self.__dialog_locked_flag = False

        self.init_toolbar()

        self.current_song = None
        self.next_lrc_to_download = None
        self.condition = threading.Condition()
        self.thread = threading.Thread(target=self.func_thread)
        self.thread.setDaemon(True)
        self.thread.start()

    def init_toolbar(self):
        self.toolbar = Window(window_type=gtk.WINDOW_POPUP)
        self.toolbar.set_size_request(-1, 41)
        padding_x, padding_y = 10, 5
        play_box = gtk.HBox(spacing=2)
        play_box.connect("expose-event", self.expose_toolbar_mask)

        # swap played status handler
        Player.connect("played", self.__swap_play_status, True)
        Player.connect("paused", self.__swap_play_status, False)
        Player.connect("stopped", self.__swap_play_status, False)
        Player.connect("play-end", self.__swap_play_status, False)
        self.playpause_button = ToggleButton(
            app_theme.get_pixbuf("lyric/play_normal.png"),
            app_theme.get_pixbuf("lyric/pause_normal.png"),
            app_theme.get_pixbuf("lyric/play_hover.png"),
            app_theme.get_pixbuf("lyric/pause_hover.png"),
            app_theme.get_pixbuf("lyric/play_press.png"),
            app_theme.get_pixbuf("lyric/pause_press.png"),
        )
        self.__id_signal_play = self.playpause_button.connect(
            "toggled", lambda w: Player.playpause())
        prev = self.__create_button("previous")
        next = self.__create_button("next")

        prev_align = gtk.Alignment()
        prev_align.set(0.5, 0.5, 0, 0)
        prev_align.add(prev)
        next_align = gtk.Alignment()
        next_align.set(0.5, 0.5, 0, 0)
        next_align.add(next)

        play_align = gtk.Alignment()
        play_align.set_padding(2, 0, 0, 0)
        play_align.set(0.5, 0.5, 0, 0)
        play_align.add(self.playpause_button)

        # separte line
        separate_line = ImageBox(app_theme.get_pixbuf("lyric/separate.png"))
        sep_align = gtk.Alignment()
        sep_align.set(0.5, 0.5, 0, 0)
        sep_align.add(separate_line)

        zoom_in_align = self.__create_zoom_button(
            "zoom_in", _("Increase the lyrics size"))
        zoom_out_align = self.__create_zoom_button(
            "zoom_out", _("Decrease the lyrics size"))
        predefine_align = self.__create_simple_button(
            "predefine_color", self.popup_predefine_menu,
            _("Select color theme"), True)
        lock_align = self.__create_simple_button("lock", self.__lock_lyrics,
                                                 _("Lock Lyrics"))
        karaoke_align, self.karaoke_button = self.__create_single_toggle_button(
            "karaoke", self.change_karaoke_status, _("Karaoke on/off"))
        line_align, self.line_button = self.__create_simple_toggle_button(
            "single_line", "double_line", None, _("Switch lines"))
        self.line_button_toggled_id = self.line_button.connect(
            "toggled", self.change_line_status)
        setting_align = self.__create_simple_button("setting",
                                                    self.open_setting_window,
                                                    _("Open settings panel"))
        search_align = self.__create_simple_button(
            "search", self.open_search_window,
            _("Search lrc file for current track"))
        close_align = self.__create_simple_button("close",
                                                  self.close_lyric_window,
                                                  _("Close lyrics"))
        before_align = self.__create_simple_button("before",
                                                   self.before_offset,
                                                   _("Lyrics rewind"))
        after_align = self.__create_simple_button("after", self.after_offset,
                                                  _("Lyrics forward"))
        lrc_align = self.__create_simple_button("lrc",
                                                self.switch_to_scroll_lyrics,
                                                _("Switch to window mode"))

        play_box.pack_start(prev_align, False, False)
        play_box.pack_start(play_align, False, False)
        play_box.pack_start(next_align, False, False)
        play_box.pack_start(sep_align, False, False)
        play_box.pack_start(zoom_in_align, False, False)
        play_box.pack_start(zoom_out_align, False, False)
        play_box.pack_start(before_align, False, False)
        play_box.pack_start(after_align, False, False)
        play_box.pack_start(predefine_align, False, False)
        play_box.pack_start(karaoke_align, False, False)
        play_box.pack_start(line_align, False, False)
        play_box.pack_start(lock_align, False, False)
        play_box.pack_start(setting_align, False, False)
        play_box.pack_start(lrc_align, False, False)
        play_box.pack_start(search_align, False, False)
        play_box.pack_start(close_align, False, False)

        main_align = gtk.Alignment()
        main_align.set_padding(0, 0, padding_x, padding_x)
        main_align.set(0.5, 0.5, 0, 0)
        main_align.add(play_box)
        self.toolbar.window_frame.pack_start(main_align)

        self.load_button_status()

    def on_config_changed(self, obj, selection, option, value):
        if selection == "lyrics" and option == "line_count":
            is_active = self.line_button.get_active()
            if value == "1" and not is_active:
                with self.line_button_toggled_status():
                    self.line_button.set_active(True)
            elif value == "2" and is_active:
                with self.line_button_toggled_status():
                    self.line_button.set_active(False)

    @contextmanager
    def line_button_toggled_status(self):
        self.line_button.disconnect(self.line_button_toggled_id)
        try:
            yield
        finally:
            self.line_button_toggled_id = self.line_button.connect(
                "toggled", self.change_line_status)

    def expose_toolbar_mask(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation
        draw_alpha_mask(cr, rect.x - 9, rect.y, rect.width + 18, rect.height,
                        "lyricsMask")
        return False

    def scroll_right_press_cb(self, widget, event):
        menu_items = [
            (self.get_scroll_menu_pixbufs("lrc"), _("Switch to desktop mode"),
             self.switch_to_desktop_lyrics),
            None,
            (self.get_scroll_menu_pixbufs("before"), _("Lyrics rewind"),
             lambda: self.before_offset(None)),
            (self.get_scroll_menu_pixbufs("after"), _("Lyrics forward"),
             lambda: self.after_offset(None)),
            None,
            (self.get_scroll_menu_pixbufs("search"), _("Search"),
             lambda: self.open_search_window(None)),
            (self.get_scroll_menu_pixbufs("setting"), _("Settings"),
             lambda: Dispatcher.show_scroll_page()),
        ]
        Menu(menu_items, True).show((int(event.x_root), int(event.y_root)))

    def popup_desktop_right_menu(self, widget, event):
        if event.button == 3 and Player.song:
            adjust_menu_item = [(None, _("Forward 0.5 seconds"),
                                 lambda: self.after_offset(None)),
                                (None, _("Rewind 0.5 seconds"),
                                 lambda: self.before_offset(None))]
            menu_items = [
                (None, _("Search"), lambda: self.open_search_window(None)),
                (None, _("Adjust lyrics"), Menu(adjust_menu_item)), None,
                (None, _("Choose local lrc"), self.allocation_lrc),
                (None, _("Open directory"), self.open_lrc_dir), None,
                (None, _("Settings"), lambda: self.open_setting_window(None)),
                (None, _("Switch to window mode"),
                 lambda: self.switch_to_scroll_lyrics(None))
            ]

            if Player.song.get("location_lrc", None):
                menu_items.insert(4, (None, _("Lyrics acquired by Network"),
                                      self.disassociate_lrc))
            Menu(menu_items, True).show((int(event.x_root), int(event.y_root)))

    def allocation_lrc(self):
        lrc_path = WinFile(False).run()
        if lrc_path:
            self.lrc_manager.allocation_lrc_file(Player.song, lrc_path)

    def disassociate_lrc(self):
        self.lrc_manager.unallocation_lrc_file(Player.song)

    def open_lrc_dir(self):
        save_dir = os.path.expanduser(
            config.get("lyrics", "save_lrc_path", "~/.lyrics"))
        utils.run_command("xdg-open %s" % save_dir)

    def get_scroll_menu_pixbufs(self, name):
        return (app_theme.get_pixbuf("lyric/%s_normal.png" % name), None, None)

    def switch_to_scroll_lyrics(self, widget):
        config.set("lyrics", "mode", str(LRC_WINDOW_MODE))
        self.__lyrics_mode = LRC_WINDOW_MODE
        self.hide_desktop_lyrics()
        self.show_scroll_lyrics()
        self.play_time_source()

    def switch_to_desktop_lyrics(self):
        config.set("lyrics", "mode", str(LRC_DESKTOP_MODE))
        self.__lyrics_mode = LRC_DESKTOP_MODE
        self.hide_scroll_lyrics()
        self.show_desktop_lyrics()
        self.play_time_source()

    def seek_cb(self, widget, lyric_id, percentage):
        item_time = self.lrc.get_item_time(lyric_id)
        new_time = item_time / 1000
        if Player.song.get_type() == "cue":
            new_time += Player.song.get("seek", 0)
        Player.seek(new_time)
        self.scroll_lyrics.set_progress(lyric_id, percentage)
        time.sleep(0.1)

    def load_button_status(self):
        if not config.getboolean("lyrics", "karaoke_mode"):
            self.karaoke_button.set_active(True)
        if config.getint("lyrics", "line_count") == 1:
            self.line_button.set_active(True)

    def __create_simple_button(self,
                               name,
                               callback,
                               tip_msg=None,
                               has_event=False):
        button = ImageButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % name),
            app_theme.get_pixbuf("lyric/%s_press.png" % name))
        if has_event:
            button.connect("button-press-event", callback)
        else:
            button.connect("clicked", callback)

        if tip_msg:
            Tooltip.text(button, tip_msg)

        button_align = gtk.Alignment()
        button_align.set(0.5, 0.5, 0, 0)
        button_align.add(button)
        return button_align

    def __create_simple_toggle_button(self,
                                      normal_name,
                                      active_name,
                                      callback=None,
                                      tip_msg=None):
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % normal_name),
            app_theme.get_pixbuf("lyric/%s_normal.png" % active_name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % normal_name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % active_name),
            app_theme.get_pixbuf("lyric/%s_press.png" % normal_name),
            app_theme.get_pixbuf("lyric/%s_press.png" % active_name),
        )

        if callback:
            toggle_button.connect("toggled", callback)
        toggle_align = gtk.Alignment()
        toggle_align.set(0.5, 0.5, 0, 0)
        toggle_align.add(toggle_button)

        if tip_msg:
            Tooltip.text(toggle_button, tip_msg)
        return toggle_align, toggle_button

    def __create_single_toggle_button(self,
                                      normal_name,
                                      callback,
                                      tip_msg=None):
        if normal_name == "karaoke":
            toggle_button = ToggleButton(
                app_theme.get_pixbuf("lyric/%s_press.png" % normal_name),
                app_theme.get_pixbuf("lyric/%s_normal.png" % normal_name),
                app_theme.get_pixbuf("lyric/%s_hover.png" % normal_name),
            )
        else:
            toggle_button = ToggleButton(
                app_theme.get_pixbuf("lyric/%s_normal.png" % normal_name),
                app_theme.get_pixbuf("lyric/%s_press.png" % normal_name),
                app_theme.get_pixbuf("lyric/%s_hover.png" % normal_name),
            )

        toggle_button.connect("toggled", callback)
        toggle_align = gtk.Alignment()
        toggle_align.set(0.5, 0.5, 0, 0)
        toggle_align.add(toggle_button)

        if tip_msg:
            Tooltip.text(toggle_button, tip_msg)
        return toggle_align, toggle_button

    def __create_button(self, name, tip_msg=None):
        button = ImageButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % name),
            app_theme.get_pixbuf("lyric/%s_press.png" % name))
        button.connect("clicked", self.player_control, name)
        return button

    def __swap_play_status(self, obj, active):
        self.playpause_button.handler_block(self.__id_signal_play)
        self.playpause_button.set_active(active)
        self.playpause_button.handler_unblock(self.__id_signal_play)

    def __create_zoom_button(self, name, msg=None):
        button = ImageButton(
            app_theme.get_pixbuf("lyric/%s_normal.png" % name),
            app_theme.get_pixbuf("lyric/%s_hover.png" % name),
            app_theme.get_pixbuf("lyric/%s_press.png" % name))
        button.connect("clicked", self.change_font_size, name)
        if msg:
            Tooltip.text(button, msg)
        align = gtk.Alignment()
        align.set(0.5, 0.5, 0, 0)
        align.add(button)
        return align

    def change_font_size(self, widget, name):
        old_size = self.desktop_lyrics_win.get_font_size()
        if name == "zoom_in":
            new_size = old_size + 2
            if new_size > 70:
                new_size = 70
            config.set("lyrics", "font_size", str(new_size))
        elif name == "zoom_out":
            new_size = old_size - 2
            if new_size < 16:
                new_size = 16
            config.set("lyrics", "font_size", str(new_size))

    def player_control(self, button, name):
        if name == "next":
            getattr(Player, name)(True)
        else:
            getattr(Player, name)()

    def before_offset(self, widget):
        self.lrc.set_offset(-500)

    def after_offset(self, widget):
        self.lrc.set_offset(500)

    def open_search_window(self, widget):
        try:
            self.search_ui.result_view.clear()
            self.search_ui.artist_entry.entry.set_text(
                Player.song.get_str("artist"))
            self.search_ui.title_entry.entry.set_text(
                Player.song.get_str("title"))
            self.search_ui.search_lyric_cb(None)
        except:
            pass
        self.search_ui.show_window()

    def close_lyric_window(self, widget):
        Dispatcher.close_lyrics()

    def open_setting_window(self, widget):
        Dispatcher.show_desktop_page()

    def on_dialog_close(self, sender):
        if self.__dialog_locked_flag:
            self.desktop_lyrics_win.set_locked(False)

    def on_dialog_run(self, sender):
        if config.getboolean("lyrics", "status"):
            if not self.desktop_lyrics_win.get_locked():
                self.__dialog_locked_flag = True
                self.desktop_lyrics_win.set_locked()

    def __unlock_lyrics(self, *args):
        self.desktop_lyrics_win.set_locked(False)

    def __lock_lyrics(self, *args):
        self.desktop_lyrics_win.set_locked()

    def change_karaoke_status(self, widget):
        self.desktop_lyrics_win.set_karaoke_mode()

    def change_line_status(self, widget):
        if widget.get_active():
            self.desktop_lyrics_win.set_line_count(1)
        else:
            self.desktop_lyrics_win.set_line_count(2)

    def popup_predefine_menu(self, widget, event):
        menu_dict = OrderedDict()
        menu_dict["vitality_yellow"] = _("Vitality yellow")
        menu_dict["fresh_green"] = _("Fresh green")
        menu_dict["playful_pink"] = _("Playful pink")
        menu_dict["cool_blue"] = _("Cool blue")

        menu_items = []
        save_predefine_color = config.get("lyrics", "predefine_color",
                                          "vitality_yellow")
        for key, value in menu_dict.iteritems():
            item_pixbuf = None
            if key == save_predefine_color:
                item_pixbuf = (app_theme.get_pixbuf("menu/tick.png"),
                               app_theme.get_pixbuf("menu/tick_press.png"),
                               app_theme.get_pixbuf("menu/tick_disable.png"))

            if item_pixbuf is None:
                menu_items.append((None, value, self.set_predefine_color, key))
            else:
                menu_items.append(
                    (item_pixbuf, value, self.set_predefine_color, key))
        predefine_menu = Menu(menu_items, True)
        predefine_menu.show((int(event.x_root), int(event.y_root)))

    def set_predefine_color(self, key):
        if key in PREDEFINE_COLORS.keys():
            values = PREDEFINE_COLORS[key]
            config.set("lyrics", "predefine_color", key)
            config.set("lyrics", "inactive_color_upper", values[0])
            config.set("lyrics", "inactive_color_middle", values[1])
            config.set("lyrics", "inactive_color_bottom", values[2])
            config.set("lyrics", "active_color_upper", values[3])
            config.set("lyrics", "active_color_middle", values[4])
            config.set("lyrics", "active_color_bottom", values[5])

    def func_thread(self):
        while True:
            self.condition.acquire()
            while not self.next_lrc_to_download:
                self.condition.wait()
            next_lrc_to_download = self.next_lrc_to_download
            self.next_lrc_to_download = None
            self.condition.release()
            self.set_current_lrc(True, next_lrc_to_download)

    def set_duration(self, duration):
        if not duration:
            return
        self.song_duration = duration

    def set_lrc_file(self, filename):
        if filename and self.message_source != None:
            self.clear_message()
        # self.clear_lyrics()
        self.lrc.set_filename(filename)
        self.scroll_lyrics.set_whole_lyrics(self.lrc.scroll_lyrics)

    def set_scroll_played_time(self, played_time):
        info = self.lrc.get_lyric_by_time(played_time, self.song_duration)
        if not info:
            return
        text, percentage, lyric_id = info
        self.scroll_lyrics.set_progress(lyric_id, percentage)

    def set_played_time(self, played_time):
        info = self.lrc.get_lyric_by_time(played_time, self.song_duration)
        if not info:
            return
        text, percentage, lyric_id = info
        real_id, real_lyric = self.get_real_lyric(lyric_id)
        if real_lyric == None:
            nid = -1
        else:
            nid = real_id

        if self.lrc_id != nid:
            if nid == -1:
                self.clear_lyrics()
                return
            if nid != self.lrc_next_id:
                self.current_line = 0
                if real_lyric:
                    self.desktop_lyrics_win.set_lyric(self.current_line,
                                                      real_lyric)
                if nid != lyric_id:
                    self.desktop_lyrics_win.set_current_percentage(0.0)
                self.update_next_lyric(real_id)
            else:
                self.desktop_lyrics_win.set_line_percentage(
                    self.current_line, 1.0)
                self.current_line = 1 - self.current_line

            self.lrc_id = nid
            self.desktop_lyrics_win.set_current_line(self.current_line)

        if nid == lyric_id and percentage > 0.5:
            self.update_next_lyric(real_id)

        if nid == lyric_id:
            self.desktop_lyrics_win.set_current_percentage(percentage)

    def update_next_lyric(self, item_id):
        if self.desktop_lyrics_win.get_line_count() == 1:
            self.lrc_next_id = -1
            return
        item_id += 1
        real_id, real_lyric = self.get_real_lyric(item_id)
        if real_lyric == None:
            if self.lrc_next_id == -1:
                return
            else:
                self.lrc_next_id = -1
                self.desktop_lyrics_win.set_lyric(1 - self.current_line, "")
        else:
            if self.lrc_next_id == real_id:
                return
            if real_lyric:
                self.lrc_next_id = real_id
                self.desktop_lyrics_win.set_lyric(1 - self.current_line,
                                                  real_lyric)
        self.desktop_lyrics_win.set_line_percentage(1 - self.current_line, 0.0)

    def get_real_lyric(self, item_id):
        while True:
            if self.lrc.get_item_lyric(item_id) != "":
                break
            item_id += 1
        return item_id, self.lrc.get_item_lyric(item_id)

    def clear_lyrics(self):
        self.desktop_lyrics_win.set_lyric(0, "")
        self.desktop_lyrics_win.set_lyric(1, "")
        self.current_line = 0
        self.lrc_id = -1
        self.lrc_next_id = -1

    def set_message(self, message, duration_ms=None):
        if not message:
            return
        self.desktop_lyrics_win.set_current_line(0)
        self.desktop_lyrics_win.set_current_percentage(0.0)
        self.desktop_lyrics_win.set_lyric(0, message)
        self.desktop_lyrics_win.set_lyric(1, "")

        if self.message_source != None:
            gobject.source_remove(self.message_source)

        if duration_ms:
            self.message_source = gobject.timeout_add(duration_ms,
                                                      self.hide_message)

    def hide_message(self):
        self.desktop_lyrics_win.set_lyric(0, "")
        self.message_source = None
        return False

    def clear_message(self):
        if self.message_source != None:
            gobject.source_remove(self.message_source)
            self.hide_message()

    def set_search_message(self, message):
        self.set_message(message, -1)

    def set_search_fail_message(self, message):
        self.set_message(message, MESSAGE_DURATION_MS)

    def set_download_fail_message(self, message):
        self.set_message(message, MESSAGE_DURATION_MS)

    def run(self):
        config.set("lyrics", "status", "true")
        self.play_time_source()
        if self.__lyrics_mode == LRC_WINDOW_MODE:
            self.show_scroll_lyrics()
        else:
            self.show_desktop_lyrics()

    def hide_toolbar(self, widget):
        self.toolbar.hide_all()

    def show_toolbar(self, widget):
        self.toolbar.show_all()
        self.toolbar.hide_all()
        l_x, l_y = self.desktop_lyrics_win.get_position()
        l_w, l_h = self.desktop_lyrics_win.get_size()
        rect = gtk.gdk.Rectangle(int(l_x), int(l_y), int(l_w), int(l_h))
        self.adjust_toolbar_rect(None, rect)
        self.toolbar.show_all()

    def hide_all(self):
        config.set("lyrics", "status", "false")
        self.hide_scroll_lyrics()
        self.hide_desktop_lyrics()
        self.pause_time_source()

    def hide_without_config(self):
        self.hide_scroll_lyrics()
        self.hide_desktop_lyrics()
        self.pause_time_source()

    def hide_scroll_lyrics(self):
        self.scroll_lyrics.hide_all()

    def lyrcis_scroll_configure_event(self, widget, event):
        if widget.get_property("visible"):
            if widget.get_resizable():
                config.set("lyrics", "scroll_w", "%d" % event.width)
                config.set("lyrics", "scroll_h", "%d" % event.height)
            config.set("lyrics", "scroll_x", "%d" % event.x)
            config.set("lyrics", "scroll_y", "%d" % event.y)

    def show_scroll_lyrics(self):
        if config.get("lyrics", "scroll_x") != "-1":
            x = config.getint("lyrics", "scroll_x")
            y = config.getint("lyrics", "scroll_y")
            self.scroll_lyrics.move(int(x), int(y))
        try:
            w = config.getint("lyrics", "scroll_w")
            h = config.getint("lyrics", "scroll_h")
            self.scroll_lyrics.resize(int(w), int(h))
        except:
            pass

        if not self.__find_flag:
            self.update_lrc(None, Player.song)
        self.scroll_lyrics.show_all()

    def hide_desktop_lyrics(self):
        self.desktop_lyrics_win.hide_all()
        self.toolbar.hide_all()

    def lyrics_desktop_configure_event(self, widget, event):
        if widget.get_property("visible"):
            if widget.get_resizable():
                config.set("lyrics", "desktop_h", "%d" % event.height)
                config.set("lyrics", "desktop_w", "%d" % event.width)
            config.set("lyrics", "desktop_y", "%d" % event.y)
            config.set("lyrics", "desktop_x", "%d" % event.x)
            widget.update_lyric_rects()

    def show_desktop_lyrics(self):
        if config.get("lyrics", "desktop_x") == "-1":
            screen_w, screen_h = gtk.gdk.get_default_root_window().get_size()
            w, h = self.desktop_lyrics_win.get_size()
            x = screen_w / 2 - w / 2
            y = screen_h - h
        else:
            x = config.getint("lyrics", "desktop_x")
            y = config.getint("lyrics", "desktop_y")

        self.desktop_lyrics_win.move(x, y)
        try:
            d_w = config.getint("lyrics", "desktop_w")
            d_h = config.getint("lyrics", "desktop_h")
            self.desktop_lyrics_win.resize(d_w, d_h)
        except:
            pass

        if not self.__find_flag:
            self.update_lrc(None, Player.song)
        self.desktop_lyrics_win.show_all()

    def adjust_toolbar_rect(self, widget, rect):
        screen_w, screen_h = gtk.gdk.get_default_root_window().get_size()
        centre_x = rect.x + rect.width / 2
        l_w, l_h = self.toolbar.get_size()
        l_x = centre_x - l_w / 2
        if rect.y < l_h:
            l_y = rect.y + rect.height
        elif rect.y > screen_h - rect.height:
            l_y = rect.y - l_h
        else:
            l_y = rect.y - l_h
        self.toolbar.move(l_x, l_y)

    def update_lrc(self, widget, songs):
        if not config.getboolean("lyrics", "status"):
            return
        if isinstance(songs, list):
            if self.current_song in songs:
                self.current_song = songs[songs.index(self.current_song)]
        else:
            self.current_song = songs

        if self.current_song is not None:
            if not self.set_current_lrc(False):
                self.condition.acquire()
                self.next_lrc_to_download = self.current_song
                self.condition.notify()
                self.condition.release()

    def real_show_lyrics(self):
        played_timed = Player.get_lyrics_position()
        if self.__lyrics_mode == LRC_WINDOW_MODE:
            self.set_scroll_played_time(played_timed)
        else:
            self.set_played_time(played_timed)
        return True

    def pause_time_source(self, *args):
        if self.time_source != None:
            gobject.source_remove(self.time_source)
            self.time_source = None

    def play_time_source(self, *args):
        self.pause_time_source()
        if not self.__find_flag:
            return
        if not config.getboolean("lyrics", "status"):
            return

        if self.__lyrics_mode == LRC_WINDOW_MODE:
            self.time_source = gobject.timeout_add(200, self.real_show_lyrics)
        else:
            self.time_source = gobject.timeout_add(100, self.real_show_lyrics)

    def set_current_lrc(self, try_web=True, force_song=None):
        ret = False
        if not force_song:
            force_song = self.current_song
        filename = self.lrc_manager.get_lrc(force_song, try_web)
        if filename and os.path.exists(filename):
            if self.time_source != None:
                gobject.source_remove(self.time_source)
                self.time_source = None
                self.clear_lyrics()
            if try_web:
                gobject.idle_add(self.set_lrc_file, filename)
            else:
                self.set_lrc_file(filename)
                ret = True
            self.set_duration(force_song.get("#duration"))
            self.__find_flag = True
            if config.getboolean("lyrics", "status"):
                self.play_time_source()
        else:
            if self.current_song != force_song:
                return
            if self.time_source != None:
                gobject.source_remove(self.time_source)
                self.time_source = None
                self.clear_lyrics()
            if try_web:
                self.set_message(
                    self.get_default_message(force_song) + " " +
                    _("No lyrics found!"))
                self.scroll_lyrics.set_message(
                    self.get_default_message(force_song) + " " +
                    _("No lyrics found!"))
            else:
                self.set_search_fail_message(_("Searching for lyrics..."))
                self.scroll_lyrics.set_message(_("Searching for lyrics..."))
            self.__find_flag = False
        return ret

    def instant_update_lrc(self, widget, song):
        if song.get_type() in ('webcast', 'cue'):
            return
        self.scroll_lyrics.set_whole_lyrics([])
        self.set_message(self.get_default_message(song))
        self.update_lrc(widget, song)

    def get_default_message(self, song):
        artist = song.get_str("artist")
        title = song.get_str("title")
        if artist:
            return "%s-%s" % (artist, title)
        else:
            return "%s" % title
Ejemplo n.º 8
0
class FullHeaderBar(gtk.EventBox):
    def __init__(self):
        super(FullHeaderBar, self).__init__()
        self.set_visible_window(False)
        
        # init.
        self.cover_box = PlayerCoverButton()
        self.cover_box.show_all()
        
        # Main table
        main_table = gtk.Table(2, 3)
        # swap played status handler
        Player.connect("played", self.__swap_play_status, True)
        Player.connect("paused", self.__swap_play_status, False)
        Player.connect("stopped", self.__swap_play_status, False)
        Player.connect("play-end", self.__swap_play_status, False)
        
        # play button
        play_normal_pixbuf = app_theme.get_pixbuf("action/play_large_normal.png")
        pause_normal_pixbuf = app_theme.get_pixbuf("action/pause_large_normal.png")
        play_hover_pixbuf = app_theme.get_pixbuf("action/play_large_hover.png")
        pause_hover_pixbuf = app_theme.get_pixbuf("action/pause_large_hover.png")
        play_press_pixbuf = app_theme.get_pixbuf("action/play_large_press.png")
        pause_press_pixbuf = app_theme.get_pixbuf("action/pause_large_press.png")
       
        self.__play = ToggleButton(play_normal_pixbuf, pause_normal_pixbuf,
                                   play_hover_pixbuf, pause_hover_pixbuf,
                                   play_press_pixbuf, pause_press_pixbuf,
                                   )
        Tooltip.text(self.__play, _("Play/Pause"))
        
        self.__play.show_all()

        self.__id_signal_play = self.__play.connect("toggled", lambda w: Player.playpause())
        
        prev_button = self.__create_button("previous_large", _("Previous track"))
        next_button = self.__create_button("next_large", _("Next track"))
        
        self.vol = VolumeSlider()
        song_timer = SongTimer()
        
        mainbtn = gtk.HBox(spacing=3)
        prev_align = gtk.Alignment()
        prev_align.set(0.5, 0.5, 0, 0)
        prev_align.add(prev_button)
        
        next_align = gtk.Alignment()
        next_align.set(0.5, 0.5, 0, 0)
        next_align.add(next_button)
        
        # button group.
        mainbtn.pack_start(prev_align, False, False)
        mainbtn.pack_start(self.__play, False, False)
        mainbtn.pack_start(next_align, False, False)
         
        mainbtn_align = gtk.Alignment()
        mainbtn_align.set_padding(10, 0, 0, 0)
        mainbtn_align.add(mainbtn)
        
        mainbtn_box = gtk.HBox()
        mainbtn_box.pack_start(mainbtn_align, False, False)
        mainbtn_box.pack_start(create_left_align(), True, True)
        
        # time box.
        self.lyrics_button = self.__create_simple_toggle_button("lyrics", self.change_lyrics_status)        
        Tooltip.text(self.lyrics_button, _("Lyrics on/off"))
        
        plug_box = gtk.HBox(spacing=12)       
        lyrics_button_align = gtk.Alignment()
        lyrics_button_align.set_padding(1, 0, 0, 0)
        lyrics_button_align.add(self.lyrics_button)
        plug_box.pack_start(lyrics_button_align, False, False)
        vol_align = gtk.Alignment()
        vol_align.set_padding(2, 0, 0, 0)
        vol_align.add(self.vol)
        plug_box.pack_start(vol_align, False, False)        
        
        timer_align = gtk.Alignment()
        timer_align.set(0, 0, 0, 1)
        timer_box = gtk.HBox()
        timer_box.pack_start(timer_align, True, True)
        timer_box.pack_start(song_timer.get_label(), False, False)
        
        main_table.attach(PlayInfo(), 0, 1, 0, 1, xoptions=gtk.FILL)
        main_table.attach(plug_box, 0, 1, 1, 2, xoptions=gtk.FILL)
        main_table.attach(mainbtn_box, 1, 2, 0, 2, xoptions=gtk.FILL, xpadding=25)
        main_table.attach(timer_box, 2, 3, 1, 2, xpadding=17)
        
        cover_main_box = gtk.HBox(spacing=5)
        cover_main_box.pack_start(self.cover_box, False, False)
        cover_main_box.pack_start(main_table, True, True)
        cover_main_align = gtk.Alignment()
        cover_main_align.set_padding(5, 0, 12, 5)
        cover_main_align.set(1, 1, 1, 1)
        cover_main_align.add(cover_main_box)
        
        main_box = gtk.VBox(spacing=9)
        main_box.pack_start(cover_main_align, True, True)
        main_box.pack_start(ProgressBox(song_timer), True, True)
        
        self.add(main_box)
        
        # right click
        self.connect("button-press-event", self.right_click_cb)
        # foreach_recursive(self, lambda w: w.connect("button-press-event", self.right_click_cb))
        Dispatcher.connect("close-lyrics", lambda w : self.lyrics_button.set_active(False))
        Dispatcher.connect("show-lyrics", lambda w: self.lyrics_button.set_active(True))
 
        self.signal_auto = False        
        if config.getboolean("lyrics", "status"):
            self.lyrics_button.set_active(True)
        self.signal_auto = True    
        
    def change_lyrics_status(self, widget):    
        if self.signal_auto:
            if widget.get_active():
                Dispatcher.show_lyrics()
            else:    
                Dispatcher.close_lyrics()
            
    def __create_simple_toggle_button(self, name, callback): 
        prefix = get_prefix()
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("header/%s_%s_inactive_normal.png" % (prefix, name)),
            app_theme.get_pixbuf("header/%s_%s_active_normal.png" % (prefix, name)),
            app_theme.get_pixbuf("header/%s_%s_inactive_hover.png" % (prefix, name)),
            app_theme.get_pixbuf("header/%s_%s_active_hover.png" % (prefix, name)),
            app_theme.get_pixbuf("header/%s_%s_inactive_press.png" % (prefix, name)),
            app_theme.get_pixbuf("header/%s_%s_active_press.png" % (prefix, name)),
            )
        if callback:
            toggle_button.connect("toggled", callback)
        return toggle_button

    def right_click_cb(self, widget, event):    
        if event.button == 3:
            Dispatcher.show_main_menu(int(event.x_root), int(event.y_root))
                    
    def __swap_play_status(self, obj, active):    
        self.__play.handler_block(self.__id_signal_play)
        self.__play.set_active(active)
        self.__play.handler_unblock(self.__id_signal_play)
        
    def __create_button(self, name, tip_msg=None):    
        button = ImageButton(
            app_theme.get_pixbuf("action/%s_normal.png" % name),
            app_theme.get_pixbuf("action/%s_hover.png" % name),
            app_theme.get_pixbuf("action/%s_press.png" % name),
            )
        button.connect("clicked", self.player_control, name)
        if tip_msg:
            Tooltip.text(button, tip_msg)
        # todo tip
        return button
    
    def player_control(self, button, name):
        name = name.strip("_large")
        if name == "next":
            getattr(Player, name)(True)
        else:    
            getattr(Player, name)()
Ejemplo n.º 9
0
class SimpleHeadbar(gtk.EventBox):            
    def __init__(self):
        gtk.EventBox.__init__(self)
        self.set_visible_window(False)
        
        # init.
        self.cover_box = PlayerCoverButton()
        self.cover_box.show_all()
        
        
        # play button
        play_normal_pixbuf = app_theme.get_pixbuf("action/play_normal.png")
        pause_normal_pixbuf = app_theme.get_pixbuf("action/pause_normal.png")
        play_hover_pixbuf = app_theme.get_pixbuf("action/play_hover.png")
        pause_hover_pixbuf = app_theme.get_pixbuf("action/pause_hover.png")
        play_press_pixbuf = app_theme.get_pixbuf("action/play_press.png")
        pause_press_pixbuf = app_theme.get_pixbuf("action/pause_press.png")
       
        self.__play = ToggleButton(play_normal_pixbuf, pause_normal_pixbuf,
                                   play_hover_pixbuf, pause_hover_pixbuf,
                                   play_press_pixbuf, pause_press_pixbuf,
                                   )
        Tooltip.text(self.__play, _("Play/Pause"))
        # swap played status handler
        Player.connect("played", self.__swap_play_status, True)
        Player.connect("paused", self.__swap_play_status, False)
        Player.connect("stopped", self.__swap_play_status, False)
        Player.connect("play-end", self.__swap_play_status, False)
        
        self.__id_signal_play = self.__play.connect("toggled", self.on_player_playpause)
        prev_button = self.__create_button("previous", _("Previous"))
        next_button = self.__create_button("next", _("Next"))
        
        
        # lyrics button
        self.lyrics_button = self.__create_simple_toggle_button("lyrics", self.change_lyrics_status)        
        Tooltip.text(self.lyrics_button, _("Show/Hide Lyrics"))
        
        
        lyrics_button_align = gtk.Alignment()
        lyrics_button_align.set_padding(0, 0, 0, 10)
        lyrics_button_align.set(0.5, 0.5, 0, 0)
        lyrics_button_align.add(self.lyrics_button)
        
        volume_button_align = gtk.Alignment()
        volume_button_align.set_padding(0, 0, 10, 0)
        volume_button_align.set(0.5, 0.5, 0, 0)
        self.volume_slider = VolumeSlider()
        volume_button_align.add(self.volume_slider)
        # volume_button_align.add(VolumeButton())
        
        # action_box
        action_box = gtk.HBox()
        action_box.pack_start(lyrics_button_align, False, False)
        action_box.pack_start(set_widget_vcenter(prev_button), False, False)
        action_box.pack_start(set_widget_vcenter(self.__play), False, False)
        action_box.pack_start(set_widget_vcenter(next_button), False, False)
        action_box.pack_start(volume_button_align, False, False)
         
        # combo_box
        playinfo_align = gtk.Alignment()
        playinfo_align.set_padding(0, 0, 12, 0)
        playinfo_align.add(PlayInfo(200))
        
        self.action_box_align = gtk.Alignment()
        self.action_box_align.set_padding(6, 0, 6, 0)
        self.action_box_align.add(action_box)
        self.action_box_align.connect("expose-event", self.on_expose_event)
        
        self.timer_label = "00:00"
        self.song_timer = SongTimer(self.draw_timer_label)
        
        combo_vbox = gtk.VBox(spacing=5)
        combo_vbox.pack_start(playinfo_align, False, False)
        combo_vbox.pack_start(self.action_box_align, False, False)
        
        cover_box_align = gtk.Alignment()
        cover_box_align.set_padding(0, 0, 10, 0)
        cover_box_align.add(self.cover_box)
        
        cover_main_box = gtk.HBox()
        cover_main_box.pack_start(cover_box_align, False, False)
        cover_main_box.pack_start(combo_vbox, False, False)
        
        body_vbox = gtk.VBox(spacing=6)
        body_vbox.pack_start(cover_main_box, False, True)
        body_vbox.pack_start(self.song_timer, False, True)
        # progressbar_align = gtk.Alignment()
        # progressbar_align.add(ProgressBar())
        # progressbar_align.set(1, 1, 1, 1)
        # progressbar_align.set_padding(0, 0, 2, 2)
        # body_vbox.pack_start(progressbar_align, False, True)
        
        
        
        self.add(body_vbox)

        # right click
        self.connect("button-press-event", self.right_click_cb)
        Dispatcher.connect("close-lyrics", lambda w : self.lyrics_button.set_active(False))
        Dispatcher.connect("show-lyrics", lambda w: self.lyrics_button.set_active(True))
 
        self.signal_auto = False        
        if config.getboolean("lyrics", "status"):
            self.lyrics_button.set_active(True)
        self.signal_auto = True    
        
        
    def draw_timer_label(self, timer_text):    
        self.timer_text = timer_text
        rect = self.action_box_align.allocation
        rect.x += 12
        rect.width  = 68
        rect.height = 15
        self.action_box_align.queue_draw_area(rect.x, rect.y, rect.width, rect.height)
        
    def on_expose_event(self, widget, event):    
        cr = widget.window.cairo_create()
        rect = widget.allocation
        
        rect.x += 12
        rect.width  = 68
        rect.height = 15
        
        draw_text(cr, self.timer_text, rect.x, rect.y, rect.width, rect.height, text_size=8,
                  gaussian_radious=2,
                  gaussian_color="#000000",
                  border_radious=1,
                  border_color="#000000",
                  text_color = "#FFFFFF"
                  )
        
    def on_player_playpause(self, widget):    
        if Player.song:
            Player.playpause()
        
    def change_lyrics_status(self, widget):    
        if self.signal_auto:
            if widget.get_active():
                Dispatcher.show_lyrics()
            else:    
                Dispatcher.close_lyrics()
        
    def __create_simple_toggle_button(self, name, callback): 
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("lyrics_button/%s_inactive_normal.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_active_normal.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_inactive_hover.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_active_hover.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_inactive_press.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_active_press.png" % name),
            ) 
        if callback:
            toggle_button.connect("toggled", callback)
        return toggle_button
        
    def right_click_cb(self, widget, event):    
        if event.button == 3:
            Dispatcher.show_main_menu(int(event.x_root), int(event.y_root))
                    
    def __swap_play_status(self, obj, active):    
        self.__play.handler_block(self.__id_signal_play)
        self.__play.set_active(active)
        self.__play.handler_unblock(self.__id_signal_play)
        
    def __create_button(self, name, tip_msg=None):    
        button = ImageButton(
            app_theme.get_pixbuf("action/%s_normal.png" % name),
            app_theme.get_pixbuf("action/%s_hover.png" % name),
            app_theme.get_pixbuf("action/%s_press.png" % name),
            )
        button.connect("clicked", self.player_control, name)
        if tip_msg:
            Tooltip.text(button, tip_msg)
        return button
    
    def player_control(self, button, name):
        if name == "next":
            getattr(Player, name)(True)
        else:    
            getattr(Player, name)()
            
    def sync_volume(self):        
        self.volume_slider.load_volume_config()
Ejemplo n.º 10
0
class SimpleHeadbar(gtk.EventBox):
    def __init__(self):
        gtk.EventBox.__init__(self)
        self.set_visible_window(False)

        # init.
        self.cover_box = PlayerCoverButton()
        self.cover_box.show_all()

        # play button
        play_normal_pixbuf = app_theme.get_pixbuf("action/play_normal.png")
        pause_normal_pixbuf = app_theme.get_pixbuf("action/pause_normal.png")
        play_hover_pixbuf = app_theme.get_pixbuf("action/play_hover.png")
        pause_hover_pixbuf = app_theme.get_pixbuf("action/pause_hover.png")
        play_press_pixbuf = app_theme.get_pixbuf("action/play_press.png")
        pause_press_pixbuf = app_theme.get_pixbuf("action/pause_press.png")

        self.__play = ToggleButton(
            play_normal_pixbuf,
            pause_normal_pixbuf,
            play_hover_pixbuf,
            pause_hover_pixbuf,
            play_press_pixbuf,
            pause_press_pixbuf,
        )
        Tooltip.text(self.__play, _("Play/Pause"))
        # swap played status handler
        Player.connect("played", self.__swap_play_status, True)
        Player.connect("paused", self.__swap_play_status, False)
        Player.connect("stopped", self.__swap_play_status, False)
        Player.connect("play-end", self.__swap_play_status, False)

        self.__id_signal_play = self.__play.connect("toggled",
                                                    self.on_player_playpause)
        prev_button = self.__create_button("previous", _("Previous"))
        next_button = self.__create_button("next", _("Next"))

        # lyrics button
        self.lyrics_button = self.__create_simple_toggle_button(
            "lyrics", self.change_lyrics_status)
        Tooltip.text(self.lyrics_button, _("Show/Hide Lyrics"))

        lyrics_button_align = gtk.Alignment()
        lyrics_button_align.set_padding(0, 0, 0, 10)
        lyrics_button_align.set(0.5, 0.5, 0, 0)
        lyrics_button_align.add(self.lyrics_button)

        volume_button_align = gtk.Alignment()
        volume_button_align.set_padding(0, 0, 10, 0)
        volume_button_align.set(0.5, 0.5, 0, 0)
        self.volume_slider = VolumeSlider()
        volume_button_align.add(self.volume_slider)
        # volume_button_align.add(VolumeButton())

        # action_box
        action_box = gtk.HBox()
        action_box.pack_start(lyrics_button_align, False, False)
        action_box.pack_start(set_widget_vcenter(prev_button), False, False)
        action_box.pack_start(set_widget_vcenter(self.__play), False, False)
        action_box.pack_start(set_widget_vcenter(next_button), False, False)
        action_box.pack_start(volume_button_align, False, False)

        # combo_box
        playinfo_align = gtk.Alignment()
        playinfo_align.set_padding(0, 0, 12, 0)
        playinfo_align.add(PlayInfo(200))

        self.action_box_align = gtk.Alignment()
        self.action_box_align.set_padding(6, 0, 6, 0)
        self.action_box_align.add(action_box)
        self.action_box_align.connect("expose-event", self.on_expose_event)

        self.timer_label = "00:00"
        self.song_timer = SongTimer(self.draw_timer_label)

        combo_vbox = gtk.VBox(spacing=5)
        combo_vbox.pack_start(playinfo_align, False, False)
        combo_vbox.pack_start(self.action_box_align, False, False)

        cover_box_align = gtk.Alignment()
        cover_box_align.set_padding(0, 0, 10, 0)
        cover_box_align.add(self.cover_box)

        cover_main_box = gtk.HBox()
        cover_main_box.pack_start(cover_box_align, False, False)
        cover_main_box.pack_start(combo_vbox, False, False)

        body_vbox = gtk.VBox(spacing=6)
        body_vbox.pack_start(cover_main_box, False, True)
        body_vbox.pack_start(self.song_timer, False, True)
        # progressbar_align = gtk.Alignment()
        # progressbar_align.add(ProgressBar())
        # progressbar_align.set(1, 1, 1, 1)
        # progressbar_align.set_padding(0, 0, 2, 2)
        # body_vbox.pack_start(progressbar_align, False, True)

        self.add(body_vbox)

        # right click
        self.connect("button-press-event", self.right_click_cb)
        Dispatcher.connect("close-lyrics",
                           lambda w: self.lyrics_button.set_active(False))
        Dispatcher.connect("show-lyrics",
                           lambda w: self.lyrics_button.set_active(True))

        self.signal_auto = False
        if config.getboolean("lyrics", "status"):
            self.lyrics_button.set_active(True)
        self.signal_auto = True

    def draw_timer_label(self, timer_text):
        self.timer_text = timer_text
        rect = self.action_box_align.allocation
        rect.x += 12
        rect.width = 68
        rect.height = 15
        self.action_box_align.queue_draw_area(rect.x, rect.y, rect.width,
                                              rect.height)

    def on_expose_event(self, widget, event):
        cr = widget.window.cairo_create()
        rect = widget.allocation

        rect.x += 12
        rect.width = 68
        rect.height = 15

        draw_text(cr,
                  self.timer_text,
                  rect.x,
                  rect.y,
                  rect.width,
                  rect.height,
                  text_size=8,
                  gaussian_radious=2,
                  gaussian_color="#000000",
                  border_radious=1,
                  border_color="#000000",
                  text_color="#FFFFFF")

    def on_player_playpause(self, widget):
        if Player.song:
            Player.playpause()

    def change_lyrics_status(self, widget):
        if self.signal_auto:
            if widget.get_active():
                Dispatcher.show_lyrics()
            else:
                Dispatcher.close_lyrics()

    def __create_simple_toggle_button(self, name, callback):
        toggle_button = ToggleButton(
            app_theme.get_pixbuf("lyrics_button/%s_inactive_normal.png" %
                                 name),
            app_theme.get_pixbuf("lyrics_button/%s_active_normal.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_inactive_hover.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_active_hover.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_inactive_press.png" % name),
            app_theme.get_pixbuf("lyrics_button/%s_active_press.png" % name),
        )
        if callback:
            toggle_button.connect("toggled", callback)
        return toggle_button

    def right_click_cb(self, widget, event):
        if event.button == 3:
            Dispatcher.show_main_menu(int(event.x_root), int(event.y_root))

    def __swap_play_status(self, obj, active):
        self.__play.handler_block(self.__id_signal_play)
        self.__play.set_active(active)
        self.__play.handler_unblock(self.__id_signal_play)

    def __create_button(self, name, tip_msg=None):
        button = ImageButton(
            app_theme.get_pixbuf("action/%s_normal.png" % name),
            app_theme.get_pixbuf("action/%s_hover.png" % name),
            app_theme.get_pixbuf("action/%s_press.png" % name),
        )
        button.connect("clicked", self.player_control, name)
        if tip_msg:
            Tooltip.text(button, tip_msg)
        return button

    def player_control(self, button, name):
        if name == "next":
            getattr(Player, name)(True)
        else:
            getattr(Player, name)()

    def sync_volume(self):
        self.volume_slider.load_volume_config()
Ejemplo n.º 11
0
class MediaView(gtk.VBox):
    ENTRY_WIDTH = 200
    LEFT_WIDTH = STANDARD_LINE - TEXT_WINDOW_LEFT_PADDING

    def __init__(self):
        gtk.VBox.__init__(self)
        self.all_app_default_value = {}
        style.draw_background_color(self)
        self.media_handle = MediaAutorun()
        self.app_manager = AppManager()
        self.init_table()
        
    def __get_index_from_value(self, value, _list):
        for tup in _list:
            if tup[1] == value:
                return _list.index(tup)

    def init_table(self):

        table = gtk.Table(8, 3, False)

        #info_label = Label(_("You can choose the operation after plugining media or device"))

        cd_label = Label(_("CD"))
        dvd_label = Label(_("DVD"))
        player_label = Label(_("Audio Player"))
        photo_label = Label(_("Camera"))
        software_label = Label(_("Applications"))
        auto_mount_label = Label(_("Automatically Mount"))

        self.all_label_list = [cd_label, dvd_label, player_label,
                               photo_label, software_label]

        default_list = [(_("Other applications"), "other_app"),
                        (_("Ask"), "ask"),
                        (_("Do nothing"), "do_nothing"),
                        (_("Open folder"),"open_folder")]
        auto_mount_list = [(_("Do nothing"), "do_nothing"), 
                           (_("Ask"), "ask"),
                           (_("Mount"), "mount"),
                           (_("Mount and open folder"), "mount_and_open")]
        #self.auto_mount_box = gtk.HBox(spacing = WIDGET_SPACING)
        #self.auto_mount_label = Label(_("apply auto open for all media and devices"))
        self.auto_mount_label = Label(_("AutoPlay"))
        self.auto_mount_toggle = ToggleButton(app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
            app_theme.get_pixbuf("toggle_button/active_normal.png"))
        #self.auto_mount_box.pack_start(self.auto_mount_label, False, False)
        #self.auto_mount_box.pack_start(self.auto_mount_toggle, False, False)

        self.cd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.dvd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.player= ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.photo = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.software = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.auto_mount = ComboBox(auto_mount_list, fixed_width=self.ENTRY_WIDTH)
        self.auto_mount.set_select_index(self.__get_index_from_value(get_auto_mount(), auto_mount_list))
        #self.more_option = Button(_("more option"))

        ###below content type displayed as more option is clicked"
        self.audio_dvd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.blank_bd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.blank_cd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.blank_hddvd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.video_bluray = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.ebook_reader = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.video_hddvd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.image_picturecd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.video_svcd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)
        self.video_vcd = ComboBox(default_list, fixed_width=self.ENTRY_WIDTH)

        #table.attach(style.wrap_with_align(info_label, width=self.LEFT_WIDTH), 0, 3, 0, 1)
        table.attach(style.wrap_with_align(cd_label, width=self.LEFT_WIDTH), 0, 1, 4, 5)
        table.attach(style.wrap_with_align(dvd_label, width=self.LEFT_WIDTH), 0, 1, 5, 6)
        table.attach(style.wrap_with_align(player_label, width=self.LEFT_WIDTH), 0, 1, 6, 7)
        table.attach(style.wrap_with_align(photo_label, width=self.LEFT_WIDTH), 0, 1, 7, 8)
        table.attach(style.wrap_with_align(software_label, width=self.LEFT_WIDTH), 0, 1, 8, 9)
        table.attach(style.wrap_with_align(auto_mount_label, width=self.LEFT_WIDTH), 0, 1, 9, 10)

        #table.attach(style.wrap_with_align(self.auto_mount_box, align = "left", left = 180), 0, 3, 1, 2)
        table.attach(style.wrap_with_align(self.auto_mount_label, width=self.LEFT_WIDTH), 0, 1, 1, 2)
        table.attach(style.wrap_with_align(self.auto_mount_toggle), 1, 3, 1, 2)

        table.attach(style.wrap_with_align(self.cd), 1, 3, 4, 5)
        table.attach(style.wrap_with_align(self.dvd), 1, 3, 5, 6)
        table.attach(style.wrap_with_align(self.player), 1, 3, 6, 7)
        table.attach(style.wrap_with_align(self.photo), 1, 3, 7, 8)
        table.attach(style.wrap_with_align(self.software), 1, 3, 8, 9)
        table.attach(style.wrap_with_align(self.auto_mount), 1, 3, 9, 10)

        # UI style
        table_align = style.set_box_with_align(table, "text")
        style.set_table(table)

        self.pack_start(table_align, False, False)

        combo_list = [self.cd, self.dvd, self.player, self.photo, self.software]
        for combo in combo_list:
            combo.set_size_request(self.ENTRY_WIDTH, 22)

        self.refresh_app_list(default_list)

        self.media_handle.auto_mount = True
        if self.media_handle.automount_open:
            for combo in self.all_app_dict:
                combo.set_sensitive(True)
            for l in self.all_label_list:
                l.set_sensitive(True)
        else:
            for combo in self.all_app_dict:
                combo.set_sensitive(False)
            for l in self.all_label_list:
                l.set_sensitive(False)
    
        self.auto_mount_toggle.set_active(self.media_handle.automount_open)

        self.connect_signal_to_combos()

    def refresh_app_list(self, default_list):
        self.default_list = default_list
        self.all_app_dict = {self.cd: self.media_handle.cd_content_type,
                             self.dvd: self.media_handle.dvd_content_type,
                             self.player: self.media_handle.player_content_type,
                             self.photo: self.media_handle.photo_content_type,
                             self.software: self.media_handle.software_content_type,
                             }

        for key, value in self.all_app_dict.iteritems():
            app_info_list = []
            app_info_list.extend(self.app_manager.get_all_for_type(value))
            
            state = self.get_state(value)
            if state == "set_default":
                default_value = 0
            else:
                default_value = len(app_info_list) + ["ask", "do_nothing","open_folder"].index(state) + 1

            key.add_items(map(lambda info:(info.get_name(), info), app_info_list) + default_list, select_index=default_value)

        self.all_app_default_value = {self.cd: self.cd.get_select_index(), 
                                      self.dvd: self.dvd.get_select_index(), 
                                      self.player: self.player.get_select_index(), 
                                      self.photo: self.photo.get_select_index(), 
                                      self.software: self.software.get_select_index(),
                                     }

    def connect_signal_to_combos(self):
        for combo in self.all_app_dict:
            combo.connect("item-selected", self.change_autorun_callback)
        self.auto_mount.connect("item-selected", self.auto_mount_combo_changed)
        self.auto_mount_toggle.connect("toggled", self.automount_open_toggle_cb)
        
    def auto_mount_combo_changed(self, widget, content, value, index):
        set_auto_mount(value)

    def change_autorun_callback(self, widget, content, value, index):
        if value != "other_app":
            self.all_app_default_value[widget] = index
        if type(value) is not str:
            self.set_media_handler_preference(self.all_app_dict[widget], widget, "set_default")
            self.app_manager.set_default_for_type(value, self.all_app_dict[widget])
        else:
            self.set_media_handler_preference(self.all_app_dict[widget], widget, value)

    def automount_open_toggle_cb(self, widget):
        self.media_handle.automount_open = widget.get_active()
        
        if widget.get_active():
            for combo in self.all_app_dict:
                combo.set_sensitive(True)
            for l in self.all_label_list:
                l.set_sensitive(True)
        else:
            for combo in self.all_app_dict:
                combo.set_sensitive(False)
            for l in self.all_label_list:
                l.set_sensitive(False)

    def set_media_handler_preference(self, x_content, widget, action_name=None):
        if action_name == "ask":
            self.media_handle.remove_x_content_start_app(x_content)
            self.media_handle.remove_x_content_ignore(x_content)
            self.media_handle.remove_x_content_open_folder(x_content)
            print action_name, ">>>",self.get_state(x_content)

        elif action_name == "do_nothing":
            self.media_handle.remove_x_content_start_app(x_content)
            self.media_handle.add_x_content_ignore(x_content)
            self.media_handle.remove_x_content_open_folder(x_content)
            print action_name, ">>>",self.get_state(x_content)

        elif action_name == "open_folder":
            self.media_handle.remove_x_content_start_app(x_content)
            self.media_handle.remove_x_content_ignore(x_content)
            self.media_handle.add_x_content_open_folder(x_content)
            print action_name, ">>>",self.get_state(x_content)

        elif action_name == "set_default":
            self.media_handle.add_x_content_start_app(x_content)
            self.media_handle.remove_x_content_ignore(x_content)
            self.media_handle.remove_x_content_open_folder(x_content)
            print action_name, ">>>",self.get_state(x_content)
        else:
            from dtk.ui.dialog import OpenFileDialog
            OpenFileDialog(
                _("Other applications"), 
                self.get_toplevel(), 
                lambda name: self.add_app_info(name, x_content), 
                self.__cancel_other_application(widget))

    def __cancel_other_application(self, widget):
        widget.set_select_index(self.all_app_default_value[widget])

    def add_app_info(self, app_name, x_content):
        import os
        app_name = os.path.basename(app_name)
        app_info = self.app_manager.get_app_info(app_name + " %u", app_name)
        self.set_media_handler_preference(x_content, "set_default")
        self.app_manager.set_default_for_type(app_info, x_content)
        self.app_manager.get_all_for_type(x_content)
        self.refresh_app_list(self.default_list)

    def get_state(self, x_content):
        start_up = self.media_handle.autorun_x_content_start_app
        ignore = self.media_handle.autorun_x_content_ignore
        open_folder = self.media_handle.autorun_x_content_open_folder

        start_up_flag = x_content in start_up
        ignore_flag = x_content in ignore
        open_folder_flag = x_content in open_folder

        if start_up_flag:
            return "set_default"
        elif ignore_flag:
            return "do_nothing"
        elif open_folder_flag:
            return "open_folder"
        else:
            return "ask"