Package dtk :: Package ui :: Module combo

Source Code for Module dtk.ui.combo

  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 button import DisableButton 
 24  from droplist import Droplist 
 25  from keymap import get_keyevent_name 
 26  from label import Label 
 27  from theme import ui_theme 
 28  import gobject 
 29  import gtk 
 30  from utils import (propagate_expose, cairo_disable_antialias,  
 31                     color_hex_to_cairo, get_widget_root_coordinate,  
 32                     WIDGET_POS_BOTTOM_LEFT, alpha_color_hex_to_cairo) 
 33   
34 -class ComboBox(gtk.VBox):
35 ''' 36 ComboBox class. 37 38 @undocumented: focus_in_combo 39 @undocumented: focus_out_combo 40 @undocumented: click_drop_button 41 @undocumented: key_press_combo 42 @undocumented: key_release_combo 43 @undocumented: update_select_content 44 @undocumented: set_sensitive 45 @undocumented: expose_combobox_frame 46 ''' 47 48 __gsignals__ = { 49 "item-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)), 50 "key-release" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)), 51 } 52
53 - def __init__(self, 54 items, 55 droplist_height=None, 56 select_index=0, 57 max_width=None):
58 ''' 59 Initialize ComboBox class. 60 61 @param items: ComboBox item, item format: (item_label, item_value) 62 @param droplist_height: You can set maximum height of droplist, default is None. 63 @param select_index: Initialize selected index, default is 0. 64 @param max_width: Maximum width of ComboBox, default is None that width along with content. 65 ''' 66 # Init. 67 gtk.VBox.__init__(self) 68 self.set_can_focus(True) 69 self.items = items 70 self.droplist_height = droplist_height 71 self.select_index = select_index 72 self.focus_flag = False 73 74 self.droplist = Droplist(self.items, max_width=max_width) 75 if self.droplist_height: 76 self.droplist.set_size_request(-1, self.droplist_height) 77 self.width = self.droplist.get_droplist_width() 78 self.height = 22 79 self.label_padding_left = 6 80 self.box = gtk.HBox() 81 self.dropbutton_width = ui_theme.get_pixbuf("combo/dropbutton_normal.png").get_pixbuf().get_width() 82 self.label = Label(self.items[select_index][0], 83 label_width=self.width - self.dropbutton_width - 1 - self.label_padding_left, 84 enable_select=False, 85 enable_double_click=False) 86 self.label.text_color = ui_theme.get_color("menu_font") 87 self.dropbutton = DisableButton( 88 (ui_theme.get_pixbuf("combo/dropbutton_normal.png"), 89 ui_theme.get_pixbuf("combo/dropbutton_hover.png"), 90 ui_theme.get_pixbuf("combo/dropbutton_press.png"), 91 ui_theme.get_pixbuf("combo/dropbutton_disable.png")), 92 ) 93 94 self.align = gtk.Alignment() 95 self.align.set(0.5, 0.5, 0.0, 0.0) 96 self.align.set_padding(1, 1, 1 + self.label_padding_left, 1) 97 98 self.pack_start(self.align, False, False) 99 self.align.add(self.box) 100 self.box.pack_start(self.label, False, False) 101 self.box.pack_start(self.dropbutton, False, False) 102 103 self.align.connect("expose-event", self.expose_combobox_frame) 104 self.label.connect("button-press-event", self.click_drop_button) 105 self.dropbutton.connect("button-press-event", self.click_drop_button) 106 self.droplist.connect("item-selected", self.update_select_content) 107 self.droplist.connect("key-release", lambda dl, s, o, i: self.emit("key-release", s, o, i)) 108 self.connect("key-press-event", self.key_press_combo) 109 self.connect("key-release-event", self.key_release_combo) 110 self.connect("focus-in-event", self.focus_in_combo) 111 self.connect("focus-out-event", self.focus_out_combo) 112 113 self.keymap = { 114 "Home" : self.select_first_item, 115 "End" : self.select_last_item, 116 "Up" : self.select_prev_item, 117 "Down" : self.select_next_item}
118
119 - def focus_in_combo(self, widget, event):
120 ''' 121 Internal function, focus in ComboBox. 122 123 @param widget: Gtk.Widget instance. 124 @param event: Focus in event. 125 ''' 126 self.focus_flag = True 127 self.label.text_color = ui_theme.get_color("menu_select_font") 128 129 self.queue_draw()
130
131 - def focus_out_combo(self, widget, event):
132 ''' 133 Internal function, focus out ComboBox. 134 135 @param widget: Gtk.Widget instance. 136 @param event: Focus out event. 137 ''' 138 self.focus_flag = False 139 self.label.text_color = ui_theme.get_color("menu_font") 140 141 self.queue_draw()
142
143 - def click_drop_button(self, *args):
144 ''' 145 Internal function to handle `button-press-event` signal. 146 ''' 147 if self.droplist.get_visible(): 148 self.droplist.hide() 149 else: 150 (align_x, align_y) = get_widget_root_coordinate(self.align, WIDGET_POS_BOTTOM_LEFT) 151 self.droplist.show( 152 (align_x - 1, align_y - 1), 153 (0, -self.height + 1)) 154 155 self.droplist.item_select_index = self.select_index 156 self.droplist.active_item() 157 self.droplist.scroll_page_to_select_item() 158 159 self.queue_draw()
160
161 - def select_first_item(self):
162 ''' 163 Select first item. 164 ''' 165 if len(self.droplist.droplist_items) > 0: 166 first_index = self.droplist.get_first_index() 167 if first_index != None: 168 self.droplist.item_select_index = first_index 169 self.droplist.active_item() 170 self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action()
171
172 - def select_last_item(self):
173 ''' 174 Select last item. 175 ''' 176 if len(self.droplist.droplist_items) > 0: 177 last_index = self.droplist.get_last_index() 178 if last_index != None: 179 self.droplist.item_select_index = last_index 180 self.droplist.active_item() 181 self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action()
182
183 - def select_prev_item(self):
184 ''' 185 Select preview item. 186 ''' 187 if len(self.droplist.droplist_items) > 0: 188 prev_index = self.droplist.get_prev_index() 189 if prev_index != None: 190 self.droplist.item_select_index = prev_index 191 self.droplist.active_item() 192 self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action()
193
194 - def select_next_item(self):
195 ''' 196 Select next item. 197 ''' 198 if len(self.droplist.droplist_items) > 0: 199 next_index = self.droplist.get_next_index() 200 if next_index != None: 201 self.droplist.item_select_index = next_index 202 self.droplist.active_item() 203 self.droplist.droplist_items[self.droplist.item_select_index].wrap_droplist_clicked_action()
204
205 - def key_press_combo(self, widget, event):
206 ''' 207 Internal function to handle `key-press-event` signal. 208 209 @param widget: Gtk.Widget instance. 210 @param event: Key press event. 211 ''' 212 if not self.droplist.get_visible(): 213 key_name = get_keyevent_name(event) 214 if self.keymap.has_key(key_name): 215 self.keymap[key_name]() 216 217 return True
218
219 - def set_select_index(self, item_index):
220 ''' 221 Set select index. 222 223 @param item_index: The index of selected item. 224 ''' 225 if 0 <= item_index < len(self.items): 226 item = self.items[item_index] 227 if item: 228 self.select_index = item_index 229 self.label.set_text(item[0])
230
231 - def get_item_with_index(self, item_index):
232 ''' 233 Get item with given index. 234 235 @return: Return item that match given index, or return None if haven't special index. 236 ''' 237 if 0 <= item_index < len(self.items): 238 return self.items[item_index] 239 else: 240 return None
241
242 - def get_current_item(self):
243 ''' 244 Get current item. 245 246 @return: Return current item. 247 ''' 248 return self.get_item_with_index(self.select_index)
249
250 - def key_release_combo(self, widget, event):
251 ''' 252 Internal function to handle `key-release-event` signal. 253 254 @param widget: Gtk.Widget instance. 255 @param event: Key release event. 256 ''' 257 self.emit("key-release", 258 self.items[self.select_index][0], 259 self.items[self.select_index][1], 260 self.select_index)
261
262 - def update_select_content(self, droplist, item_content, item_value, item_index):
263 ''' 264 Internal function to update select content. 265 266 @param droplist: Droplist. 267 @param item_content: Item content. 268 @param item_value: Item value. 269 @param item_index: Item index. 270 ''' 271 self.select_index = item_index 272 self.label.set_text(item_content) 273 274 self.emit("item-selected", item_content, item_value, item_index) 275 276 self.grab_focus() 277 278 self.queue_draw()
279
280 - def set_sensitive(self, sensitive):
281 ''' 282 Internal function to overwrite function `set_sensitive`. 283 ''' 284 super(ComboBox, self).set_sensitive(sensitive) 285 self.label.set_sensitive(sensitive) 286 self.dropbutton.set_sensitive(sensitive)
287
288 - def expose_combobox_frame(self, widget, event):
289 ''' 290 Internal function to handle `expose-event` signal of frame. 291 ''' 292 # Init. 293 cr = widget.window.cairo_create() 294 rect = widget.allocation 295 296 # Draw frame. 297 with cairo_disable_antialias(cr): 298 cr.set_line_width(1) 299 if self.get_sensitive(): 300 cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("combo_entry_frame").get_color())) 301 else: 302 cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("disable_frame").get_color())) 303 cr.rectangle(rect.x, rect.y, rect.width, rect.height) 304 cr.stroke() 305 306 if self.focus_flag: 307 cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_select_background").get_color(), 0.9))) 308 cr.rectangle(rect.x, rect.y, rect.width - 1 - self.dropbutton_width, rect.height - 1) 309 cr.fill() 310 311 cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9))) 312 cr.rectangle(rect.x + rect.width - 1 - self.dropbutton_width, rect.y, self.dropbutton_width, rect.height - 1) 313 cr.fill() 314 else: 315 cr.set_source_rgba(*alpha_color_hex_to_cairo((ui_theme.get_color("combo_entry_background").get_color(), 0.9))) 316 cr.rectangle(rect.x, rect.y, rect.width - 1, rect.height - 1) 317 cr.fill() 318 319 # Propagate expose to children. 320 propagate_expose(widget, event) 321 322 return True
323 324 gobject.type_register(ComboBox) 325