예제 #1
0
파일: menu.py 프로젝트: masums/deepin-ui
 def create_separator_item(self):
     '''
     Internal function to create separator item.
     '''
     self.item_box = HSeparator(
         ui_theme.get_shadow_color("h_separator").get_color_info(),
         self.item_padding_x, self.item_padding_y)
     self.item_box_height = self.item_padding_y * 2 + 1
예제 #2
0
 def create_separator_item(self):
     '''Create separator item.'''
     self.item_box = HSeparator(
         ui_theme.get_shadow_color("h_separator").get_color_info(),
         self.item_padding_left, 
         self.item_padding_y)
     self.item_box_height = self.item_padding_y * 2 + 1
예제 #3
0
파일: menu.py 프로젝트: web3d/deepin-ui
 def create_separator_item(self):
     """
     Internal function to create separator item.
     """
     self.item_box = HSeparator(
         ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_x, self.item_padding_y
     )
     self.item_box_height = self.item_padding_y * 2 + 1
예제 #4
0
class DroplistItem(object):
    '''Droplist item.'''
    
    def __init__(self, droplist, index, item, font_size, 
                 droplist_padding_x, droplist_padding_y,
                 item_padding_left, item_padding_right, item_padding_y, max_width):
        '''Init droplist item.'''
        # Init.
        self.droplist = droplist
        self.index = index
        self.item = item
        self.font_size = font_size
        self.droplist_padding_x = droplist_padding_x
        self.droplist_padding_y = droplist_padding_y
        self.item_padding_left = item_padding_left
        self.item_padding_right = item_padding_right
        self.item_padding_y = item_padding_y
        self.subdroplist_active = False
        self.max_width = max_width
        self.arrow_padding_x = 5

        # Create.
        if self.item:
            self.create_droplist_item()
        else:
            self.create_separator_item()
        
    def create_separator_item(self):
        '''Create separator item.'''
        self.item_box = HSeparator(
            ui_theme.get_shadow_color("h_separator").get_color_info(),
            self.item_padding_left, 
            self.item_padding_y)
        self.item_box_height = self.item_padding_y * 2 + 1
        
    def create_droplist_item(self):
        '''Create droplist item.'''
        # Get item information.
        (item_content, item_value) = self.item[0:2]
        
        # Create button.
        self.item_box = gtk.Button()
        
        # Expose button.
        self.item_box.connect(
            "expose-event", 
            lambda w, e: self.expose_droplist_item(
                w, e, item_content))
        
        # Wrap droplist aciton.
        self.item_box.connect("button-press-event", lambda w, e: self.wrap_droplist_clicked_action())        
        
        self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content))
        
    def realize_item_box(self, widget, item_content):
        '''Realize item box.'''
        # Set button size.
        (width, height) = get_content_size(item_content, self.font_size)
        self.item_box_height = self.item_padding_y * 2 + int(height)
        self.item_box_width = self.item_padding_left + self.item_padding_right + int(width)

        if self.max_width != None:
            self.item_box_width = min(self.item_box_width, self.max_width)        
        else:
            self.item_box_width = self.item_box_width        
            
        self.item_box.set_size_request(self.item_box_width, self.item_box_height)        
        
    def wrap_droplist_clicked_action(self):
        '''Wrap droplist action.'''
        # Emit item-selected signal.
        self.droplist.emit("item-selected", self.item[0], self.item[1], self.index)
            
        # Hide droplist.
        droplist_grab_window_focus_out()
            
    def expose_droplist_item(self, widget, event, item_content):
        '''Expose droplist item.'''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        font_color = ui_theme.get_color("menu_font").get_color()
        
        # Draw select effect.
        if self.subdroplist_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
            # Draw background.
            draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, 
                         ui_theme.get_shadow_color("menu_item_select").get_color_info())
            
            # Set font color.
            font_color = ui_theme.get_color("menu_select_font").get_color()
            
        # Draw item content.
        draw_text(cr, item_content, 
                    rect.x + self.item_padding_left,
                    rect.y,
                    rect.width,
                    rect.height,
                    self.font_size, font_color,
                    )
        
        # Propagate expose to children.
        propagate_expose(widget, event)
    
        return True
예제 #5
0
class DroplistItem(object):
    '''
    DroplistItem for L{ I{Droplist} <Droplist>}.

    @undocumented: create_separator_item
    @undocumented: create_droplist_item
    @undocumented: realize_item_box
    @undocumented: wrap_droplist_clicked_action
    @undocumented: expose_droplist_item
    '''

    def __init__(self,
                 droplist,
                 index,
                 item,
                 font_size,
                 droplist_padding_x,
                 droplist_padding_y,
                 item_padding_left,
                 item_padding_right,
                 item_padding_y,
                 max_width,
                 fixed_width):
        '''
        Initialize DroplistItem class.

        @param droplist: Droplist.
        @param index: Drop item index.
        @param item: Drop item, format (item_content, item_value)
        @param font_size: Drop item font size.
        @param droplist_padding_x: Padding x of droplist.
        @param droplist_padding_y: Padding y of droplist.
        @param item_padding_left: Padding at left of item.
        @param item_padding_right: Padding at right of item.
        @param item_padding_y: Padding at top or bottom of item.
        @param max_width: Maximum width of droplist item.
        @param fixed_width: Fxied width of droplist item.
        '''
        # Init.
        self.droplist = droplist
        self.index = index
        self.item = item
        self.font_size = font_size
        self.droplist_padding_x = droplist_padding_x
        self.droplist_padding_y = droplist_padding_y
        self.item_padding_left = item_padding_left
        self.item_padding_right = item_padding_right
        self.item_padding_y = item_padding_y
        self.subdroplist_active = False
        self.max_width = max_width
        self.fixed_width = fixed_width
        self.arrow_padding_x = 5

        # Create.
        if self.item:
            self.create_droplist_item()
        else:
            self.create_separator_item()

    def create_separator_item(self):
        '''
        Internal function, create separator item.
        '''
        self.item_box = HSeparator(
            ui_theme.get_shadow_color("h_separator").get_color_info(),
            self.item_padding_left,
            self.item_padding_y)
        self.item_box_height = self.item_padding_y * 2 + 1

    def create_droplist_item(self):
        '''
        Internal function, create droplist item.
        '''
        # Get item information.
        (item_content, item_value) = self.item[0:2]

        # Create button.
        self.item_box = gtk.Button()

        # Expose button.
        self.item_box.connect(
            "expose-event",
            lambda w, e: self.expose_droplist_item(
                w, e, item_content))

        # Wrap droplist aciton.
        self.item_box.connect("button-press-event", lambda w, e: self.wrap_droplist_clicked_action())

        self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content))

    def realize_item_box(self, widget, item_content):
        '''
        Internal function, realize item box.

        @param widget: DropItem widget.
        @param item_content: Item content.
        '''
        # Set button size.
        (width, height) = get_content_size(item_content, self.font_size)
        self.item_box_height = self.item_padding_y * 2 + int(height)
        self.item_box_width = self.item_padding_left + self.item_padding_right + int(width)

        if self.fixed_width != None:
            self.item_box_width = self.fixed_width
        elif self.max_width != None:
            '''
            when max_width > item_box_width, it might choosing the max one
            '''
            self.item_box_width = max(self.item_box_width, self.max_width)
        else:
            self.item_box_width = self.item_box_width

        self.item_box.set_size_request(self.item_box_width, self.item_box_height)

    def wrap_droplist_clicked_action(self):
        '''
        Internal function to wrap clicked action.
        '''
        # Hide droplist.
        droplist_grab_window_focus_out()

        # Emit item-selected signal.
        self.droplist.emit("item-selected", self.item[0], self.item[1], self.index)

    def expose_droplist_item(self, widget, event, item_content):
        '''
        Internal function to handle `expose-event` signal of item.

        @param widget: DropItem widget.
        @param event: Expose event.
        @param item_content: Item content.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        font_color = ui_theme.get_color("menu_font").get_color()

        # Draw select effect.
        if self.subdroplist_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
            # Draw background.
            draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height,
                         ui_theme.get_shadow_color("menu_item_select").get_color_info())

            # Set font color.
            font_color = ui_theme.get_color("menu_select_font").get_color()

        # Draw item content.
        draw_text(cr, item_content,
                    rect.x + self.item_padding_left,
                    rect.y,
                    rect.width,
                    rect.height,
                    self.font_size, font_color,
                    )

        # Propagate expose to children.
        propagate_expose(widget, event)

        return True
예제 #6
0
파일: menu.py 프로젝트: netphi/deepin-ui
class MenuItem(object):
    '''Menu item.'''
    
    def __init__(self, item, font_size, 
                 select_scale,
                 show_submenu_callback, 
                 hide_submenu_callback,
                 get_root_menu_callback,
                 get_menu_items_callback,
                 icon_width, icon_height, 
                 have_submenu, submenu_width, submenu_height,
                 menu_padding_x, menu_padding_y,
                 item_padding_x, item_padding_y, min_width):
        '''Init menu item.'''
        # Init.
        self.item = item
        self.font_size = font_size
        self.select_scale = select_scale
        self.menu_padding_x = menu_padding_x
        self.menu_padding_y = menu_padding_y
        self.item_padding_x = item_padding_x
        self.item_padding_y = item_padding_y
        self.show_submenu_callback = show_submenu_callback
        self.hide_submenu_callback = hide_submenu_callback
        self.get_root_menu_callback = get_root_menu_callback
        self.get_menu_items_callback = get_menu_items_callback
        self.icon_width = icon_width
        self.icon_height = icon_height
        self.have_submenu = have_submenu
        self.submenu_width = submenu_width
        self.submenu_height = submenu_height
        self.submenu_active = False
        self.min_width = min_width
        self.arrow_padding_x = 5

        # Create.
        if self.item:
            self.create_menu_item()
        else:
            self.create_separator_item()
        
    def create_separator_item(self):
        '''Create separator item.'''
        self.item_box = HSeparator(
            ui_theme.get_shadow_color("h_separator").get_color_info(),
            self.item_padding_x, 
            self.item_padding_y)
        self.item_box_height = self.item_padding_y * 2 + 1
        
    def create_menu_item(self):
        '''Create menu item.'''
        # Get item information.
        (item_icons, item_content, item_node) = self.item[0:3]
        
        # Create button.
        self.item_box = gtk.Button()
        
        # Expose button.
        self.item_box.connect("expose-event", self.expose_menu_item)
        self.item_box.connect("enter-notify-event", lambda w, e: self.enter_notify_menu_item(w))
        
        # Wrap menu aciton.
        self.item_box.connect("button-press-event", self.wrap_menu_clicked_action)        
        
        self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content))
        
    def realize_item_box(self, widget, item_content):
        '''Realize item box.'''
        # Set button size.
        (width, height) = get_content_size(item_content, self.font_size)
        self.item_box_height = self.item_padding_y * 2 + max(int(height), self.icon_height)
        if self.select_scale:
            self.item_box_width = widget.get_parent().get_parent().allocation.width
        else:
            self.item_box_width = self.item_padding_x * 3 + self.icon_width + int(width)

            if self.have_submenu:
                self.item_box_width += self.item_padding_x + self.submenu_width + self.arrow_padding_x * 2
                
        self.item_box_width = max(self.item_box_width, self.min_width)        
                
        self.item_box.set_size_request(self.item_box_width, self.item_box_height)        
        
    def wrap_menu_clicked_action(self, button, event):
        '''Wrap menu action.'''
        item_node = self.item[2]
        if not isinstance(item_node, Menu):
            # Hide menu.
            menu_grab_window_focus_out()
            
            # Execute callback.
            if item_node:
                if len(self.item) > 3:
                    item_node(*self.item[3:])
                else:
                    item_node()
            
    def expose_menu_item(self, widget, event):
        '''Expose menu item.'''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        font_color = ui_theme.get_color("menu_font").get_color()
        (item_icons, item_content, item_node) = self.item[0:3]
        
        # Draw select effect.
        if self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
            # Draw background.
            draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, 
                         ui_theme.get_shadow_color("menu_item_select").get_color_info(),
                         MENU_ITEM_RADIUS)
            
            # Set font color.
            font_color = ui_theme.get_color("menu_select_font").get_color()
            
        # Draw item icon.
        pixbuf = None
        pixbuf_width = 0
        if item_icons:
            (item_normal_dpixbuf, item_hover_dpixbuf) = item_icons
            if self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
                if item_hover_dpixbuf == None:
                    pixbuf = item_normal_dpixbuf.get_pixbuf()
                else:
                    pixbuf = item_hover_dpixbuf.get_pixbuf()
            else:
                pixbuf = item_normal_dpixbuf.get_pixbuf()
            pixbuf_width += pixbuf.get_width()
            draw_pixbuf(cr, pixbuf, rect.x + self.item_padding_x, rect.y + (rect.height - pixbuf.get_height()) / 2)
            
        # Draw item content.
        draw_text(cr, item_content, 
                    rect.x + self.item_padding_x * 2 + self.icon_width,
                    rect.y,
                    rect.width,
                    rect.height,
                    self.font_size, font_color,
                    )
        
        # Draw submenu arrow.
        if isinstance(item_node, Menu):
            if self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
                submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_hover.png").get_pixbuf()
            else:
                submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_normal.png").get_pixbuf()
            draw_pixbuf(cr, submenu_pixbuf,
                        rect.x + rect.width - self.item_padding_x - submenu_pixbuf.get_width() - self.arrow_padding_x,
                        rect.y + (rect.height - submenu_pixbuf.get_height()) / 2)
        
        # Propagate expose to children.
        propagate_expose(widget, event)
    
        return True

    def enter_notify_menu_item(self, widget):
        '''Callback for `enter-notify-event` signal.'''
        # Reset all items in same menu.
        for menu_item in self.get_menu_items_callback():
            if menu_item != self and menu_item.submenu_active:
                menu_item.submenu_active = False
                menu_item.item_box.queue_draw()
        
        (item_icons, item_content, item_node) = self.item[0:3]
        if isinstance(item_node, Menu):
            menu_window = self.item_box.get_toplevel()
            (menu_window_x, menu_window_y) = get_widget_root_coordinate(menu_window, WIDGET_POS_RIGHT_CENTER)
            (item_x, item_y) = get_widget_root_coordinate(self.item_box)
            self.show_submenu_callback(
                item_node, 
                (menu_window_x - menu_window.shadow_radius, 
                 item_y - widget.get_allocation().height - menu_window.shadow_radius),
                self.item_box.allocation.height + menu_window.shadow_radius)
            
            self.submenu_active = True
        else:
            self.hide_submenu_callback()
예제 #7
0
파일: menu.py 프로젝트: web3d/deepin-ui
class MenuItem(object):
    """
    Menu item for L{ I{Menu} <Menu>}.

    @undocumented: create_separator_item
    @undocumented: create_menu_item
    @undocumented: realize_item_box
    @undocumented: wrap_menu_clicked_action
    @undocumented: expose_menu_item
    @undocumented: enter_notify_menu_item
    """

    def __init__(
        self,
        item,
        font_size,
        select_scale,
        show_submenu_callback,
        hide_submenu_callback,
        get_root_menu_callback,
        get_menu_items_callback,
        icon_width,
        icon_height,
        have_submenu,
        submenu_width,
        submenu_height,
        menu_padding_x,
        menu_padding_y,
        item_padding_x,
        item_padding_y,
        min_width,
        menu_item_select_color=None,
    ):
        """
        Initialize MenuItem class.

        @param item: item format: ((item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf), item_name, item_node).
        @param font_size: Menu font size.
        @param select_scale: Default is False, it will use parant's width if it set True.
        @param show_submenu_callback: Callback when show submenus.
        @param hide_submenu_callback: Callback when hide submenus.
        @param get_root_menu_callback: Callback to get root menu.
        @param get_menu_items_callback: Callback to get menu items.
        @param icon_width: Icon width.
        @param icon_height: Icon height.
        @param have_submenu: Whether have submenu.
        @param submenu_width: Width of submenu.
        @param submenu_height: Height of submenu.
        @param menu_padding_x: Horizontal padding of menu.
        @param menu_padding_y: Vertical padding of menu.
        @param item_padding_x: Horizontal padding of item.
        @param item_padding_y: Vertical padding of item.
        @param min_width: Minimum width.
        """
        # Init.
        self.item = item
        self.font_size = font_size
        self.select_scale = select_scale
        self.menu_padding_x = menu_padding_x
        self.menu_padding_y = menu_padding_y
        self.item_padding_x = item_padding_x
        self.item_padding_y = item_padding_y
        self.show_submenu_callback = show_submenu_callback
        self.hide_submenu_callback = hide_submenu_callback
        self.get_root_menu_callback = get_root_menu_callback
        self.get_menu_items_callback = get_menu_items_callback
        self.icon_width = icon_width
        self.icon_height = icon_height
        self.have_submenu = have_submenu
        self.submenu_width = submenu_width
        self.submenu_height = submenu_height
        self.submenu_active = False
        self.min_width = min_width
        self.arrow_padding_x = 5
        self.menu_item_select_color = menu_item_select_color

        # Create.
        if self.item:
            self.create_menu_item()
        else:
            self.create_separator_item()

    def set_item_icons(self, icons):
        # deepin media player modify icons.
        if self.item:
            (item_icons, item_content, item_node) = self.item[0:3]
            item_icons = icons
            if len(self.item) > 3:
                self.item = (item_icons, item_content, item_node, self.item[-1])
            else:
                self.item = (item_icons, item_content, item_node)

    def create_separator_item(self):
        """
        Internal function to create separator item.
        """
        self.item_box = HSeparator(
            ui_theme.get_shadow_color("h_separator").get_color_info(), self.item_padding_x, self.item_padding_y
        )
        self.item_box_height = self.item_padding_y * 2 + 1

    def create_menu_item(self):
        """
        Internal function to create menu item.
        """
        # Get item information.
        (item_icons, item_content, item_node) = self.item[0:3]

        # Create button.
        self.item_box = gtk.Button()

        # Expose button.
        self.item_box.connect("expose-event", self.expose_menu_item)
        self.item_box.connect("enter-notify-event", lambda w, e: self.enter_notify_menu_item(w))

        # Wrap menu aciton.
        self.item_box.connect("button-press-event", self.wrap_menu_clicked_action)

        self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content))

    def realize_item_box(self, widget, item_content):
        """
        Internal callback for `realize` signal.
        """
        # Set button size.
        (width, height) = get_content_size(item_content, self.font_size)
        self.item_box_height = self.item_padding_y * 2 + max(int(height), self.icon_height)
        if self.select_scale:
            self.item_box_width = widget.get_parent().get_parent().allocation.width
        else:
            self.item_box_width = self.item_padding_x * 3 + self.icon_width + int(width)

            if self.have_submenu:
                self.item_box_width += self.item_padding_x + self.submenu_width + self.arrow_padding_x * 2

        self.item_box_width = max(self.item_box_width, self.min_width)

        self.item_box.set_size_request(self.item_box_width, self.item_box_height)

    def wrap_menu_clicked_action(self, button, event):
        """
        Internal function to wrap clicked menu action.
        """
        item_node = self.item[2]
        if not isinstance(item_node, Menu):
            # Hide menu.
            menu_grab_window_focus_out()

            # Execute callback.
            if item_node:
                if len(self.item) > 3:
                    item_node(*self.item[3:])
                else:
                    item_node()

    def expose_menu_item(self, widget, event):
        """
        Internal callback for `expose` signal.
        """
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        font_color = ui_theme.get_color("menu_font").get_color()
        (item_icons, item_content, item_node) = self.item[0:3]

        # Draw select effect.
        if widget.state == gtk.STATE_INSENSITIVE:
            # Set font color.
            font_color = ui_theme.get_color("menu_disable_font").get_color()
        elif self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
            # Draw background.
            if self.menu_item_select_color:
                item_select_color = self.menu_item_select_color
            else:
                item_select_color = ui_theme.get_shadow_color("menu_item_select").get_color_info()
            draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height, item_select_color, MENU_ITEM_RADIUS)

            # Set font color.
            font_color = ui_theme.get_color("menu_select_font").get_color()

        # Draw item icon.
        pixbuf = None
        pixbuf_width = 0
        if item_icons:
            (item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf) = item_icons
            if widget.state == gtk.STATE_INSENSITIVE:
                pixbuf = item_disable_dpixbuf.get_pixbuf()
            elif self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
                if item_hover_dpixbuf == None:
                    pixbuf = item_normal_dpixbuf.get_pixbuf()
                else:
                    pixbuf = item_hover_dpixbuf.get_pixbuf()
            else:
                pixbuf = item_normal_dpixbuf.get_pixbuf()
            pixbuf_width += pixbuf.get_width()
            draw_pixbuf(cr, pixbuf, rect.x + self.item_padding_x, rect.y + (rect.height - pixbuf.get_height()) / 2)

        # Draw item content.
        draw_text(
            cr,
            item_content,
            rect.x + self.item_padding_x * 2 + self.icon_width,
            rect.y,
            rect.width,
            rect.height,
            self.font_size,
            font_color,
        )

        # Draw submenu arrow.
        if isinstance(item_node, Menu):
            if widget.state == gtk.STATE_INSENSITIVE:
                submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_disable.png").get_pixbuf()
            elif self.submenu_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
                submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_hover.png").get_pixbuf()
            else:
                submenu_pixbuf = ui_theme.get_pixbuf("menu/arrow_normal.png").get_pixbuf()
            draw_pixbuf(
                cr,
                submenu_pixbuf,
                rect.x + rect.width - self.item_padding_x - submenu_pixbuf.get_width() - self.arrow_padding_x,
                rect.y + (rect.height - submenu_pixbuf.get_height()) / 2,
            )

        # Propagate expose to children.
        propagate_expose(widget, event)

        return True

    def enter_notify_menu_item(self, widget):
        """
        Internal callback for `enter-notify-event` signal.
        """
        # Reset all items in same menu.
        for menu_item in self.get_menu_items_callback():
            if menu_item != self and menu_item.submenu_active:
                menu_item.submenu_active = False
                menu_item.item_box.queue_draw()

        (item_icons, item_content, item_node) = self.item[0:3]
        if isinstance(item_node, Menu):
            if widget.state != gtk.STATE_INSENSITIVE:
                menu_window = self.item_box.get_toplevel()
                (menu_window_x, menu_window_y) = get_widget_root_coordinate(menu_window, WIDGET_POS_RIGHT_CENTER)
                (item_x, item_y) = get_widget_root_coordinate(self.item_box)
                self.show_submenu_callback(
                    item_node,
                    (
                        menu_window_x - menu_window.shadow_radius,
                        item_y - widget.get_allocation().height - menu_window.shadow_radius,
                    ),
                    self.item_box.allocation.height + menu_window.shadow_radius,
                )

                self.submenu_active = True
        else:
            self.hide_submenu_callback()
예제 #8
0
파일: menu.py 프로젝트: masums/deepin-ui
class MenuItem(object):
    '''
    Menu item for L{ I{Menu} <Menu>}.

    @undocumented: create_separator_item
    @undocumented: create_menu_item
    @undocumented: realize_item_box
    @undocumented: wrap_menu_clicked_action
    @undocumented: expose_menu_item
    @undocumented: enter_notify_menu_item
    '''
    def __init__(self,
                 item,
                 font_size,
                 select_scale,
                 show_submenu_callback,
                 hide_submenu_callback,
                 get_root_menu_callback,
                 get_menu_items_callback,
                 icon_width,
                 icon_height,
                 have_submenu,
                 submenu_width,
                 submenu_height,
                 menu_padding_x,
                 menu_padding_y,
                 item_padding_x,
                 item_padding_y,
                 min_width,
                 menu_item_select_color=None):
        '''
        Initialize MenuItem class.

        @param item: item format: ((item_normal_dpixbuf, item_hover_dpixbuf, item_disable_dpixbuf), item_name, item_node).
        @param font_size: Menu font size.
        @param select_scale: Default is False, it will use parant's width if it set True.
        @param show_submenu_callback: Callback when show submenus.
        @param hide_submenu_callback: Callback when hide submenus.
        @param get_root_menu_callback: Callback to get root menu.
        @param get_menu_items_callback: Callback to get menu items.
        @param icon_width: Icon width.
        @param icon_height: Icon height.
        @param have_submenu: Whether have submenu.
        @param submenu_width: Width of submenu.
        @param submenu_height: Height of submenu.
        @param menu_padding_x: Horizontal padding of menu.
        @param menu_padding_y: Vertical padding of menu.
        @param item_padding_x: Horizontal padding of item.
        @param item_padding_y: Vertical padding of item.
        @param min_width: Minimum width.
        '''
        # Init.
        self.item = item
        self.font_size = font_size
        self.select_scale = select_scale
        self.menu_padding_x = menu_padding_x
        self.menu_padding_y = menu_padding_y
        self.item_padding_x = item_padding_x
        self.item_padding_y = item_padding_y
        self.show_submenu_callback = show_submenu_callback
        self.hide_submenu_callback = hide_submenu_callback
        self.get_root_menu_callback = get_root_menu_callback
        self.get_menu_items_callback = get_menu_items_callback
        self.icon_width = icon_width
        self.icon_height = icon_height
        self.have_submenu = have_submenu
        self.submenu_width = submenu_width
        self.submenu_height = submenu_height
        self.submenu_active = False
        self.min_width = min_width
        self.arrow_padding_x = 5
        self.menu_item_select_color = menu_item_select_color

        # Create.
        if self.item:
            self.create_menu_item()
        else:
            self.create_separator_item()

    def set_item_icons(self, icons):
        # deepin media player modify icons.
        if self.item:
            (item_icons, item_content, item_node) = self.item[0:3]
            item_icons = icons
            if len(self.item) > 3:
                self.item = (item_icons, item_content, item_node,
                             self.item[-1])
            else:
                self.item = (item_icons, item_content, item_node)

    def create_separator_item(self):
        '''
        Internal function to create separator item.
        '''
        self.item_box = HSeparator(
            ui_theme.get_shadow_color("h_separator").get_color_info(),
            self.item_padding_x, self.item_padding_y)
        self.item_box_height = self.item_padding_y * 2 + 1

    def create_menu_item(self):
        '''
        Internal function to create menu item.
        '''
        # Get item information.
        (item_icons, item_content, item_node) = self.item[0:3]

        # Create button.
        self.item_box = gtk.Button()

        # Expose button.
        self.item_box.connect("expose-event", self.expose_menu_item)
        self.item_box.connect("enter-notify-event",
                              lambda w, e: self.enter_notify_menu_item(w))

        # Wrap menu aciton.
        self.item_box.connect("button-press-event",
                              self.wrap_menu_clicked_action)

        self.item_box.connect("realize",
                              lambda w: self.realize_item_box(w, item_content))

    def realize_item_box(self, widget, item_content):
        '''
        Internal callback for `realize` signal.
        '''
        # Set button size.
        (width, height) = get_content_size(item_content, self.font_size)
        self.item_box_height = self.item_padding_y * 2 + max(
            int(height), self.icon_height)
        if self.select_scale:
            self.item_box_width = widget.get_parent().get_parent(
            ).allocation.width
        else:
            self.item_box_width = self.item_padding_x * 3 + self.icon_width + int(
                width)

            if self.have_submenu:
                self.item_box_width += self.item_padding_x + self.submenu_width + self.arrow_padding_x * 2

        self.item_box_width = max(self.item_box_width, self.min_width)

        self.item_box.set_size_request(self.item_box_width,
                                       self.item_box_height)

    def wrap_menu_clicked_action(self, button, event):
        '''
        Internal function to wrap clicked menu action.
        '''
        item_node = self.item[2]
        if not isinstance(item_node, Menu):
            # Hide menu.
            menu_grab_window_focus_out()

            # Execute callback.
            if item_node:
                if len(self.item) > 3:
                    item_node(*self.item[3:])
                else:
                    item_node()

    def expose_menu_item(self, widget, event):
        '''
        Internal callback for `expose` signal.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        font_color = ui_theme.get_color("menu_font").get_color()
        (item_icons, item_content, item_node) = self.item[0:3]

        # Draw select effect.
        if widget.state == gtk.STATE_INSENSITIVE:
            # Set font color.
            font_color = ui_theme.get_color("menu_disable_font").get_color()
        elif self.submenu_active or widget.state in [
                gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE
        ]:
            # Draw background.
            if self.menu_item_select_color:
                item_select_color = self.menu_item_select_color
            else:
                item_select_color = ui_theme.get_shadow_color(
                    "menu_item_select").get_color_info()
            draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height,
                         item_select_color, MENU_ITEM_RADIUS)

            # Set font color.
            font_color = ui_theme.get_color("menu_select_font").get_color()

        # Draw item icon.
        pixbuf = None
        pixbuf_width = 0
        if item_icons:
            (item_normal_dpixbuf, item_hover_dpixbuf,
             item_disable_dpixbuf) = item_icons
            if widget.state == gtk.STATE_INSENSITIVE:
                pixbuf = item_disable_dpixbuf.get_pixbuf()
            elif self.submenu_active or widget.state in [
                    gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE
            ]:
                if item_hover_dpixbuf == None:
                    pixbuf = item_normal_dpixbuf.get_pixbuf()
                else:
                    pixbuf = item_hover_dpixbuf.get_pixbuf()
            else:
                pixbuf = item_normal_dpixbuf.get_pixbuf()
            pixbuf_width += pixbuf.get_width()
            draw_pixbuf(cr, pixbuf, rect.x + self.item_padding_x,
                        rect.y + (rect.height - pixbuf.get_height()) / 2)

        # Draw item content.
        draw_text(
            cr,
            item_content,
            rect.x + self.item_padding_x * 2 + self.icon_width,
            rect.y,
            rect.width,
            rect.height,
            self.font_size,
            font_color,
        )

        # Draw submenu arrow.
        if isinstance(item_node, Menu):
            if widget.state == gtk.STATE_INSENSITIVE:
                submenu_pixbuf = ui_theme.get_pixbuf(
                    "menu/arrow_disable.png").get_pixbuf()
            elif self.submenu_active or widget.state in [
                    gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE
            ]:
                submenu_pixbuf = ui_theme.get_pixbuf(
                    "menu/arrow_hover.png").get_pixbuf()
            else:
                submenu_pixbuf = ui_theme.get_pixbuf(
                    "menu/arrow_normal.png").get_pixbuf()
            draw_pixbuf(
                cr, submenu_pixbuf, rect.x + rect.width - self.item_padding_x -
                submenu_pixbuf.get_width() - self.arrow_padding_x,
                rect.y + (rect.height - submenu_pixbuf.get_height()) / 2)

        # Propagate expose to children.
        propagate_expose(widget, event)

        return True

    def enter_notify_menu_item(self, widget):
        '''
        Internal callback for `enter-notify-event` signal.
        '''
        # Reset all items in same menu.
        for menu_item in self.get_menu_items_callback():
            if menu_item != self and menu_item.submenu_active:
                menu_item.submenu_active = False
                menu_item.item_box.queue_draw()

        (item_icons, item_content, item_node) = self.item[0:3]
        if isinstance(item_node, Menu):
            if widget.state != gtk.STATE_INSENSITIVE:
                menu_window = self.item_box.get_toplevel()
                (menu_window_x, menu_window_y) = get_widget_root_coordinate(
                    menu_window, WIDGET_POS_RIGHT_CENTER)
                (item_x, item_y) = get_widget_root_coordinate(self.item_box)
                self.show_submenu_callback(
                    item_node, (menu_window_x - menu_window.shadow_radius,
                                item_y - widget.get_allocation().height -
                                menu_window.shadow_radius),
                    self.item_box.allocation.height +
                    menu_window.shadow_radius)

                self.submenu_active = True
        else:
            self.hide_submenu_callback()
예제 #9
0
class DroplistItem(object):
    '''
    DroplistItem for L{ I{Droplist} <Droplist>}.

    @undocumented: create_separator_item
    @undocumented: create_droplist_item
    @undocumented: realize_item_box
    @undocumented: wrap_droplist_clicked_action
    @undocumented: expose_droplist_item
    '''
    def __init__(self, droplist, index, item, font_size, droplist_padding_x,
                 droplist_padding_y, item_padding_left, item_padding_right,
                 item_padding_y, max_width, fixed_width):
        '''
        Initialize DroplistItem class.

        @param droplist: Droplist.
        @param index: Drop item index.
        @param item: Drop item, format (item_content, item_value)
        @param font_size: Drop item font size.
        @param droplist_padding_x: Padding x of droplist.
        @param droplist_padding_y: Padding y of droplist.
        @param item_padding_left: Padding at left of item.
        @param item_padding_right: Padding at right of item.
        @param item_padding_y: Padding at top or bottom of item.
        @param max_width: Maximum width of droplist item.
        @param fixed_width: Fxied width of droplist item.
        '''
        # Init.
        self.droplist = droplist
        self.index = index
        self.item = item
        self.font_size = font_size
        self.droplist_padding_x = droplist_padding_x
        self.droplist_padding_y = droplist_padding_y
        self.item_padding_left = item_padding_left
        self.item_padding_right = item_padding_right
        self.item_padding_y = item_padding_y
        self.subdroplist_active = False
        self.max_width = max_width
        self.fixed_width = fixed_width
        self.arrow_padding_x = 5

        # Create.
        if self.item:
            self.create_droplist_item()
        else:
            self.create_separator_item()

    def create_separator_item(self):
        '''
        Internal function, create separator item.
        '''
        self.item_box = HSeparator(
            ui_theme.get_shadow_color("h_separator").get_color_info(),
            self.item_padding_left, self.item_padding_y)
        self.item_box_height = self.item_padding_y * 2 + 1

    def create_droplist_item(self):
        '''
        Internal function, create droplist item.
        '''
        # Get item information.
        (item_content, item_value) = self.item[0:2]

        # Create button.
        self.item_box = gtk.Button()

        # Expose button.
        self.item_box.connect(
            "expose-event",
            lambda w, e: self.expose_droplist_item(w, e, item_content))

        # Wrap droplist aciton.
        self.item_box.connect("button-press-event",
                              lambda w, e: self.wrap_droplist_clicked_action())

        self.item_box.connect("realize",
                              lambda w: self.realize_item_box(w, item_content))

    def realize_item_box(self, widget, item_content):
        '''
        Internal function, realize item box.

        @param widget: DropItem widget.
        @param item_content: Item content.
        '''
        # Set button size.
        (width, height) = get_content_size(item_content, self.font_size)
        self.item_box_height = self.item_padding_y * 2 + int(height)
        self.item_box_width = self.item_padding_left + self.item_padding_right + int(
            width)

        if self.fixed_width != None:
            self.item_box_width = self.fixed_width
        elif self.max_width != None:
            '''
            when max_width > item_box_width, it might choosing the max one
            '''
            self.item_box_width = max(self.item_box_width, self.max_width)
        else:
            self.item_box_width = self.item_box_width

        self.item_box.set_size_request(self.item_box_width,
                                       self.item_box_height)

    def wrap_droplist_clicked_action(self):
        '''
        Internal function to wrap clicked action.
        '''
        # Hide droplist.
        droplist_grab_window_focus_out()

        # Emit item-selected signal.
        self.droplist.emit("item-selected", self.item[0], self.item[1],
                           self.index)

    def expose_droplist_item(self, widget, event, item_content):
        '''
        Internal function to handle `expose-event` signal of item.

        @param widget: DropItem widget.
        @param event: Expose event.
        @param item_content: Item content.
        '''
        # Init.
        cr = widget.window.cairo_create()
        rect = widget.allocation
        font_color = ui_theme.get_color("menu_font").get_color()

        # Draw select effect.
        if self.subdroplist_active or widget.state in [
                gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE
        ]:
            # Draw background.
            draw_vlinear(
                cr, rect.x, rect.y, rect.width, rect.height,
                ui_theme.get_shadow_color("menu_item_select").get_color_info())

            # Set font color.
            font_color = ui_theme.get_color("menu_select_font").get_color()

        # Draw item content.
        draw_text(
            cr,
            item_content,
            rect.x + self.item_padding_left,
            rect.y,
            rect.width,
            rect.height,
            self.font_size,
            font_color,
        )

        # Propagate expose to children.
        propagate_expose(widget, event)

        return True