1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from constant import DEFAULT_FONT_SIZE, ALIGN_START, ALIGN_MIDDLE, WIDGET_POS_TOP_LEFT
24 from draw import draw_vlinear, draw_text
25 from keymap import get_keyevent_name
26 from line import HSeparator
27 from scrolled_window import ScrolledWindow
28 from theme import ui_theme
29 import gobject
30 import gtk
31 from utils import (is_in_rect, get_content_size, propagate_expose,
32 get_widget_root_coordinate, get_screen_size,
33 alpha_color_hex_to_cairo,
34 cairo_disable_antialias, color_hex_to_cairo)
35
36 __all__ = ["DroplistScrolledWindow", "Droplist", "DroplistItem"]
37
38 droplist_grab_window = gtk.Window(gtk.WINDOW_POPUP)
39 droplist_grab_window.move(0, 0)
40 droplist_grab_window.set_default_size(0, 0)
41 droplist_grab_window.show()
42 droplist_active_item = None
43 droplist_grab_window_press_flag = False
44
45 root_droplists = []
46
48 '''
49 Handle `focus-in` signal of droplist_grab_window.
50 '''
51 droplist_grab_window.grab_add()
52 gtk.gdk.pointer_grab(
53 droplist_grab_window.window,
54 True,
55 gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK | gtk.gdk.ENTER_NOTIFY_MASK | gtk.gdk.LEAVE_NOTIFY_MASK,
56 None, None, gtk.gdk.CURRENT_TIME)
57
71
73 '''
74 Whether press on droplist of droplist_grab_window.
75
76 @param window: gtk.Window or gtk.gdk.Window
77 '''
78 for toplevel in gtk.window_list_toplevels():
79 if isinstance(window, gtk.Window):
80 if window == toplevel:
81 return True
82 elif isinstance(window, gtk.gdk.Window):
83 if window == toplevel.window:
84 return True
85
86 return False
87
89 '''
90 Handle `enter-notify` signal of droplist_grab_window.
91
92 @param widget: Droplist widget.
93 @param event: Enter notify event.
94 '''
95 if event and event.window:
96 event_widget = event.window.get_user_data()
97 if isinstance(event_widget, DroplistScrolledWindow):
98 event_widget.event(event)
99
101 '''
102 Handle `leave-notify` signal of droplist_grab_window.
103
104 @param widget: Droplist widget.
105 @param event: Leave notify event.
106 '''
107 if event and event.window:
108 event_widget = event.window.get_user_data()
109 if isinstance(event_widget, DroplistScrolledWindow):
110 event_widget.event(event)
111
124
126 '''
127 Handle `key-press-event` signal of droplist_grab_window.
128
129 @param widget: Droplist widget.
130 @param event: Key press event.
131 '''
132 global root_droplists
133
134 if event and event.window:
135 for droplist in root_droplists:
136 droplist.event(event)
137
139 '''
140 Handle `key-release-event` signal of droplist_grab_window.
141
142 @param widget: Droplist widget.
143 @param event: Key release event.
144 '''
145 global root_droplists
146
147 if event and event.window:
148 for droplist in root_droplists:
149 droplist.event(event)
150
172
198
200 '''
201 Handle `motion-notify` signal of droplist_grab_window.
202
203 @param widget: Droplist widget.
204 @param event: Motion notify signal.
205 '''
206 global droplist_active_item
207 global droplist_grab_window_press_flag
208
209 if event and event.window:
210 event_widget = event.window.get_user_data()
211 if isinstance(event_widget, DroplistScrolledWindow):
212 event_widget.event(event)
213 elif isinstance(event_widget, Droplist):
214 for droplist in root_droplists:
215 motion_notify_event = gtk.gdk.Event(gtk.gdk.MOTION_NOTIFY)
216 motion_notify_event.window = droplist.item_scrolled_window.vwindow
217 motion_notify_event.send_event = True
218 motion_notify_event.time = event.time
219 motion_notify_event.x = event.x
220 motion_notify_event.y = event.y
221 motion_notify_event.x_root = event.x_root
222 motion_notify_event.y_root = event.y_root
223 motion_notify_event.state = event.state
224
225 droplist.item_scrolled_window.event(motion_notify_event)
226
227 if not droplist_grab_window_press_flag:
228 droplist_item = event_widget.get_droplist_item_at_coordinate(event.get_root_coords())
229 if droplist_item and isinstance(droplist_item.item_box, gtk.Button):
230 if droplist_active_item:
231 droplist_active_item.item_box.set_state(gtk.STATE_NORMAL)
232
233 droplist_item.item_box.set_state(gtk.STATE_PRELIGHT)
234 droplist_active_item = droplist_item
235
236 enter_notify_event = gtk.gdk.Event(gtk.gdk.ENTER_NOTIFY)
237 enter_notify_event.window = event.window
238 enter_notify_event.time = event.time
239 enter_notify_event.send_event = True
240 enter_notify_event.x_root = event.x_root
241 enter_notify_event.y_root = event.y_root
242 enter_notify_event.x = event.x
243 enter_notify_event.y = event.y
244 enter_notify_event.state = event.state
245
246 droplist_item.item_box.event(enter_notify_event)
247
248 droplist_item.item_box.queue_draw()
249 else:
250 for droplist in root_droplists:
251 motion_notify_event = gtk.gdk.Event(gtk.gdk.MOTION_NOTIFY)
252 motion_notify_event.window = droplist.item_scrolled_window.vwindow
253 motion_notify_event.send_event = True
254 motion_notify_event.time = event.time
255 motion_notify_event.x = event.x
256 motion_notify_event.y = event.y
257 motion_notify_event.x_root = event.x_root
258 motion_notify_event.y_root = event.y_root
259 motion_notify_event.state = event.state
260
261 droplist.item_scrolled_window.event(motion_notify_event)
262
263 droplist_grab_window.connect("button-press-event", droplist_grab_window_button_press)
264 droplist_grab_window.connect("button-release-event", droplist_grab_window_button_release)
265 droplist_grab_window.connect("motion-notify-event", droplist_grab_window_motion_notify)
266 droplist_grab_window.connect("enter-notify-event", droplist_grab_window_enter_notify)
267 droplist_grab_window.connect("leave-notify-event", droplist_grab_window_leave_notify)
268 droplist_grab_window.connect("scroll-event", droplist_grab_window_scroll_event)
269 droplist_grab_window.connect("key-press-event", droplist_grab_window_key_press)
270 droplist_grab_window.connect("key-release-event", droplist_grab_window_key_release)
271
287
288 gobject.type_register(DroplistScrolledWindow)
289
291 '''
292 Droplist.
293
294 @undocumented: expose_item_align
295 @undocumented: droplist_key_press
296 @undocumented: droplist_key_release
297 @undocumented: expose_droplist_frame
298 @undocumented: init_droplist
299 @undocumented: adjust_droplist_position
300 '''
301
302 __gsignals__ = {
303 "item-selected" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)),
304 "key-release" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, gobject.TYPE_PYOBJECT, int,)),
305 }
306
307 - def __init__(self,
308 items,
309 x_align=ALIGN_START,
310 y_align=ALIGN_START,
311 font_size=DEFAULT_FONT_SIZE,
312 opacity=1.0,
313 padding_x=0,
314 padding_y=0,
315 item_padding_left=6,
316 item_padding_right=32,
317 item_padding_y=3,
318 max_width=None):
319 '''
320 Initialize Droplist class.
321
322 @param items: A list of item, item format: (item_content, item_value).
323 @param x_align: Horticultural alignment.
324 @param y_align: Vertical alignment.
325 @param font_size: Font size of droplist, default is DEFAULT_FONT_SIZE
326 @param opacity: Opacity of droplist window, default is 1.0.
327 @param padding_x: Padding x, default is 0.
328 @param padding_y: Padding y, default is 0.
329 @param item_padding_left: Padding at left of item, default is 6.
330 @param item_padding_right: Padding at right of item, default is 32.
331 @param item_padding_y: Padding of item vertically, default is 3.
332 @param max_width: Maximum width of droplist, default is None.
333 '''
334
335 gtk.Window.__init__(self, gtk.WINDOW_POPUP)
336 self.items = items
337 self.set_can_focus(True)
338 self.add_events(gtk.gdk.ALL_EVENTS_MASK)
339 self.set_decorated(False)
340 self.set_colormap(gtk.gdk.Screen().get_rgba_colormap())
341 global root_droplists
342 self.font_size = font_size
343 self.x_align = x_align
344 self.y_align = y_align
345 self.subdroplist = None
346 self.root_droplist = None
347 self.offset_x = 0
348 self.offset_y = 0
349 self.padding_x = padding_x
350 self.padding_y = padding_y
351 self.item_padding_left = item_padding_left
352 self.item_padding_right = item_padding_right
353 self.item_padding_y = item_padding_y
354 self.max_width = max_width
355 self.item_select_index = 0
356
357
358 self.set_opacity(opacity)
359 self.set_skip_taskbar_hint(True)
360 self.set_keep_above(True)
361 self.connect_after("show", self.init_droplist)
362
363 self.droplist_frame = gtk.Alignment()
364 self.droplist_frame.set(0.5, 0.5, 1.0, 1.0)
365 self.droplist_frame.set_padding(1, 1, 1, 1)
366
367
368 self.item_box = gtk.VBox()
369 self.item_align = gtk.Alignment()
370 self.item_align.set_padding(padding_y, padding_y, padding_x, padding_x)
371 self.item_align.add(self.item_box)
372 self.item_scrolled_window = DroplistScrolledWindow(0, 0)
373 self.add(self.droplist_frame)
374 self.droplist_frame.add(self.item_scrolled_window)
375 self.item_scrolled_window.add_child(self.item_align)
376 self.droplist_items = []
377
378 if items:
379 for (index, item) in enumerate(items):
380 droplist_item = DroplistItem(
381 self,
382 index, item, font_size,
383 padding_x, padding_y,
384 item_padding_left, item_padding_right, item_padding_y, self.max_width)
385 self.droplist_items.append(droplist_item)
386 self.item_box.pack_start(droplist_item.item_box, False, False)
387
388 self.connect_after("show", self.adjust_droplist_position)
389 self.droplist_frame.connect("expose-event", self.expose_droplist_frame)
390 self.item_align.connect("expose-event", self.expose_item_align)
391 self.connect("key-press-event", self.droplist_key_press)
392 self.connect("key-release-event", self.droplist_key_release)
393
394 self.keymap = {
395 "Home" : self.select_first_item,
396 "End" : self.select_last_item,
397 "Page_Up" : self.scroll_page_up,
398 "Page_Down" : self.scroll_page_down,
399 "Return" : self.press_select_item,
400 "Up" : self.select_prev_item,
401 "Down" : self.select_next_item,
402 "Escape" : self.hide}
403
404 self.select_first_item()
405 self.grab_focus()
406
408 '''
409 Get droplist width.
410 '''
411 item_content_width = max(map(lambda item: get_content_size(item.item[0], self.font_size)[0],
412 filter(lambda item: isinstance(item.item_box, gtk.Button), self.droplist_items)))
413 if self.max_width != None:
414 return self.padding_x * 2 + min(self.max_width,
415 self.item_padding_left + self.item_padding_right + int(item_content_width))
416 else:
417 return self.padding_x * 2 + self.item_padding_left + self.item_padding_right + int(item_content_width)
418
420 '''
421 Internal function to handle `expose-event` signal.
422
423 @param widget: Droplist widget.
424 @param event: Expose event.
425 '''
426
427 cr = widget.window.cairo_create()
428 rect = widget.allocation
429 x, y, w, h = rect.x, rect.y, rect.width, rect.height
430
431
432 cr.set_source_rgba(*alpha_color_hex_to_cairo(ui_theme.get_alpha_color("droplist_mask").get_color_info()))
433 cr.rectangle(x, y, w, h)
434 cr.fill()
435
437 '''
438 Get index of first item.
439
440 @return: Return index of first item, or return None if haven't item in droplist.
441 '''
442 item_indexs = filter(lambda (index, item): isinstance(item.item_box, gtk.Button), enumerate(self.droplist_items))
443 if len(item_indexs) > 0:
444 return item_indexs[0][0]
445 else:
446 return None
447
449 '''
450 Get index of last item.
451
452 @return: Return index of last item, or return None if haven't item in droplist.
453 '''
454 item_indexs = filter(lambda (index, item): isinstance(item.item_box, gtk.Button), enumerate(self.droplist_items))
455 if len(item_indexs) > 0:
456 return item_indexs[-1][0]
457 else:
458 return None
459
461 '''
462 Get index of previous item.
463
464 @return: Return index of previous item, or return None if haven't item in droplist.
465 '''
466 item_indexs = filter(lambda (index, item): isinstance(item.item_box, gtk.Button), enumerate(self.droplist_items))
467 if len(item_indexs) > 0:
468 index_list = map(lambda (index, item): index, item_indexs)
469 if self.item_select_index in index_list:
470 current_index = index_list.index(self.item_select_index)
471 if current_index > 0:
472 return index_list[current_index - 1]
473 else:
474 return self.item_select_index
475 else:
476 return None
477 else:
478 return None
479
481 '''
482 Get index of next item.
483
484 @return: Return index of next item, or return None if haven't item in droplist.
485 '''
486 item_indexs = filter(lambda (index, item): isinstance(item.item_box, gtk.Button), enumerate(self.droplist_items))
487 if len(item_indexs) > 0:
488 index_list = map(lambda (index, item): index, item_indexs)
489 if self.item_select_index in index_list:
490 current_index = index_list.index(self.item_select_index)
491 if current_index < len(index_list) - 1:
492 return index_list[current_index + 1]
493 else:
494 return self.item_select_index
495 else:
496 return None
497 else:
498 return None
499
501 '''
502 Get item rectangle with given index.
503
504 @param item_index: If item_index is None, use select index.
505
506 @return: Return (x, y, w, h) rectangle for match item.
507 '''
508 if item_index == None:
509 item_index = self.item_select_index
510 item_offset_y = sum(map(lambda item: item.item_box_height, self.droplist_items)[0:item_index])
511 item_rect = self.droplist_items[item_index].item_box.get_allocation()
512 return (0, item_offset_y, item_rect.width, item_rect.height)
513
515 '''
516 Select item with given index.
517
518 @param item_index: If item_index is None, use select index.
519 '''
520 global droplist_active_item
521
522 if item_index == None:
523 item_index = self.item_select_index
524
525 if droplist_active_item:
526 droplist_active_item.item_box.set_state(gtk.STATE_NORMAL)
527
528 item = self.droplist_items[item_index]
529 item.item_box.set_state(gtk.STATE_PRELIGHT)
530 droplist_active_item = item
531
533 '''
534 Select first item.
535 '''
536 if len(self.droplist_items) > 0:
537 first_index = self.get_first_index()
538 if first_index != None:
539 self.item_select_index = first_index
540 self.active_item()
541
542
543 vadjust = self.item_scrolled_window.get_vadjustment()
544 vadjust.set_value(vadjust.get_lower())
545
559
581
583 '''
584 Select next item.
585 '''
586 if len(self.droplist_items) > 0:
587 next_index = self.get_next_index()
588 if next_index != None:
589 global droplist_active_item
590
591 if droplist_active_item:
592 if self.item_select_index < len(self.droplist_items) - 1:
593 self.item_select_index = next_index
594 self.active_item()
595
596
597 (item_x, item_y, item_width, item_height) = self.get_select_item_rect()
598 vadjust = self.item_scrolled_window.get_vadjustment()
599 if self.padding_y + item_y + item_height > vadjust.get_value() + vadjust.get_page_size():
600 vadjust.set_value(self.padding_y * 2 + item_y + item_height - vadjust.get_page_size())
601 else:
602 self.select_first_item()
603
605 '''
606 Scroll page to select item.
607 '''
608 (item_x, item_y, item_width, item_height) = self.get_select_item_rect()
609 vadjust = self.item_scrolled_window.get_vadjustment()
610 vadjust.set_value(min(max(vadjust.get_lower(), item_y - self.padding_y * 2),
611 vadjust.get_upper() - vadjust.get_page_size()))
612
614 '''
615 Scroll page up.
616 '''
617 if len(self.droplist_items) > 0:
618
619 vadjust = self.item_scrolled_window.get_vadjustment()
620 vadjust.set_value(max(vadjust.get_lower(), vadjust.get_value() - vadjust.get_page_size()))
621
622
623 item_infos = map(lambda (index, item): (index, self.get_select_item_rect(index)), enumerate(self.droplist_items))
624 for (index, (item_x, item_y, item_width, item_height)) in item_infos:
625 if item_y + self.padding_y > vadjust.get_value():
626 self.item_select_index = index
627 self.active_item()
628 break
629
631 '''
632 Scroll page down.
633 '''
634 if len(self.droplist_items) > 0:
635
636 vadjust = self.item_scrolled_window.get_vadjustment()
637 vadjust.set_value(min(vadjust.get_upper() - vadjust.get_page_size(),
638 vadjust.get_value() + vadjust.get_page_size()))
639
640
641 item_infos = map(lambda (index, item): (index, self.get_select_item_rect(index)), enumerate(self.droplist_items))
642 item_infos.reverse()
643 for (index, (item_x, item_y, item_width, item_height)) in item_infos:
644 if item_y + item_height + self.padding_y < vadjust.get_value() + vadjust.get_page_size():
645 self.item_select_index = index
646 self.active_item()
647 break
648
650 '''
651 Press select item.
652 '''
653 if len(self.droplist_items) > 0:
654 if 0 <= self.item_select_index < len(self.droplist_items):
655 self.droplist_items[self.item_select_index].wrap_droplist_clicked_action()
656
658 '''
659 Internal function for `key-press-event` signal.
660
661 @param widget: Droplist widget.
662 @param event: Key press event.
663 '''
664 key_name = get_keyevent_name(event)
665 if self.keymap.has_key(key_name):
666 self.keymap[key_name]()
667
668 return True
669
671 '''
672 Internal function for `key-release-event` signal.
673
674 @param widget: Droplist widget.
675 @param event: Key release event.
676 '''
677 self.emit("key-release",
678 self.items[self.item_select_index][0],
679 self.items[self.item_select_index][1],
680 self.item_select_index)
681
683 '''
684 Callback for `expose-event` siangl of droplist frame.
685
686 @param widget: Droplist widget.
687 @param event: Expose event.
688 '''
689 cr = widget.window.cairo_create()
690 rect = widget.allocation
691
692 with cairo_disable_antialias(cr):
693 cr.set_line_width(1)
694 cr.set_source_rgb(*color_hex_to_cairo(ui_theme.get_color("droplist_frame").get_color()))
695 cr.rectangle(rect.x, rect.y, rect.width, rect.height)
696 cr.fill()
697
699 '''
700 Get droplist item at coordinate, return None if haven't any droplist item at given coordinate.
701
702 @param x: X coordiante.
703 @param y: Y coordiante.
704
705 @return: Return match item with given coordinate, return None if haven't any item match coordinate.
706 '''
707 match_droplist_item = None
708
709 item_heights = map(lambda item: item.item_box_height, self.droplist_items)
710 item_offsets = map(lambda (index, height): sum(item_heights[0:index]), enumerate(item_heights))
711
712 vadjust = self.item_scrolled_window.get_vadjustment()
713 (scrolled_window_x, scrolled_window_y) = get_widget_root_coordinate(self.item_scrolled_window, WIDGET_POS_TOP_LEFT)
714 for (index, droplist_item) in enumerate(self.droplist_items):
715 item_rect = droplist_item.item_box.get_allocation()
716 if is_in_rect((x, y), (scrolled_window_x,
717 scrolled_window_y + item_offsets[index] - (vadjust.get_value() - vadjust.get_lower()),
718 item_rect.width,
719 item_rect.height)):
720 match_droplist_item = droplist_item
721 break
722
723 return match_droplist_item
724
726 '''
727 Callback after `show` signal.
728
729 @param widget: Droplist widget.
730 '''
731 global root_droplists
732 droplist_grab_window_focus_out()
733
734 if not gtk.gdk.pointer_is_grabbed():
735 droplist_grab_window_focus_in()
736
737 if not self in root_droplists:
738 root_droplists.append(self)
739
740 - def show(self, (x, y), (offset_x, offset_y)=(0, 0)):
741 '''
742 Show droplist.
743
744 @param x: Show x coordinate.
745 @param y: Show y coordinate.
746 @param offset_x: Offset x value when droplist haven't space to show in origin coordinate, default is 0.
747 @param offset_y: Offset y value when droplist haven't space to show in origin coordinate, default is 0.
748 '''
749
750 self.expect_x = x
751 self.expect_y = y
752 self.offset_x = offset_x
753 self.offset_y = offset_y
754
755
756 self.show_all()
757
759 '''
760 Internal function to adjust droplist position after `realize` signal.
761
762 @param widget: Droplist widget.
763 '''
764
765 (screen_width, screen_height) = get_screen_size(self)
766
767 droplist_width = 0
768 for droplist_item in self.droplist_items:
769 if droplist_width == 0 and isinstance(droplist_item.item_box, gtk.Button):
770 droplist_width = droplist_item.item_box_width
771 droplist_width += self.padding_x * 2
772 droplist_height = self.allocation.height
773
774 if self.x_align == ALIGN_START:
775 dx = self.expect_x
776 elif self.x_align == ALIGN_MIDDLE:
777 dx = self.expect_x - droplist_width / 2
778 else:
779 dx = self.expect_x - droplist_width
780
781 if self.y_align == ALIGN_START:
782 dy = self.expect_y
783 elif self.y_align == ALIGN_MIDDLE:
784 dy = self.expect_y - droplist_height / 2
785 else:
786 dy = self.expect_y - droplist_height
787
788 if self.expect_x + droplist_width > screen_width:
789 dx = self.expect_x - droplist_width + self.offset_x
790 if self.expect_y + droplist_height > screen_height:
791 dy = self.expect_y - droplist_height + self.offset_y
792
793 self.move(dx, dy)
794
796 '''
797 Hide droplist.
798 '''
799
800 self.hide_all()
801
802
803 self.subdroplist = None
804 self.root_droplist = None
805
806 gobject.type_register(Droplist)
807
809 '''
810 DroplistItem for L{ I{Droplist} <Droplist>}.
811
812 @undocumented: create_separator_item
813 @undocumented: create_droplist_item
814 @undocumented: realize_item_box
815 @undocumented: wrap_droplist_clicked_action
816 @undocumented: expose_droplist_item
817 '''
818
819 - def __init__(self,
820 droplist,
821 index,
822 item,
823 font_size,
824 droplist_padding_x,
825 droplist_padding_y,
826 item_padding_left,
827 item_padding_right,
828 item_padding_y,
829 max_width):
830 '''
831 Initialize DroplistItem class.
832
833 @param droplist: Droplist.
834 @param index: Drop item index.
835 @param item: Drop item, format (item_content, item_value)
836 @param font_size: Drop item font size.
837 @param droplist_padding_x: Padding x of droplist.
838 @param droplist_padding_y: Padding y of droplist.
839 @param item_padding_left: Padding at left of item.
840 @param item_padding_right: Padding at right of item.
841 @param item_padding_y: Padding at top or bottom of item.
842 @param max_width: Maximum width of droplist item.
843 '''
844
845 self.droplist = droplist
846 self.index = index
847 self.item = item
848 self.font_size = font_size
849 self.droplist_padding_x = droplist_padding_x
850 self.droplist_padding_y = droplist_padding_y
851 self.item_padding_left = item_padding_left
852 self.item_padding_right = item_padding_right
853 self.item_padding_y = item_padding_y
854 self.subdroplist_active = False
855 self.max_width = max_width
856 self.arrow_padding_x = 5
857
858
859 if self.item:
860 self.create_droplist_item()
861 else:
862 self.create_separator_item()
863
865 '''
866 Internal function, create separator item.
867 '''
868 self.item_box = HSeparator(
869 ui_theme.get_shadow_color("h_separator").get_color_info(),
870 self.item_padding_left,
871 self.item_padding_y)
872 self.item_box_height = self.item_padding_y * 2 + 1
873
875 '''
876 Internal function, create droplist item.
877 '''
878
879 (item_content, item_value) = self.item[0:2]
880
881
882 self.item_box = gtk.Button()
883
884
885 self.item_box.connect(
886 "expose-event",
887 lambda w, e: self.expose_droplist_item(
888 w, e, item_content))
889
890
891 self.item_box.connect("button-press-event", lambda w, e: self.wrap_droplist_clicked_action())
892
893 self.item_box.connect("realize", lambda w: self.realize_item_box(w, item_content))
894
896 '''
897 Internal function, realize item box.
898
899 @param widget: DropItem widget.
900 @param item_content: Item content.
901 '''
902
903 (width, height) = get_content_size(item_content, self.font_size)
904 self.item_box_height = self.item_padding_y * 2 + int(height)
905 self.item_box_width = self.item_padding_left + self.item_padding_right + int(width)
906
907 if self.max_width != None:
908 self.item_box_width = min(self.item_box_width, self.max_width)
909 else:
910 self.item_box_width = self.item_box_width
911
912 self.item_box.set_size_request(self.item_box_width, self.item_box_height)
913
915 '''
916 Internal function to wrap clicked action.
917 '''
918
919 self.droplist.emit("item-selected", self.item[0], self.item[1], self.index)
920
921
922 droplist_grab_window_focus_out()
923
925 '''
926 Internal function to handle `expose-event` signal of item.
927
928 @param widget: DropItem widget.
929 @param event: Expose event.
930 @param item_content: Item content.
931 '''
932
933 cr = widget.window.cairo_create()
934 rect = widget.allocation
935 font_color = ui_theme.get_color("menu_font").get_color()
936
937
938 if self.subdroplist_active or widget.state in [gtk.STATE_PRELIGHT, gtk.STATE_ACTIVE]:
939
940 draw_vlinear(cr, rect.x, rect.y, rect.width, rect.height,
941 ui_theme.get_shadow_color("menu_item_select").get_color_info())
942
943
944 font_color = ui_theme.get_color("menu_select_font").get_color()
945
946
947 draw_text(cr, item_content,
948 rect.x + self.item_padding_left,
949 rect.y,
950 rect.width,
951 rect.height,
952 self.font_size, font_color,
953 )
954
955
956 propagate_expose(widget, event)
957
958 return True
959