def __init__(self,
                 name,
                 text_size=TITLE_FONT_SIZE,
                 always_show=False,
                 toggle_callback=None,
                 label_right=False):
        gtk.HBox.__init__(self)
        self.set_size_request(-1, 30)

        self.label = Label(
            name,
            text_size=text_size,
            text_color=app_theme.get_color("globalTitleForeground"),
            enable_select=False,
            enable_double_click=False)
        if label_right:
            self.label_box = style.wrap_with_align(self.label, width=210)
        else:
            self.label_box = style.wrap_with_align(self.label,
                                                   align="left",
                                                   width=210)
        self.label_box.set_size_request(210, 30)
        self.pack_start(self.label_box, False, False)

        if not always_show:
            self.switch = SwitchButton(
                False,
                inactive_disable_dpixbuf=app_theme.get_pixbuf(
                    "toggle_button/inactive_normal.png"),
                active_disable_dpixbuf=app_theme.get_pixbuf(
                    "toggle_button/active_disable.png"))
            align = style.wrap_with_align(self.switch, align="left")
            self.pack_start(align, False, False)
            self.switch.connect("toggled", toggle_callback)
            align.set_padding(0, 0, 15, 0)
    def row_toggle(self, label_name, table=None):
        label = self.__label(label_name)

        toggle = SwitchButton()
        self._wrap_align((label, toggle), table)

        return toggle
 def __make_playback_box(self, stream, index):
     process_id = int(stream['proplist']['application.process.id'])
     # if it has show mpris, then don't show sink_input
     if process_id in self.mpris_list:
         self.mpris_stream[process_id] = index
         self.stream_mpris[index] = process_id
         return
     self.stream_list[index] = {}
     volume_max_percent = pypulse.MAX_VOLUME_VALUE * 100 / pypulse.NORMAL_VOLUME_VALUE
     icon_name = self.__white_list_check(stream)
     if icon_name:
         if icon_name[0] == '/' and os.path.exists(icon_name):
             try:
                 img = gtk.image_new_from_pixbuf(gtk.gdk.pixbuf_new_from_file(
                     icon_name).scale_simple(16, 16, gtk.gdk.INTERP_TILES))
             except:
                 img = gtk.image_new_from_pixbuf(self.stream_icon)
         else:
             img = gtk.image_new_from_icon_name(icon_name, gtk.ICON_SIZE_MENU)
     else:
         img = gtk.image_new_from_pixbuf(self.stream_icon)
     scale = HScalebar(show_value=False, format_value="%", value_min=0, value_max=volume_max_percent)
     scale.set_magnetic_values([(0, 5), (100, 5), (volume_max_percent, 5)])
     scale.set_size_request(90, 10)
     mute_button = SwitchButton(
         inactive_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
         active_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
     hbox = gtk.HBox()
     hbox.pack_start(self.__make_align(img), False, False)
     hbox.pack_start(self.__make_align(scale, yalign=0.0, yscale=1.0, padding_left=5, padding_right=5, height=25), False, False)
     hbox.pack_start(self.__make_align(mute_button), False, False)
     self.stream_list[index]['scale'] = scale
     self.stream_list[index]['button'] = mute_button
     self.stream_list[index]['container'] = hbox
     self.stream_list[index]['process_id'] = process_id
     self.stream_list[index]['stream_id'] = index
     self.stream_process[process_id] = self.stream_list[index]
     self.__set_playback_status(stream, scale, mute_button)
     if stream['volume_writable']:
         scale.connect("value-changed", self.playback_stream_scale_changed_cb, index, mute_button)
         mute_button.connect("toggled", self.playback_stream_toggled_cb, index, scale)
     hbox.show_all()
     self.__app_vbox.pack_start(hbox, False, False)
    def __create_widget(self):
        '''create gtk widget'''
        title_item_font_size = TITLE_FONT_SIZE
        option_item_font_szie = CONTENT_FONT_SIZE

        self.label_widgets["speaker"] = Label(_("Speaker"), app_theme.get_color("globalTitleForeground"), text_size=title_item_font_size, enable_select=False, enable_double_click=False)
        self.label_widgets["microphone"] = Label(_("Microphone"), app_theme.get_color("globalTitleForeground"), text_size=title_item_font_size, enable_select=False, enable_double_click=False)
        self.label_widgets["left"] = Label(_("Left"), enable_select=False, enable_double_click=False)
        self.label_widgets["right"] = Label(_("Right"), enable_select=False, enable_double_click=False)
        self.label_widgets["speaker_port"] = Label(_("Output Port"), text_size=option_item_font_szie,
                                                   text_x_align=ALIGN_END, enable_select=False,
                                                   enable_double_click=False, fixed_width=STANDARD_LINE)
        self.label_widgets["speaker_volume"] = Label(_("Output Volume"), text_size=option_item_font_szie,
                                                     text_x_align=ALIGN_END, enable_select=False,
                                                     enable_double_click=False, fixed_width=STANDARD_LINE)
        self.label_widgets["speaker_mute"] = Label(_("Sound Enabled"), text_size=option_item_font_szie,
                                                   text_x_align=ALIGN_END, enable_select=False,
                                                   enable_double_click=False, fixed_width=STANDARD_LINE)
        self.label_widgets["speaker_balance"] = Label(_("Balance"), text_size=option_item_font_szie,
                                                      text_x_align=ALIGN_END, enable_select=False,
                                                      enable_double_click=False, fixed_width=STANDARD_LINE)
        self.label_widgets["microphone_port"] = Label(_("Input Port"), text_size=option_item_font_szie,
                                                      text_x_align=ALIGN_END, enable_select=False,
                                                      enable_double_click=False, fixed_width=STANDARD_LINE)
        self.label_widgets["microphone_volume"] = Label(_("Input Volume"), text_size=option_item_font_szie,
                                                        text_x_align=ALIGN_END, enable_select=False,
                                                        enable_double_click=False, fixed_width=STANDARD_LINE)
        self.label_widgets["microphone_mute"] = Label(_("Sound Enabled"), text_size=option_item_font_szie,
                                                      text_x_align=ALIGN_END, enable_select=False,
                                                      enable_double_click=False, fixed_width=STANDARD_LINE)
        #####################################
        # image init
        self.image_widgets["balance"] = ImageBox(app_theme.get_pixbuf("%s/balance.png" % MODULE_NAME))
        self.image_widgets["speaker"] = ImageBox(app_theme.get_pixbuf("%s/speaker-3.png" % MODULE_NAME))
        self.image_widgets["microphone"] = ImageBox(app_theme.get_pixbuf("%s/microphone.png" % MODULE_NAME))
        self.image_widgets["device"] = app_theme.get_pixbuf("%s/device.png" % MODULE_NAME)
        # button init
        self.button_widgets["balance"] = SwitchButton(
            inactive_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
            active_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
        self.button_widgets["speaker"] = SwitchButton(
            inactive_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
            active_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
        self.button_widgets["microphone"] = SwitchButton(
            inactive_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
            active_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
        self.button_widgets["advanced"] = Button(_("Advanced"))
        self.button_widgets["speaker_combo"] = ComboBox(fixed_width=HSCALEBAR_WIDTH)
        self.button_widgets["microphone_combo"] = ComboBox(fixed_width=HSCALEBAR_WIDTH)
        # container init
        self.container_widgets["main_vbox"] = gtk.VBox(False)
        self.container_widgets["statusbar"] = StatusBar()
        self.container_widgets["slider"] = HSlider()
        self.container_widgets["swin"] = ScrolledWindow()
        self.container_widgets["advance_set_tab_box"] = TabBox()
        self.container_widgets["advance_set_tab_box"].draw_title_background = self.draw_tab_title_background
        self.container_widgets["main_hbox"] = gtk.HBox(False)
        self.container_widgets["left_vbox"] = gtk.VBox(False)
        self.container_widgets["right_vbox"] = gtk.VBox(False)
        self.container_widgets["balance_hbox"] = gtk.HBox(False)
        self.container_widgets["speaker_main_vbox"] = gtk.VBox(False)     # speaker
        self.container_widgets["speaker_label_hbox"] = gtk.HBox(False)
        self.container_widgets["speaker_table"] = gtk.Table(4, 2)
        self.container_widgets["microphone_main_vbox"] = gtk.VBox(False)     # microphone
        self.container_widgets["microphone_label_hbox"] = gtk.HBox(False)
        self.container_widgets["microphone_table"] = gtk.Table(4, 2)
        # alignment init
        self.alignment_widgets["slider"] = gtk.Alignment()
        self.alignment_widgets["main_hbox"] = gtk.Alignment()
        self.alignment_widgets["advance_set_tab_box"] = gtk.Alignment()
        self.alignment_widgets["left"] = gtk.Alignment()
        self.alignment_widgets["right"] = gtk.Alignment()
        self.alignment_widgets["speaker_label"] = gtk.Alignment()      # speaker
        self.alignment_widgets["speaker_set"] = gtk.Alignment()
        self.alignment_widgets["microphone_label"] = gtk.Alignment()      # microphone
        self.alignment_widgets["microphone_set"] = gtk.Alignment()
        # adjust init
        volume_max_percent = pypulse.MAX_VOLUME_VALUE * 100 / pypulse.NORMAL_VOLUME_VALUE
        self.adjust_widgets["balance"] = gtk.Adjustment(0, -1.0, 1.0, 0.1, 0.2)
        self.adjust_widgets["speaker"] = gtk.Adjustment(0, 0, volume_max_percent, 1, 5)
        self.adjust_widgets["microphone"] = gtk.Adjustment(0, 0, volume_max_percent, 1, 5)
        # scale init
        self.scale_widgets["balance"] = HScalebar(value_min=-1, value_max=1, gray_progress=True)
        self.scale_widgets["balance"].set_magnetic_values([(0, 0.1), (1, 0.1), (2, 0.1)])
        self.scale_widgets["speaker"] = HScalebar(show_value=True, format_value="%", value_min=0, value_max=volume_max_percent)
        self.scale_widgets["speaker"].set_magnetic_values([(0, 5), (100, 5), (volume_max_percent, 5)])
        self.scale_widgets["microphone"] = HScalebar(show_value=True, format_value="%", value_min=0, value_max=volume_max_percent)
        self.scale_widgets["microphone"].set_magnetic_values([(0, 5), (100, 5), (volume_max_percent, 5)])
        ###################################
        # advance set
        self.container_widgets["advance_input_box"] = gtk.VBox(False)
        self.container_widgets["advance_output_box"] = gtk.VBox(False)
        self.container_widgets["advance_hardware_box"] = gtk.VBox(False)
        self.alignment_widgets["advance_input_box"] = gtk.Alignment()
        self.alignment_widgets["advance_output_box"] = gtk.Alignment()
        self.alignment_widgets["advance_hardware_box"] = gtk.Alignment()
        #
        self.label_widgets["ad_output"] = Label(_("Choose a device for sound output:"), enable_select=False, enable_double_click=False)
        self.label_widgets["ad_input"] = Label(_("Choose a device for sound input:"), enable_select=False, enable_double_click=False)
        self.label_widgets["ad_hardware"] = Label(_("Choose a device to configure:"), enable_select=False, enable_double_click=False)
        #
        self.container_widgets["ad_output"] = gtk.VBox(False)
        self.container_widgets["ad_input"] = gtk.VBox(False)
        self.container_widgets["ad_hardware"] = gtk.VBox(False)
        #
        self.view_widgets["ad_output"] = TreeView()
        self.view_widgets["ad_input"] = TreeView()
        self.view_widgets["ad_hardware"] = TreeView()
    def __init__(self, tray_obj=None):
        super(TrayGui, self).__init__(False)
        self.tray_obj = tray_obj

        self.stream_icon = app_theme.get_pixbuf("sound/device.png").get_pixbuf().scale_simple(16, 16, gtk.gdk.INTERP_TILES)
        self.stream_num = 0
        self.stream_list = {}    # stream widgets
        self.stream_process = {} # process id to stream widgets
        self.stream_mpris = {}   # stream id to mpris process id

        self.__mpris_total_height = 0
        self.mpris_base_height = 70
        self.mpris_list = {}     # mpris widgets
        self.mpris_stream = {}   # mpris process id to stream id
        self.mpris2 = Mpris2()
        self.mpris2.connect("new", self.mpris2_new_cb)
        self.mpris2.connect("removed", self.mpris2_removed_cb)
        self.mpris2.connect("changed", self.mpris2_changed_cb)

        hbox = gtk.HBox(False)
        hbox.set_spacing(WIDGET_SPACING)
        #separator_color = [(0, ("#000000", 0.3)), (0.5, ("#000000", 0.2)), (1, ("#777777", 0.0))]
        #hseparator = HSeparator(app_theme.get_shadow_color("hSeparator").get_color_info(), 0, 0)
        #hseparator.set_size_request(150, 3)
        separator_color = [(0, ("#777777", 0.0)), (0.5, ("#000000", 0.3)), (1, ("#777777", 0.0))]
        hseparator = HSeparator(separator_color, 0, 0)
        hseparator.set_size_request(140, 5)
        #hbox.pack_start(self.__make_align(Label(_("Device"), enable_select=False, enable_double_click=False)), False, False)
        #hbox.pack_start(self.__make_align(hseparator), True, True)
        self.pack_start(self.__make_align(Label(_("Device"), enable_select=False, enable_double_click=False), height=-1), False, False)
        self.pack_start(self.__make_align(hseparator, xalign=0.5, height=5), False, False)

        volume_max_percent = pypulse.MAX_VOLUME_VALUE * 100 / pypulse.NORMAL_VOLUME_VALUE

        table = gtk.Table(2, 3)
        speaker_img = ImageBox(app_theme.get_pixbuf("sound/speaker-3.png"))
        self.speaker_scale = HScalebar(show_value=False, format_value="%", value_min=0, value_max=volume_max_percent)
        self.speaker_scale.set_magnetic_values([(0, 5), (100, 5), (volume_max_percent, 5)])
        self.speaker_scale.set_size_request(90, 10)
        self.speaker_mute_button = SwitchButton(
            inactive_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
            active_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
        table.attach(self.__make_align(speaker_img), 0, 1, 0, 1, 4)
        table.attach(self.__make_align(self.speaker_scale, yalign=0.0, yscale=1.0, padding_left=5, padding_right=5, height=25), 1, 2, 0, 1, 4)
        table.attach(self.__make_align(self.speaker_mute_button), 2, 3, 0, 1, 4)

        #microphone_img = ImageBox(app_theme.get_pixbuf("sound/microphone.png"))
        #self.microphone_scale = HScalebar(show_value=False, format_value="%", value_min=0, value_max=volume_max_percent)
        #self.microphone_scale.set_size_request(90, 10)
        #self.microphone_mute_button = SwitchButton(
            #inactive_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"), 
            #active_disable_dpixbuf=app_theme.get_pixbuf("toggle_button/inactive_normal.png"))
        #table.attach(self.__make_align(microphone_img), 0, 1, 1, 2, 4)
        #table.attach(self.__make_align(self.microphone_scale, yalign=0.0, yscale=1.0, padding_left=5, padding_right=5, height=25), 1, 2, 1, 2, 4)
        #table.attach(self.__make_align(self.microphone_mute_button), 2, 3, 1, 2, 4)

        self.pack_start(table, False, False)

        self.__app_vbox = gtk.VBox(False)
        separator_color = [(0, ("#777777", 0.0)), (0.5, ("#000000", 0.3)), (1, ("#777777", 0.0))]
        hseparator = HSeparator(separator_color, 0, 0)
        hseparator.set_size_request(140, 5)
        self.__app_vbox.pack_start(self.__make_align(Label(_("Applications"), enable_select=False, enable_double_click=False)), False, False)
        self.__app_vbox.pack_start(self.__make_align(hseparator, xalign=0.5, height=5), False, False)

        self.__mpris_vbox = gtk.VBox(False)
        self.__app_vbox.pack_start(self.__mpris_vbox)
        self.pack_start(self.__app_vbox)

        hseparator = HSeparator(separator_color, 0, 0)
        hseparator.set_size_request(140, 7)
        self.pack_start(self.__make_align(hseparator, xalign=0.5, height=7), False, False)

        self.button_more = SelectButton(_("Advanced..."), font_size=10, ali_padding=5)
        self.button_more.set_size_request(-1, 25)
        self.pack_start(self.button_more, False, False)
        #self.pack_start(self.__make_align(height=10))
        ##########################################
        self.__set_output_status()
        #self.__set_input_status()

        # widget signals
        self.speaker_mute_button.connect("toggled", self.speaker_toggled)
        #self.microphone_mute_button.connect("toggled", self.microphone_toggled)
        self.speaker_scale.connect("value-changed", self.speaker_scale_value_changed)
        #self.microphone_scale.connect("value-changed", self.microphone_scale_value_changed)
        # pulseaudio signals
        pypulse.PULSE.connect("sink-changed", self.sink_changed_cb)
        #pypulse.PULSE.connect("source-changed", self.source_changed_cb)
        pypulse.PULSE.connect("server-changed", self.server_changed_cb)
        pypulse.PULSE.connect("sink-input-new", self.sink_input_new_cb)
        pypulse.PULSE.connect("sink-input-changed", self.sink_input_changed_cb)
        pypulse.PULSE.connect("sink-input-removed", self.sink_input_removed_cb)
        playback_streams = pypulse.PULSE.get_playback_streams()
        self.stream_num = len(playback_streams.keys())
        self.mpris2.get_mpris_list()
        self.mpris_num = len(self.mpris2.mpris_process.keys())
        if self.stream_num == 0 and self.mpris_num == 0:
            self.__app_vbox.set_no_show_all(True)
        for stream in playback_streams:
            self.__make_playback_box(playback_streams[stream], stream)