Example #1
0
    def on_app_startup(self, app):
        self.conf = Config.load_conf()
        self.icon_theme = Gtk.IconTheme.get_default()
        self.icon_theme.append_search_path(Config.ICON_PATH)

        GLib.set_application_name(Config.APPNAME)
        self.window = Gtk.ApplicationWindow(application=app)
        self.window.set_default_size(*self.conf['window-size'])
        self.window.set_title(Config.APPNAME)
        self.window.set_default_icon_name(Config.NAME)
        self.window.props.hide_titlebar_when_maximized = True
        app.add_window(self.window)
        self.window.connect('check-resize', self.on_main_window_resized)
        self.window.connect('delete-event', self.on_main_window_deleted)

        self.accel_group = Gtk.AccelGroup()
        self.window.add_accel_group(self.accel_group)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.window.add(box)

        self.osdlrc = OSDLrc(self)
        self.notify = None
        self.init_notify()

        self.player = Player(self)
        box.pack_start(self.player, False, False, 0)

        self.notebook = Gtk.Notebook()
        self.notebook.props.tab_pos = Gtk.PositionType.BOTTOM
        self.notebook.get_style_context().add_class('main_tab')
        box.pack_start(self.notebook, True, True, 0)
        self.init_notebook()
        self.notebook.connect('switch-page', self.on_notebook_switch_page)
        self.init_status_icon()

        # load default styles when all widgets have been constructed.
        self.load_styles()
Example #2
0
    def on_app_startup(self, app):
        self.conf = Config.load_conf()
        self.icon_theme = Gtk.IconTheme.get_default()
        self.icon_theme.append_search_path(Config.ICON_PATH)

        GLib.set_application_name(Config.APPNAME)
        self.window = Gtk.ApplicationWindow(application=app)
        self.window.set_default_size(*self.conf['window-size'])
        self.window.set_title(Config.APPNAME)
        self.window.set_default_icon_name(Config.NAME)
        self.window.props.hide_titlebar_when_maximized = True
        app.add_window(self.window)
        self.window.connect('check-resize', self.on_main_window_resized)
        self.window.connect('delete-event', self.on_main_window_deleted)

        self.accel_group = Gtk.AccelGroup()
        self.window.add_accel_group(self.accel_group)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.window.add(box)

        self.osdlrc = OSDLrc(self)
        self.notify = None
        self.init_notify()

        self.player = Player(self)
        box.pack_start(self.player, False, False, 0)

        self.notebook = Gtk.Notebook()
        self.notebook.props.tab_pos = Gtk.PositionType.BOTTOM
        self.notebook.get_style_context().add_class('main_tab')
        box.pack_start(self.notebook, True, True, 0)
        self.init_notebook()
        self.notebook.connect('switch-page', self.on_notebook_switch_page)
        self.init_status_icon()

        # load default styles when all widgets have been constructed.
        self.load_styles()
Example #3
0
class App:

    def __init__(self):
        self.app = Gtk.Application.new(DBUS_APP_NAME, 0)
        self.app.connect('startup', self.on_app_startup)
        self.app.connect('activate', self.on_app_activate)
        self.app.connect('shutdown', self.on_app_shutdown)

    def on_app_startup(self, app):
        self.conf = Config.load_conf()
        self.icon_theme = Gtk.IconTheme.get_default()
        self.icon_theme.append_search_path(Config.ICON_PATH)

        GLib.set_application_name(Config.APPNAME)
        self.window = Gtk.ApplicationWindow(application=app)
        self.window.set_default_size(*self.conf['window-size'])
        self.window.set_title(Config.APPNAME)
        self.window.set_default_icon_name(Config.NAME)
        self.window.props.hide_titlebar_when_maximized = True
        app.add_window(self.window)
        self.window.connect('check-resize', self.on_main_window_resized)
        self.window.connect('delete-event', self.on_main_window_deleted)

        self.accel_group = Gtk.AccelGroup()
        self.window.add_accel_group(self.accel_group)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.window.add(box)

        self.osdlrc = OSDLrc(self)
        self.notify = None
        self.init_notify()

        self.player = Player(self)
        box.pack_start(self.player, False, False, 0)

        self.notebook = Gtk.Notebook()
        self.notebook.props.tab_pos = Gtk.PositionType.BOTTOM
        self.notebook.get_style_context().add_class('main_tab')
        box.pack_start(self.notebook, True, True, 0)
        self.init_notebook()
        self.notebook.connect('switch-page', self.on_notebook_switch_page)
        self.init_status_icon()

        # load default styles when all widgets have been constructed.
        self.load_styles()

    def on_app_activate(self, app):
        self.window.show_all()
        # Make some changes after main window is shown.
        # Like hiding some unnecessory widgets.
        self.artists.after_init()
        self.player.after_init()
        self.search.after_init()
        self.shortcut = Shortcut(self.player)
        self.osdlrc.after_init()

        # Cleanup temporary media files
        Net.cleanup_temp_files(self.conf['song-dir'])
        Net.cleanup_temp_files(self.conf['mv-dir'])

    def on_app_shutdown(self, app):
        Config.dump_conf(self.conf)

    def run(self, argv):
        self.app.run(argv)

    def quit(self):
        gdk_win = self.window.get_window()
        if gdk_win and not gdk_win.is_destroyed():
            if self.player.default_cursor:
                gdk_win.set_cursor(self.player.default_cursor)
            self.window.destroy()
        self.shortcut.quit()
        self.app.quit()

    def on_main_window_resized(self, window, event=None):
        self.conf['window-size'] = window.get_size()

    def on_main_window_deleted(self, window, event):
        if self.conf['use-status-icon']:
            window.hide()
            return True
        else:
            return False

    def init_notebook(self):
        self.tab_first_show = []
        self.lrc = Lrc(self)
        self.append_page(self.lrc)

        self.playlist = PlayList(self)
        self.append_page(self.playlist)

        self.search = Search(self)
        self.append_page(self.search)

        self.toplist = TopList(self)
        self.append_page(self.toplist)

        self.radio = Radio(self)
        self.append_page(self.radio)

        self.mv = MV(self)
        self.append_page(self.mv)

        self.artists = Artists(self)
        self.append_page(self.artists)

        self.topcategories = TopCategories(self)
        self.append_page(self.topcategories)

        self.themes = Themes(self)
        self.append_page(self.themes)

    def append_page(self, widget):
        '''Append a new widget to notebook.'''
        label = Gtk.Label(widget.title)
        widget.app_page = self.notebook.append_page(widget, label)

    def popup_page(self, page):
        '''Switch to this widget in notebook.'''
        self.notebook.set_current_page(page)

    def load_styles(self):
        '''Load default CssStyle.'''
        if Config.GTK_LE_36:
            css = '\n'.join([
                'GtkScale {',
                    'outline-color: transparent;',
                    'outline-offset: 0;',
                    'outline-style: none;',
                    'outline-width: 0;',
                '}',
                'GtkTextView.lrc_tv {',
                    'font-size: {0};'.format(self.conf['lrc-text-size']),
                    'color: {0};'.format(self.conf['lrc-text-color']),
                    'border-radius: 0 25 0 50;',
                    'border-width: 5;',
                    'background-color: {0};'.format(
                        self.conf['lrc-back-color']),
                '}',
                '.info-label {',
                    'color: rgb(136, 139, 132);',
                    'font-size: 9;',
                '}',
                ])
        else:
            css = '\n'.join([
                'GtkScrolledWindow.lrc_window {',
                    'transition-property: background-image;',
                    'transition-duration: 1s;',
                '}',
                'GtkScale {',
                    'outline-color: transparent;',
                    'outline-offset: 0;',
                    'outline-style: none;',
                    'outline-width: 0;',
                '}',
                'GtkTextView.lrc_tv {',
                    'transition-property: font-size;',
                    'transition: 500ms ease-in-out;',
                    'font-size: {0}px;'.format(self.conf['lrc-text-size']),
                    'color: {0};'.format(self.conf['lrc-text-color']),
                    'border-radius: 0px 25px 0px 50px;',
                    'border-width: 5px;',
                    'background-color: {0};'.format(
                        self.conf['lrc-back-color']),
                '}',
                '.info-label {',
                    'color: rgb(136, 139, 132);',
                    'font-size: 9px;',
                '}',
                ])

        Widgets.apply_css(self.window, css, overall=True)

        settings = Gtk.Settings.get_default()
        settings.props.gtk_application_prefer_dark_theme = \
                self.conf.get('use-dark-theme', False)

    def init_status_icon(self):
        def on_status_icon_popup_menu(status_icon, event_button,
                                      event_time):
            menu.popup(None, None,
                    lambda a,b: Gtk.StatusIcon.position_menu(menu, status_icon),
                    None, event_button, event_time)

        def on_status_icon_activate(tatus_icon):
            if self.window.props.visible:
                self.window.hide()
            else:
                self.window.present()

        if not self.conf['use-status-icon']:
            return

        menu = Gtk.Menu()

        show_item = Gtk.MenuItem(_('Show App'))
        show_item.connect('activate', lambda item: self.window.present())
        menu.append(show_item)

        sep_item = Gtk.SeparatorMenuItem()
        menu.append(sep_item)

        previous_item = Gtk.MenuItem(_('Previous Song'))
        previous_item.connect('activate', lambda item: self.player.load_prev())
        menu.append(previous_item)

        play_item = Gtk.MenuItem()
        play_item.props.related_action = self.player.playback_action
        menu.append(play_item)

        next_item = Gtk.MenuItem(_('Next Song'))
        next_item.connect('activate', lambda item: self.player.load_next())
        menu.append(next_item)

        sep_item = Gtk.SeparatorMenuItem()
        menu.append(sep_item)

        show_osd_item = Gtk.MenuItem()
        show_osd_item.props.related_action = self.osdlrc.show_window_action
        menu.append(show_osd_item)

        lock_osd_item = Gtk.MenuItem()
        lock_osd_item.props.related_action = self.osdlrc.lock_window_action
        menu.append(lock_osd_item)

        sep_item = Gtk.SeparatorMenuItem()
        menu.append(sep_item)
        
        quit_item = Gtk.MenuItem(_('Quit'))
        quit_item.connect('activate', lambda item: self.quit())
        menu.append(quit_item)

        menu.show_all()
        self.status_menu = menu

        if 'AppIndicator' in globals():
            self.status_icon = AppIndicator.Indicator.new(Config.NAME,
                    Config.NAME,
                    AppIndicator.IndicatorCategory.APPLICATION_STATUS)
            self.status_icon.set_menu(menu)
            self.status_icon.set_status(AppIndicator.IndicatorStatus.ACTIVE)
        else: 
            self.status_icon = Gtk.StatusIcon.new_from_icon_name(Config.NAME)
            # left click
            self.status_icon.connect('activate', on_status_icon_activate)
            # right click
            self.status_icon.connect('popup_menu', on_status_icon_popup_menu)

    def on_notebook_switch_page(self, notebook, page, page_num):
        if page not in self.tab_first_show:
            page.first()
            self.tab_first_show.append(page)

    def init_notify(self):
        try:
            self.notify = Notify.Notification.new(Config.APPNAME, '',
                                                  Config.NAME)
        except Exception:
            logger.warn('App.init_notify: %s' % traceback.format_exc())
            self.notify = None

    # Open API
    def toast(self, text):
        '''在用户界面显示一个消息通知.

        可以使用系统提供的Notification工具, 也可以在窗口的最下方滚动弹出
        这个消息
        '''
        if self.notify:
            self.notify.update(Config.APPNAME, text, Config.NAME)
            self.notify.show()
Example #4
0
class App:
    def __init__(self):
        self.app = Gtk.Application.new(DBUS_APP_NAME, 0)
        self.app.connect('startup', self.on_app_startup)
        self.app.connect('activate', self.on_app_activate)
        self.app.connect('shutdown', self.on_app_shutdown)

    def on_app_startup(self, app):
        self.conf = Config.load_conf()
        self.icon_theme = Gtk.IconTheme.get_default()
        self.icon_theme.append_search_path(Config.ICON_PATH)

        GLib.set_application_name(Config.APPNAME)
        self.window = Gtk.ApplicationWindow(application=app)
        self.window.set_default_size(*self.conf['window-size'])
        self.window.set_title(Config.APPNAME)
        self.window.set_default_icon_name(Config.NAME)
        self.window.props.hide_titlebar_when_maximized = True
        app.add_window(self.window)
        self.window.connect('check-resize', self.on_main_window_resized)
        self.window.connect('delete-event', self.on_main_window_deleted)

        self.accel_group = Gtk.AccelGroup()
        self.window.add_accel_group(self.accel_group)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.window.add(box)

        self.osdlrc = OSDLrc(self)
        self.notify = None
        self.init_notify()

        self.player = Player(self)
        box.pack_start(self.player, False, False, 0)

        self.notebook = Gtk.Notebook()
        self.notebook.props.tab_pos = Gtk.PositionType.BOTTOM
        self.notebook.get_style_context().add_class('main_tab')
        box.pack_start(self.notebook, True, True, 0)
        self.init_notebook()
        self.notebook.connect('switch-page', self.on_notebook_switch_page)
        self.init_status_icon()

        # load default styles when all widgets have been constructed.
        self.load_styles()

    def on_app_activate(self, app):
        self.window.show_all()
        # Make some changes after main window is shown.
        # Like hiding some unnecessory widgets.
        self.artists.after_init()
        self.player.after_init()
        self.search.after_init()
        self.shortcut = Shortcut(self.player)
        self.osdlrc.after_init()

        # Cleanup temporary media files
        Net.cleanup_temp_files(self.conf['song-dir'])
        Net.cleanup_temp_files(self.conf['mv-dir'])

    def on_app_shutdown(self, app):
        Config.dump_conf(self.conf)

    def run(self, argv):
        self.app.run(argv)

    def quit(self):
        gdk_win = self.window.get_window()
        if gdk_win and not gdk_win.is_destroyed():
            if self.player.default_cursor:
                gdk_win.set_cursor(self.player.default_cursor)
            self.window.destroy()
        self.shortcut.quit()
        self.app.quit()

    def on_main_window_resized(self, window, event=None):
        self.conf['window-size'] = window.get_size()

    def on_main_window_deleted(self, window, event):
        if self.conf['use-status-icon']:
            window.hide()
            return True
        else:
            return False

    def init_notebook(self):
        self.tab_first_show = []
        self.lrc = Lrc(self)
        self.append_page(self.lrc)

        self.playlist = PlayList(self)
        self.append_page(self.playlist)

        self.search = Search(self)
        self.append_page(self.search)

        self.toplist = TopList(self)
        self.append_page(self.toplist)

        self.radio = Radio(self)
        self.append_page(self.radio)

        self.mv = MV(self)
        self.append_page(self.mv)

        self.artists = Artists(self)
        self.append_page(self.artists)

        self.topcategories = TopCategories(self)
        self.append_page(self.topcategories)

        self.themes = Themes(self)
        self.append_page(self.themes)

    def append_page(self, widget):
        '''Append a new widget to notebook.'''
        label = Gtk.Label(widget.title)
        widget.app_page = self.notebook.append_page(widget, label)

    def popup_page(self, page):
        '''Switch to this widget in notebook.'''
        self.notebook.set_current_page(page)

    def load_styles(self):
        '''Load default CssStyle.'''
        if Config.GTK_LE_36:
            css = '\n'.join([
                'GtkScale {',
                'outline-color: transparent;',
                'outline-offset: 0;',
                'outline-style: none;',
                'outline-width: 0;',
                '}',
                'GtkTextView.lrc_tv {',
                'font-size: {0};'.format(self.conf['lrc-text-size']),
                'color: {0};'.format(self.conf['lrc-text-color']),
                'border-radius: 0 25 0 50;',
                'border-width: 5;',
                'background-color: {0};'.format(self.conf['lrc-back-color']),
                '}',
                '.info-label {',
                'color: rgb(136, 139, 132);',
                'font-size: 9;',
                '}',
            ])
        else:
            css = '\n'.join([
                'GtkScrolledWindow.lrc_window {',
                'transition-property: background-image;',
                'transition-duration: 1s;',
                '}',
                'GtkScale {',
                'outline-color: transparent;',
                'outline-offset: 0;',
                'outline-style: none;',
                'outline-width: 0;',
                '}',
                'GtkTextView.lrc_tv {',
                'transition-property: font-size;',
                'transition: 500ms ease-in-out;',
                'font-size: {0}px;'.format(self.conf['lrc-text-size']),
                'color: {0};'.format(self.conf['lrc-text-color']),
                'border-radius: 0px 25px 0px 50px;',
                'border-width: 5px;',
                'background-color: {0};'.format(self.conf['lrc-back-color']),
                '}',
                '.info-label {',
                'color: rgb(136, 139, 132);',
                'font-size: 9px;',
                '}',
            ])

        Widgets.apply_css(self.window, css, overall=True)

        settings = Gtk.Settings.get_default()
        settings.props.gtk_application_prefer_dark_theme = \
                self.conf.get('use-dark-theme', False)

    def init_status_icon(self):
        def on_status_icon_popup_menu(status_icon, event_button, event_time):
            menu.popup(
                None, None,
                lambda a, b: Gtk.StatusIcon.position_menu(menu, status_icon),
                None, event_button, event_time)

        def on_status_icon_activate(tatus_icon):
            if self.window.props.visible:
                self.window.hide()
            else:
                self.window.present()

        if not self.conf['use-status-icon']:
            return

        menu = Gtk.Menu()

        show_item = Gtk.MenuItem(_('Show App'))
        show_item.connect('activate', lambda item: self.window.present())
        menu.append(show_item)

        sep_item = Gtk.SeparatorMenuItem()
        menu.append(sep_item)

        previous_item = Gtk.MenuItem(_('Previous Song'))
        previous_item.connect('activate', lambda item: self.player.load_prev())
        menu.append(previous_item)

        play_item = Gtk.MenuItem()
        play_item.props.related_action = self.player.playback_action
        menu.append(play_item)

        next_item = Gtk.MenuItem(_('Next Song'))
        next_item.connect('activate', lambda item: self.player.load_next())
        menu.append(next_item)

        sep_item = Gtk.SeparatorMenuItem()
        menu.append(sep_item)

        show_osd_item = Gtk.MenuItem()
        show_osd_item.props.related_action = self.osdlrc.show_window_action
        menu.append(show_osd_item)

        lock_osd_item = Gtk.MenuItem()
        lock_osd_item.props.related_action = self.osdlrc.lock_window_action
        menu.append(lock_osd_item)

        sep_item = Gtk.SeparatorMenuItem()
        menu.append(sep_item)

        quit_item = Gtk.MenuItem(_('Quit'))
        quit_item.connect('activate', lambda item: self.quit())
        menu.append(quit_item)

        menu.show_all()
        self.status_menu = menu

        if 'AppIndicator' in globals():
            self.status_icon = AppIndicator.Indicator.new(
                Config.NAME, Config.NAME,
                AppIndicator.IndicatorCategory.APPLICATION_STATUS)
            self.status_icon.set_menu(menu)
            self.status_icon.set_status(AppIndicator.IndicatorStatus.ACTIVE)
        else:
            self.status_icon = Gtk.StatusIcon.new_from_icon_name(Config.NAME)
            # left click
            self.status_icon.connect('activate', on_status_icon_activate)
            # right click
            self.status_icon.connect('popup_menu', on_status_icon_popup_menu)

    def on_notebook_switch_page(self, notebook, page, page_num):
        if page not in self.tab_first_show:
            page.first()
            self.tab_first_show.append(page)

    def init_notify(self):
        try:
            self.notify = Notify.Notification.new(Config.APPNAME, '',
                                                  Config.NAME)
        except Exception:
            logger.warn('App.init_notify: %s' % traceback.format_exc())
            self.notify = None

    # Open API
    def toast(self, text):
        '''在用户界面显示一个消息通知.

        可以使用系统提供的Notification工具, 也可以在窗口的最下方滚动弹出
        这个消息
        '''
        if self.notify:
            self.notify.update(Config.APPNAME, text, Config.NAME)
            self.notify.show()