root/trunk/umitGUI/radialnet/ControlWidget.py @ 3798

Revision 3798, 37.2 kB (checked in by luis, 4 years ago)

Integration of RadialNet:
- higwidgets
- Added Mapper to Notebook
- Change version number
Credit for commit: me and Daniel Cassiano
AUTHOR of RadialNet: Joao Medeiros

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