"Fossies" - the Fresh Open Source Software Archive 
Member "radialnet/gui/ControlWidget.py" (18 Feb 2008, 38217 Bytes) of package /linux/privat/old/radialnet-0.44.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ControlWidget.py" see the
Fossies "Dox" file reference documentation.
1 # vim: set fileencoding=utf-8 :
2
3 # Copyright (C) 2007, 2008 Insecure.Com LLC.
4 #
5 # Author: João Paulo de Souza Medeiros <ignotus21@gmail.com>
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21 import gtk
22 import math
23 import gobject
24
25 import bestwidgets as bw
26 import util.drawing as drawing
27 import util.geometry as geometry
28
29 from core.Coordinate import PolarCoordinate
30 from gui.RadialNet import *
31
32
33 OPTIONS = ['address',
34 'hostname',
35 'icon',
36 'latency',
37 'ring',
38 'region',
39 'slow in/out']
40
41 REFRESH_RATE = 500
42
43
44
45 class ControlWidget(bw.BWVBox):
46 """
47 """
48 def __init__(self, radialnet):
49 """
50 """
51 bw.BWVBox.__init__(self)
52 self.set_border_width(6)
53
54 self.radialnet = radialnet
55
56 self.__create_widgets()
57
58
59 def __create_widgets(self):
60 """
61 """
62 self.__action = ControlAction(self.radialnet)
63 self.__interpolation = ControlInterpolation(self.radialnet)
64 self.__layout = ControlLayout(self.radialnet)
65 self.__view = ControlView(self.radialnet)
66
67 self.bw_pack_start_noexpand_nofill(self.__action)
68 self.bw_pack_start_noexpand_nofill(self.__interpolation)
69 self.bw_pack_start_noexpand_nofill(self.__layout)
70 self.bw_pack_start_noexpand_nofill(self.__view)
71
72
73
74 class ControlAction(bw.BWExpander):
75 """
76 """
77 def __init__(self, radialnet):
78 """
79 """
80 bw.BWExpander.__init__(self, 'Action')
81 self.set_expanded(True)
82
83 self.radialnet = radialnet
84
85 self.__create_widgets()
86
87
88 def __create_widgets(self):
89 """
90 """
91 self.__tbox = bw.BWTable(1, 4)
92 self.__tbox.bw_set_spacing(0)
93 self.__vbox = bw.BWVBox()
94
95 self.__tooltips = gtk.Tooltips()
96
97 self.__jump_to = gtk.RadioToolButton(None, gtk.STOCK_JUMP_TO)
98 self.__jump_to.set_tooltip(self.__tooltips, 'Change focus')
99 self.__jump_to.connect('toggled',
100 self.__change_pointer,
101 POINTER_JUMP_TO)
102
103 self.__info = gtk.RadioToolButton(self.__jump_to, gtk.STOCK_INFO)
104 self.__info.set_tooltip(self.__tooltips, 'Show information')
105 self.__info.connect('toggled',
106 self.__change_pointer,
107 POINTER_INFO)
108
109 self.__group = gtk.RadioToolButton(self.__jump_to, gtk.STOCK_ADD)
110 self.__group.set_tooltip(self.__tooltips, 'Group children')
111 self.__group.connect('toggled',
112 self.__change_pointer,
113 POINTER_GROUP)
114
115 self.__region = gtk.RadioToolButton(self.__jump_to,
116 gtk.STOCK_SELECT_COLOR)
117 self.__region.set_tooltip(self.__tooltips, 'Fill region')
118 self.__region.connect('toggled',
119 self.__change_pointer,
120 POINTER_FILL)
121
122 self.__region_color = gtk.combo_box_new_text()
123 self.__region_color.append_text('Red')
124 self.__region_color.append_text('Yellow')
125 self.__region_color.append_text('Green')
126 self.__region_color.connect('changed', self.__change_region)
127 self.__region_color.set_active(self.radialnet.get_region_color())
128
129 self.__tbox.bw_attach_next(self.__jump_to)
130 self.__tbox.bw_attach_next(self.__info)
131 self.__tbox.bw_attach_next(self.__group)
132 self.__tbox.bw_attach_next(self.__region)
133
134 self.__vbox.bw_pack_start_noexpand_nofill(self.__tbox)
135 self.__vbox.bw_pack_start_noexpand_nofill(self.__region_color)
136
137 self.bw_add(self.__vbox)
138
139 self.__jump_to.set_active(True)
140 self.__region_color.set_no_show_all(True)
141 self.__region_color.hide()
142
143
144 def __change_pointer(self, widget, pointer):
145 """
146 """
147 if pointer != self.radialnet.get_pointer_status():
148 self.radialnet.set_pointer_status(pointer)
149
150 if pointer == POINTER_FILL:
151 self.__region_color.show()
152 else:
153 self.__region_color.hide()
154
155
156 def __change_region(self, widget):
157 """
158 """
159 self.radialnet.set_region_color(self.__region_color.get_active())
160
161
162
163 class ControlVariableWidget(gtk.DrawingArea):
164 """
165 """
166 def __init__(self, name, value, update, increment=1):
167 """
168 """
169 gtk.DrawingArea.__init__(self)
170
171 self.__variable_name = name
172 self.__value = value
173 self.__update = update
174 self.__increment_pass = increment
175
176 self.__radius = 6
177 self.__increment_time = 100
178
179 self.__pointer_position = 0
180 self.__active_increment = False
181
182 self.__last_value = self.__value()
183
184 self.connect('expose_event', self.expose)
185 self.connect('button_press_event', self.button_press)
186 self.connect('button_release_event', self.button_release)
187 self.connect('motion_notify_event', self.motion_notify)
188
189 self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
190 gtk.gdk.BUTTON_RELEASE_MASK |
191 gtk.gdk.MOTION_NOTIFY |
192 gtk.gdk.POINTER_MOTION_HINT_MASK |
193 gtk.gdk.POINTER_MOTION_MASK)
194
195 gobject.timeout_add(REFRESH_RATE, self.verify_value)
196
197
198 def verify_value(self):
199 """
200 """
201 if self.__value() != self.__last_value:
202 self.__last_value = self.__value()
203
204 self.queue_draw()
205
206 return True
207
208
209 def button_press(self, widget, event):
210 """
211 """
212 self.__active_increment = False
213 pointer = self.get_pointer()
214
215 if self.__button_is_clicked(pointer) and event.button == 1:
216
217 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
218 self.__active_increment = True
219 self.__increment_value()
220
221
222 def button_release(self, widget, event):
223 """
224 """
225 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
226
227 self.__active_increment = False
228 self.__pointer_position = 0
229
230 self.queue_draw()
231
232
233 def motion_notify(self, widget, event):
234 """
235 Drawing callback
236 @type widget: GtkWidget
237 @param widget: Gtk widget superclass
238 @type event: GtkEvent
239 @param event: Gtk event of widget
240 @rtype: boolean
241 @return: Indicator of the event propagation
242 """
243 if self.__active_increment == True:
244
245 xc, yc = self.__center_of_widget
246 x, _ = self.get_pointer()
247
248 if x - self.__radius > 0 and x + self.__radius < 2 * xc:
249 self.__pointer_position = x - xc
250
251 self.queue_draw()
252
253
254 def expose(self, widget, event):
255 """
256 Drawing callback
257 @type widget: GtkWidget
258 @param widget: Gtk widget superclass
259 @type event: GtkEvent
260 @param event: Gtk event of widget
261 @rtype: boolean
262 @return: Indicator of the event propagation
263 """
264 self.set_size_request(100, 30)
265
266 self.context = widget.window.cairo_create()
267 self.__draw()
268
269 return True
270
271
272 def __draw(self):
273 """
274 """
275 allocation = self.get_allocation()
276
277 self.__center_of_widget = (allocation.width / 2,
278 allocation.height / 2)
279
280 xc, yc = self.__center_of_widget
281
282 # draw line
283 self.context.set_line_width(1)
284 self.context.set_dash([1,2])
285 self.context.move_to(self.__radius,
286 yc + self.__radius)
287 self.context.line_to(2 * xc - 5,
288 yc + self.__radius)
289 self.context.stroke()
290
291 # draw text
292 self.context.set_dash([1,0])
293 self.context.set_font_size(10)
294
295 width = self.context.text_extents(self.__variable_name)[2]
296 self.context.move_to(5, yc - self.__radius)
297 self.context.show_text(self.__variable_name)
298
299 width = self.context.text_extents(str(self.__value()))[2]
300 self.context.move_to(2 * xc - width - 5, yc - self.__radius)
301 self.context.show_text(str(self.__value()))
302
303 self.context.set_line_width(1)
304 self.context.stroke()
305
306 # draw node
307 self.context.arc(xc + self.__pointer_position,
308 yc + self.__radius,
309 self.__radius, 0, 2 * math.pi)
310 if self.__active_increment == True:
311 self.context.set_source_rgb(0.0, 0.0, 0.0)
312 else:
313 self.context.set_source_rgb(1.0, 1.0, 1.0)
314 self.context.fill_preserve()
315 self.context.set_source_rgb(0.0, 0.0, 0.0)
316 self.context.stroke()
317
318
319 def __button_is_clicked(self, pointer):
320 """
321 """
322 xc, yc = self.__center_of_widget
323 center = (xc, yc + self.__radius)
324
325 if geometry.is_in_circle(pointer, 6, center) == True:
326 return True
327
328 return False
329
330
331 def __increment_value(self):
332 """
333 """
334 self.__update(self.__value() + self.__pointer_position / 4)
335
336 self.queue_draw()
337
338 if self.__active_increment == True:
339
340 gobject.timeout_add(self.__increment_time,
341 self.__increment_value)
342
343
344 def set_value_function(self, value):
345 """
346 """
347 self.__value = value
348
349
350 def set_update_function(self, update):
351 """
352 """
353 self.__update = update
354
355
356
357 class ControlVariable(bw.BWHBox):
358 """
359 """
360 def __init__(self, name, get_function, set_function, increment=1):
361 """
362 """
363 bw.BWHBox.__init__(self, spacing=0)
364
365 self.__increment_pass = increment
366 self.__increment_time = 200
367 self.__increment = False
368
369 self.__name = name
370 self.__get_function = get_function
371 self.__set_function = set_function
372
373 self.__create_widgets()
374
375
376 def __create_widgets(self):
377 """
378 """
379 self.__control = ControlVariableWidget(self.__name,
380 self.__get_function,
381 self.__set_function,
382 self.__increment_pass)
383
384 self.__left_button = gtk.Button()
385 self.__left_button.set_size_request(20, 20)
386 self.__left_arrow = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_NONE)
387 self.__left_button.add(self.__left_arrow)
388 self.__left_button.connect('pressed',
389 self.__pressed,
390 -self.__increment_pass)
391 self.__left_button.connect('released', self.__released)
392
393 self.__right_button = gtk.Button()
394 self.__right_button.set_size_request(20, 20)
395 self.__right_arrow = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_NONE)
396 self.__right_button.add(self.__right_arrow)
397 self.__right_button.connect('pressed',
398 self.__pressed,
399 self.__increment_pass)
400 self.__right_button.connect('released', self.__released)
401
402 self.bw_pack_start_noexpand_nofill(self.__left_button)
403 self.bw_pack_start_expand_fill(self.__control)
404 self.bw_pack_start_noexpand_nofill(self.__right_button)
405
406
407 def __pressed(self, widget, increment):
408 """
409 """
410 self.__increment = True
411 self.__increment_function(increment)
412
413
414 def __increment_function(self, increment):
415 """
416 """
417 if self.__increment:
418
419 self.__set_function(self.__get_function() + increment)
420 self.__control.verify_value()
421
422 gobject.timeout_add(self.__increment_time,
423 self.__increment_function,
424 increment)
425
426
427 def __released(self, widget):
428 """
429 """
430 self.__increment = False
431
432
433
434
435 class ControlFisheye(bw.BWVBox):
436 """
437 """
438 def __init__(self, radialnet):
439 """
440 """
441 bw.BWVBox.__init__(self)
442 self.set_border_width(6)
443
444 self.radialnet = radialnet
445 self.__ring_max_value = self.radialnet.get_number_of_rings()
446
447 self.__create_widgets()
448
449
450 def __create_widgets(self):
451 """
452 """
453 self.__params = bw.BWHBox()
454
455 self.__fisheye_label = gtk.Label('<b>Fisheye</b> on ring')
456 self.__fisheye_label.set_use_markup(True)
457
458 self.__ring = gtk.Adjustment(0, 0, self.__ring_max_value, 0.01, 0.01)
459
460 self.__ring_spin = gtk.SpinButton(self.__ring)
461 self.__ring_spin.set_digits(2)
462
463 self.__ring_scale = gtk.HScale(self.__ring)
464 self.__ring_scale.set_size_request(100, -1)
465 self.__ring_scale.set_digits(2)
466 self.__ring_scale.set_value_pos(gtk.POS_LEFT)
467 self.__ring_scale.set_draw_value(False)
468 self.__ring_scale.set_update_policy(gtk.UPDATE_CONTINUOUS)
469
470 self.__interest_label = gtk.Label('with interest factor')
471 self.__interest = gtk.Adjustment(0, 0, 10, 0.01)
472 self.__interest_spin = gtk.SpinButton(self.__interest)
473 self.__interest_spin.set_digits(2)
474
475 self.__spread_label = gtk.Label('and spread factor')
476 self.__spread = gtk.Adjustment(0, -1.0, 1.0, 0.01, 0.01)
477 self.__spread_spin = gtk.SpinButton(self.__spread)
478 self.__spread_spin.set_digits(2)
479
480 self.__params.bw_pack_start_noexpand_nofill(self.__fisheye_label)
481 self.__params.bw_pack_start_noexpand_nofill(self.__ring_spin)
482 self.__params.bw_pack_start_expand_fill(self.__ring_scale)
483 self.__params.bw_pack_start_noexpand_nofill(self.__interest_label)
484 self.__params.bw_pack_start_noexpand_nofill(self.__interest_spin)
485 self.__params.bw_pack_start_noexpand_nofill(self.__spread_label)
486 self.__params.bw_pack_start_noexpand_nofill(self.__spread_spin)
487
488 self.bw_pack_start_noexpand_nofill(self.__params)
489
490 self.__ring.connect('value_changed', self.__change_ring)
491 self.__interest.connect('value_changed', self.__change_interest)
492 self.__spread.connect('value_changed', self.__change_spread)
493
494 gobject.timeout_add(REFRESH_RATE, self.__update_fisheye)
495
496
497 def __update_fisheye(self):
498 """
499 """
500 # adjust ring scale to radialnet number of nodes
501 ring_max_value = self.radialnet.get_number_of_rings() - 1
502
503 if ring_max_value != self.__ring_max_value:
504
505 value = self.__ring.get_value()
506
507 if value == 0 and ring_max_value != 0:
508 value = 1
509
510 elif value > ring_max_value:
511 value = ring_max_value
512
513 self.__ring.set_all(value, 1, ring_max_value, 0.01, 0.01, 0)
514 self.__ring_max_value = ring_max_value
515
516 self.__ring_scale.queue_draw()
517
518 # check ring value
519 ring_value = self.radialnet.get_fisheye_ring()
520
521 if self.__ring.get_value() != ring_value:
522 self.__ring.set_value(ring_value)
523
524 # check interest value
525 interest_value = self.radialnet.get_fisheye_interest()
526
527 if self.__interest.get_value() != interest_value:
528 self.__interest.set_value(interest_value)
529
530 # check spread value
531 spread_value = self.radialnet.get_fisheye_spread()
532
533 if self.__spread.get_value() != spread_value:
534 self.__spread.set_value(spread_value)
535
536 return True
537
538
539 def active_fisheye(self):
540 """
541 """
542 self.radialnet.set_fisheye(True)
543 self.__change_ring()
544 self.__change_interest()
545
546
547 def deactive_fisheye(self):
548 """
549 """
550 self.radialnet.set_fisheye(False)
551
552
553 def __change_ring(self, widget=None):
554 """
555 """
556 if not self.radialnet.is_in_animation():
557 self.radialnet.set_fisheye_ring(self.__ring.get_value())
558 else:
559 self.__ring.set_value(self.radialnet.get_fisheye_ring())
560
561
562 def __change_interest(self, widget=None):
563 """
564 """
565 if not self.radialnet.is_in_animation():
566 self.radialnet.set_fisheye_interest(self.__interest.get_value())
567 else:
568 self.__interest.set_value(self.radialnet.get_fisheye_interest())
569
570
571 def __change_spread(self, widget=None):
572 """
573 """
574 if not self.radialnet.is_in_animation():
575 self.radialnet.set_fisheye_spread(self.__spread.get_value())
576 else:
577 self.__spread.set_value(self.radialnet.get_fisheye_spread())
578
579
580
581 class ControlInterpolation(bw.BWExpander):
582 """
583 """
584 def __init__(self, radialnet):
585 """
586 """
587 bw.BWExpander.__init__(self, 'Interpolation')
588
589 self.radialnet = radialnet
590
591 self.__create_widgets()
592
593
594 def __create_widgets(self):
595 """
596 """
597 self.__vbox = bw.BWVBox()
598
599 self.__cartesian_radio = gtk.RadioButton(None, 'Cartesian')
600 self.__polar_radio = gtk.RadioButton(self.__cartesian_radio, 'Polar')
601 self.__cartesian_radio.connect('toggled',
602 self.__change_system,
603 INTERPOLATION_CARTESIAN)
604 self.__polar_radio.connect('toggled',
605 self.__change_system,
606 INTERPOLATION_POLAR)
607
608 self.__system_box = bw.BWHBox()
609 self.__system_box.bw_pack_start_noexpand_nofill(self.__polar_radio)
610 self.__system_box.bw_pack_start_noexpand_nofill(self.__cartesian_radio)
611
612 self.__frames_box = bw.BWHBox()
613 self.__frames_label = gtk.Label('Frames')
614 self.__frames_label.set_alignment(0.0, 0.5)
615 self.__frames = gtk.Adjustment(self.radialnet.get_number_of_frames(),
616 1,
617 1000,
618 1)
619 self.__frames.connect('value_changed', self.__change_frames)
620 self.__frames_spin = gtk.SpinButton(self.__frames)
621 self.__frames_box.bw_pack_start_expand_fill(self.__frames_label)
622 self.__frames_box.bw_pack_start_noexpand_nofill(self.__frames_spin)
623
624 self.__vbox.bw_pack_start_noexpand_nofill(self.__frames_box)
625 self.__vbox.bw_pack_start_noexpand_nofill(self.__system_box)
626
627 self.bw_add(self.__vbox)
628
629 gobject.timeout_add(REFRESH_RATE, self.__update_animation)
630
631
632 def __update_animation(self):
633 """
634 """
635 active = self.radialnet.get_interpolation()
636
637 if active == INTERPOLATION_CARTESIAN:
638 self.__cartesian_radio.set_active(True)
639
640 else:
641 self.__polar_radio.set_active(True)
642
643 return True
644
645
646 def __change_system(self, widget, value):
647 """
648 """
649 if not self.radialnet.set_interpolation(value):
650
651 active = self.radialnet.get_interpolation()
652
653 if active == INTERPOLATION_CARTESIAN:
654 self.__cartesian_radio.set_active(True)
655
656 else:
657 self.__polar_radio.set_active(True)
658
659
660 def __change_frames(self, widget):
661 """
662 """
663 if not self.radialnet.set_number_of_frames(self.__frames.get_value()):
664 self.__frames.set_value(self.radialnet.get_number_of_frames())
665
666
667
668 class ControlLayout(bw.BWExpander):
669 """
670 """
671 def __init__(self, radialnet):
672 """
673 """
674 bw.BWExpander.__init__(self, 'Layout')
675
676 self.radialnet = radialnet
677
678 self.__create_widgets()
679
680
681 def __create_widgets(self):
682 """
683 """
684 self.__hbox = bw.BWHBox()
685
686 self.__layout = gtk.combo_box_new_text()
687 self.__layout.append_text('Symmetric')
688 self.__layout.append_text('Weighted')
689 self.__layout.set_active(self.radialnet.get_layout())
690 self.__layout.connect('changed', self.__change_layout)
691 self.__force = gtk.ToolButton(gtk.STOCK_REFRESH)
692 self.__force.connect('clicked', self.__force_update)
693
694 self.__hbox.bw_pack_start_expand_fill(self.__layout)
695 self.__hbox.bw_pack_start_noexpand_nofill(self.__force)
696
697 self.bw_add(self.__hbox)
698
699 self.__check_layout()
700
701
702 def __check_layout(self):
703 """
704 """
705 if self.__layout.get_active() == LAYOUT_WEIGHTED:
706 self.__force.set_sensitive(True)
707
708 else:
709 self.__force.set_sensitive(False)
710
711 return True
712
713
714 def __force_update(self, widget):
715 """
716 """
717 self.__fisheye_ring = self.radialnet.get_fisheye_ring()
718 self.radialnet.update_layout()
719
720
721 def __change_layout(self, widget):
722 """
723 """
724 if not self.radialnet.set_layout(self.__layout.get_active()):
725 self.__layout.set_active(self.radialnet.get_layout())
726
727 else:
728 self.__check_layout()
729
730
731
732 class ControlRingGap(bw.BWVBox):
733 """
734 """
735 def __init__(self, radialnet):
736 """
737 """
738 bw.BWVBox.__init__(self)
739
740 self.radialnet = radialnet
741
742 self.__create_widgets()
743
744
745 def __create_widgets(self):
746 """
747 """
748 self.__radius = ControlVariable('Ring gap',
749 self.radialnet.get_ring_gap,
750 self.radialnet.set_ring_gap)
751
752 self.__label = gtk.Label('Lower ring gap')
753 self.__label.set_alignment(0.0, 0.5)
754 self.__adjustment = gtk.Adjustment(self.radialnet.get_min_ring_gap(),
755 0,
756 50,
757 1)
758 self.__spin = gtk.SpinButton(self.__adjustment)
759 self.__spin.connect('value_changed', self.__change_lower)
760
761 self.__lower_hbox = bw.BWHBox()
762 self.__lower_hbox.bw_pack_start_expand_fill(self.__label)
763 self.__lower_hbox.bw_pack_start_noexpand_nofill(self.__spin)
764
765 self.bw_pack_start_noexpand_nofill(self.__radius)
766 self.bw_pack_start_noexpand_nofill(self.__lower_hbox)
767
768
769 def __change_lower(self, widget):
770 """
771 """
772 if not self.radialnet.set_min_ring_gap(self.__adjustment.get_value()):
773 self.__adjustment.set_value(self.radialnet.get_min_ring_gap())
774
775
776
777 class ControlOptions(bw.BWScrolledWindow):
778 """
779 """
780 def __init__(self, radialnet):
781 """
782 """
783 bw.BWScrolledWindow.__init__(self)
784
785 self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
786 self.set_shadow_type(gtk.SHADOW_NONE)
787
788 self.radialnet = radialnet
789
790 self.__create_widgets()
791
792
793 def __create_widgets(self):
794 """
795 """
796 self.__liststore = gtk.ListStore(gobject.TYPE_BOOLEAN,
797 gobject.TYPE_STRING)
798
799 self.__liststore.append([None, OPTIONS[0]])
800 self.__liststore.append([None, OPTIONS[1]])
801 self.__liststore.append([None, OPTIONS[2]])
802 self.__liststore.append([None, OPTIONS[3]])
803 self.__liststore.append([None, OPTIONS[4]])
804 self.__liststore.append([None, OPTIONS[5]])
805 self.__liststore.append([None, OPTIONS[6]])
806
807 self.__cell_toggle = gtk.CellRendererToggle()
808 self.__cell_toggle.set_property('activatable', True)
809 self.__cell_toggle.connect('toggled',
810 self.__change_option,
811 self.__liststore)
812
813 self.__column_toggle = gtk.TreeViewColumn('', self.__cell_toggle)
814 self.__column_toggle.add_attribute(self.__cell_toggle, 'active', 0)
815
816 self.__cell_text = gtk.CellRendererText()
817
818 self.__column_text = gtk.TreeViewColumn('Enable',
819 self.__cell_text,
820 text=1)
821
822 self.__treeview = gtk.TreeView(self.__liststore)
823 self.__treeview.set_enable_search(True)
824 self.__treeview.set_search_column(1)
825 self.__treeview.append_column(self.__column_toggle)
826 self.__treeview.append_column(self.__column_text)
827
828 self.add_with_viewport(self.__treeview)
829
830 gobject.timeout_add(REFRESH_RATE, self.__update_options)
831
832
833 def __update_options(self):
834 """
835 """
836 model = self.__liststore
837
838 model[OPTIONS.index('address')][0] = self.radialnet.get_show_address()
839 model[OPTIONS.index('hostname')][0] = self.radialnet.get_show_hostname()
840 model[OPTIONS.index('icon')][0] = self.radialnet.get_show_icon()
841 model[OPTIONS.index('latency')][0] = self.radialnet.get_show_latency()
842 model[OPTIONS.index('ring')][0] = self.radialnet.get_show_ring()
843 model[OPTIONS.index('region')][0] = self.radialnet.get_show_region()
844 model[OPTIONS.index('slow in/out')][0] = self.radialnet.get_slow_inout()
845
846 return True
847
848
849 def __change_option(self, cell, option, model):
850 """
851 """
852 option = int(option)
853 model[option][0] = not model[option][0]
854
855 if OPTIONS[option] == 'address':
856 self.radialnet.set_show_address(model[option][0])
857
858 elif OPTIONS[option] == 'hostname':
859 self.radialnet.set_show_hostname(model[option][0])
860
861 elif OPTIONS[option] == 'icon':
862 self.radialnet.set_show_icon(model[option][0])
863
864 elif OPTIONS[option] == 'latency':
865 self.radialnet.set_show_latency(model[option][0])
866
867 elif OPTIONS[option] == 'ring':
868 self.radialnet.set_show_ring(model[option][0])
869
870 elif OPTIONS[option] == 'region':
871 self.radialnet.set_show_region(model[option][0])
872
873 elif OPTIONS[option] == 'slow in/out':
874 self.radialnet.set_slow_inout(model[option][0])
875
876
877
878 class ControlView(bw.BWExpander):
879 """
880 """
881 def __init__(self, radialnet):
882 """
883 """
884 bw.BWExpander.__init__(self, 'View')
885 self.set_expanded(True)
886
887 self.radialnet = radialnet
888
889 self.__create_widgets()
890
891
892 def __create_widgets(self):
893 """
894 """
895 self.__vbox = bw.BWVBox(spacing=0)
896
897 self.__zoom = ControlVariable('Zoom',
898 self.radialnet.get_zoom,
899 self.radialnet.set_zoom)
900
901 self.__ring_gap = ControlRingGap(self.radialnet)
902 self.__navigation = ControlNavigation(self.radialnet)
903
904 self.__options = ControlOptions(self.radialnet)
905 self.__options.set_border_width(0)
906
907 self.__vbox.bw_pack_start_expand_nofill(self.__options)
908 self.__vbox.bw_pack_start_noexpand_nofill(self.__navigation)
909 self.__vbox.bw_pack_start_noexpand_nofill(self.__zoom)
910 self.__vbox.bw_pack_start_noexpand_nofill(self.__ring_gap)
911
912 self.bw_add(self.__vbox)
913
914
915
916 class ControlNavigation(gtk.DrawingArea):
917 """
918 """
919 def __init__(self, radialnet):
920 """
921 """
922 gtk.DrawingArea.__init__(self)
923
924 self.radialnet = radialnet
925
926 self.__rotate_node = PolarCoordinate()
927 self.__rotate_node.set_coordinate(40, 90)
928 self.__center_of_widget = (50, 50)
929 self.__moving = None
930 self.__centering = False
931 self.__rotating = False
932 self.__move_pass = 100
933
934 self.__move_position = (0, 0)
935 self.__move_addition = [(-1, 0),
936 (-1,-1),
937 ( 0,-1),
938 ( 1,-1),
939 ( 1, 0),
940 ( 1, 1),
941 ( 0, 1),
942 (-1, 1)]
943
944 self.__move_factor = 1
945 self.__move_factor_limit = 20
946
947 self.__rotate_radius = 6
948 self.__move_radius = 6
949
950 self.__rotate_clicked = False
951 self.__move_clicked = None
952
953 self.connect('expose_event', self.expose)
954 self.connect('button_press_event', self.button_press)
955 self.connect('button_release_event', self.button_release)
956 self.connect('motion_notify_event', self.motion_notify)
957 self.connect('enter_notify_event', self.enter_notify)
958 self.connect('leave_notify_event', self.leave_notify)
959 self.connect('key_press_event', self.key_press)
960 self.connect('key_release_event', self.key_release)
961
962 self.add_events(gtk.gdk.BUTTON_PRESS_MASK |
963 gtk.gdk.BUTTON_RELEASE_MASK |
964 gtk.gdk.ENTER_NOTIFY |
965 gtk.gdk.LEAVE_NOTIFY |
966 gtk.gdk.MOTION_NOTIFY |
967 gtk.gdk.NOTHING |
968 gtk.gdk.KEY_PRESS_MASK |
969 gtk.gdk.KEY_RELEASE_MASK |
970 gtk.gdk.POINTER_MOTION_HINT_MASK |
971 gtk.gdk.POINTER_MOTION_MASK)
972
973 self.__rotate_node.set_coordinate(40, self.radialnet.get_rotation())
974
975
976 def key_press(self, widget, event):
977 """
978 """
979 key = gtk.gdk.keyval_name(event.keyval)
980
981 self.queue_draw()
982
983 return True
984
985
986 def key_release(self, widget, event):
987 """
988 """
989 key = gtk.gdk.keyval_name(event.keyval)
990
991 self.queue_draw()
992
993 return True
994
995
996 def enter_notify(self, widget, event):
997 """
998 """
999 return False
1000
1001
1002 def leave_notify(self, widget, event):
1003 """
1004 """
1005 self.queue_draw()
1006
1007 return False
1008
1009
1010 def button_press(self, widget, event):
1011 """
1012 Drawing callback
1013 @type widget: GtkWidget
1014 @param widget: Gtk widget superclass
1015 @type event: GtkEvent
1016 @param event: Gtk event of widget
1017 @rtype: boolean
1018 @return: Indicator of the event propagation
1019 """
1020 pointer = self.get_pointer()
1021
1022 direction = False
1023
1024 if self.__rotate_is_clicked(pointer) == True:
1025
1026 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
1027 self.__rotating = True
1028
1029 direction = self.__move_is_clicked(pointer)
1030
1031 if direction != None and self.__moving == None:
1032
1033 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
1034 self.__moving = direction
1035 self.__move_in_direction(direction)
1036
1037 if self.__center_is_clicked(pointer) == True:
1038
1039 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
1040 self.__centering = True
1041 self.__move_position = (0, 0)
1042 self.radialnet.set_translation(self.__move_position)
1043
1044 self.queue_draw()
1045
1046 return False
1047
1048
1049 def button_release(self, widget, event):
1050 """
1051 Drawing callback
1052 @type widget: GtkWidget
1053 @param widget: Gtk widget superclass
1054 @type event: GtkEvent
1055 @param event: Gtk event of widget
1056 @rtype: boolean
1057 @return: Indicator of the event propagation
1058 """
1059 self.__moving = None # stop moving
1060 self.__centering = False
1061 self.__rotating = False # stop rotate
1062 self.__move_factor = 1
1063
1064 event.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
1065
1066 self.queue_draw()
1067
1068 return False
1069
1070
1071 def motion_notify(self, widget, event):
1072 """
1073 Drawing callback
1074 @type widget: GtkWidget
1075 @param widget: Gtk widget superclass
1076 @type event: GtkEvent
1077 @param event: Gtk event of widget
1078 @rtype: boolean
1079 @return: Indicator of the event propagation
1080 """
1081 xc, yc = self.__center_of_widget
1082 x, y = self.get_pointer()
1083
1084 status = not self.radialnet.is_in_animation()
1085 status = status and not self.radialnet.is_empty()
1086
1087 if self.__rotating == True and status:
1088
1089 r, t = self.__rotate_node.get_coordinate()
1090 t = math.degrees(math.atan2(yc - y, x - xc))
1091
1092 if t < 0:
1093 t = 360 + t
1094
1095 self.radialnet.set_rotation(t)
1096 self.__rotate_node.set_coordinate(r, t)
1097
1098 self.queue_draw()
1099
1100 return False
1101
1102
1103 def expose(self, widget, event):
1104 """
1105 Drawing callback
1106 @type widget: GtkWidget
1107 @param widget: Gtk widget superclass
1108 @type event: GtkEvent
1109 @param event: Gtk event of widget
1110 @rtype: boolean
1111 @return: Indicator of the event propagation
1112 """
1113 self.set_size_request(120, 130)
1114
1115 self.context = widget.window.cairo_create()
1116 self.__draw()
1117
1118 return False
1119
1120
1121 def __draw_rotate_control(self):
1122 """
1123 """
1124 xc, yc = self.__center_of_widget
1125 r, t = self.__rotate_node.get_coordinate()
1126 x, y = self.__rotate_node.to_cartesian()
1127
1128 # draw text
1129 self.context.set_font_size(10)
1130 self.context.move_to(xc - 49, yc - 48)
1131 self.context.show_text("Navigation")
1132
1133 width = self.context.text_extents(str(int(t)))[2]
1134 self.context.move_to(xc + 49 - width - 2, yc - 48)
1135 self.context.show_text(str(round(t, 1)))
1136 self.context.set_line_width(1)
1137 self.context.stroke()
1138
1139 # draw arc
1140 self.context.set_dash([1,2])
1141 self.context.arc(xc, yc, 40, 0, 2 * math.pi)
1142 self.context.set_source_rgb(0.0, 0.0, 0.0)
1143 self.context.set_line_width(1)
1144 self.context.stroke()
1145
1146 # draw node
1147 self.context.set_dash([1,0])
1148 self.context.arc(xc + x, yc - y, self.__rotate_radius, 0, 2 * math.pi)
1149
1150 if self.__rotating == True:
1151 self.context.set_source_rgb(0.0, 0.0, 0.0)
1152
1153 else:
1154 self.context.set_source_rgb(1.0, 1.0, 1.0)
1155
1156 self.context.fill_preserve()
1157 self.context.set_source_rgb(0.0, 0.0, 0.0)
1158 self.context.set_line_width(1)
1159 self.context.stroke()
1160
1161 return False
1162
1163
1164 def __draw_move_control(self):
1165 """
1166 """
1167 xc, yc = self.__center_of_widget
1168 pc = PolarCoordinate()
1169
1170 self.context.set_dash([1,1])
1171 self.context.arc(xc, yc, 23, 0, 2 * math.pi)
1172 self.context.set_source_rgb(0.0, 0.0, 0.0)
1173 self.context.set_line_width(1)
1174 self.context.stroke()
1175
1176 for i in range(8):
1177
1178 pc.set_coordinate(23, 45 * i)
1179 x, y = pc.to_cartesian()
1180
1181 self.context.set_dash([1,1])
1182 self.context.move_to(xc, yc)
1183 self.context.line_to(xc + x, yc - y)
1184 self.context.stroke()
1185
1186 self.context.set_dash([1,0])
1187 self.context.arc(xc + x, yc - y, self.__move_radius, 0, 2 * math.pi)
1188
1189 if i == self.__moving:
1190 self.context.set_source_rgb(0.0, 0.0, 0.0)
1191 else:
1192 self.context.set_source_rgb(1.0, 1.0, 1.0)
1193 self.context.fill_preserve()
1194 self.context.set_source_rgb(0.0, 0.0, 0.0)
1195 self.context.set_line_width(1)
1196 self.context.stroke()
1197
1198 self.context.arc(xc, yc, 6, 0, 2 * math.pi)
1199
1200 if self.__centering == True:
1201 self.context.set_source_rgb(0.0, 0.0, 0.0)
1202 else:
1203 self.context.set_source_rgb(1.0, 1.0, 1.0)
1204 self.context.fill_preserve()
1205 self.context.set_source_rgb(0.0, 0.0, 0.0)
1206 self.context.set_line_width(1)
1207 self.context.stroke()
1208
1209 return False
1210
1211
1212 def __draw(self):
1213 """
1214 Drawing method
1215 """
1216 # Getting allocation reference
1217 allocation = self.get_allocation()
1218
1219 self.__center_of_widget = (allocation.width / 2,
1220 allocation.height / 2)
1221
1222 self.__draw_rotate_control()
1223 self.__draw_move_control()
1224
1225 return False
1226
1227
1228 def __move_in_direction(self, direction):
1229 """
1230 """
1231 if self.__moving != None:
1232
1233 bx, by = self.__move_position
1234 ax, ay = self.__move_addition[direction]
1235
1236 self.__move_position = (bx + self.__move_factor * ax,
1237 by + self.__move_factor * ay)
1238 self.radialnet.set_translation(self.__move_position)
1239
1240 if self.__move_factor < self.__move_factor_limit:
1241 self.__move_factor += 1
1242
1243 gobject.timeout_add(self.__move_pass,
1244 self.__move_in_direction,
1245 direction)
1246
1247 return False
1248
1249
1250 def __rotate_is_clicked(self, pointer):
1251 """
1252 """
1253 xn, yn = self.__rotate_node.to_cartesian()
1254 xc, yc = self.__center_of_widget
1255
1256 center = (xc + xn, yc - yn)
1257 result = geometry.is_in_circle(pointer, self.__rotate_radius, center)
1258
1259 if result == True:
1260 return True
1261
1262 return False
1263
1264
1265 def __center_is_clicked(self, pointer):
1266 """
1267 """
1268 result = geometry.is_in_circle(pointer,
1269 self.__move_radius,
1270 self.__center_of_widget)
1271
1272 if result == True:
1273 return True
1274
1275 return False
1276
1277
1278 def __move_is_clicked(self, pointer):
1279 """
1280 """
1281 xc, yc = self.__center_of_widget
1282 pc = PolarCoordinate()
1283
1284 for i in range(8):
1285
1286 pc.set_coordinate(23, 45 * i)
1287 x, y = pc.to_cartesian()
1288
1289 center = (xc + x, yc - y)
1290 result = geometry.is_in_circle(pointer,
1291 self.__move_radius,
1292 center)
1293
1294 if result == True:
1295 return i
1296
1297 return None
1298
1299