Changeset 3268
- Timestamp:
- 07/31/08 15:40:50 (5 years ago)
- Location:
- branch/PacketManipulator/widgets
- Files:
-
- 2 modified
-
Expander.py (modified) (7 diffs)
-
PropertyGrid.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branch/PacketManipulator/widgets/Expander.py
r3261 r3268 19 19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 20 21 21 22 import gtk 22 23 import gobject 23 24 25 from gtk import gdk 24 26 from higwidgets.higbuttons import HIGArrowButton 27 28 # 29 # Reimplementation of gtk.Layout in python 30 # Example on how to implement a scrollable container in python 31 # 32 # Johan Dahlin <johan@gnome.org>, 2006 33 # 34 # Readaption for implementing show/hide animation and only one child by 35 # Francesco Piccinno <stack.box@gmail.com>, 2008 36 # 37 # Requires PyGTK 2.8.0 or later 38 39 class Child: 40 widget = None 41 x = 0 42 y = 0 43 44 def set_adjustment_upper(adj, upper, always_emit): 45 changed = False 46 value_changed = False 47 48 min = max(0.0, upper - adj.page_size) 49 50 if upper != adj.upper: 51 adj.upper = upper 52 changed = True 53 54 if adj.value > min: 55 adj.value = min 56 value_changed = True 57 58 if changed or always_emit: 59 adj.changed() 60 if value_changed: 61 adj.value_changed() 62 63 def new_adj(): 64 return gtk.Adjustment(0.0, 0.0, 0.0, 65 0.0, 0.0, 0.0) 66 67 class Layout(gtk.Container): 68 __gsignals__ = { 69 'animation-end' : (gobject.SIGNAL_RUN_LAST, None, (gobject.TYPE_BOOLEAN, )), 70 'set_scroll_adjustments' : (gobject.SIGNAL_RUN_LAST, None, 71 (gtk.Adjustment, gtk.Adjustment)) 72 } 73 74 def __init__(self): 75 self._child = None 76 self._width = 100 77 self._height = 100 78 self._hadj = None 79 self._vadj = None 80 self._bin_window = None 81 self._hadj_changed_id = -1 82 self._vadj_changed_id = -1 83 84 self._animating = False 85 self._to_show = True 86 87 self._current = 0 88 self._dest = 0 89 self._speed = 5 90 91 self._time_int = 10 92 self._time_tot = 300 93 94 gtk.Container.__init__(self) 95 96 if not self._hadj or not self._vadj: 97 self._set_adjustments(self._vadj or new_adj(), 98 self._hadj or new_adj()) 99 100 def _move(self, x=0, y=0): 101 if not self._child: 102 return 103 104 if x != self._child.x or \ 105 y != self._child.y: 106 107 self._child.x = x 108 self._child.y = y 109 110 self.queue_resize() 111 112 def set_size(self, width, height): 113 if self._width != width: 114 self._width = width 115 if self._height != height: 116 self._height = height 117 if self._hadj: 118 set_adjustment_upper(self._hadj, self._width, False) 119 if self._vadj: 120 set_adjustment_upper(self._vadj, self._height, False) 121 122 if self.flags() & gtk.REALIZED: 123 self._bin_window.resize(max(width, self.allocation.width), 124 max(height, self.allocation.height)) 125 126 def do_realize(self): 127 self.set_flags(self.flags() | gtk.REALIZED) 128 129 self.window = gdk.Window( 130 self.get_parent_window(), 131 window_type=gdk.WINDOW_CHILD, 132 x=self.allocation.x, 133 y=self.allocation.y, 134 width=self.allocation.width, 135 height=self.allocation.height, 136 wclass=gdk.INPUT_OUTPUT, 137 colormap=self.get_colormap(), 138 event_mask=gdk.VISIBILITY_NOTIFY_MASK) 139 self.window.set_user_data(self) 140 141 self._bin_window = gdk.Window( 142 self.window, 143 window_type=gdk.WINDOW_CHILD, 144 x=int(-self._hadj.value), 145 y=int(-self._vadj.value), 146 width=max(self._width, self.allocation.width), 147 height=max(self._height, self.allocation.height), 148 colormap=self.get_colormap(), 149 wclass=gdk.INPUT_OUTPUT, 150 event_mask=(self.get_events() | gdk.EXPOSURE_MASK | 151 gdk.SCROLL_MASK)) 152 self._bin_window.set_user_data(self) 153 154 self.set_style(self.style.attach(self.window)) 155 self.style.set_background(self.window, gtk.STATE_NORMAL) 156 self.style.set_background(self._bin_window, gtk.STATE_NORMAL) 157 158 if self._child: 159 self._child.widget.set_parent_window(self._bin_window) 160 161 self.queue_resize() 162 163 def do_unrealize(self): 164 self._bin_window.set_user_data(None) 165 self._bin_window.destroy() 166 self._bin_window = None 167 gtk.Container.do_unrealize(self) 168 169 def _do_style_set(self, style): 170 gtk.Widget.do_style_set(self, style) 171 172 if self.flags() & gtk.REALIZED: 173 self.style.set_background(self._bin_window, gtk.STATE_NORMAL) 174 175 def do_expose_event(self, event): 176 if event.window != self._bin_window: 177 return False 178 179 gtk.Container.do_expose_event(self, event) 180 181 return False 182 183 def do_map(self): 184 self.set_flags(self.flags() | gtk.MAPPED) 185 186 if self._child: 187 flags = self._child.widget.flags() 188 189 if flags & gtk.VISIBLE and not (flags & gtk.MAPPED): 190 self._child.widget.map() 191 192 self._bin_window.show() 193 self.window.show() 194 195 def do_size_request(self, req): 196 req.width = 0 197 req.height = 0 198 199 if self._child and (self._animating or self._to_show): 200 #if self._child: 201 req.width, req.height = self._child.widget.size_request() 202 203 def do_size_allocate(self, allocation): 204 self.allocation = allocation 205 206 if self._child: 207 rect = gdk.Rectangle(self._child.x, self._child.y, 208 allocation.width, allocation.height) 209 self._child.widget.size_allocate(rect) 210 211 if self.flags() & gtk.REALIZED: 212 self.window.move_resize(*allocation) 213 self._bin_window.resize(max(self._width, allocation.width), 214 max(self._height, allocation.height)) 215 216 self._hadj.page_size = allocation.width 217 self._hadj.page_increment = allocation.width * 0.9 218 self._hadj.lower = 0 219 set_adjustment_upper(self._hadj, 220 max(allocation.width, self._width), True) 221 222 self._vadj.page_size = allocation.height 223 self._vadj.page_increment = allocation.height * 0.9 224 self._vadj.lower = 0 225 self._vadj.upper = max(allocation.height, self._height) 226 set_adjustment_upper(self._vadj, 227 max(allocation.height, self._height), True) 228 229 def do_set_scroll_adjustments(self, hadj, vadj): 230 self._set_adjustments(hadj, vadj) 231 232 def do_forall(self, include_internals, callback, data): 233 if self._child: 234 callback(self._child.widget, data) 235 236 def do_add(self, widget): 237 if self._child: 238 raise AttributeError 239 240 child = Child() 241 child.widget = widget 242 child.x, child.y = 0, 0 243 244 self._child = child 245 246 if self.flags() & gtk.REALIZED: 247 widget.set_parent_window(self._bin_window) 248 249 widget.set_parent(self) 250 251 def do_remove(self, widget): 252 if self._animating: 253 raise Exception("Try later please :)") 254 255 if self._child and self._child.widget == widget: 256 self._child = None 257 widget.unparent() 258 else: 259 raise AttributeError 260 261 # Private 262 263 def _set_adjustments(self, hadj, vadj): 264 if not hadj and self._hadj: 265 hadj = new_adj() 266 267 if not vadj and self._vadj: 268 vadj = new_adj() 269 270 if self._hadj and self._hadj != hadj: 271 self._hadj.disconnect(self._hadj_changed_id) 272 273 if self._vadj and self._vadj != vadj: 274 self._vadj.disconnect(self._vadj_changed_id) 275 276 need_adjust = False 277 278 if self._hadj != hadj: 279 self._hadj = hadj 280 set_adjustment_upper(hadj, self._width, False) 281 self._hadj_changed_id = hadj.connect( 282 "value-changed", 283 self._adjustment_changed) 284 need_adjust = True 285 286 if self._vadj != vadj: 287 self._vadj = vadj 288 set_adjustment_upper(vadj, self._height, False) 289 self._vadj_changed_id = vadj.connect( 290 "value-changed", 291 self._adjustment_changed) 292 need_adjust = True 293 294 if need_adjust and vadj and hadj: 295 self._adjustment_changed() 296 297 def _adjustment_changed(self, adj=None): 298 if self.flags() & gtk.REALIZED: 299 self._bin_window.move(int(-self._hadj.value), 300 int(-self._vadj.value)) 301 self._bin_window.process_updates(True) 302 303 def _do_animation(self): 304 if not self._child: 305 return False 306 307 if not self._child.widget.flags() & gtk.VISIBLE: 308 self._child.widget.show() 309 310 if self._to_show: 311 if self._current < 0: 312 self._current += self._speed 313 self._move(0, self._current) 314 315 return True 316 317 self._current = 0 318 self._move(0, self._current) 319 else: 320 if self._current > self._dest: 321 self._current -= self._speed 322 self._move(0, self._current) 323 324 return True 325 326 self._current = -self.allocation.height 327 self._move(0, self._current) 328 329 self.hide() 330 331 self.emit('animation-end', self._to_show) 332 self._child.widget.set_sensitive(True) 333 return False 334 335 def toggle_animation(self): 336 if self._animating or not self._child: 337 return False 338 339 self._to_show = not self._to_show 340 self._speed = max(self.allocation.height / (self._time_tot / self._time_int), 1) 341 self._child.widget.set_sensitive(False) 342 343 if self._to_show: 344 self.show() 345 self.set_size_request(-1, -1) 346 self._dest = 0 347 else: 348 self.set_size_request(0, 0) 349 self._dest = -self.allocation.height 350 351 gobject.timeout_add(self._time_int, self._do_animation) 352 353 return True 354 355 Layout.set_set_scroll_adjustments_signal('set-scroll-adjustments') 25 356 26 357 class AnimatedExpander(gtk.VBox): … … 33 364 # optionally a close button :) 34 365 35 self. arrow = HIGArrowButton(gtk.ORIENTATION_VERTICAL)36 self. arrow.set_relief(gtk.RELIEF_NONE)37 self. arrow.connect('clicked', self.__on_toggle)366 self._arrow = HIGArrowButton(gtk.ORIENTATION_VERTICAL) 367 self._arrow.set_relief(gtk.RELIEF_NONE) 368 self._arrow.connect('clicked', self.__on_toggle) 38 369 39 370 self._label = gtk.Label() … … 45 376 46 377 # The layout part 47 self.layout = gtk.Layout() 48 self.child = None 49 50 self.animating = False 51 self.to_show = False 52 53 self.speed = 10 54 self.current = 0 55 self.dest = 0 56 57 self.tot_time = 100 58 self.int_time = 5 378 self._layout = Layout() 59 379 60 380 # Pack all 61 381 hbox = gtk.HBox(False, 2) 62 hbox.pack_start(self. arrow, False, False)382 hbox.pack_start(self._arrow, False, False) 63 383 hbox.pack_start(self._image, False, False) 64 384 hbox.pack_start(self._label) … … 67 387 frame.add(hbox) 68 388 69 self. happy_box = gtk.EventBox()70 self. happy_box.add(frame)71 72 self.pack_start(self. happy_box, False, False)73 self.pack_ end(self.layout)389 self._happy_box = gtk.EventBox() 390 self._happy_box.add(frame) 391 392 self.pack_start(self._happy_box, False, False) 393 self.pack_start(self._layout) 74 394 75 395 self.show_all() … … 81 401 gtk.gdk.colormap_get_system().alloc_color(bg_color) 82 402 83 self.happy_box.modify_bg(gtk.STATE_NORMAL, bg_color) 84 85 def do_size_allocate(self, allocation): 86 ret = gtk.VBox.do_size_allocate(self, allocation) 87 88 if self.animating: 89 self.layout.show() 90 elif self.child and not self.animating: 91 alloc = self.layout.get_allocation() 92 w, h = alloc.width, alloc.height 93 94 alloc = self.child.get_allocation() 95 96 #if w > alloc.width: 97 if w >= self.child.size_request()[0]: 98 alloc.width = w 99 else: 100 alloc.width = self.child.size_request()[0] 101 102 #if h > alloc.height: 103 if h >= self.child.size_request()[1]: 104 alloc.height = h 105 else: 106 alloc.height = self.child.size_request()[1] 107 108 self.child.size_allocate(alloc) 109 110 if self.to_show: 111 self.layout.show() 112 else: 113 self.layout.hide() 114 115 return ret 403 self._happy_box.modify_bg(gtk.STATE_NORMAL, bg_color) 116 404 117 405 def add_widget(self, widget, show=False): 118 406 """ 119 407 Add a widget to the expander. 120 408 121 409 @param widget the widget to add 122 410 @param show if the widget should be showed 123 411 """ 124 125 if self.child: 126 raise Exception("Could not add another widget as child.") 127 128 self.child = widget 129 130 self.layout.put(self.child, 0, 0) 131 self.do_size_allocate(self.get_allocation()) 132 self.set_expanded(show) 412 413 #FIXME: this 414 self._layout.add(widget) 133 415 134 416 def add(self, widget): 135 417 self.add_widget(widget, True) 136 137 def set_expanded(self, val):138 """139 Show or hide the child widget without animation140 """141 142 if not self.child:143 return144 145 self.arrow.set_active(val)146 self.to_show = val147 148 if val:149 self.current = 0150 self.layout.move(self.child, 0, self.current)151 self.layout.show()152 else:153 self.layout.hide()154 self.current = self.__get_child_height()155 self.layout.move(self.child, 0, self.current)156 157 if not self.animating:158 self.__set_animating(False)159 418 160 419 def get_label(self): … … 168 427 self._label.set_use_markup(True) 169 428 170 def __animate_hide(self):171 if self.current > self.dest:172 self.current -= self.speed173 self.layout.move(self.child, 0, self.current)174 175 return True176 177 if self.dest < 0:178 self.layout.hide()179 180 self.current = self.__get_child_height()181 self.__set_animating(False)182 self.arrow.set_sensitive(True)183 184 return False185 186 def __animate_show(self):187 if self.current < 0:188 self.current += self.speed189 self.layout.move(self.child, 0, self.current)190 191 return True192 193 self.current = 0194 self.layout.move(self.child, 0, 0)195 self.__set_animating(False)196 self.arrow.set_sensitive(True)197 198 return False199 200 201 429 def __on_toggle(self, btn): 202 if not self.child: 203 return 204 205 self.arrow.set_active(not self.arrow.get_active()) 206 self.to_show = self.arrow.get_active() 207 self.__set_animating(True) 208 209 self.arrow.set_sensitive(False) 210 211 # We need to calculate the speed offset to complete 212 # the scrolling in self.tot_time 213 214 self.speed = self.__get_child_height() / (self.tot_time / self.int_time) 215 216 # Avoid null scrolling 217 if self.speed < 5: 218 self.speed = 5 219 220 if self.to_show: 221 self.dest = 0 222 self.current = -self.__get_child_height() 223 224 gobject.timeout_add(self.int_time, self.__animate_show) 225 else: 226 self.dest = -self.__get_child_height() 227 self.current = 0 228 229 gobject.timeout_add(self.int_time, self.__animate_hide) 230 231 def __get_child_height(self): 232 if self.child.flags() & gtk.REALIZED: 233 return self.child.get_allocation().height 234 else: 235 return self.child.size_request()[1] 236 237 def __set_animating(self, val): 238 self.animating = val 239 240 if not self.child: 241 return 242 243 self.child.set_sensitive(not self.animating) 244 245 alloc = self.layout.get_allocation() 246 247 if self.to_show: 248 alloc.height = self.__get_child_height() 249 self.layout.set_size_request(-1, alloc.height + 2) 250 else: 251 alloc.height = 0 252 self.layout.set_size_request(-1, -1) 253 254 self.layout.size_allocate(alloc) 255 self.size_allocate(self.get_allocation()) 430 if self._layout.toggle_animation(): 431 self._arrow.set_active(not self._arrow.get_active()) 256 432 257 433 def get_image(self): … … 266 442 gobject.type_register(AnimatedExpander) 267 443 444 class ToolPage(AnimatedExpander): 445 def __init__(self, parent, label=None, image=gtk.STOCK_PROPERTIES): 446 super(ToolPage, self).__init__(label, image) 447 448 self._parent = parent 449 self._active = False 450 451 self._layout.connect('animation-end', lambda w, v: self.set_active(v)) 452 453 def get_active(self): 454 return self._active 455 456 def set_active(self, val): 457 self._active = val 458 self._parent.realloc(self) 459 460 class ToolBox(gtk.VBox): 461 def __init__(self): 462 super(ToolBox, self).__init__(False, 2) 463 self.set_border_width(4) 464 465 self._active_page = None 466 self._pages = [] 467 468 def append_page(self, child, txt): 469 page = ToolPage(self, txt) 470 page.add(child) 471 472 self._pages.append(page) 473 474 475 self._active_page = page 476 self.pack_start(page, True, True) 477 478 def realloc(self, page): 479 if page.get_active(): 480 self.set_child_packing(page, True, True, 0, gtk.PACK_START) 481 482 if self._active_page: 483 self._active_page.set_active(False) 484 self._active_page = page 485 else: 486 self.set_child_packing(page, False, False, 0, gtk.PACK_START) 487 488 def main(klass): 489 w = gtk.Window() 490 vbox = gtk.VBox() 491 492 sw = gtk.ScrolledWindow() 493 sw.add(gtk.TextView()) 494 sw.set_size_request(400, 400) 495 496 exp = klass("miao") 497 exp.add(sw) 498 499 vbox.pack_start(exp, False, False) 500 501 sw = gtk.ScrolledWindow() 502 sw.add(gtk.TextView()) 503 504 exp = klass("miao") 505 exp.add(sw) 506 vbox.pack_start(exp) 507 508 vbox.pack_start(gtk.Label("mias"), False, False) 509 w.add(vbox) 510 w.show_all() 511 512 def toolbox(): 513 w = gtk.Window() 514 box = ToolBox() 515 box.append_page(gtk.Label("Testing"), "miao") 516 box.append_page(gtk.Label("Testing"), "miao") 517 w.add(box) 518 w.show_all() 519 268 520 if __name__ == "__main__": 269 w = gtk.Window() 270 exp = AnimatedExpander("<b>Testinggggg</b>") 271 sw = gtk.ScrolledWindow() 272 exp.add_widget(gtk.Label("Miao")) 273 w.add(exp) 274 w.show_all() 521 #main(AnimatedExpander) 522 #main(gtk.Expander) 523 toolbox() 275 524 gtk.main() -
branch/PacketManipulator/widgets/PropertyGrid.py
r3249 r3268 36 36 # Higwidgets 37 37 from higwidgets.hignetwidgets import HIGIpEntry 38 from widgets.Expander import AnimatedExpander 38 39 39 40 class Editor(gtk.HBox): … … 595 596 class PropertyGrid(gtk.VBox): 596 597 def __init__(self): 597 gtk.VBox.__init__(self) 598 gtk.VBox.__init__(self, False, 2) 599 600 self.set_border_width(2) 598 601 599 602 self.__create_toolbar() … … 605 608 self.tree = PropertyGridTree() 606 609 607 self.expander = gtk.Expander("Description")608 609 610 self.desc_text = gtk.TextView() 610 611 self.desc_text.set_wrap_mode(gtk.WRAP_WORD) 611 self.desc_text.set_size_request(1, 70)612 #self.desc_text.set_size_request(1, 70) 612 613 self.desc_text.set_editable(False) 613 614 self.desc_text.set_left_margin(5) … … 619 620 sw.add(self.desc_text) 620 621 621 self.expander.add(sw) 622 623 self.pack_start(self.tree) 624 self.pack_start(self.expander, False, False) 622 expander = AnimatedExpander('Protocol') 623 expander.add(self.tree) 624 625 self.pack_start(expander) 626 627 expander = AnimatedExpander('Description') 628 expander.add(sw) 629 630 self.pack_start(expander, False, False) 625 631 626 632 self.clear = self.tree.clear
