Package dtk :: Package ui :: Module notebook

Source Code for Module dtk.ui.notebook

  1  #! /usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # Copyright (C) 2011 ~ 2012 Deepin, Inc. 
  5  #               2011 ~ 2012 Wang Yong 
  6  #  
  7  # Author:     Wang Yong <lazycat.manatee@gmail.com> 
  8  # Maintainer: Wang Yong <lazycat.manatee@gmail.com> 
  9  #  
 10  # This program is free software: you can redistribute it and/or modify 
 11  # it under the terms of the GNU General Public License as published by 
 12  # the Free Software Foundation, either version 3 of the License, or 
 13  # any later version. 
 14  #  
 15  # This program is distributed in the hope that it will be useful, 
 16  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 18  # GNU General Public License for more details. 
 19  #  
 20  # You should have received a copy of the GNU General Public License 
 21  # along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 22   
 23  from cache_pixbuf import CachePixbuf 
 24  from constant import DEFAULT_FONT_SIZE 
 25  from draw import draw_pixbuf, draw_text 
 26  from theme import ui_theme 
 27  from utils import get_content_size, propagate_expose 
 28  import gtk 
 29   
30 -class Notebook(gtk.EventBox):
31 ''' 32 Notebook. 33 34 @undocumented: calculate_tab_width 35 @undocumented: expose_notebook 36 ''' 37
38 - def __init__(self, 39 items, 40 foreground_left_pixbuf = ui_theme.get_pixbuf("notebook/foreground_left.png"), 41 foreground_middle_pixbuf = ui_theme.get_pixbuf("notebook/foreground_middle.png"), 42 foreground_right_pixbuf = ui_theme.get_pixbuf("notebook/foreground_right.png"), 43 background_left_pixbuf = ui_theme.get_pixbuf("notebook/background_left.png"), 44 background_middle_pixbuf = ui_theme.get_pixbuf("notebook/background_middle.png"), 45 background_right_pixbuf = ui_theme.get_pixbuf("notebook/background_right.png"), 46 ):
47 ''' 48 Initialize Notebook class. 49 50 @param items: Notebook item, foramt (item_icon, item_content, item_callback). 51 @param foreground_left_pixbuf: Left foreground pixbuf. 52 @param foreground_middle_pixbuf: Middle foreground pixbuf. 53 @param foreground_right_pixbuf: Right foreground pixbuf. 54 @param background_left_pixbuf: Left background pixbuf. 55 @param background_middle_pixbuf: Middle background pixbuf. 56 @param background_right_pixbuf: Right background pixbuf. 57 ''' 58 # Init. 59 gtk.EventBox.__init__(self) 60 self.set_visible_window(False) 61 self.set_can_focus(True) 62 self.add_events(gtk.gdk.ALL_EVENTS_MASK) 63 64 self.items = items 65 self.current_item_index = 0 66 self.padding_side = 27 # pixel 67 self.padding_middle = 10 # pixel 68 self.foreground_left_pixbuf = foreground_left_pixbuf 69 self.foreground_middle_pixbuf = foreground_middle_pixbuf 70 self.foreground_right_pixbuf = foreground_right_pixbuf 71 self.background_left_pixbuf = background_left_pixbuf 72 self.background_middle_pixbuf = background_middle_pixbuf 73 self.background_right_pixbuf = background_right_pixbuf 74 self.cache_bg_pixbuf = CachePixbuf() 75 self.cache_fg_pixbuf = CachePixbuf() 76 77 # Calcuate tab width. 78 (self.tab_width, self.tab_height) = self.calculate_tab_width() 79 self.set_size_request(-1, self.tab_height) 80 81 # Expose. 82 self.connect("expose-event", self.expose_notebook) 83 self.connect("button-press-event", self.button_press_notebook)
84
85 - def calculate_tab_width(self):
86 ''' 87 Internal function to calculate tab width. 88 ''' 89 self.icon_width = 0 90 max_tab_content_width = 0 91 for (item_icon, item_content, item_callback) in self.items: 92 if self.icon_width == 0 and item_icon != None: 93 self.icon_width = item_icon.get_pixbuf().get_width() 94 95 (content_width, content_height) = get_content_size(item_content, DEFAULT_FONT_SIZE) 96 if content_width > max_tab_content_width: 97 max_tab_content_width = content_width 98 99 tab_image_height = self.foreground_left_pixbuf.get_pixbuf().get_height() 100 101 if self.icon_width == 0: 102 tab_width = self.padding_side * 2 + max_tab_content_width 103 else: 104 tab_width = self.padding_side * 2 + self.padding_middle + self.icon_width + max_tab_content_width 105 106 return (tab_width, tab_image_height)
107
108 - def expose_notebook(self, widget, event):
109 ''' 110 Internal callback for `expose-event` signal. 111 112 @param widget: Notebook wiget. 113 @param event: Expose event. 114 ''' 115 # Init. 116 cr = widget.window.cairo_create() 117 rect = widget.allocation 118 foreground_left_pixbuf = self.foreground_left_pixbuf.get_pixbuf() 119 self.cache_fg_pixbuf.scale(self.foreground_middle_pixbuf.get_pixbuf(), 120 self.tab_width - foreground_left_pixbuf.get_width() * 2, 121 self.tab_height) 122 foreground_middle_pixbuf = self.cache_fg_pixbuf.get_cache() 123 foreground_right_pixbuf = self.foreground_right_pixbuf.get_pixbuf() 124 background_left_pixbuf = self.background_left_pixbuf.get_pixbuf() 125 self.cache_bg_pixbuf.scale(self.background_middle_pixbuf.get_pixbuf(), 126 self.tab_width - background_left_pixbuf.get_width() * 2, 127 self.tab_height) 128 background_middle_pixbuf = self.cache_bg_pixbuf.get_cache() 129 background_right_pixbuf = self.background_right_pixbuf.get_pixbuf() 130 131 # Draw tab. 132 for (index, (item_icon, item_content, item_callback)) in enumerate(self.items): 133 # Draw background. 134 if self.current_item_index == index: 135 draw_pixbuf(cr, 136 foreground_left_pixbuf, 137 rect.x + index * self.tab_width, 138 rect.y) 139 draw_pixbuf(cr, 140 foreground_middle_pixbuf, 141 rect.x + index * self.tab_width + foreground_left_pixbuf.get_width(), 142 rect.y) 143 draw_pixbuf(cr, 144 foreground_right_pixbuf, 145 rect.x + (index + 1) * self.tab_width - foreground_left_pixbuf.get_width(), 146 rect.y) 147 else: 148 draw_pixbuf(cr, 149 background_left_pixbuf, 150 rect.x + index * self.tab_width, 151 rect.y) 152 draw_pixbuf(cr, 153 background_middle_pixbuf, 154 rect.x + index * self.tab_width + background_left_pixbuf.get_width(), 155 rect.y) 156 draw_pixbuf(cr, 157 background_right_pixbuf, 158 rect.x + (index + 1) * self.tab_width - background_left_pixbuf.get_width(), 159 rect.y) 160 161 # Draw content. 162 (content_width, content_height) = get_content_size(item_content, DEFAULT_FONT_SIZE) 163 if item_icon != None: 164 tab_render_width = self.icon_width + self.padding_middle + content_width 165 draw_pixbuf(cr, 166 item_icon.get_pixbuf(), 167 rect.x + index * self.tab_width + (self.tab_width - tab_render_width) / 2, 168 rect.y + (self.tab_height - item_icon.get_pixbuf().get_height()) / 2) 169 170 draw_text(cr, 171 item_content, 172 rect.x + index * self.tab_width + (self.tab_width - tab_render_width) / 2 + self.icon_width + self.padding_middle, 173 rect.y + (self.tab_height - content_height) / 2, 174 content_width, 175 content_height, 176 DEFAULT_FONT_SIZE, 177 ui_theme.get_color("notebook_font").get_color(), 178 ) 179 else: 180 tab_render_width = content_width 181 draw_text(cr, 182 item_content, 183 rect.x + index * self.tab_width + (self.tab_width - tab_render_width) / 2 + self.icon_width + self.padding_middle, 184 rect.y + (self.tab_height - content_height) / 2, 185 content_width, 186 content_height, 187 DEFAULT_FONT_SIZE, 188 ui_theme.get_color("notebook_font").get_color(), 189 ) 190 191 propagate_expose(widget, event) 192 193 return True
194
195 - def button_press_notebook(self, widget, event):
196 ''' 197 Internal callback for `button-press-event` signal. 198 199 @param widget: Notebook widget. 200 @param event: Button press event. 201 ''' 202 # Get tab index. 203 tab_index = int(event.x / self.tab_width) 204 if tab_index < len(self.items): 205 self.current_item_index = tab_index 206 207 # Redraw. 208 self.queue_draw() 209 210 # Callback. 211 if self.items[tab_index][2] != None: 212 self.items[tab_index][2]()
213