示例#1
0
    def __init__(self, player):
        super(VolumeMenu, self).__init__()

        # ubuntu 12.04..
        if hasattr(player, "bind_property"):
            # Translators: player state, no action
            item = Gtk.CheckMenuItem(label=_("_Mute"), use_underline=True)
            player.bind_property("mute", item, "active",
                                 GObject.BindingFlags.BIDIRECTIONAL)
            self.append(item)
            item.show()

        item = Gtk.MenuItem(label=_("_Replay Gain Mode"), use_underline=True)
        self.append(item)
        item.show()

        # Set replaygain mode as saved in configuration
        replaygain_mode = config.gettext("player", "replaygain_mode", "auto")
        self.__set_mode(player, replaygain_mode)

        rg = Gtk.Menu()
        rg.show()
        item.set_submenu(rg)
        item = None
        for mode, title, profile in self.__modes:
            item = RadioMenuItem(group=item, label=title,
                                 use_underline=True)
            rg.append(item)
            item.connect("toggled", self.__changed, player, mode)
            if replaygain_mode == mode:
                item.set_active(True)
            item.show()
示例#2
0
    def __init__(self, browser, model):
        super(PreferencesButton, self).__init__()

        sort_orders = [
            (_("_Title"), self.__compare_title),
            (_("_Artist"), self.__compare_artist),
            (_("_Date"), self.__compare_date),
            (_("_Genre"), self.__compare_genre),
            (_("_Rating"), self.__compare_rating),
            (_("_Playcount"), self.__compare_avgplaycount),
        ]

        menu = Gtk.Menu()

        sort_item = Gtk.MenuItem(
            label=_(u"Sort _by…"), use_underline=True)
        sort_menu = Gtk.Menu()

        active = config.getint('browsers', 'album_sort', 1)

        item = None
        for i, (label, func) in enumerate(sort_orders):
            item = RadioMenuItem(group=item, label=label,
                                 use_underline=True)
            model.set_sort_func(100 + i, func)
            if i == active:
                model.set_sort_column_id(100 + i, Gtk.SortType.ASCENDING)
                item.set_active(True)
            item.connect("toggled",
                         util.DeferredSignal(self.__sort_toggled_cb),
                         model, i)
            sort_menu.append(item)

        sort_item.set_submenu(sort_menu)
        menu.append(sort_item)

        pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM)
        menu.append(pref_item)
        connect_obj(pref_item, "activate", Preferences, browser)

        menu.show_all()

        button = MenuButton(
                SymbolicIconImage(Icons.EMBLEM_SYSTEM, Gtk.IconSize.MENU),
                arrow=True)
        button.set_menu(menu)
        self.pack_start(button, True, True, 0)
示例#3
0
    def __init__(self, browser, model):
        super(PreferencesButton, self).__init__()

        sort_orders = [
            (_("_Title"), self.__compare_title),
            (_("_Artist"), self.__compare_artist),
            (_("_Date"), self.__compare_date),
            (_("_Genre"), self.__compare_genre),
            (_("_Rating"), self.__compare_rating),
        ]

        menu = Gtk.Menu()

        sort_item = Gtk.MenuItem(label=_("Sort _by..."), use_underline=True)
        sort_menu = Gtk.Menu()

        active = config.getint('browsers', 'album_sort', 1)

        item = None
        for i, (label, func) in enumerate(sort_orders):
            item = RadioMenuItem(group=item, label=label,
                                 use_underline=True)
            model.set_sort_func(100 + i, func)
            if i == active:
                model.set_sort_column_id(100 + i, Gtk.SortType.ASCENDING)
                item.set_active(True)
            gobject_weak(item.connect, "toggled",
                         util.DeferredSignal(self.__sort_toggled_cb),
                         model, i)
            sort_menu.append(item)

        sort_item.set_submenu(sort_menu)
        menu.append(sort_item)

        pref_item = MenuItem(_("_Preferences"), Gtk.STOCK_PREFERENCES)
        menu.append(pref_item)
        gobject_weak(pref_item.connect_object,
                     "activate", Preferences, browser)

        menu.show_all()

        button = MenuButton(
                SymbolicIconImage("emblem-system", Gtk.IconSize.MENU),
                arrow=True)
        button.set_menu(menu)
        self.pack_start(button, True, True, 0)
示例#4
0
    def __init__(self, player):
        super(VolumeMenu, self).__init__()

        # ubuntu 12.04..
        if hasattr(player, "bind_property"):
            # Translators: player state, no action
            item = Gtk.CheckMenuItem(label=_("_Mute"), use_underline=True)
            player.bind_property("mute", item, "active",
                                 GObject.BindingFlags.BIDIRECTIONAL)
            self.append(item)
            item.show()

        item = Gtk.MenuItem(label=_("_Replay Gain Mode"), use_underline=True)
        self.append(item)
        item.show()

        rg = Gtk.Menu()
        rg.show()
        item.set_submenu(rg)
        item = None
        for mode, title, profile in self.__modes:
            item = RadioMenuItem(group=item, label=title,
                                 use_underline=True)
            rg.append(item)
            item.connect("toggled", self.__changed, player, profile)
            if player.replaygain_profiles[0] == profile:
                item.set_active(True)
            item.show()
示例#5
0
    def __rebuild_menu(self):

        def toggled_cb(item, order):
            if item.get_active():
                self.current = order

        menu = Gtk.Menu()
        group = None
        for order in self.__orders:
            group = RadioMenuItem(
                label=order.accelerated_name,
                use_underline=True,
                group=group)
            group.set_active(order == self.__current)
            group.connect("toggled", toggled_cb, order)
            menu.append(group)
        menu.show_all()
        self._menu_button.set_menu(menu)
    def __init__(self, player):
        super(ReplayGainMenu, self).__init__()

        item = None
        for mode, title, profile in self.__modes:
            item = RadioMenuItem(group=item, label=title, use_underline=True)
            self.append(item)
            item.connect("toggled", self.__changed, player, profile)
            if player.replaygain_profiles[0] == profile:
                item.set_active(True)
            item.show()
示例#7
0
    def __rebuild_menu(self):

        def toggled_cb(item, order):
            if item.get_active():
                self.current = order

        menu = Gtk.Menu()
        group = None
        prev_priority = None

        def ui_sorted(items):
            return sorted(items, key=lambda k: (k.priority, k.display_name))

        for order in ui_sorted(self.__orders):
            if prev_priority and order.priority > prev_priority:
                menu.append(SeparatorMenuItem())
            prev_priority = order.priority
            group = RadioMenuItem(
                label=order.accelerated_name,
                use_underline=True,
                group=group)
            group.set_active(order == self.__current)
            group.connect("toggled", toggled_cb, order)
            menu.append(group)
        menu.show_all()
        self._menu_button.set_menu(menu)
示例#8
0
    def _refresh_menu(self):
        is_shuffle = self._shuffle.get_active()

        def toggled_cb(item, order):
            if item.get_active():
                self._set_order(order)

        active_order = self._get_order(is_shuffle)

        menu = Gtk.Menu()
        group = None
        for order in ORDERS:
            if order.is_shuffle == is_shuffle:
                group = RadioMenuItem(
                    label=order.accelerated_name,
                    use_underline=True,
                    group=group)
                group.set_active(order == active_order)
                group.connect("toggled", toggled_cb, order)
                menu.append(group)
        menu.show_all()
        self._shuffle.set_menu(menu)
示例#9
0
    def __init__(self, player):
        super(ReplayGainMenu, self).__init__()

        item = None
        for mode, title, profile in self.__modes:
            item = RadioMenuItem(group=item, label=title,
                                 use_underline=True)
            self.append(item)
            item.connect("toggled", self.__changed, player, profile)
            if player.replaygain_profiles[0] == profile:
                item.set_active(True)
            item.show()
示例#10
0
    def __rebuild_menu(self):
        def toggled_cb(item, order):
            if item.get_active():
                self.current = order

        menu = Gtk.Menu()
        group = None
        for order in self.__orders:
            group = RadioMenuItem(label=order.accelerated_name,
                                  use_underline=True,
                                  group=group)
            group.set_active(order == self.__current)
            group.connect("toggled", toggled_cb, order)
            menu.append(group)
        menu.show_all()
        self._menu_button.set_menu(menu)
示例#11
0
文件: main.py 项目: WammKD/quodlibet
    def __init__(self, browser, model):
        Gtk.HBox.__init__(self)

        sort_orders = [
            (_("_Title"), self.__compare_title),
            (_("_Artist"), self.__compare_artist),
            (_("_Date"), self.__compare_date),
            (_("_Date Added"), self.__compare_date_added),
            (_("_Original Date"), self.__compare_original_date),
            (_("_Genre"), self.__compare_genre),
            (_("_Rating"), self.__compare_rating),
            (_("_Playcount"), self.__compare_avgplaycount),
        ]

        menu = Gtk.Menu()

        sort_item = Gtk.MenuItem(label=_(u"Sort _by…"), use_underline=True)
        sort_menu = Gtk.Menu()

        active = config.getint('browsers', 'album_sort', 1)

        item = None
        for i, (label, func) in enumerate(sort_orders):
            item = RadioMenuItem(group=item, label=label, use_underline=True)
            model.set_sort_func(100 + i, func)
            if i == active:
                model.set_sort_column_id(100 + i, Gtk.SortType.ASCENDING)
                item.set_active(True)
            item.connect("toggled",
                         util.DeferredSignal(self.__sort_toggled_cb), model, i)
            sort_menu.append(item)

        sort_item.set_submenu(sort_menu)
        menu.append(sort_item)

        pref_item = MenuItem(_("_Preferences"), Icons.PREFERENCES_SYSTEM)
        menu.append(pref_item)
        connect_obj(pref_item, "activate", Preferences, browser)

        menu.show_all()

        button = MenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM,
                                              Gtk.IconSize.MENU),
                            arrow=True)
        button.set_menu(menu)
        self.pack_start(button, True, True, 0)
示例#12
0
    def _refresh_menu(self):
        is_shuffle = self._shuffle.get_active()

        def toggled_cb(item, order):
            if item.get_active():
                self._set_order(order)

        active_order = self._get_order(is_shuffle)

        menu = Gtk.Menu()
        group = None
        for order in ORDERS:
            if order.is_shuffle == is_shuffle:
                group = RadioMenuItem(label=order.accelerated_name,
                                      use_underline=True,
                                      group=group)
                group.set_active(order == active_order)
                group.connect("toggled", toggled_cb, order)
                menu.append(group)
        menu.show_all()
        self._shuffle.set_menu(menu)
示例#13
0
    def _popup_menu(self, icon, button, time):
        if self.__destroy_win32_menu():
            return
        self.__menu = menu = Gtk.Menu()

        player = app.player
        window = app.window

        if player.paused:
            playpause = MenuItem(_("_Play"), Icons.MEDIA_PLAYBACK_START)
        else:
            playpause = MenuItem(_("P_ause"), Icons.MEDIA_PLAYBACK_PAUSE)
        playpause.connect('activate', self.__play_pause)

        previous = MenuItem(_("Pre_vious"), Icons.MEDIA_SKIP_BACKWARD)
        previous.connect('activate', lambda *args: player.previous())

        next = MenuItem(_("_Next"), Icons.MEDIA_SKIP_FORWARD)
        next.connect('activate', lambda *args: player.next())

        orders = Gtk.MenuItem(label=_("Play _Order"), use_underline=True)

        repeat = Gtk.CheckMenuItem(label=_("_Repeat"), use_underline=True)
        repeat.set_active(window.repeat.get_active())
        repeat.connect('toggled',
            lambda s: window.repeat.set_active(s.get_active()))

        def set_safter(widget, safter_action):
            safter_action.set_active(widget.get_active())

        safter_action = app.window.stop_after
        safter = Gtk.CheckMenuItem(label=_("Stop _after this song"),
                                   use_underline=True)
        safter.set_active(safter_action.get_active())
        safter.connect('toggled', set_safter, safter_action)

        def set_order(widget, order):
            name = order.name
            try:
                window.order.set_active_by_name(name)
            except ValueError:
                pass

        order_items = []
        item = None
        active_order = window.order.get_active()
        for Kind in ORDERS:
            item = RadioMenuItem(
                    group=item,
                    label=Kind.accelerated_name,
                    use_underline=True)
            order_items.append(item)
            if Kind is active_order:
                item.set_active(True)
            item.connect('toggled', set_order, Kind)

        order_sub = Gtk.Menu()
        order_sub.append(repeat)
        order_sub.append(safter)
        order_sub.append(SeparatorMenuItem())
        for item in order_items:
            order_sub.append(item)
        orders.set_submenu(order_sub)

        browse = qltk.MenuItem(_("_Browse Library"), Icons.EDIT_FIND)
        browse_sub = Gtk.Menu()

        for Kind in browsers.browsers:
            if Kind.is_empty:
                continue
            i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True)
            connect_obj(i,
                'activate', LibraryBrowser.open, Kind, app.library, app.player)
            browse_sub.append(i)

        browse.set_submenu(browse_sub)

        props = qltk.MenuItem(_("Edit _Tags"), Icons.DOCUMENT_PROPERTIES)
        props.connect('activate', self.__properties)

        info = MenuItem(_("_Information"), Icons.DIALOG_INFORMATION)
        info.connect('activate', self.__information)

        def set_rating(value):
            song = player.song
            if song is None:
                return
            else:
                song["~#rating"] = value
                app.librarian.changed([song])

        rating = Gtk.MenuItem(label=_("_Rating"), use_underline=True)
        rating_sub = Gtk.Menu()
        for r in RATINGS.all:
            item = Gtk.MenuItem(label="%0.2f\t%s" % (r, util.format_rating(r)))
            connect_obj(item, 'activate', set_rating, r)
            rating_sub.append(item)
        rating.set_submenu(rating_sub)

        quit = MenuItem(_("_Quit"), Icons.APPLICATION_EXIT)
        quit.connect('activate', lambda *x: app.quit())

        menu.append(playpause)
        menu.append(SeparatorMenuItem())
        menu.append(previous)
        menu.append(next)
        menu.append(orders)
        menu.append(SeparatorMenuItem())
        menu.append(browse)
        menu.append(SeparatorMenuItem())
        menu.append(props)
        menu.append(info)
        menu.append(rating)
        menu.append(SeparatorMenuItem())
        menu.append(quit)

        menu.show_all()

        if sys.platform in ("win32", "darwin"):
            pos_func = pos_arg = None
        else:
            pos_func = Gtk.StatusIcon.position_menu
            pos_arg = self._icon

        menu.popup(None, None, pos_func, pos_arg, button, time)
示例#14
0
    def __init__(self, library, player):
        super().__init__(spacing=3)
        sw = ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(Gtk.ShadowType.IN)
        save_interval_secs = config.getint("autosave", "queue_interval")
        self.queue = PlayQueue(library, player, save_interval_secs)
        self.queue.props.expand = True
        sw.add(self.queue)

        add_css(self, ".ql-expanded title { margin-bottom: 5px; }")

        outer = ExpandBoxHack()

        left = Gtk.HBox(spacing=12)

        hb2 = Gtk.HBox(spacing=3)
        state_icon = PlaybackStatusIcon()
        state_icon.stop()
        state_icon.show()
        hb2.pack_start(state_icon, True, True, 0)
        name_label = Gtk.Label(label=_("_Queue"), use_underline=True)
        name_label.set_size_request(-1, 24)
        hb2.pack_start(name_label, True, True, 0)
        left.pack_start(hb2, False, True, 0)

        menu = Gtk.Menu()

        self.count_label = count_label = Gtk.Label()
        self.count_label.set_property("ellipsize", Pango.EllipsizeMode.END)
        self.count_label.set_width_chars(10)
        self.count_label.get_style_context().add_class("dim-label")
        left.pack_start(count_label, False, True, 0)

        outer.pack_start(left, True, True, 0)

        self.set_label_fill(True)

        clear_item = SmallImageButton(image=SymbolicIconImage(
            Icons.USER_TRASH, Gtk.IconSize.MENU),
                                      relief=Gtk.ReliefStyle.NONE,
                                      tooltip_text=_("Clear Queue"))
        clear_item.connect("clicked", self.__clear_queue)
        outer.pack_start(clear_item, False, False, 3)

        toggle = SmallImageToggleButton(
            image=SymbolicIconImage(Icons.SYSTEM_LOCK_SCREEN,
                                    Gtk.IconSize.MENU),
            relief=Gtk.ReliefStyle.NONE,
            tooltip_text=_(
                "Disable queue - the queue will be ignored when playing"))
        disabled = config.getboolean("memory", "queue_disable", False)
        toggle.props.active = disabled
        self.__queue_disable(disabled)
        toggle.connect('toggled',
                       lambda b: self.__queue_disable(b.props.active))
        outer.pack_start(toggle, False, False, 3)

        mode_menu = Gtk.Menu()

        norm_mode_item = RadioMenuItem(
            label=_("Ephemeral"),
            tooltip_text=_("Remove songs from the queue after playing them"),
            group=None)
        mode_menu.append(norm_mode_item)
        norm_mode_item.set_active(True)
        norm_mode_item.connect("toggled",
                               lambda _: self.__keep_songs_enable(False))

        keep_mode_item = RadioMenuItem(
            label=_("Persistent"),
            tooltip_text=_("Keep songs in the queue after playing them"),
            group=norm_mode_item)
        mode_menu.append(keep_mode_item)
        keep_mode_item.connect("toggled",
                               lambda b: self.__keep_songs_enable(True))
        keep_mode_item.set_active(
            config.getboolean("memory", "queue_keep_songs", False))

        mode_item = MenuItem(_("Mode"), Icons.SYSTEM_RUN)
        mode_item.set_submenu(mode_menu)
        menu.append(mode_item)

        rand_checkbox = ConfigCheckMenuItem(_("_Random"),
                                            "memory",
                                            "shufflequeue",
                                            populate=True)
        rand_checkbox.connect('toggled', self.__queue_shuffle)
        self.set_shuffled(rand_checkbox.get_active())
        menu.append(rand_checkbox)

        stop_checkbox = ConfigCheckMenuItem(_("Stop at End"),
                                            "memory",
                                            "queue_stop_at_end",
                                            populate=True)
        menu.append(stop_checkbox)

        button = SmallMenuButton(SymbolicIconImage(Icons.EMBLEM_SYSTEM,
                                                   Gtk.IconSize.MENU),
                                 arrow=True)
        button.set_relief(Gtk.ReliefStyle.NORMAL)
        button.show_all()
        button.hide()
        button.set_no_show_all(True)
        menu.show_all()
        button.set_menu(menu)

        outer.pack_start(button, False, False, 3)

        close_button = SmallImageButton(image=SymbolicIconImage(
            "window-close", Gtk.IconSize.MENU),
                                        relief=Gtk.ReliefStyle.NONE)

        close_button.connect("clicked", lambda *x: self.hide())

        outer.pack_start(close_button, False, False, 6)

        self.set_label_widget(outer)
        self.add(sw)
        self.connect('notify::expanded', self.__expand, button)
        self.connect('notify::expanded', self.__expand, button)

        targets = [("text/x-quodlibet-songs", Gtk.TargetFlags.SAME_APP,
                    DND_QL), ("text/uri-list", 0, DND_URI_LIST)]
        targets = [Gtk.TargetEntry.new(*t) for t in targets]

        self.drag_dest_set(Gtk.DestDefaults.ALL, targets, Gdk.DragAction.COPY)
        self.connect('drag-motion', self.__motion)
        self.connect('drag-data-received', self.__drag_data_received)

        self.queue.model.connect_after('row-inserted',
                                       DeferredSignal(self.__check_expand),
                                       count_label)
        self.queue.model.connect_after('row-deleted',
                                       DeferredSignal(self.__update_count),
                                       count_label)

        self.__update_count(self.model, None, count_label)

        connect_destroy(player, 'song-started', self.__update_state_icon,
                        state_icon)
        connect_destroy(player, 'paused', self.__update_state_icon_pause,
                        state_icon, True)
        connect_destroy(player, 'unpaused', self.__update_state_icon_pause,
                        state_icon, False)

        connect_destroy(player, 'song-started', self.__song_started,
                        self.queue.model)
        connect_destroy(player, 'song-ended', self.__update_queue_stop,
                        self.queue.model)

        # to make the children clickable if mapped
        # ....no idea why, but works
        def hack(expander):
            label = expander.get_label_widget()
            if label:
                label.unmap()
                label.map()

        self.connect("map", hack)

        self.set_expanded(config.getboolean("memory", "queue_expanded"))
        self.notify("expanded")

        for child in self.get_children():
            child.show_all()
    def _popup_menu(self, icon, button, time):
        if self.__destroy_win32_menu():
            return
        self.__menu = menu = Gtk.Menu()

        player = app.player
        window = app.window

        pp_icon = [Gtk.STOCK_MEDIA_PAUSE, Gtk.STOCK_MEDIA_PLAY][player.paused]
        playpause = Gtk.ImageMenuItem.new_from_stock(pp_icon, None)
        playpause.connect('activate', self.__play_pause)

        previous = Gtk.ImageMenuItem.new_from_stock(
            Gtk.STOCK_MEDIA_PREVIOUS, None)
        previous.connect('activate', lambda *args: player.previous())
        next = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_MEDIA_NEXT, None)
        next.connect('activate', lambda *args: player.next())

        orders = Gtk.MenuItem(label=_("Play _Order"), use_underline=True)

        repeat = Gtk.CheckMenuItem(label=_("_Repeat"), use_underline=True)
        repeat.set_active(window.repeat.get_active())
        repeat.connect('toggled',
            lambda s: window.repeat.set_active(s.get_active()))

        def set_safter(widget, safter_action):
            safter_action.set_active(widget.get_active())

        safter_action = app.window.stop_after
        safter = Gtk.CheckMenuItem(label=_("Stop _after this song"),
                                   use_underline=True)
        safter.set_active(safter_action.get_active())
        safter.connect('toggled', set_safter, safter_action)

        def set_order(widget, num):
            window.order.set_active(num)

        order_items = []
        item = None
        for i, Kind in enumerate(ORDERS):
            item = RadioMenuItem(
                    group=item,
                    label=Kind.accelerated_name,
                    use_underline=True)
            order_items.append(item)
            item.connect('toggled', set_order, i)

        order_items[window.order.get_active()].set_active(True)

        order_sub = Gtk.Menu()
        order_sub.append(repeat)
        order_sub.append(safter)
        order_sub.append(SeparatorMenuItem())
        for item in order_items:
            order_sub.append(item)
        orders.set_submenu(order_sub)

        browse = qltk.MenuItem(_("_Browse Library"), Gtk.STOCK_FIND)
        browse_sub = Gtk.Menu()

        for Kind in browsers.browsers:
            if not Kind.in_menu:
                continue
            i = Gtk.MenuItem(label=Kind.accelerated_name, use_underline=True)
            i.connect_object(
                'activate', LibraryBrowser.open, Kind, app.library)
            browse_sub.append(i)

        browse.set_submenu(browse_sub)

        props = qltk.MenuItem(_("Edit _Tags"), Gtk.STOCK_PROPERTIES)
        props.connect('activate', self.__properties)

        info = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_INFO, None)
        info.connect('activate', self.__information)

        def set_rating(value):
            song = player.song
            if song is None:
                return
            else:
                song["~#rating"] = value
                app.librarian.changed([song])

        rating = Gtk.MenuItem(label=_("_Rating"), use_underline=True)
        rating_sub = Gtk.Menu()
        for r in RATINGS.all:
            item = Gtk.MenuItem("%0.2f\t%s" % (r, util.format_rating(r)))
            item.connect_object('activate', set_rating, r)
            rating_sub.append(item)
        rating.set_submenu(rating_sub)

        quit = Gtk.ImageMenuItem.new_from_stock(Gtk.STOCK_QUIT, None)
        quit.connect('activate', lambda *x: app.quit())

        menu.append(playpause)
        menu.append(SeparatorMenuItem())
        menu.append(previous)
        menu.append(next)
        menu.append(orders)
        menu.append(SeparatorMenuItem())
        menu.append(browse)
        menu.append(SeparatorMenuItem())
        menu.append(props)
        menu.append(info)
        menu.append(rating)
        menu.append(SeparatorMenuItem())
        menu.append(quit)

        menu.show_all()

        if sys.platform != "win32":
            pos_func = Gtk.StatusIcon.position_menu
            pos_arg = self._icon
        else:
            pos_func = pos_arg = None

        menu.popup(None, None, pos_func, pos_arg, button, time)