class InkToolBar(gtk.Toolbar): # Constructor def __init__(self, arbiter): gtk.Toolbar.__init__(self) self.__arbiter = arbiter self.__logger = logging.getLogger('InkToolBar') self.__logger.setLevel(logging.DEBUG) self.__cur_color = self.__arbiter.get_pen_color() self.__cur_color_str = "blue" self.__cur_pen = self.__arbiter.get_pen_size() self.__arbiter.connect_slide_redraw(self.update_buttons) self.__arbiter.connect_undo_redo_changed(self.update_buttons) # Red Ink self.__red = gtk.RadioToolButton() self.__red.set_icon_name('red-button') self.insert(self.__red, -1) self.__red.show() #self.__red.set_tooltip('Red Ink') self.__red.connect('clicked', self.set_ink_color, 1.0, 0.0, 0.0, "red") # Green Ink self.__green = gtk.RadioToolButton(group=self.__red) self.__green.set_icon_name('green-button') self.insert(self.__green, -1) self.__green.show() #self.__green.set_tooltip('Green Ink') self.__green.connect('clicked', self.set_ink_color, 0.0, 1.0, 0.0, "green") # Blue Ink self.__blue = gtk.RadioToolButton(group=self.__red) self.__blue.set_icon_name('blue-button') self.insert(self.__blue, -1) self.__blue.show() #self.__blue.set_tooltip('Blue Ink') self.__blue.connect('clicked', self.set_ink_color, 0.0, 0.0, 1.0, "blue") # Black Ink self.__black = gtk.RadioToolButton(group=self.__red) self.__black.set_icon_name('black-button') self.insert(self.__black, -1) self.__black.show() #self.__black.set_tooltip('Black Ink') self.__black.connect('clicked', self.set_ink_color, 0.0, 0.0, 0.0, "black") # Separate ink from untensils separator = gtk.SeparatorToolItem() separator.set_draw(False) self.insert(separator, -1) separator.show() # Pencil self.__pencil = gtk.RadioToolButton() self.__pencil.set_icon_name('tool-pencil') self.insert(self.__pencil, -1) self.__pencil.show() #self.__pencil.set_tooltip('Pencil') self.__pencil.connect('clicked', self.set_cur_pen, 4) # Brush self.__brush = gtk.RadioToolButton(self.__pencil) self.__brush.set_icon_name('tool-brush') self.insert(self.__brush, -1) self.__brush.show() #self.__brush.set_tooltip('Brush') self.__brush.connect('clicked', self.set_cur_pen, 8) # Erase self.__erase = ToolButton('tool-eraser') self.insert(self.__erase, -1) self.__erase.show() self.__erase.set_tooltip(_('Erase All Ink')) self.__erase.connect('clicked', self.erase_btn_clicked) """ # Text self.__text = ToolButton('text') self.insert(self.__text, -1) self.__text.show() self.__text.set_tooltip('Text') """ # Separate tools from text separator = gtk.SeparatorToolItem() separator.set_draw(False) self.insert(separator, -1) separator.show() # Undo self.__undo = ToolButton('edit-undo') self.insert(self.__undo, -1) self.__undo.show() self.__undo.set_tooltip(_('Undo')) self.__undo.connect('clicked', self.undo) # Redo self.__redo = ToolButton('edit-redo') self.insert(self.__redo, -1) self.__redo.show() self.__redo.set_tooltip(_('Redo')) self.__redo.connect('clicked', self.redo) separator = gtk.SeparatorToolItem() separator.set_draw(False) separator.set_expand(True) self.insert(separator, -1) separator.show() self.__submit = ToolButton('broadcast') self.insert(self.__submit, -1) self.__submit.show() self.__submit.set_tooltip(_('Broadcast Submission')) self.__submit.connect('clicked', self.submit_ink_cb) self.__arbiter.connect_joined(self.activity_joined_cb) self.set_tool_buttons() self.show() self.update_buttons() def activity_joined_cb(self, widget): self.__submit.set_tooltip(_('Submit Ink')) self.__submit.set_icon('dialog-ok') def set_cur_pen(self, widget, size): self.__arbiter.do_set_pen(size) def set_ink_color(self, widget, r, g, b, color): self.__arbiter.do_set_color(r, g, b) def erase_btn_clicked(self, widget): self.__arbiter.do_clear_ink() def set_tool_buttons(self): if self.__cur_color == (1.0, 0.0, 0.0): self.__red.set_active(True) elif self.__cur_color == (0.0, 1.0, 0.0): self.__green.set_active(True) elif self.__cur_color == (0.0, 0.0, 1.0): self.__blue.set_active(True) else: self.__black.set_active(True) if self.__cur_pen == 2: self.__pencil.set_active(True) elif self.__cur_pen == 5: self.__brush.set_active(True) def submit_ink_cb(self, widget): if self.__arbiter.get_is_instructor(): self.__logger.debug("Broadcast clicked") self.broadcast_ink() else: self.__logger.debug("Submit clicked") self.__submit.set_sensitive(False) self.__timer = threading.Timer(10.0, self.reenable_submissions) self.__timer.start() self.__arbiter.do_submit_ink() def broadcast_ink(self): self.__arbiter.do_broadcast_ink() def reenable_submissions(self): gtk.gdk.threads_enter() self.__submit.set_sensitive(True) self.__submit.queue_draw() gtk.gdk.threads_leave() def undo(self, widget): self.__arbiter.do_undo() def redo(self, widget): self.__arbiter.do_redo() def update_buttons(self, widget=None): can_undo, can_redo = self.__arbiter.get_can_undo_redo() self.__undo.set_sensitive(can_undo) self.__redo.set_sensitive(can_redo) if self.__arbiter.get_is_instructor(): if self.__arbiter.get_active_submission() == -1: self.__submit.set_sensitive(False) else: self.__submit.set_sensitive(True)
class SlideruleActivity(activity.Activity): def __init__(self, handle): super(SlideruleActivity, self).__init__(handle) try: # Use 0.86 toolbar design toolbar_box = ToolbarBox() # Buttons added to the Activity toolbar activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() # C slider self.c_slider = ToolButton("Con") self.c_slider.set_tooltip(_('C')) self.c_slider.props.sensitive = True self.c_slider.connect('clicked', self._c_slider_cb) toolbar_box.toolbar.insert(self.c_slider, -1) self.c_slider.show() # A slider self.a_slider = ToolButton("Aoff") self.a_slider.set_tooltip(_('A')) self.a_slider.props.sensitive = True self.a_slider.connect('clicked', self._a_slider_cb) toolbar_box.toolbar.insert(self.a_slider, -1) self.a_slider.show() # Label for showing status self.results_label = gtk.Label("1.0 × 1.0 = 1.0") self.results_label.show() results_toolitem = gtk.ToolItem() results_toolitem.add(self.results_label) toolbar_box.toolbar.insert(results_toolitem, -1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) # The ever-present Stop Button stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>Q' toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() except NameError: # Use pre-0.86 toolbar design self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.projectToolbar = ProjectToolbar(self) self.toolbox.add_toolbar(_('Project'), self.projectToolbar) self.toolbox.show() # Create a canvas canvas = gtk.DrawingArea() canvas.set_size_request(gtk.gdk.screen_width(), \ gtk.gdk.screen_height()) self.set_canvas(canvas) canvas.show() self.show_all() # Initialize the canvas self.tw = window.new_window(canvas, \ os.path.join(activity.get_bundle_path(), \ 'images/'), \ self) # Read the slider positions from the Journal try: self.tw.A.spr.move_relative((int(self.metadata['A']), 0)) self.tw.C.spr.move_relative((int(self.metadata['C']), 0)) self.tw.C_tab_left.spr.move_relative((int(self.metadata['C']), 0)) self.tw.C_tab_right.spr.move_relative((int(self.metadata['C'])+\ SWIDTH-100,0)) self.tw.D.spr.move_relative((int(self.metadata['D']), 0)) self.tw.R.spr.move_relative((int(self.metadata['R']), 0)) self.tw.R_tab_top.spr.move_relative((int(self.metadata['R']), 0)) self.tw.R_tab_bot.spr.move_relative((int(self.metadata['R']), 0)) self.tw.slider_on_top = self.metadata['slider'] if self.tw.slider_on_top == 'A': self._show_a() else: self._show_c() window._update_results_label(self.tw) window._update_slider_labels(self.tw) except: self._show_c() def _c_slider_cb(self, button): self._show_c() return True def _show_c(self): self.c_slider.set_icon("Con") self.a_slider.set_icon("Aoff") self.tw.A.spr.hide() self.tw.C.draw_slider(1000) self.tw.C_tab_left.draw_slider(1000) self.tw.C_tab_right.draw_slider(1000) self.tw.slider_on_top = "C" def _a_slider_cb(self, button): self._show_a() return True def _show_a(self): self.c_slider.set_icon("Coff") self.a_slider.set_icon("Aon") self.tw.C.spr.hide() self.tw.C_tab_left.spr.hide() self.tw.C_tab_right.spr.hide() self.tw.A.draw_slider(1000) self.tw.slider_on_top = "A" return True """ Write the slider positions to the Journal """ def write_file(self, file_path): _logger.debug("Write slider on top: " + self.tw.slider_on_top) self.metadata['slider'] = self.tw.slider_on_top x, y = self.tw.A.spr.get_xy() _logger.debug("Write A offset: " + str(x)) self.metadata['A'] = str(x) x, y = self.tw.C.spr.get_xy() _logger.debug("Write C offset: " + str(x)) self.metadata['C'] = str(x) x, y = self.tw.D.spr.get_xy() _logger.debug("Write D offset: " + str(x)) self.metadata['D'] = str(x) x, y = self.tw.R.spr.get_xy() _logger.debug("Write r offset: " + str(x)) self.metadata['R'] = str(x)
class Navidad(activity.Activity): def __init__(self,handle): activity.Activity.__init__(self, handle, True) cs = ActivityToolbarButton(self) c = gtk.SeparatorToolItem() c.set_expand(True) lugar = activity.get_bundle_path() self.Musica = gst.element_factory_make('playbin') self.Musica.set_property('uri','file://'+lugar+'/Musica.ogg') self.Musica.set_state(gst.STATE_PLAYING) self.Toolbar = ToolbarBox() self.Toolbar.toolbar.insert(cs,-1) self.F = ToolButton('F') self.Toolbar.toolbar.insert(self.F,-1) self.cambiado = False self.cambiadoc = False self.E = ToolButton('E') self.Toolbar.toolbar.insert(self.E,-1) self.L = ToolButton('L') self.Toolbar.toolbar.insert(self.L,-1) self.I = ToolButton('I') self.Toolbar.toolbar.insert(self.I,-1) self.Z = ToolButton('Z') self.Toolbar.toolbar.insert(self.Z,-1) self.N = ToolButton('N') self.Toolbar.toolbar.insert(self.N,-1) self.AA = ToolButton('A') self.Toolbar.toolbar.insert(self.AA,-1) self.V = ToolButton('V') self.Toolbar.toolbar.insert(self.V,-1) self.II = ToolButton('I') self.Toolbar.toolbar.insert(self.II,-1) self.D = ToolButton('D') self.Toolbar.toolbar.insert(self.D,-1) self.AAA = ToolButton('A') self.Toolbar.toolbar.insert(self.AAA,-1) self.DD = ToolButton('D') self.Toolbar.toolbar.insert(self.DD,-1) self.cambiar() Stop = StopButton(self) b = gtk.SeparatorToolItem() b.set_expand(True) self.Toolbar.toolbar.insert(Stop,-1) self.vox = gtk.EventBox() vs = gtk.VBox() self.vox.add(vs) Imagen = gtk.Image() Imagen.set_from_file('Imagen.svg') bs = gtk.TextBuffer() bs.set_text('El equipo de CeibalJAM! te desea feliz navidad y prospero año nuevo') entry = gtk.TextView(bs) fuente = pango.FontDescription('11') entry.set_editable(False) entry.modify_font(fuente) self.vox.connect('button-release-event',self.color,entry) self.color('a','b',entry) self.label = gtk.Label(saber()) self.label.modify_font(fuente) vs.pack_start(self.label,False,False,0) color(self.label) vs.pack_end(entry,False,False,0) self.set_canvas(self.vox) vs.pack_start(Imagen,True,True,0) self.set_toolbar_box(self.Toolbar) self.show_all() gobject.timeout_add(37500, self.sonido) def sonido(self): self.Musica.set_state(gst.STATE_NULL) self.Musica.set_state(gst.STATE_PLAYING) gobject.timeout_add(37500, self.sonido) def color(self,widget=None,event=None,entrada=None): colores = ["#FA2635","#33DA40"] cc = random.choice(colores) entrada.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(cc)) self.vox.modify_bg(gtk.STATE_NORMAL,gtk.gdk.color_parse(cc)) self.vox.show_all() gobject.timeout_add(500, self.color,'a','b',entrada) def cc(self,a=None,b=None,c=None,d=None): if self.cambiadoc: self.cambiado = True if not self.cambiadoc: self.cambiado = False def cambiar(self,a=None,b=None): if not self.cambiado: """ a cambiar """ self.F.set_icon('Fr') # 1 self.L.set_icon('Lr') # 3 self.Z.set_icon('Zr') # self.AA.set_icon('Ar') # self.II.set_icon('Ir') # self.AAA.set_icon('Ar') # """ VUELVEN """ self.E.set_icon('E') # Feliz Navidad # self.I.set_icon('I') self.N.set_icon('N') self.V.set_icon('V') self.D.set_icon('D') self.DD.set_icon('D') self.cambiadoc = True self.Toolbar.show_all() if self.cambiado: """ a cambiar """ self.F.set_icon('F') # 1 self.L.set_icon('L') # 3 self.Z.set_icon('Z') # self.AA.set_icon('A') # self.II.set_icon('I') # self.AAA.set_icon('A') # """ VUELVEN """ self.E.set_icon('Er') # Feliz Navidad # self.I.set_icon('Ir') self.N.set_icon('Nr') self.V.set_icon('Vr') self.D.set_icon('Dr') self.DD.set_icon('Dr') self.cambiadoc = False self.Toolbar.show_all() gobject.timeout_add(500, self.cc) gobject.timeout_add(500, self.cambiar)
class RecordControl: def __init__(self, toolbar): self._timer_value = TIMER_VALUES[0] self._timer_button = ToolButton("timer-0") self._timer_button.set_tooltip(_("Select timer")) self._timer_button.connect("clicked", self._timer_selection_cb) toolbar.insert(self._timer_button, -1) self._setup_timer_palette() self._duration_value = DURATION_VALUES[0] self._duration_button = ToolButton("duration-2") self._duration_button.set_tooltip(_("Select duration")) self._duration_button.connect("clicked", self._duration_selection_cb) toolbar.insert(self._duration_button, -1) self._setup_duration_palette() self._quality_value = 0 self._quality_button = ToolButton("low-quality") self._quality_button.set_tooltip(_("Select quality")) self._quality_button.connect("clicked", self._quality_selection_cb) toolbar.insert(self._quality_button, -1) self._setup_quality_palette() def _timer_selection_cb(self, widget): if self._timer_palette: if not self._timer_palette.is_up(): self._timer_palette.popup(immediate=True, state=self._timer_palette.SECONDARY) else: self._timer_palette.popdown(immediate=True) return def _setup_timer_palette(self): self._timer_palette = self._timer_button.get_palette() for seconds in TIMER_VALUES: if seconds == 0: text = _("Immediate") else: text = ngettext("%s second", "%s seconds", seconds) % seconds menu_item = MenuItem(icon_name="timer-%d" % (seconds), text_label=text) menu_item.connect("activate", self._timer_selected_cb, seconds) self._timer_palette.menu.append(menu_item) menu_item.show() def _timer_selected_cb(self, button, seconds): self.set_timer_idx(TIMER_VALUES.index(seconds)) def _duration_selection_cb(self, widget): if self._duration_palette: if not self._duration_palette.is_up(): self._duration_palette.popup(immediate=True, state=self._duration_palette.SECONDARY) else: self._duration_palette.popdown(immediate=True) return def _setup_duration_palette(self): self._duration_palette = self._duration_button.get_palette() for minutes in DURATION_VALUES: if minutes == 0: text = gtk.Label(_("Immediate")) else: text = ngettext("%s minute", "%s minutes", minutes) % minutes menu_item = MenuItem(icon_name="duration-%d" % (minutes), text_label=text) menu_item.connect("activate", self._duration_selected_cb, minutes) self._duration_palette.menu.append(menu_item) menu_item.show() def _duration_selected_cb(self, button, minutes): self.set_duration_idx(DURATION_VALUES.index(minutes)) def _quality_selection_cb(self, widget): if self._quality_palette: if not self._quality_palette.is_up(): self._quality_palette.popup(immediate=True, state=self._quality_palette.SECONDARY) else: self._quality_palette.popdown(immediate=True) return def _setup_quality_palette(self): self._quality_palette = self._quality_button.get_palette() for quality in QUALITY_VALUES: text = _("%s quality") % (quality) menu_item = MenuItem(icon_name=quality + "-quality", text_label=text) menu_item.connect("activate", self._quality_selected_cb, quality) self._quality_palette.menu.append(menu_item) menu_item.show() def _quality_selected_cb(self, button, quality): self.set_quality(QUALITY_VALUES.index(quality)) def set_mode(self, mode): if mode == constants.MODE_PHOTO: self._quality_button.set_sensitive(False) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(False) if mode == constants.MODE_VIDEO: self._quality_button.set_sensitive(True) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(True) if mode == constants.MODE_AUDIO: self._quality_button.set_sensitive(False) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(True) def get_timer(self): return self._timer_value def get_timer_idx(self): if self._timer_value in TIMER_VALUES: return TIMER_VALUES.index(self._timer_value) else: return TIMER_VALUES[0] def set_timer_idx(self, idx): self._timer_value = TIMER_VALUES[idx] if hasattr(self, "_timer_button"): self._timer_button.set_icon("timer-%d" % (self._timer_value)) def get_duration(self): return self._duration_value def get_duration_idx(self): if self._duration_value in DURATION_VALUES: return DURATION_VALUES.index(self._duration_value) else: return DURATION_VALUES[0] def set_duration_idx(self, idx): self._duration_value = DURATION_VALUES[idx] if hasattr(self, "_duration_button"): self._duration_button.set_icon("duration-%d" % (self._duration_value)) def get_quality(self): return self._quality_value def set_quality(self, idx): self._quality_value = idx if hasattr(self, "_quality_button"): self._quality_button.set_icon("%s-quality" % (QUALITY_VALUES[idx]))
class ErikosActivity(activity.Activity): def __init__(self, handle): super(ErikosActivity, self).__init__(handle) try: # Use 0.86 toolbar design toolbar_box = ToolbarBox() # Buttons added to the Activity toolbar activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() # Play Button self.play = ToolButton("media-playback-start") self.play.set_tooltip(_('Play')) self.play.props.sensitive = True self.play.connect('clicked', self._play_cb) toolbar_box.toolbar.insert(self.play, -1) self.play.show() # Sound Toggle Button self.sound = ToolButton("speaker-muted-100") self.sound.set_tooltip(_('Mute')) self.sound.props.sensitive = True self.sound.connect('clicked', self._sound_cb) toolbar_box.toolbar.insert(self.sound, -1) self.sound.show() separator = gtk.SeparatorToolItem() separator.show() toolbar_box.toolbar.insert(separator, -1) # Label for showing level self.level_label = gtk.Label("%s %d" % (_("Level"), 1)) self.level_label.show() level_toolitem = gtk.ToolItem() level_toolitem.add(self.level_label) toolbar_box.toolbar.insert(level_toolitem, -1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) # The ever-present Stop Button stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>Q' toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() except NameError: # Use pre-0.86 toolbar design self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.projectToolbar = ProjectToolbar(self) self.toolbox.add_toolbar(_('Project'), self.projectToolbar) self.toolbox.show() # Create a canvas canvas = gtk.DrawingArea() canvas.set_size_request(gtk.gdk.screen_width(), \ gtk.gdk.screen_height()) self.set_canvas(canvas) canvas.show() self.show_all() # Initialize the canvas self.sw = window.new_window(canvas, \ os.path.join(activity.get_bundle_path(), \ 'images/'), \ self) self.sw.activity = self # Read the level from the Journal try: sw.level = int(self.metadata['level']) except: pass def _play_cb(self, button): window.play_the_game(self.sw) return True def _sound_cb(self, button): if self.sw.sound is True: self.sound.set_icon("speaker-muted-000") self.sound.set_tooltip(_('Unmute')) self.sw.sound = False else: self.sound.set_icon("speaker-muted-100") self.sound.set_tooltip(_('Mute')) self.sw.sound = True return True """ Write the slider positions to the Journal """ def write_file(self, file_path): _logger.debug("Write level: " + str(self.sw.level)) self.metadata['level'] = self.sw.level
class SideToolbar(gtk.Toolbar): ''' A toolbar on the side of the canvas for adjusting gain/bias ''' def __init__(self, activity, channel=0): ''' Set up initial toolbars ''' gtk.Toolbar.__init__(self) self.activity = activity self._channel = channel if self._channel == 0: self.show_toolbar = True else: # Don't show second channel until we need it self.show_toolbar = False self.mode = 'sound' self.mode_values = {'sound': 3, 'sensor': 2} self._toggle = gtk.CheckButton() self._toggle.set_active(True) self._toggle.connect('clicked', self.toggle_cb) self._toggle.show() self._toggle_box = gtk.HBox() self._toggle_box.pack_start(self._toggle, False, True, 18) self._invert = ToolButton('invert') self._invert.set_tooltip(_('Invert')) self._invert.connect('clicked', self.invert_control_cb) self._invert.show() self.activity.wave.set_invert_state(False, channel=self._channel) self.button_up = ToolButton('amp-high') self.button_up.set_tooltip(_('Increase amplitude')) self.button_up.connect('clicked', self._button_up_cb) self.button_up.show() self.adjustmenty = gtk.Adjustment(self.mode_values[self.mode], LOWER, UPPER, 0.1, 0.1, 0.0) self.adjustmenty.connect('value_changed', self._yscrollbar_cb, self.adjustmenty) self.yscrollbar = gtk.VScale(self.adjustmenty) self.yscrollbar.set_draw_value(False) self.yscrollbar.set_inverted(True) self.yscrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS) self.button_down = ToolButton('amp-low') self.button_down.set_tooltip(_('Decrease amplitude')) self.button_down.connect('clicked', self._button_down_cb) self.button_down.show() self.box1 = gtk.VBox(False, 0) if self._channel == 0: self.box1.pack_start(self._color_wave(self.activity.stroke_color), False, True, 0) elif self._channel == 1: self.box1.pack_start(self._color_wave(self.activity.fill_color), False, True, 0) else: self.box1.pack_start(self._color_wave('#FFFFFF'), False, True, 0) self.box1.pack_start(self._toggle_box, False, True, 0) self.box1.pack_start(self._invert, False, True, 0) self.box1.pack_start(self.button_up, False, True, 0) self.box1.pack_start(self.yscrollbar, True, True, 0) self.box1.pack_start(self.button_down, False, True, 0) self.set_show_hide(False) def _yscrollbar_cb(self, adjy, data=None): ''' Callback for scrollbar ''' if self.mode == 'sound': self.activity.wave.set_mag_params(1.0, adjy.value, channel=self._channel) self.activity.wave.set_bias_param(0, channel=self._channel) elif self.mode == 'sensor': self.activity.wave.set_bias_param(int( 300 * (adjy.value - (UPPER - LOWER) / 2.)), channel=self._channel) self.mode_values[self.mode] = adjy.value return True def _button_up_cb(self, data=None): '''Moves slider up''' new_value = self.yscrollbar.get_value() + (UPPER - LOWER) \ / 100. if new_value <= UPPER: self.yscrollbar.set_value(new_value) else: self.yscrollbar.set_value(UPPER) return True def _button_down_cb(self, data=None): '''Moves slider down''' new_value = self.yscrollbar.get_value() - (UPPER - LOWER) \ / 100. if new_value >= LOWER: self.yscrollbar.set_value(new_value) else: self.yscrollbar.set_value(LOWER) return True def set_show_hide(self, show=True, mode='sound'): ''' Show or hide the toolbar ''' self.show_toolbar = show self.set_side_mode(mode) def set_side_mode(self, mode='sound'): ''' Set the toolbar to either 'sound' or 'sensor' ''' self.mode = mode if self.mode == 'sound': self.button_up.set_icon('amp-high') self.button_up.set_tooltip(_('Increase amplitude')) self.button_down.set_icon('amp-low') self.button_down.set_tooltip(_('Decrease amplitude')) elif self.mode == 'sensor': self.button_up.set_icon('bias-high') self.button_up.set_tooltip(_('Increase bias')) self.button_down.set_icon('bias-low') self.button_down.set_tooltip(_('Decrease bias')) self._invert.show() self.yscrollbar.set_value(self.mode_values[self.mode]) return def toggle_cb(self, data=None): self.activity.wave.set_visibility(self._toggle.get_active(), channel=self._channel) return True def invert_control_cb(self, data=None): ''' Callback for Invert Button ''' if self.activity.wave.get_invert_state(channel=self._channel): self.activity.wave.set_invert_state(False, self._channel) self._invert.set_icon('invert') self._invert.show() elif not self.activity.wave.get_fft_mode(): self.activity.wave.set_invert_state(True, self._channel) self._invert.set_icon('invert2') self._invert.show() self.activity.sensor_toolbar.update_string_for_textbox() return False def _color_wave(self, color): ''' Generate a wave graphic in color to label each side toolbar ''' svg = '<?xml version="1.0" ?>\n\ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n\ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n\ <svg enable-background="new 0 0 55.125 55" height="55px" version="1.1"\n\ viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve"\n\ xmlns="http://www.w3.org/2000/svg"\n\ xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">\n\ <path d="M9.066,27.5 c2.32-6.917,4.666-13.834,9.255-13.834\n\ c9.179,0,9.179,27.668,18.358,27.668c4.59,0,6.986-6.917,9.332-13.834"\n\ fill="none" stroke="%s" stroke-linecap="round" stroke-width="3.5"/>\n\ </svg>' % (color) pixbuf = svg_str_to_pixbuf(svg) img = gtk.Image() img.set_from_pixbuf(pixbuf) img_tool = gtk.ToolItem() img_tool.add(img) return img_tool
class AbacusActivity(activity.Activity): def __init__(self, handle): """ Initiate activity. """ super(AbacusActivity, self).__init__(handle) if _new_sugar_system: # Use 0.86 toolbar design toolbar_box = ToolbarBox() # Buttons added to the Activity toolbar activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() # Suanpan (Chinese abacus) 2:5 self.chinese = ToolButton("Con") self.chinese.set_tooltip(_('Suanpan')) self.chinese.props.sensitive = True self.chinese.connect('clicked', self._chinese_cb) toolbar_box.toolbar.insert(self.chinese, -1) self.chinese.show() # Soroban (Japanese abacus) 1:4 self.japanese = ToolButton("Joff") self.japanese.set_tooltip(_('Soroban')) self.japanese.props.sensitive = True self.japanese.connect('clicked', self._japanese_cb) toolbar_box.toolbar.insert(self.japanese, -1) self.japanese.show() # Schety (Russian abacus) 0:10 self.russian = ToolButton("Roff") self.russian.set_tooltip(_('Schety')) self.russian.props.sensitive = True self.russian.connect('clicked', self._russian_cb) toolbar_box.toolbar.insert(self.russian, -1) self.russian.show() # Nepohualtzintzin (Mayan abacus) 3:4 (base 20) self.mayan = ToolButton("Moff") self.mayan.set_tooltip(_('Nepohualtzintzin')) self.mayan.props.sensitive = True self.mayan.connect('clicked', self._mayan_cb) toolbar_box.toolbar.insert(self.mayan, -1) self.mayan.show() # Binary (base 2) self.binary = ToolButton("Boff") self.binary.set_tooltip(_('Binary')) self.binary.props.sensitive = True self.binary.connect('clicked', self._binary_cb) toolbar_box.toolbar.insert(self.binary, -1) self.binary.show() # Hexadecimal (base 16) self.hex = ToolButton("Hoff") self.hex.set_tooltip(_('Hexadecimal')) self.hex.props.sensitive = True self.hex.connect('clicked', self._hex_cb) toolbar_box.toolbar.insert(self.hex, -1) self.hex.show() # Fractions (1/2, 1/3, 1/4, 1/5, 1/6, 1/8, 1/9, 1/10, 1/12) self.fraction = ToolButton("Foff") self.fraction.set_tooltip(_('Fraction')) self.fraction.props.sensitive = True self.fraction.connect('clicked', self._fraction_cb) toolbar_box.toolbar.insert(self.fraction, -1) self.fraction.show() separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(False) separator.show() toolbar_box.toolbar.insert(separator, -1) # The Customization submenu (roll your own) custom_toolbar = gtk.Toolbar() self._rods_label = gtk.Label(_("Rods:") + " ") self._rods_label.set_line_wrap(True) self._rods_label.show() self._rods_toolitem = gtk.ToolItem() self._rods_toolitem.add(self._rods_label) custom_toolbar.insert(self._rods_toolitem, -1) self._rods_toolitem.show() self._rods_spin_adj = gtk.Adjustment(15, 1, 20, 1, 32, 0) self._rods_spin = gtk.SpinButton(self._rods_spin_adj, 0, 0) self._rods_spin_id = self._rods_spin.connect( 'value-changed', self._rods_spin_cb) self._rods_spin.set_numeric(True) self._rods_spin.show() self.tool_item_rods = gtk.ToolItem() self.tool_item_rods.add(self._rods_spin) custom_toolbar.insert(self.tool_item_rods, -1) self.tool_item_rods.show() self._top_label = gtk.Label(" " + _("Top:") + " ") self._top_label.set_line_wrap(True) self._top_label.show() self._top_toolitem = gtk.ToolItem() self._top_toolitem.add(self._top_label) custom_toolbar.insert(self._top_toolitem, -1) self._top_toolitem.show() self._top_spin_adj = gtk.Adjustment(2, 0, 4, 1, 32, 0) self._top_spin = gtk.SpinButton(self._top_spin_adj, 0, 0) self._top_spin_id = self._top_spin.connect('value-changed', self._top_spin_cb) self._top_spin.set_numeric(True) self._top_spin.show() self.tool_item_top = gtk.ToolItem() self.tool_item_top.add(self._top_spin) custom_toolbar.insert(self.tool_item_top, -1) self.tool_item_top.show() self._bottom_label = gtk.Label(" " + _("Bottom:") + " ") self._bottom_label.set_line_wrap(True) self._bottom_label.show() self._bottom_toolitem = gtk.ToolItem() self._bottom_toolitem.add(self._bottom_label) custom_toolbar.insert(self._bottom_toolitem, -1) self._bottom_toolitem.show() self._bottom_spin_adj = gtk.Adjustment(5, 1, 15, 1, 32, 0) self._bottom_spin = gtk.SpinButton(self._bottom_spin_adj, 0, 0) self._bottom_spin_id = self._bottom_spin.connect( 'value-changed', self._bottom_spin_cb) self._bottom_spin.set_numeric(True) self._bottom_spin.show() self.tool_item_bottom = gtk.ToolItem() self.tool_item_bottom.add(self._bottom_spin) custom_toolbar.insert(self.tool_item_bottom, -1) self.tool_item_bottom.show() self._value_label = gtk.Label(" " + _("Factor:") + " ") self._value_label.set_line_wrap(True) self._value_label.show() self._value_toolitem = gtk.ToolItem() self._value_toolitem.add(self._value_label) custom_toolbar.insert(self._value_toolitem, -1) self._value_toolitem.show() self._value_spin_adj = gtk.Adjustment(5, 1, 20, 1, 32, 0) self._value_spin = gtk.SpinButton(self._value_spin_adj, 0, 0) self._value_spin_id = self._value_spin.connect( 'value-changed', self._value_spin_cb) self._value_spin.set_numeric(True) self._value_spin.show() self.tool_item_value = gtk.ToolItem() self.tool_item_value.add(self._value_spin) custom_toolbar.insert(self.tool_item_value, -1) self.tool_item_value.show() self._base_label = gtk.Label(" " + _("Base:") + " ") self._base_label.set_line_wrap(True) self._base_label.show() self._base_toolitem = gtk.ToolItem() self._base_toolitem.add(self._base_label) custom_toolbar.insert(self._base_toolitem, -1) self._base_toolitem.show() self._base_spin_adj = gtk.Adjustment(10, 1, 20, 1, 32, 0) self._base_spin = gtk.SpinButton(self._base_spin_adj, 0, 0) self._base_spin_id = self._base_spin.connect( 'value-changed', self._base_spin_cb) self._base_spin.set_numeric(True) self._base_spin.show() self.tool_item_base = gtk.ToolItem() self.tool_item_base.add(self._base_spin) custom_toolbar.insert(self.tool_item_base, -1) self.tool_item_base.show() # Custom self._custom = ToolButton("new-game") self._custom.set_tooltip(_('Custom')) self._custom.props.sensitive = True self._custom.connect('clicked', self._custom_cb) custom_toolbar.insert(self._custom, -1) self._custom.show() custom_toolbar_button = ToolbarButton(page=custom_toolbar, icon_name='view-source') custom_toolbar.show() toolbar_box.toolbar.insert(custom_toolbar_button, -1) custom_toolbar_button.show() separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) # The ever-present Stop Button stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() else: # Use pre-0.86 toolbar design self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.projectToolbar = ProjectToolbar(self) self.toolbox.add_toolbar(_('Project'), self.projectToolbar) self.customToolbar = CustomToolbar(self) self.toolbox.add_toolbar(_('Custom'), self.customToolbar) self.toolbox.show() # Create a canvas canvas = gtk.DrawingArea() canvas.set_size_request(gtk.gdk.screen_width(), gtk.gdk.screen_height()) self.set_canvas(canvas) canvas.show() self.show_all() # Initialize the canvas self.abacus = Abacus(canvas, self) # Read the current mode from the Journal try: if self.metadata['abacus'] == 'suanpan': self._chinese_cb(None) elif self.metadata['abacus'] == 'soroban': self._japanese_cb(None) elif self.metadata['abacus'] == 'schety': self._russian_cb(None) elif self.metadata['abacus'] == 'nepohualtzintzin': self._mayan_cb(None) elif self.metadata['abacus'] == 'binary': self._binary_cb(None) elif self.metadata['abacus'] == 'hexadecimal': self._hex_cb(None) elif self.metadata['abacus'] == 'fraction': self._fraction_cb(None) else: self._chinese_cb(None) except: pass try: self.abacus.mode.set_value(self.metadata['value']) self.abacus.mode.label(self.abacus.mode.value()) except: pass def _all_off(self): self.chinese.set_icon("Coff") self.japanese.set_icon("Joff") self.russian.set_icon("Roff") self.mayan.set_icon("Moff") self.binary.set_icon("Boff") self.hex.set_icon("Hoff") self.fraction.set_icon("Foff") self.abacus.chinese.hide() self.abacus.japanese.hide() self.abacus.russian.hide() self.abacus.mayan.hide() self.abacus.binary.hide() self.abacus.hex.hide() self.abacus.fraction.hide() if self.abacus.custom is not None: self.abacus.custom.hide() def _rods_spin_cb(self, button): return def _top_spin_cb(self, button): return def _bottom_spin_cb(self, button): return def _value_spin_cb(self, button): return def _base_spin_cb(self, button): return def _custom_cb(self, button): """ Display the custom abacus; hide the others """ self._all_off() self.abacus.custom = Custom(self.abacus, self._rods_spin.get_value_as_int(), self._top_spin.get_value_as_int(), self._bottom_spin.get_value_as_int(), self._value_spin.get_value_as_int(), self._base_spin.get_value_as_int()) self.abacus.custom.show() self.abacus.mode = self.abacus.custom _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _chinese_cb(self, button): """ Display the suanpan; hide the others """ self._all_off() self.chinese.set_icon("Con") self.abacus.chinese.show() self.abacus.mode = self.abacus.chinese _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _japanese_cb(self, button): """ Display the soroban; hide the others """ self._all_off() self.japanese.set_icon("Jon") self.abacus.japanese.show() self.abacus.mode = self.abacus.japanese _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _russian_cb(self, button): """ Display the schety; hide the others """ self._all_off() self.russian.set_icon("Ron") self.abacus.russian.show() self.abacus.mode = self.abacus.russian _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _mayan_cb(self, button): """ Display the nepohualtzintzin; hide the others """ self._all_off() self.mayan.set_icon("Mon") self.abacus.mayan.show() self.abacus.mode = self.abacus.mayan _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _binary_cb(self, button): """ Display the binary; hide the others """ self._all_off() self.binary.set_icon("Bon") self.abacus.binary.show() self.abacus.mode = self.abacus.binary _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _hex_cb(self, button): """ Display the hex; hide the others """ self._all_off() self.hex.set_icon("Hon") self.abacus.hex.show() self.abacus.mode = self.abacus.hex _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def _fraction_cb(self, button): """ Display the fraction; hide the others """ self._all_off() self.fraction.set_icon("Fon") self.abacus.fraction.show() self.abacus.mode = self.abacus.fraction _logger.debug("Setting mode to %s" % (self.abacus.mode.name)) def write_file(self, file_path): """ Write the bead positions to the Journal """ _logger.debug("Saving current abacus to Journal: %s " % (self.abacus.mode.name)) try: self.metadata['abacus'] = self.abacus.mode.name self.metadata['value'] = self.abacus.mode.value(True) except: pass
class TuningToolbar(gtk.Toolbar): ''' The toolbar for tuning instruments ''' def __init__(self, activity): gtk.Toolbar.__init__(self) self.activity = activity self._show_tuning_line = False self._updating_note = True self._tuning_tool = None # Set up Instrument Combo box self.instrument_combo = ComboBox() self.instrument = [_('None')] for k in INSTRUMENT_DICT.keys(): self.instrument.append(k) self._instrument_changed_id = self.instrument_combo.connect( 'changed', self.update_instrument_control) for i, instrument in enumerate(self.instrument): self.instrument_combo.append_item(i, instrument, None) self.instrument_combo.set_active(0) if hasattr(self.instrument_combo, 'set_tooltip_text'): self.instrument_combo.set_tooltip_text(_('Tune an instrument.')) self._instrument_tool = ToolComboBox(self.instrument_combo) self.insert(self._instrument_tool, -1) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._notes_combo = ComboBox() n = 0 for octave in range(9): for i in range(len(NOTES)): if octave == 0 and i < 9: # Start with A0 continue self._notes_combo.append_item(n, note_octave(i, octave), None) n += 1 self._notes_combo.set_active(48) # A4 self._notes_changed_id = self._notes_combo.connect( 'changed', self.update_note) if hasattr(self._notes_combo, 'set_tooltip_text'): self._notes_combo.set_tooltip_text(_('Notes')) self._notes_tool = ToolComboBox(self._notes_combo) self.insert(self._notes_tool, -1) # The entry is used to display a note or for direct user input self._freq_entry = gtk.Entry() self._freq_entry.set_text('440') # A self._freq_entry_changed_id = self._freq_entry.connect( 'changed', self.update_freq_entry) if hasattr(self._freq_entry, 'set_tooltip_text'): self._freq_entry.set_tooltip_text( _('Enter a frequency to display.')) self._freq_entry.set_width_chars(8) self._freq_entry.show() toolitem = gtk.ToolItem() toolitem.add(self._freq_entry) self.insert(toolitem, -1) toolitem.show() self._new_tuning_line = ToolButton('tuning-tools') self._new_tuning_line.show() self.insert(self._new_tuning_line, -1) self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._new_tuning_line.connect('clicked', self.tuning_line_cb) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._harmonic = ToolButton('harmonics') self._harmonic.show() self.insert(self._harmonic, -1) self._harmonic.set_tooltip(_('Show harmonics.')) self._harmonic.connect('clicked', self.harmonic_cb) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._play_tone = ToolButton('media-playback-start') self._play_tone.show() self.insert(self._play_tone, -1) self._play_tone.set_tooltip(_('Play a note.')) self._play_tone.connect('clicked', self.play_cb) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) self.label = gtk.Label('') self.label.set_use_markup(True) self.label.show() toolitem = gtk.ToolItem() toolitem.add(self.label) self.insert(toolitem, -1) toolitem.show() self.show_all() def update_note(self, *args): ''' Calculate the frequency based on note combo ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar return i = self._notes_combo.get_active() freq = A0 * pow(TWELTHROOT2, i) self._updating_note = True self._freq_entry.set_text('%0.3f' % (freq)) self.label.set_markup( SPAN % (style.COLOR_WHITE.get_html(), note_octave(index_to_note(i), index_to_octave(i)))) if self._show_tuning_line: self.activity.wave.tuning_line = freq return def update_tuning_control(self, *args): ''' Update note ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar? return instrument = self.instrument[self.instrument_combo.get_active()] if not instrument in INSTRUMENT_DICT: return if self.tuning[self._tuning_combo.get_active()] == _('All notes'): self._notes_combo.set_active( freq_index(INSTRUMENT_DICT[instrument][0])) self.activity.wave.instrument = instrument self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: freq = INSTRUMENT_DICT[instrument][self._tuning_combo.get_active() - 1] # All notes is 0 self._notes_combo.set_active( freq_index(INSTRUMENT_DICT[instrument][ self._tuning_combo.get_active() - 1])) self.activity.wave.instrument = None self.activity.wave.tuning_line = freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True self._updating_note = False def update_freq_entry(self, *args): # Calcualte a note from a frequency if not self._updating_note: # Only if user types in a freq. try: freq = float(self._freq_entry.get_text()) # Only consider notes in piano range if freq < A0 * 0.97: self.label.set_text('< A0') return if freq > C8 * 1.03: self.label.set_text('> C8') return self.label.set_markup(freq_note(freq, flatsharp=True)) except ValueError: return self._updating_note = False def update_instrument_control(self, *args): ''' Callback for instrument control ''' instrument = self.instrument[self.instrument_combo.get_active()] if self._tuning_tool is not None: self.remove(self._tuning_tool) if instrument == _('None'): self.activity.wave.instrument = None if hasattr(self, '_notes_tool'): self.insert(self._notes_tool, 2) return self.remove(self._notes_tool) self.activity.wave.instrument = instrument # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Add a Tuning Combo box for this instrument self._tuning_combo = ComboBox() self.tuning = [_('All notes')] for f in INSTRUMENT_DICT[instrument]: self.tuning.append(freq_note(f)) self._tuning_changed_id = self._tuning_combo.connect( 'changed', self.update_tuning_control) for i, s in enumerate(self.tuning): self._tuning_combo.append_item(i, s, None) self._tuning_combo.set_active(0) if hasattr(self._tuning_combo, 'set_tooltip_text'): self._tuning_combo.set_tooltip_text(instrument) self._tuning_tool = ToolComboBox(self._tuning_combo) self.insert(self._tuning_tool, 1) self._tuning_combo.show() self._tuning_tool.show() self.show_all() def harmonic_cb(self, *args): ''' Callback for harmonics control ''' self.activity.wave.harmonics = not self.activity.wave.harmonics if self.activity.wave.harmonics: self._harmonic.set_icon('harmonics-off') self._harmonic.set_tooltip(_('Hide harmonics.')) if self.activity.wave.instrument is None and \ self.activity.wave.tuning_line == 0.0: self._load_tuning_line() else: self._harmonic.set_icon('harmonics') self._harmonic.set_tooltip(_('Show harmonics.')) def tuning_line_cb(self, *args): ''' Callback for tuning insert ''' if self._show_tuning_line: self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: self._load_tuning_line() def _load_tuning_line(self): ''' Read the freq entry and use value to set tuning line ''' freq = self._freq_entry.get_text() try: self.activity.wave.tuning_line = float(freq) if freq < 0: freq = -freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True except ValueError: self.activity.wave.tuning_line = 0.0 self._freq_entry.set_text('0') # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() def play_cb(self, *args): ''' Save settings, turn off display, and then play a tone at the current frequency ''' freq = float(self._freq_entry.get_text()) channels = [] for c in range(self.activity.audiograb.channels): channels.append(self.activity.wave.get_visibility(channel=c)) self.activity.wave.set_visibility(False, channel=c) wave_status = self.activity.wave.get_active() self.activity.wave.set_context_off() self.activity.wave.set_active(False) gobject.timeout_add(200, self.play_sound, freq, channels, wave_status) def play_sound(self, freq, channels, wave_status): ''' Play the sound and then restore wave settings ''' if hasattr(subprocess, 'check_output'): try: output = subprocess.check_output([ 'speaker-test', '-t', 'sine', '-l', '1', '-f', '%f' % (freq) ]) except subprocess.CalledProcessError: log.warning('call to speaker-test failed?') else: import commands (status, output) = commands.getstatusoutput( 'speaker-test -t sine -l 1 -f %f' % (freq)) if status != 0: log.warning('call to speaker-test failed?') for c in range(self.activity.audiograb.channels): self.activity.wave.set_visibility(channels[c], channel=c) self.activity.wave.set_context_on() self.activity.wave.set_active(wave_status)
class SensorToolbar(gtk.Toolbar): """ The toolbar for specifiying the sensor: sound, resitance, or voltage """ LOWER = 0.0 UPPER = 1.0 STR_DC_R = ( _( "Resistive sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + " " ) STR_DC_V = ( _( "Voltage sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + " " ) STR_AC = _("Sound") + " " STR_RESISTANCE = _("Resistance") + " (" + _("Ohms") + ") " STR_VOLTAGE = _("Voltage") + " (" + _("Volts") + ") " STR_TIME = _("Time Base") + " " STR_FREQUENCY = _("Frequency Base") + " " STR_INVERT = " " + _("Invert") + " " STR_XAXIS_TEXT = _("X Axis Scale: 1 division = %(division)s %(unit)s") # TRANSLATORS: This is milli seconds. MS = _("ms") # TRANSLATORS: This is Hertz, so 1/second. HZ = _("Hz") def __init__(self, activity, channels): """ By default, start with resistance mode """ gtk.Toolbar.__init__(self) self.activity = activity self._channels = channels self._lock_radio_buttons = False self._radio_button_pushed = False self.values = [] for i in range(self._channels): self.values.append("") self.string_for_textbox = "" self.gain = 1.0 self.y_mag = 3.0 self.capture_gain = CAPTURE_GAIN self.mic_boost = MIC_BOOST self.mode = "sound" # Set up Time-domain Button self.time = RadioToolButton(group=None) self.time.set_named_icon("media-audio") self.insert(self.time, -1) self.time.set_tooltip(_("Sound")) self.time.connect("clicked", self.analog_resistance_voltage_mode_cb, "sound") # Set up Resistance Button self.resistance = RadioToolButton(group=self.time) self.resistance.set_named_icon("resistance") if _is_xo(self.activity.hw): self.insert(self.resistance, -1) self.resistance.show() self.resistance.set_tooltip(_("Resistance Sensor")) self.resistance.connect("clicked", self.analog_resistance_voltage_mode_cb, "resistance") # Set up Voltage Button self.voltage = RadioToolButton(group=self.time) self.voltage.set_named_icon("voltage") if _is_xo(self.activity.hw): self.insert(self.voltage, -1) self.voltage.set_tooltip(_("Voltage Sensor")) self.voltage.connect("clicked", self.analog_resistance_voltage_mode_cb, "voltage") separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_value = LOG_TIMER_VALUES[1] self.log_label = gtk.Label(self._log_to_string(self._log_value)) toolitem = gtk.ToolItem() toolitem.add(self.log_label) self.insert(toolitem, -1) self._log_button = ToolButton("timer-10") self._log_button.set_tooltip(_("Select logging interval")) self._log_button.connect("clicked", self._log_selection_cb) self.insert(self._log_button, -1) self._setup_log_palette() # Set up Logging/Stop Logging Button self._record = ToolButton("media-record") self.insert(self._record, -1) self._record.set_tooltip(_("Start logging")) self._record.connect("clicked", self.record_control_cb) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) toolitem = gtk.ToolItem() self.trigger_label = gtk.Label(_("Trigger")) toolitem.add(self.trigger_label) self.insert(toolitem, -1) # Set up Trigger Combo box self.trigger_none = RadioToolButton() self.trigger_none.set_named_icon("trigger-none") self.insert(self.trigger_none, -1) self.trigger_none.set_tooltip(_("None")) self.trigger_none.connect("clicked", self.update_trigger_control_cb, self.activity.wave.TRIGGER_NONE) self.trigger_rise = RadioToolButton(group=self.trigger_none) self.trigger_rise.set_named_icon("trigger-rise") self.insert(self.trigger_rise, -1) self.trigger_rise.set_tooltip(_("Rising Edge")) self.trigger_rise.connect("clicked", self.update_trigger_control_cb, self.activity.wave.TRIGGER_POS) self.trigger_fall = RadioToolButton(group=self.trigger_none) self.trigger_fall.set_named_icon("trigger-fall") self.insert(self.trigger_fall, -1) self.trigger_fall.set_tooltip(_("Falling Edge")) self.trigger_fall.connect("clicked", self.update_trigger_control_cb, self.activity.wave.TRIGGER_NEG) self.show_all() def get_log(self): return self._log_value def get_log_idx(self): if self._log_value in LOG_TIMER_VALUES: return LOG_TIMER_VALUES.index(self._log_value) else: return LOG_TIMER_VALUES[0] def set_log_idx(self, idx): self._log_value = LOG_TIMER_VALUES[idx] self.log_label.set_text(self._log_to_string(self._log_value)) if hasattr(self, "_log_button"): self._log_button.set_icon("timer-%d" % (self._log_value)) def _log_selection_cb(self, widget): if self._log_palette: if not self._log_palette.is_up(): self._log_palette.popup(immediate=True, state=self._log_palette.SECONDARY) else: self._log_palette.popdown(immediate=True) return def _log_to_seconds(self, tenth_seconds): return tenth_seconds / 10.0 def _log_to_string(self, tenth_seconds): if tenth_seconds in LOG_TIMER_LABELS: return LOG_TIMER_LABELS[tenth_seconds] else: return _("1 second") def _setup_log_palette(self): self._log_palette = self._log_button.get_palette() for tenth_seconds in LOG_TIMER_VALUES: text = self._log_to_string(tenth_seconds) menu_item = MenuItem(icon_name="timer-%d" % (tenth_seconds), text_label=self._log_to_string(tenth_seconds)) menu_item.connect("activate", self._log_selected_cb, tenth_seconds) self._log_palette.menu.append(menu_item) menu_item.show() def _log_selected_cb(self, button, seconds): self.set_log_idx(LOG_TIMER_VALUES.index(seconds)) def add_frequency_slider(self, toolbox): """ Either on the Sound toolbar or the Main toolbar """ self._freq_stepper_up = ToolButton("freq-high") self._freq_stepper_up.set_tooltip(_("Zoom out")) self._freq_stepper_up.connect("clicked", self._freq_stepper_up_cb) self._freq_stepper_up.show() self.activity.adjustmentf = gtk.Adjustment(0.5, self.LOWER, self.UPPER, 0.01, 0.1, 0) self.activity.adjustmentf.connect("value_changed", self.cb_page_sizef) self._freq_range = gtk.HScale(self.activity.adjustmentf) self._freq_range.set_inverted(True) self._freq_range.set_draw_value(False) self._freq_range.set_update_policy(gtk.UPDATE_CONTINUOUS) self._freq_range.set_size_request(120, 15) self._freq_range.show() self._freq_stepper_down = ToolButton("freq-low") self._freq_stepper_down.set_tooltip(_("Zoom in")) self._freq_stepper_down.connect("clicked", self._freq_stepper_down_cb) self._freq_stepper_down.show() self._freq_range_tool = gtk.ToolItem() self._freq_range_tool.add(self._freq_range) self._freq_range_tool.show() toolbox.add(self._freq_stepper_up) toolbox.add(self._freq_range_tool) toolbox.add(self._freq_stepper_down) return def update_trigger_control_cb(self, button, value): if button is None: value = self.activity.wave.TRIGGER_NONE if self.activity.wave.get_fft_mode(): self.trigger_none.set_active(True) else: self.activity.wave.set_trigger(value) def analog_resistance_voltage_mode_cb(self, button=None, mode_to_set="sound"): """ Callback for Analog/Resistance/Voltage Buttons """ if self._lock_radio_buttons: logging.debug("mode selector locked") self._radio_button_pushed = True return if self.mode == mode_to_set: logging.debug("mode already set to %s" % mode_to_set) return self._lock_radio_buttons = True if self.activity.CONTEXT == "sound": self.sound_context_off() else: self.sensor_context_off() # Force time domain when switching modes if self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Turn off logging when switching modes if self.activity.audiograb.we_are_logging: self.record_control_cb() self.set_mode(mode_to_set) if mode_to_set == "sound": self.set_sound_context() elif mode_to_set == "resistance": self.set_sensor_context() elif mode_to_set == "voltage": self.set_sensor_context() self.update_string_for_textbox() return False def unlock_radio_buttons(self): """ Enable radio button selection """ logging.debug("unlocking radio buttons") if self._radio_button_pushed: if self.mode == "sound": self.time.set_active(True) elif self.mode == "resistance": self.resistance.set_active(True) elif self.mode == "voltage": self.voltage.set_active(True) self._lock_radio_buttons = False self._radio_button_pushed = False def set_mode(self, mode="sound"): """ Set the mixer settings to match the current mode. """ self.mode = mode self.activity.audiograb.set_sensor_type(self.mode) for i in range(self._channels): self.values[i] = 0.0 return def get_mode(self): """ Get the mixer settings. """ return self.mode def _freq_stepper_up_cb(self, button=None): """ Moves the horizontal zoom slider to the left one notch, where one notch is 1/100 of the total range. This correspond to zooming out as a larger number of Hertz or milliseconds will be represented by the same space on the screen. """ new_value = self._freq_range.get_value() + (self.UPPER - self.LOWER) / 100.0 if new_value <= self.UPPER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.UPPER) def _freq_stepper_down_cb(self, button=None): """ Moves the horizontal zoom slider to the right one notch, where one notch is 1/100 of the total range. This corresponds to zooming in. """ new_value = self._freq_range.get_value() - (self.UPPER - self.LOWER) / 100.0 if new_value >= self.LOWER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.LOWER) def cb_page_sizef(self, button=None): """ Callback to scale the frequency range (zoom in and out) """ if self._update_page_size_id: gobject.source_remove(self._update_page_size_id) self._update_page_size_id = gobject.timeout_add(250, self.update_page_size) return True def update_page_size(self): """ Set up the scaling of the display. """ self._update_page_size_id = None new_value = round(self.activity.adjustmentf.value * 100.0) / 100.0 if self.activity.adjustmentf.value != new_value: self.activity.adjustmentf.value = new_value return False time_div = 0.001 * max(self.activity.adjustmentf.value, 0.05) freq_div = 1000 * max(self.activity.adjustmentf.value, 0.01) self.activity.wave.set_div(time_div, freq_div) self.update_string_for_textbox() return False def set_sound_context(self): """ Called when analog sensing is selected """ self.set_show_hide_windows(mode="sound") gobject.timeout_add(500, self.sound_context_on) self.activity.CONTEXT = "sound" def set_sensor_context(self): """ Called when digital sensing is selected """ self.set_show_hide_windows(mode="sensor") gobject.timeout_add(500, self.sensor_context_on) self.activity.CONTEXT = "sensor" def set_show_hide_windows(self, mode="sound"): """ Shows the appropriate window identified by the mode """ self.activity.wave.set_context_on() for i in range(self._channels): self.activity.side_toolbars[i].set_show_hide(True, mode) def sensor_context_off(self): """ Called when a DC sensor is no longer selected """ # self.activity.audiograb.pause_grabbing() self.activity.audiograb.stop_grabbing() def sensor_context_on(self): """ Called when a DC sensor is selected """ self.update_string_for_textbox() self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE) # self.activity.audiograb.resume_grabbing() self.activity.audiograb.start_grabbing() return False def sound_context_off(self): """ Called when an analog sensor is no longer selected """ self.gain, self.y_mag = self.activity.wave.get_mag_params() self.capture_gain = self.activity.audiograb.get_capture_gain() self.mic_boost = self.activity.audiograb.get_mic_boost() self.activity.audiograb.stop_grabbing() def sound_context_on(self): """ Called when an analog sensor is selected """ self.activity.wave.set_mag_params(self.gain, self.y_mag) self.update_string_for_textbox() self.update_trigger_control_cb(None, self.activity.wave.TRIGGER_NONE) self.activity.audiograb.start_grabbing() return False def set_sample_value(self, value="", channel=0): """ Write a sample value to the textbox. """ gtk.threads_enter() self.values[channel] = value self.update_string_for_textbox() gtk.threads_leave() return def record_control_cb(self, button=None): """ Depending upon the selected interval, does either a logging session, or just logs the current buffer. """ if self.activity.audiograb.we_are_logging: self.activity.audiograb.set_logging_params(start_stop=False) self._record.set_icon("media-record") self._record.show() self._record.set_tooltip(_("Start Recording")) else: Xscale = 1.00 / self.activity.audiograb.get_sampling_rate() Yscale = 0.0 interval = self._log_value / 10.0 # self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode="frequency", ) else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode=self.mode, ) self.activity.audiograb.set_logging_params(start_stop=True, interval=interval, screenshot=False) self._record.set_icon("record-stop") self._record.show() self._record.set_tooltip(_("Stop Recording")) self.activity.new_recording = True def update_string_for_textbox(self): """ Update the status field at the bottom of the canvas. """ if self.mode == "resistance": string_for_textbox = self.STR_DC_R + "\n" string_for_textbox += self.STR_RESISTANCE elif self.mode == "voltage": string_for_textbox = self.STR_DC_V + "\n" string_for_textbox += self.STR_VOLTAGE else: string_for_textbox = self.STR_AC + "\t" if self.activity.wave.get_fft_mode(): scalex = self.STR_XAXIS_TEXT % {"unit": self.HZ, "division": self.activity.wave.freq_div} string_for_textbox += self.STR_FREQUENCY string_for_textbox += "\n" + scalex elif self.mode == "sound": scalex = self.STR_XAXIS_TEXT % {"unit": self.MS, "division": self.activity.wave.time_div * 1000} string_for_textbox += self.STR_TIME string_for_textbox += "\n" + scalex else: for i in range(self._channels): string_for_textbox += "\t(%s)" % (self.values[i]) invert = False for i in range(self._channels): if self.activity.wave.get_invert_state(channel=i): invert = True if invert: string_for_textbox += self.STR_INVERT self.activity.text_box.set_label(string_for_textbox)
class ArduinoToolbar(gtk.Toolbar): ''' The toolbar for specifiying the sensor: temp, distance, light or gray ''' def __init__(self, activity, channels): self._arduino_context_id = None gtk.Toolbar.__init__(self) self.activity = activity self._channels = channels self.mode = 'arduino' # Set up Sensores Button self.time = RadioToolButton(group=None) self.lista_sensores_button = [] self.we_are_logging = False self._log_this_sample = False self._logging_timer = None self._logging_counter = 0 self._image_counter = 0 self._logging_interval = 0 self._channels_logged = [] self._busy = False self._take_screenshot = True log.debug('se agrega el boton refrescar') self.refrescar_button = RadioToolButton(group=None) self.refrescar_button.set_named_icon('recargar') self.refrescar_button.connect('clicked', self.click_refresh_button) self.insert(self.refrescar_button, -1) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self.robot = Arduino() self._port_entry = gtk.Entry() self._port_entry.set_text('A5') # A self._port_entry_changed_id = self._port_entry.connect( 'changed', self._read_sensor) if hasattr(self._port_entry, 'set_tooltip_text'): self._port_entry.set_tooltip_text(_('Enter a port to read.')) self._port_entry.set_width_chars(2) self._port_entry.show() toolitem = gtk.ToolItem() toolitem.add(self._port_entry) self.insert(toolitem, -1) toolitem.show() separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_value = LOG_TIMER_VALUES[1] self.log_label = gtk.Label(self._log_to_string(self._log_value)) toolitem = gtk.ToolItem() toolitem.add(self.log_label) self.insert(toolitem, -1) self._log_button = ToolButton('timer-10') self._log_button.set_tooltip(_('Select logging interval')) self._log_button.connect('clicked', self._log_selection_cb) self.insert(self._log_button, -1) self._setup_log_palette() # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start Recording')) self._record.connect('clicked', self.record_control_cb) self.show_all() def get_log(self): return self._log_value def get_log_idx(self): if self._log_value in LOG_TIMER_VALUES: return LOG_TIMER_VALUES.index(self._log_value) else: return LOG_TIMER_VALUES[0] def set_log_idx(self, idx): self._log_value = LOG_TIMER_VALUES[idx] self.log_label.set_text(self._log_to_string(self._log_value)) if hasattr(self, '_log_button'): self._log_button.set_icon('timer-%d' % (self._log_value)) def _log_selection_cb(self, widget): if self._log_palette: if not self._log_palette.is_up(): self._log_palette.popup(immediate=True, state=self._log_palette.SECONDARY) else: self._log_palette.popdown(immediate=True) return def _log_to_seconds(self, tenth_seconds): return tenth_seconds / 10. def _log_to_string(self, tenth_seconds): if tenth_seconds in LOG_TIMER_LABELS: return LOG_TIMER_LABELS[tenth_seconds] else: return _('1 second') def _setup_log_palette(self): self._log_palette = self._log_button.get_palette() for tenth_seconds in LOG_TIMER_VALUES: text = self._log_to_string(tenth_seconds) menu_item = MenuItem(icon_name='timer-%d' % (tenth_seconds), text_label=self._log_to_string(tenth_seconds)) menu_item.connect('activate', self._log_selected_cb, tenth_seconds) self._log_palette.menu.append(menu_item) menu_item.show() def _log_selected_cb(self, button, seconds): self.set_log_idx(LOG_TIMER_VALUES.index(seconds)) def get_port(self): return self._port_value def get_port_idx(self): if self._port_value in PORT_VALUES: return PORT_VALUES.index(self._port_value) else: return PORT_VALUES[0] def set_port_idx(self, idx): self._port_value = PORT_VALUES[idx] self.port_label.set_text(self._port_to_string(self._port_value)) if hasattr(self, '_port_button'): self._port_button.set_icon('arduino-tools') def _port_selection_cb(self, widget): if self._port_palette: if not self._port_palette.is_up(): self._port_palette.popup(immediate=True, state=self._port_palette.SECONDARY) else: self._port_palette.popdown(immediate=True) return def _port_to_string(self, tenth_seconds): if tenth_seconds in PORT_LABELS: return PORT_LABELS[tenth_seconds] else: return _('1 second') def _setup_port_palette(self): self._port_palette = self._port_button.get_palette() for tenth_seconds in PORT_VALUES: text = self._port_to_string(tenth_seconds) menu_item = MenuItem( icon_name='arduino-tools', text_label=self._port_to_string(tenth_seconds)) menu_item.connect('activate', self._port_selected_cb, tenth_seconds) self._port_palette.menu.append(menu_item) menu_item.show() def _port_selected_cb(self, button, seconds): self.set_port_idx(PORT_VALUES.index(seconds)) def read_sensor_from_bobot_server(self): log.debug('**********Read Sensor ***********') return 0 def click_refresh_button(self, event=None): log.debug('********** clickea botton refresh ***********') self.robot.refresh() self.mode = 'reading' self.read_sensor_from_bobot_server = self._read_sensor self.activity.limpiar_canales() self.set_arduino_context() return False def _port_entry_cb(self, event=None): log.debug('********** port_changed ***********') self.robot.refresh() self.mode = 'reading' self.read_sensor_from_bobot_server = self._read_sensor self.activity.limpiar_canales() self.set_arduino_context() return False def set_arduino_context(self): self.activity.audiograb.stop_grabbing() if self._arduino_context_id: gobject.source_remove(self._arduino_context_id) self._arduino_context_id =\ gobject.timeout_add(50,self.arduino_context_on) def arduino_context_on(self): bufChannelTmp = [] #Si esta el boton de pause activada no se agregar el nuevo valor if self.activity.audiograb.get_freeze_the_display(): bufChannelTmp.append(self.read_sensor_from_bobot_server()) for i in range(self.activity.audiograb.channels): self.activity.wave.new_buffer(bufChannelTmp, i) if self.we_are_logging: self.logging_to_file(bufChannelTmp, i) #if self.activity.CONTEXT == 'arduino': return True #else: #return False def logging_to_file(self, data_buffer, channel): if self.we_are_logging: if self._logging_counter == MAX_LOG_ENTRIES: self._logging_counter = 0 self.we_are_logging = False self.activity.data_logger.stop_session() else: if self._logging_interval == 0: self._emit_for_logging(data_buffer, channel=channel) self._log_this_sample = False self.we_are_logging = False self.activity.data_logger.stop_session() elif self._log_this_sample: # Sample channels in order if self.activity.audiograb._channels_logged.index( False) == channel: self.activity.audiograb._channels_logged[ channel] = True self._emit_for_logging(data_buffer, channel=channel) # Have we logged every channel? if self.activity.audiograb._channels_logged.count( True) == self.activity.audiograb.channels: self._log_this_sample = False for i in range(self.activity.audiograb.channels): self.activity.audiograb._channels_logged[ i] = False self._logging_counter += 1 def _emit_for_logging(self, data_buffer, channel=0): '''Sends the data for logging''' if not self._busy: self._busy = True if self._take_screenshot: if self.activity.data_logger.take_screenshot( self._image_counter): self._image_counter += 1 else: log.debug('failed to take screenshot %d' % (self._logging_counter)) self._busy = False return value_string = data_buffer[0] if self.activity.audiograb.channels > 1: self.activity.data_logger.write_value( value_string, channel=channel, sample=self._logging_counter) else: self.activity.data_logger.write_value( value_string, sample=self._logging_counter) self._busy = False else: log.debug('skipping sample %d.%d' % (self._logging_counter, channel)) def _sample_now(self): ''' Log the current sample now. This method is called from the _logging_timer object when the interval expires. ''' self._log_this_sample = True self._make_timer() def _make_timer(self): ''' Create the next timer that will trigger data logging. ''' self._logging_timer = Timer(self._logging_interval, self._sample_now) self._logging_timer.start() def record_control_cb(self, button=None): ''' Depending upon the selected interval, does either a logging session, or just logs the current buffer. ''' if self.we_are_logging: self.set_logging_params(start_stop=False) self._record.set_icon('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) else: Xscale = 0.0 Yscale = 0.0 interval = self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, _(self.logging_interval_status), channels=self._channels, mode='frequency') else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, _(self.logging_interval_status), channels=self._channels, mode=self.mode) self.set_logging_params(start_stop=True, interval=interval, screenshot=False) self._record.set_icon('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) self.activity.new_recording = True def set_logging_params(self, start_stop=False, interval=0, screenshot=True): ''' Configures for logging of data: starts or stops a session; sets the logging interval; and flags if screenshot is taken. ''' self.we_are_logging = start_stop self._logging_interval = interval if not start_stop: if self._logging_timer: self._logging_timer.cancel() self._logging_timer = None self._log_this_sample = False self._logging_counter = 0 elif interval != 0: self._make_timer() self._take_screenshot = screenshot self._busy = False def interval_convert(self): ''' Converts interval string to an integer that denotes the number of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written. ''' interval_dictionary = { '1/10 second': 0.1, '1 second': 1, '30 seconds': 30, '5 minutes': 300, '30 minutes': 1800 } try: return interval_dictionary[self.logging_interval_status] except ValueError: logging.error('logging interval status = %s' %\ (str(self.logging_interval_status))) return 0 def take_screenshot(self): ''' Capture the current screen to the Journal ''' log.debug('taking a screenshot %d' % (self._logging_counter)) self.set_logging_params(start_stop=True, interval=0, screenshot=True) def _read_sensor(self, event=None): port = self._port_entry.get_text() if port.count('A'): log.debug('analogRead') value = self.robot.analogRead(port.strip('A')) else: log.debug('digitalRead') self.robot.pinMode(port, _('INPUT')) value = self.robot.digitalRead(port) log.debug('VALOR A DEVOLVER') value *= 1000 log.debug(value) gtk.gdk.flush() return value
class VisualMatchActivity(activity.Activity): def __init__(self, handle): super(VisualMatchActivity, self).__init__(handle) try: # Use 0.86 toolbar design toolbar_box = ToolbarBox() # Buttons added to the Activity toolbar activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() # New-game Button self.button1 = ToolButton("new-game") self.button1.set_tooltip(_('New game')) self.button1.props.sensitive = True self.button1.connect('clicked', self._button1_cb, self) toolbar_box.toolbar.insert(self.button1, -1) self.button1.show() # Help Button self.button3 = ToolButton("search") self.button3.set_tooltip(_('Is there a match?')) self.button3.props.sensitive = True self.button3.connect('clicked', self._button3_cb, self) toolbar_box.toolbar.insert(self.button3, -1) self.button3.show() separator = gtk.SeparatorToolItem() separator.show() toolbar_box.toolbar.insert(separator, -1) # Label for showing deck status self.deck_label = gtk.Label(_("%d cards remaining") % (96)) self.deck_label.show() deck_toolitem = gtk.ToolItem() deck_toolitem.add(self.deck_label) toolbar_box.toolbar.insert(deck_toolitem, -1) separator = gtk.SeparatorToolItem() separator.show() toolbar_box.toolbar.insert(separator, -1) # Label for showing match status self.match_label = gtk.Label(_("%d matches") % (0)) self.match_label.show() match_toolitem = gtk.ToolItem() match_toolitem.add(self.match_label) toolbar_box.toolbar.insert(match_toolitem, -1) separator = gtk.SeparatorToolItem() separator.show() toolbar_box.toolbar.insert(separator, -1) # Label for showing counter self.clock_label = gtk.Label(_("-")) self.clock_label.show() clock_toolitem = gtk.ToolItem() clock_toolitem.add(self.clock_label) toolbar_box.toolbar.insert(clock_toolitem, -1) separator = gtk.SeparatorToolItem() separator.show() toolbar_box.toolbar.insert(separator, -1) # Label for showing play status self.status_label = gtk.Label(_("Find a match.")) self.status_label.show() status_toolitem = gtk.ToolItem() status_toolitem.add(self.status_label) toolbar_box.toolbar.insert(status_toolitem, -1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) # Write in the Journal journal_button = ToolButton("journal-write") journal_button.set_tooltip(_('Write in Journal')) journal_button.props.accelerator = '<Ctrl>j' journal_button.connect('clicked', self._journal_cb, activity.get_bundle_path()) toolbar_box.toolbar.insert(journal_button, -1) journal_button.show() # The ever-present Stop Button stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>q' toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() except NameError: # Use pre-0.86 toolbar design self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.projectToolbar = ProjectToolbar(self) self.toolbox.add_toolbar(_('Project'), self.projectToolbar) self.toolbox.show() # Create a canvas canvas = gtk.DrawingArea() canvas.set_size_request(gtk.gdk.screen_width(), \ gtk.gdk.screen_height()) self.set_canvas(canvas) canvas.show() self.show_all() # Initialize the canvas self.tw = window.new_window(canvas, \ os.path.join(activity.get_bundle_path(), \ 'images/card-'), \ self) # # Button callbacks # def _button1_cb(self, button, activity): self.show_button1(activity.tw) return True def show_button1(self, tw): self.button1.set_icon("new-game-on") window.new_game(tw) self.button1.set_icon("new-game") def _button3_cb(self, button, activity): self.show_button3(activity.tw) return True def show_button3(self, tw): if window.find_a_match(tw) is True: tw.activity.status_label.set_text(_("Keep looking")) else: tw.activity.status_label.set_text(_("No matches.")) tw.deck.deal_3_extra_cards(tw) tw.activity.deck_label.set_text(_("%d cards remaining") % \ (tw.deck.count-tw.deck.index)) def _journal_cb(self, button, path): title_alert = NamingAlert(self, path) title_alert.set_transient_for(self.get_toplevel()) title_alert.show() self.reveal() return True
class SideToolbar(gtk.Toolbar): ''' A toolbar on the side of the canvas for adjusting gain/bias ''' def __init__(self, activity, channel=0): ''' Set up initial toolbars ''' gtk.Toolbar.__init__(self) self.activity = activity self._channel = channel if self._channel == 0: self.show_toolbar = True else: # Don't show second channel until we need it self.show_toolbar = False self.mode = 'sound' self.mode_values = {'sound': 3, 'sensor': 2} self._toggle = gtk.CheckButton() self._toggle.set_active(True) self._toggle.connect('clicked', self.toggle_cb) self._toggle.show() self._toggle_box = gtk.HBox() self._toggle_box.pack_start(self._toggle, False, True, 18) self._invert = ToolButton('invert') self._invert.set_tooltip(_('Invert')) self._invert.connect('clicked', self.invert_control_cb) self._invert.show() self.activity.wave.set_invert_state(False, channel=self._channel) self.button_up = ToolButton('amp-high') self.button_up.set_tooltip(_('Increase amplitude')) self.button_up.connect('clicked', self._button_up_cb) self.button_up.show() self.adjustmenty = gtk.Adjustment(self.mode_values[self.mode], LOWER, UPPER, 0.1, 0.1, 0.0) self.adjustmenty.connect('value_changed', self._yscrollbar_cb, self.adjustmenty) self.yscrollbar = gtk.VScale(self.adjustmenty) self.yscrollbar.set_draw_value(False) self.yscrollbar.set_inverted(True) self.yscrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS) self.button_down = ToolButton('amp-low') self.button_down.set_tooltip(_('Decrease amplitude')) self.button_down.connect('clicked', self._button_down_cb) self.button_down.show() self.box1 = gtk.VBox(False, 0) if self._channel == 0: self.box1.pack_start(self._color_wave(self.activity.stroke_color), False, True, 0) elif self._channel == 1: self.box1.pack_start(self._color_wave(self.activity.fill_color), False, True, 0) else: self.box1.pack_start(self._color_wave('#FFFFFF'), False, True, 0) self.box1.pack_start(self._toggle_box, False, True, 0) self.box1.pack_start(self._invert, False, True, 0) self.box1.pack_start(self.button_up, False, True, 0) self.box1.pack_start(self.yscrollbar, True, True, 0) self.box1.pack_start(self.button_down, False, True, 0) self.set_show_hide(False) def _yscrollbar_cb(self, adjy, data=None): ''' Callback for scrollbar ''' if self.mode == 'sound': self.activity.wave.set_mag_params(1.0, adjy.value, channel=self._channel) self.activity.wave.set_bias_param(0, channel=self._channel) elif self.mode == 'sensor': self.activity.wave.set_bias_param(int( 300 * (adjy.value - (UPPER - LOWER) / 2.)), channel=self._channel) self.mode_values[self.mode] = adjy.value return True def _button_up_cb(self, data=None): '''Moves slider up''' new_value = self.yscrollbar.get_value() + (UPPER - LOWER) \ / 100. if new_value <= UPPER: self.yscrollbar.set_value(new_value) else: self.yscrollbar.set_value(UPPER) return True def _button_down_cb(self, data=None): '''Moves slider down''' new_value = self.yscrollbar.get_value() - (UPPER - LOWER) \ / 100. if new_value >= LOWER: self.yscrollbar.set_value(new_value) else: self.yscrollbar.set_value(LOWER) return True def set_show_hide(self, show=True, mode='sound'): ''' Show or hide the toolbar ''' self.show_toolbar = show self.set_side_mode(mode) def set_side_mode(self, mode='sound'): ''' Set the toolbar to either 'sound' or 'sensor' ''' self.mode = mode if self.mode == 'sound': self.button_up.set_icon('amp-high') self.button_up.set_tooltip(_('Increase amplitude')) self.button_down.set_icon('amp-low') self.button_down.set_tooltip(_('Decrease amplitude')) elif self.mode == 'sensor': self.button_up.set_icon('bias-high') self.button_up.set_tooltip(_('Increase bias')) self.button_down.set_icon('bias-low') self.button_down.set_tooltip(_('Decrease bias')) self._invert.show() self.yscrollbar.set_value(self.mode_values[self.mode]) return def toggle_cb(self, data=None): self.activity.wave.set_visibility(self._toggle.get_active(), channel=self._channel) return True def invert_control_cb(self, data=None): ''' Callback for Invert Button ''' if self.activity.wave.get_invert_state(channel=self._channel): self.activity.wave.set_invert_state(False, self._channel) self._invert.set_icon('invert') self._invert.show() elif not self.activity.wave.get_fft_mode(): self.activity.wave.set_invert_state(True, self._channel) self._invert.set_icon('invert2') self._invert.show() self.activity.sensor_toolbar.update_string_for_textbox() return False def _color_wave(self, color): ''' Generate a wave graphic in color to label each side toolbar ''' svg = '<?xml version="1.0" ?>\n\ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"\n\ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n\ <svg enable-background="new 0 0 55.125 55" height="55px" version="1.1"\n\ viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve"\n\ xmlns="http://www.w3.org/2000/svg"\n\ xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">\n\ <path d="M9.066,27.5 c2.32-6.917,4.666-13.834,9.255-13.834\n\ c9.179,0,9.179,27.668,18.358,27.668c4.59,0,6.986-6.917,9.332-13.834"\n\ fill="none" stroke="%s" stroke-linecap="round" stroke-width="3.5"/>\n\ </svg>' % (color) pixbuf = svg_str_to_pixbuf(svg) img = gtk.Image() img.set_from_pixbuf(pixbuf) img_tool = gtk.ToolItem() img_tool.add(img) return img_tool
class TuningToolbar(gtk.Toolbar): ''' The toolbar for tuning instruments ''' def __init__(self, activity): gtk.Toolbar.__init__(self) self.activity = activity self._show_tuning_line = False self._updating_note = True self._tuning_tool = None self._instrument_button = ToolButton('instruments') self._instrument_button.set_tooltip(_('Tune an instrument.')) self._instrument_button.connect('clicked', self._button_selection_cb) self.insert(self._instrument_button, -1) self._setup_instrument_palette() separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._note = 'A' self._notes_button = ToolButton('notes') self._notes_button.set_tooltip(_('Notes')) self._notes_button.connect('clicked', self._button_selection_cb) self.insert(self._notes_button, -1) self._setup_notes_palette() self._octave = 4 self._octaves_button = ToolButton('octaves') self._octaves_button.set_tooltip(_('Octaves')) self._octaves_button.connect('clicked', self._button_selection_cb) self.insert(self._octaves_button, -1) self._setup_octaves_palette() # The entry is used to display a note or for direct user input self._freq_entry = gtk.Entry() self._freq_entry.set_text('440') # A self._freq_entry_changed_id = self._freq_entry.connect( 'changed', self._update_freq_entry) if hasattr(self._freq_entry, 'set_tooltip_text'): self._freq_entry.set_tooltip_text( _('Enter a frequency to display.')) self._freq_entry.set_width_chars(8) self._freq_entry.show() toolitem = gtk.ToolItem() toolitem.add(self._freq_entry) self.insert(toolitem, -1) toolitem.show() self._new_tuning_line = ToolButton('tuning-tools') self._new_tuning_line.show() self.insert(self._new_tuning_line, -1) self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._new_tuning_line.connect('clicked', self.tuning_line_cb) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._harmonic = ToolButton('harmonics') self._harmonic.show() self.insert(self._harmonic, -1) self._harmonic.set_tooltip(_('Show harmonics.')) self._harmonic.connect('clicked', self.harmonic_cb) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._play_tone = ToolButton('media-playback-start') self._play_tone.show() self.insert(self._play_tone, -1) self._play_tone.set_tooltip(_('Play a note.')) self._play_tone.connect('clicked', self.play_cb) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) self.label = gtk.Label('') self.label.set_use_markup(True) self.label.show() toolitem = gtk.ToolItem() toolitem.add(self.label) self.insert(toolitem, -1) toolitem.show() self.show_all() def _update_note(self): ''' Calculate the frequency based on note and octave ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar return i = self._octave * 12 + NOTES.index(self._note) freq = A0 * pow(TWELTHROOT2, i) self._updating_note = True self._freq_entry.set_text('%0.3f' % (freq)) self.label.set_markup( SPAN % (style.COLOR_WHITE.get_html(), self._note + str(self._octave))) if self._show_tuning_line: self.activity.wave.tuning_line = freq return def _update_freq_entry(self, widget): # Calculate a note from a frequency if not self._updating_note: # Only if user types in a freq. try: freq = float(self._freq_entry.get_text()) # Only consider notes in piano range if freq < A0 * 0.97: self.label.set_text('< A0') return if freq > C8 * 1.03: self.label.set_text('> C8') return self.label.set_markup(freq_note(freq, flatsharp=True)) except ValueError: return self._updating_note = False def _button_selection_cb(self, widget): palette = widget.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True, state=palette.SECONDARY) else: palette.popdown(immediate=True) return def _setup_notes_palette(self): self._notes_palette = self._notes_button.get_palette() for note in NOTES: menu_item = MenuItem(icon_name='', text_label=note) menu_item.connect('activate', self._note_selected_cb, note) self._notes_palette.menu.append(menu_item) menu_item.show() def _note_selected_cb(self, widget, note): self._note = note self._update_note() def _setup_octaves_palette(self): self._octaves_palette = self._octaves_button.get_palette() for octave in range(9): menu_item = MenuItem(icon_name='', text_label=str(octave)) menu_item.connect('activate', self._octave_selected_cb, octave) self._octaves_palette.menu.append(menu_item) menu_item.show() def _octave_selected_cb(self, widget, octave): self._octave = octave self._update_note() def _setup_instrument_palette(self): self.instrument_palette = self._instrument_button.get_palette() self.instrument = [] for k in INSTRUMENT_DICT.keys(): self.instrument.append(k) menu_item = MenuItem(icon_name='', text_label=k) menu_item.connect('activate', self.instrument_selected_cb, k) self.instrument_palette.menu.append(menu_item) menu_item.show() def instrument_selected_cb(self, button, instrument): ''' Callback for instrument control ''' logging.debug(instrument) if self._tuning_tool is not None: self.remove(self._tuning_tool) if instrument == _('None'): self.activity.wave.instrument = None # Remove any previous tuning button if hasattr(self, '_tuning_button'): self._tuning_button.destroy() # Restore the notes, octaves buttons if hasattr(self, '_notes_button'): self.insert(self._notes_button, 2) self.insert(self._octaves_button, 3) return self.remove(self._notes_button) self.remove(self._octaves_button) self.activity.wave.instrument = instrument # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Add a Tuning palette for this instrument self._tuning_button = ToolButton('notes') self._tuning_button.set_tooltip(instrument) self._tuning_button.connect('clicked', self._button_selection_cb) self.insert(self._tuning_button, 1) self._setup_tuning_palette(instrument) def _setup_tuning_palette(self, instrument): self._tuning_palette = self._tuning_button.get_palette() self.tuning = [] self.tuning.append(_('All notes')) menu_item = MenuItem(icon_name='', text_label=_('All notes')) menu_item.connect('activate', self._tuning_selected_cb, instrument, -1) self._tuning_palette.menu.append(menu_item) menu_item.show() for i, f in enumerate(INSTRUMENT_DICT[instrument]): self.tuning.append(freq_note(f)) menu_item = MenuItem(icon_name='', text_label=freq_note(f)) menu_item.connect('activate', self._tuning_selected_cb, instrument, i) self._tuning_palette.menu.append(menu_item) menu_item.show() self.show_all() def _tuning_selected_cb(self, widget, instrument, fidx): ''' Update note ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar? return if not instrument in INSTRUMENT_DICT: return if fidx == -1: # All notes self.activity.wave.instrument = instrument self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: freq = INSTRUMENT_DICT[instrument][fidx] self.activity.wave.instrument = None self.activity.wave.tuning_line = freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True self._updating_note = False def harmonic_cb(self, *args): ''' Callback for harmonics control ''' self.activity.wave.harmonics = not self.activity.wave.harmonics if self.activity.wave.harmonics: self._harmonic.set_icon('harmonics-off') self._harmonic.set_tooltip(_('Hide harmonics.')) if self.activity.wave.instrument is None and \ self.activity.wave.tuning_line == 0.0: self._load_tuning_line() else: self._harmonic.set_icon('harmonics') self._harmonic.set_tooltip(_('Show harmonics.')) def tuning_line_cb(self, *args): ''' Callback for tuning insert ''' if self._show_tuning_line: self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: self._load_tuning_line() def _load_tuning_line(self): ''' Read the freq entry and use value to set tuning line ''' freq = self._freq_entry.get_text() try: self.activity.wave.tuning_line = float(freq) if freq < 0: freq = -freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True except ValueError: self.activity.wave.tuning_line = 0.0 self._freq_entry.set_text('0') # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() def play_cb(self, *args): ''' Save settings, turn off display, and then play a tone at the current frequency ''' channels = [] for c in range(self.activity.audiograb.channels): channels.append(self.activity.wave.get_visibility(channel=c)) self.activity.wave.set_visibility(False, channel=c) wave_status = self.activity.wave.get_active() self.activity.wave.set_context_off() self.activity.wave.set_active(False) if self.activity.hw in [XO4, XO175]: self.activity.audiograb.stop_grabbing() freq = float(self._freq_entry.get_text()) gobject.timeout_add(200, self.play_sound, freq, channels, wave_status) def play_sound(self, freq, channels, wave_status): ''' Play the sound and then restore wave settings ''' self._play_sinewave(freq, 5000, 1) if self.activity.hw in [XO4, XO175]: self.activity.sensor_toolbar.set_mode('sound') self.activity.sensor_toolbar.set_sound_context() self.activity.audiograb.start_grabbing() for c in range(self.activity.audiograb.channels): self.activity.wave.set_visibility(channels[c], channel=c) self.activity.wave.set_context_on() self.activity.wave.set_active(wave_status) def _play_sinewave(self, pitch, amplitude=5000, duration=1): """ Create a Csound score to play a sine wave. """ self.orchlines = [] self.scorelines = [] self.instrlist = [] try: pitch = abs(float(pitch)) amplitude = abs(float(amplitude)) duration = abs(float(duration)) except ValueError: logging.error('bad args to _play_sinewave') return self._prepare_sinewave(pitch, amplitude, duration) path = os.path.join(self.activity.get_activity_root(), 'instance', 'tmp.csd') # Create a csound file from the score. self._audio_write(path) # Play the csound file. output = check_output(['csound', path], 'call to csound failed?') # os.system('csound ' + path + ' > /dev/null 2>&1') def _prepare_sinewave(self, pitch, amplitude, duration, starttime=0, pitch_envelope=99, amplitude_envelope=100, instrument=1): pitenv = pitch_envelope ampenv = amplitude_envelope if not 1 in self.instrlist: self.orchlines.append("instr 1\n") self.orchlines.append("kpitenv oscil 1, 1/p3, p6\n") self.orchlines.append("aenv oscil 1, 1/p3, p7\n") self.orchlines.append("asig oscil p5*aenv, p4*kpitenv, p8\n") self.orchlines.append("out asig\n") self.orchlines.append("endin\n\n") self.instrlist.append(1) self.scorelines.append( "i1 %s %s %s %s %s %s %s\n" % (str(starttime), str(duration), str(pitch), str(amplitude), str(pitenv), str(ampenv), str(instrument))) def _audio_write(self, file): """ Compile a .csd file. """ csd = open(file, "w") csd.write("<CsoundSynthesizer>\n\n") csd.write("<CsOptions>\n") csd.write("-+rtaudio=alsa -odevaudio -m0 -d -b256 -B512\n") csd.write("</CsOptions>\n\n") csd.write("<CsInstruments>\n\n") csd.write("sr=16000\n") csd.write("ksmps=50\n") csd.write("nchnls=1\n\n") for line in self.orchlines: csd.write(line) csd.write("\n</CsInstruments>\n\n") csd.write("<CsScore>\n\n") csd.write("f1 0 2048 10 1\n") csd.write("f2 0 2048 10 1 0 .33 0 .2 0 .143 0 .111\n") csd.write("f3 0 2048 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n") csd.write("f10 0 2048 10 1 0 0 .3 0 .2 0 0 .1\n") csd.write("f99 0 2048 7 1 2048 1\n") csd.write("f100 0 2048 7 0. 10 1. 1900 1. 132 0.\n") csd.write(self.scorelines.pop()) csd.write("e\n") csd.write("\n</CsScore>\n") csd.write("\n</CsoundSynthesizer>") csd.close()
class hMouse(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) self.mCamara = False #si se esta mostrando la camara self.pAyuda = 1 #paso de la ayuda self._logger = logging.getLogger('hMouse-activity') toolbox = activity.ActivityToolbox(self) #activity toolbar self.activity_tb = toolbox.get_activity_toolbar() self.activity_tb.keep.props.visible = False self.activity_tb.share.props.visible = False #########toolbar hMouse############ self.hMouseTB = gtk.Toolbar() TI = gtk.ToolItem() #etiqueta estado self.estado = gtk.Label(_("Presione Iniciar!")) self.estado.set_width_chars(40) TI.add(self.estado) self.estado.show() self.hMouseTB.insert(TI, -1) TI.show() #boton calibrar ArrIzq-AbjDer self.calibrar0_bt = ToolButton('calibrar0') self.calibrar0_bt.set_tooltip(_('Calibrar ArrIzq-AbjDer')) self.hMouseTB.insert(self.calibrar0_bt, -1) self.calibrar0_bt.connect('clicked', self.calibrar0) self.calibrar0_bt.show() #boton calibrar Izq-Der-Arr-Abj self.calibrar1_bt = ToolButton('calibrar1') self.calibrar1_bt.set_tooltip(_('Calibrar 1')) self.hMouseTB.insert(self.calibrar1_bt, -1) self.calibrar1_bt.connect('clicked', self.calibrar1) self.calibrar1_bt.show() #boton calibrar Centro self.calibrar2_bt = ToolButton('calibrar2') self.calibrar2_bt.set_tooltip(_('Calibrar 2')) self.hMouseTB.insert(self.calibrar2_bt, -1) self.calibrar2_bt.connect('clicked', self.calibrar2) self.calibrar2_bt.show() #boton iniciar self.iniciar_bt = ToolButton('iniciar') self.iniciar_bt.set_tooltip(_('Iniciar')) self.hMouseTB.insert(self.iniciar_bt, -1) self.iniciar_bt.connect('clicked', self.start) self.iniciar_bt.show() #boton camara self.camara_bt = ToolButton('camara') self.camara_bt.set_tooltip(_('Ver camara')) self.hMouseTB.insert(self.camara_bt, -1) self.camara_bt.connect('clicked', self.camara) self.camara_bt.show() #boton ayuda self.ayuda_bt = ToolButton('ayuda') self.ayuda_bt.set_tooltip(_('Ayuda')) self.hMouseTB.insert(self.ayuda_bt, -1) self.ayuda_bt.connect('clicked', self.ayuda) self.ayuda_bt.show() #boton acerca self.acerca_bt = ToolButton('acerca') self.acerca_bt.set_tooltip(_('Acerca de...')) self.hMouseTB.insert(self.acerca_bt, -1) self.acerca_bt.connect('clicked', self.acerca) self.acerca_bt.show() ##############toolbar velocidad################ self.velTB = gtk.Toolbar() #boton 1hz self.uno_bt = ToolButton('1hz') self.uno_bt.set_tooltip(_('Velocidad 1')) self.velTB.insert(self.uno_bt, -1) self.uno_bt.connect('clicked', self.uno) self.uno_bt.show() #boton 2hz self.dos_bt = ToolButton('2hz') self.dos_bt.set_tooltip(_('Velocidad 2')) self.velTB.insert(self.dos_bt, -1) self.dos_bt.connect('clicked', self.dos) self.dos_bt.show() #boton 3hz self.tres_bt = ToolButton('3hz') self.tres_bt.set_tooltip(_('Velocidad 3')) self.velTB.insert(self.tres_bt, -1) self.tres_bt.connect('clicked', self.tres) self.tres_bt.show() #boton 4hz self.cuatro_bt = ToolButton('4hz') self.cuatro_bt.set_tooltip(_('Velocidad 4')) self.velTB.insert(self.cuatro_bt, -1) self.cuatro_bt.connect('clicked', self.cuatro) self.cuatro_bt.show() #toolbox toolbox.add_toolbar(_("hMouse"), self.hMouseTB) toolbox.show_all() #toolbox toolbox.add_toolbar(_("Velocidad"), self.velTB) toolbox.show_all() toolbox.set_current_toolbar(1) self.set_toolbox(toolbox) toolbox.show() #canvas self.canv = sugargame.canvas.PygameCanvas(self) self.set_canvas(self.canv) self.proc = Procesador.Procesador(self.estado) time.sleep(2) self.canv.run_pygame(self.proc.iniciar) def start(self, boton): self.proc.cont = not self.proc.cont if self.proc.cont: #self.iniciar_bt.set_icon("detener") self.iniciar_bt.set_tooltip(_('Detener')) self.proc.funcionando() else: self.iniciar_bt.set_icon("iniciar") self.iniciar_bt.set_tooltip(_('Iniciar')) def sensibilidad(self, boton, dx, dy): self.proc.calibrar2SetSensib(dx, dy) def calibrar0(self, boton): self.proc.iniciarCalibrado(0) def calibrar1(self, boton): self.proc.iniciarCalibrado(1) def calibrar2(self, boton): self.proc.iniciarCalibrado(2) def camara(self, boton): self.mCamara = not self.mCamara if self.mCamara: self.proc.mostrarVideo((0, 0)) i = 0 while self.mCamara: i += 1 if i > 60: self.proc.updGTK() i = 0 else: self.proc.dejarDeMostrar() def ayuda(self, boton): self.ayuda_bt.set_tooltip(_('Siguiente')) self.ayuda_bt.set_icon('siguiente') self.proc.updFondo() self.proc.tutorial(3, self.pAyuda) self.pAyuda += 1 if self.pAyuda > 4: self.pAyuda = 1 self.ayuda_bt.set_tooltip(_('Ayuda')) self.ayuda_bt.set_icon('ayuda') self.proc.updFondo() def acerca(self, boton): self.proc.updFondo() self.proc.tutorial(4, 1) def uno(self, boton): self.proc.setVel(1) def dos(self, boton): self.proc.setVel(2) def tres(self, boton): self.proc.setVel(3) def cuatro(self, boton): self.proc.setVel(4)
class ErikosActivity(activity.Activity): def __init__(self, handle): super(ErikosActivity,self).__init__(handle) try: # Use 0.86 toolbar design toolbar_box = ToolbarBox() # Buttons added to the Activity toolbar activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() # Play Button self.play = ToolButton( "media-playback-start" ) self.play.set_tooltip(_('Play')) self.play.props.sensitive = True self.play.connect('clicked', self._play_cb) toolbar_box.toolbar.insert(self.play, -1) self.play.show() # Sound Toggle Button self.sound = ToolButton( "speaker-muted-100" ) self.sound.set_tooltip(_('Mute')) self.sound.props.sensitive = True self.sound.connect('clicked', self._sound_cb) toolbar_box.toolbar.insert(self.sound, -1) self.sound.show() separator = gtk.SeparatorToolItem() separator.show() toolbar_box.toolbar.insert(separator, -1) # Label for showing level self.level_label = gtk.Label("%s %d" % (_("Level"),1)) self.level_label.show() level_toolitem = gtk.ToolItem() level_toolitem.add(self.level_label) toolbar_box.toolbar.insert(level_toolitem,-1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) separator.show() toolbar_box.toolbar.insert(separator, -1) # The ever-present Stop Button stop_button = StopButton(self) stop_button.props.accelerator = '<Ctrl>Q' toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() except NameError: # Use pre-0.86 toolbar design self.toolbox = activity.ActivityToolbox(self) self.set_toolbox(self.toolbox) self.projectToolbar = ProjectToolbar(self) self.toolbox.add_toolbar( _('Project'), self.projectToolbar ) self.toolbox.show() # Create a canvas canvas = gtk.DrawingArea() canvas.set_size_request(gtk.gdk.screen_width(), \ gtk.gdk.screen_height()) self.set_canvas(canvas) canvas.show() self.show_all() # Initialize the canvas self.sw = window.new_window(canvas, \ os.path.join(activity.get_bundle_path(), \ 'images/'), \ self) self.sw.activity = self # Read the level from the Journal try: sw.level = int(self.metadata['level']) except: pass def _play_cb(self, button): window.play_the_game(self.sw) return True def _sound_cb(self, button): if self.sw.sound is True: self.sound.set_icon("speaker-muted-000") self.sound.set_tooltip(_('Unmute')) self.sw.sound = False else: self.sound.set_icon("speaker-muted-100") self.sound.set_tooltip(_('Mute')) self.sw.sound = True return True """ Write the slider positions to the Journal """ def write_file(self, file_path): _logger.debug("Write level: " + str(self.sw.level)) self.metadata['level'] = self.sw.level
class LegoToolbar(gtk.Toolbar): ''' The toolbar for specifiying the sensor: temp, distance, light or gray ''' def __init__(self, activity, channels): #Its used to avoid it from running twice self._lego_context_id = None gtk.Toolbar.__init__(self) self.activity = activity self._channels = channels self.mode = 'lego' # Set up Sensores Button self.time = RadioToolButton(group=None) # Keeps the button list (sensors) # added to the LegoToolbar self.lista_sensores_button = [] self.we_are_logging = False self._log_this_sample = False self._logging_timer = None self._logging_counter = 0 self._image_counter = 0 self._logging_interval = 0 self._port_status = 1 self._channels_logged = [] self._busy = False self._take_screenshot = True self.refrescar_button = RadioToolButton(group=None) self.refrescar_button.set_named_icon('recargar') self.insert(self.refrescar_button, -1) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self.load_buttons() separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._port = PORT_VALUES[0] self.port_label = gtk.Label(self._port_to_string(self._port)) toolitem = gtk.ToolItem() toolitem.add(self.port_label) self.insert(toolitem, -1) self._port_button = ToolButton('LEGO-tools') self._port_button.set_tooltip(_('Select Port')) self._port_button.connect('clicked', self._port_selection_cb) self.insert(self._port_button, -1) self._setup_port_palette() separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_value = LOG_TIMER_VALUES[1] self.log_label = gtk.Label(self._log_to_string(self._log_value)) toolitem = gtk.ToolItem() toolitem.add(self.log_label) self.insert(toolitem, -1) self._log_button = ToolButton('timer-10') self._log_button.set_tooltip(_('Select logging interval')) self._log_button.connect('clicked', self._log_selection_cb) self.insert(self._log_button, -1) self._setup_log_palette() # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start Recording')) self._record.connect('clicked', self.record_control_cb) self.show_all() def get_log(self): return self._log_value def get_log_idx(self): if self._log_value in LOG_TIMER_VALUES: return LOG_TIMER_VALUES.index(self._log_value) else: return LOG_TIMER_VALUES[0] def set_log_idx(self, idx): self._log_value = LOG_TIMER_VALUES[idx] self.log_label.set_text(self._log_to_string(self._log_value)) if hasattr(self, '_log_button'): self._log_button.set_icon('timer-%d' % (self._log_value)) def _log_selection_cb(self, widget): if self._log_palette: if not self._log_palette.is_up(): self._log_palette.popup(immediate=True, state=self._log_palette.SECONDARY) else: self._log_palette.popdown(immediate=True) return def _log_to_seconds(self, tenth_seconds): return tenth_seconds / 10. def _log_to_string(self, tenth_seconds): if tenth_seconds in LOG_TIMER_LABELS: return LOG_TIMER_LABELS[tenth_seconds] else: return _('1 second') def _setup_log_palette(self): self._log_palette = self._log_button.get_palette() for tenth_seconds in LOG_TIMER_VALUES: text = self._log_to_string(tenth_seconds) menu_item = MenuItem(icon_name='timer-%d' % (tenth_seconds), text_label=self._log_to_string(tenth_seconds)) menu_item.connect('activate', self._log_selected_cb, tenth_seconds) self._log_palette.menu.append(menu_item) menu_item.show() def _log_selected_cb(self, button, seconds): self.set_log_idx(LOG_TIMER_VALUES.index(seconds)) def get_port(self): return self._port_value def get_port_idx(self): if self._port_value in PORT_VALUES: return PORT_VALUES.index(self._port_value) else: return PORT_VALUES[0] def set_port_idx(self, idx): self._port_value = PORT_VALUES[idx] self.port_label.set_text(self._port_to_string(self._port_value)) if hasattr(self, '_port_button'): self._port_button.set_icon('LEGO-tools') def _port_selection_cb(self, widget): if self._port_palette: if not self._port_palette.is_up(): self._port_palette.popup(immediate=True, state=self._port_palette.SECONDARY) else: self._port_palette.popdown(immediate=True) return def _port_to_string(self, tenth_seconds): if tenth_seconds in PORT_LABELS: return PORT_LABELS[tenth_seconds] else: return _('1 second') def _setup_port_palette(self): self._port_palette = self._port_button.get_palette() for tenth_seconds in PORT_VALUES: text = self._port_to_string(tenth_seconds) menu_item = MenuItem(icon_name='LEGO-tools', text_label=self._port_to_string(tenth_seconds)) menu_item.connect('activate', self._port_selected_cb, tenth_seconds) self._port_palette.menu.append(menu_item) menu_item.show() def _port_selected_cb(self, button, seconds): self.set_port_idx(PORT_VALUES.index(seconds)) #LEGO set up the sensor buttons def load_buttons(self): self.sensores = [_('Light Sensor'), _('Distance Sensor'), _('Grey Sensor'), _('Button Sensor'), _('Sound Sensor')] self.lista_sensores_button = [] for i in range(len(self.sensores)): self.sensor = self.sensores[i] radio_tool_button = RadioToolButton(group=self.time) icono = self.sensor.strip('0123456789:') radio_tool_button.set_named_icon(icono) radio_tool_button.set_tooltip(_(self.sensor)) if self.sensor.count(_('Sound Sensor')): radio_tool_button.connect('clicked',self.click_sound_button) if self.sensor.count(_('Distance Sensor')): radio_tool_button.connect('clicked',self.click_dist_button) elif self.sensor.count(_('Grey Sensor')): radio_tool_button.connect('clicked',self.click_grises_button) elif self.sensor.count(_('Button Sensor')): radio_tool_button.connect('clicked',self.click_button) log.debug(self.sensores) elif self.sensor.count(_('Light sensor')): radio_tool_button.connect('clicked',self.click_luz_button) self.insert(radio_tool_button, 2) self.lista_sensores_button.append(radio_tool_button) def get_sensor_number(self): log.debug('GETING SENSOR NUMBER') log.debug(str(self._port_status)) return self._port_status # LEGO reading sensor functions def read_sound_from_bobot_server(self): return nxt.getSound(self.get_port()) def read_dist_from_bobot_server(self): return nxt.getDistance(self.get_port()) def read_boton_from_bobot_server(self): return nxt.getButton(self.get_port()) def read_grises_from_bobot_server(self): return nxt.getGray(self.get_port()) def read_luz_from_bobot_server(self): return nxt.getLight(self.get_port()) def read_sensor_from_bobot_server(self): return 0 def click_button(self,button=None): self.set_lego_context() return False def click_sound_button(self, button=None): self.mode = 'temperatura' self.read_sensor_from_bobot_server = self.read_sound_from_bobot_server self.set_lego_context() return False def click_dist_button(self, button=None): self.mode = 'distancia' self.read_sensor_from_bobot_server = self.read_dist_from_bobot_server self.activity.limpiar_canales() self.set_lego_context() return False def click_boton_button(self, button=None): self.mode = 'boton' self.read_sensor_from_bobot_server = self.read_boton_from_bobot_server self.activity.limpiar_canales() self.set_lego_context() return False def click_grises_button(self, button=None): self.mode = 'grises' self.read_sensor_from_bobot_server = self.read_grises_from_bobot_server self.activity.limpiar_canales() self.set_lego_context() return False def click_luz_button(self, button=None): self.mode = 'luz' self.read_sensor_from_bobot_server = self.read_luz_from_bobot_server self.activity.limpiar_canales() self.set_lego_context() return False def set_lego_context(self): self.activity.audiograb.stop_grabbing() if self._lego_context_id: gobject.source_remove(self._lego_context_id) self._lego_context_id =\ gobject.timeout_add(50,self.lego_context_on) def lego_context_on(self): bufChannelTmp = [] #If pause button is active, do not add the value if self.activity.audiograb.get_freeze_the_display(): bufChannelTmp.append(self.read_sensor_from_bobot_server()) for i in range(self.activity.audiograb.channels): self.activity.wave.new_buffer(bufChannelTmp,i) if self.we_are_logging: self.logging_to_file(bufChannelTmp,i) if self.activity.CONTEXT == 'lego': return True else: return False def logging_to_file(self, data_buffer, channel): if self.we_are_logging: if self._logging_counter == MAX_LOG_ENTRIES: self._logging_counter = 0 self.we_are_logging = False self.activity.data_logger.stop_session() else: if self._logging_interval == 0: self._emit_for_logging(data_buffer, channel=channel) self._log_this_sample = False self.we_are_logging = False self.activity.data_logger.stop_session() elif self._log_this_sample: # Sample channels in order if self.activity.audiograb._channels_logged.index(False) ==\ channel: self.activity.audiograb._channels_logged[channel] =\ True self._emit_for_logging(data_buffer, channel=channel) # Have we logged every channel? if self.activity.audiograb._channels_logged.count(True)\ == self.activity.audiograb.channels: self._log_this_sample = False for i in range(self.activity.audiograb.channels): self.activity.audiograb._channels_logged[i] =\ False self._logging_counter += 1 def _emit_for_logging(self, data_buffer, channel=0): '''Sends the data for logging''' if not self._busy: self._busy = True if self._take_screenshot: if self.activity.data_logger.take_screenshot( self._image_counter): self._image_counter += 1 else: log.debug('failed to take screenshot %d' % ( self._logging_counter)) self._busy = False return value_string = data_buffer[0] def _sample_now(self): ''' Log the current sample now. This method is called from the _logging_timer object when the interval expires. ''' self._log_this_sample = True self._make_timer() def _make_timer(self): ''' Create the next timer that will trigger data logging. ''' self._logging_timer = Timer(self._logging_interval, self._sample_now) self._logging_timer.start() def record_control_cb(self, button=None): ''' Depending upon the selected interval, does either a logging session, or just logs the current buffer. ''' if self.we_are_logging: self.activity.audiograb.set_logging_params(start_stop=False) self._record.set_icon('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) else: Xscale = (1.00 / self.activity.audiograb.get_sampling_rate()) Yscale = 0.0 interval = self._log_value / 10. # self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode='frequency') else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode=self.mode) self.set_logging_params( start_stop=True, interval=interval, screenshot=False) self._record.set_icon('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) self.activity.new_recording = True def set_logging_params(self, start_stop=False, interval=0, screenshot=True): ''' Configures for logging of data: starts or stops a session; sets the logging interval; and flags if screenshot is taken. ''' self.we_are_logging = start_stop self._logging_interval = interval if not start_stop: if self._logging_timer: self._logging_timer.cancel() self._logging_timer = None self._log_this_sample = False self._logging_counter = 0 elif interval != 0: self._make_timer() self._take_screenshot = screenshot self._busy = False def interval_convert(self): ''' Converts interval string to an integer that denotes the number of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written. ''' interval_dictionary = {'1/10 second': 0.1, '1 second': 1, '30 seconds': 30, '5 minutes': 300, '30 minutes': 1800} try: return interval_dictionary[self.logging_interval_status] except ValueError: logging.error('logging interval status = %s' %\ (str(self.logging_interval_status))) return 0 def take_screenshot(self): ''' Capture the current screen to the Journal ''' log.debug('taking a screenshot %d' % (self._logging_counter)) self.set_logging_params(start_stop=True, interval=0, screenshot=True)
class RecordControl(): def __init__(self, toolbar): self._timer_value = TIMER_VALUES[0] self._timer_button = ToolButton('timer-0') self._timer_button.set_tooltip(_('Select timer')) self._timer_button.connect('clicked', self._timer_selection_cb) toolbar.insert(self._timer_button, -1) self._setup_timer_palette() self._duration_value = DURATION_VALUES[0] self._duration_button = ToolButton('duration-2') self._duration_button.set_tooltip(_('Select duration')) self._duration_button.connect('clicked', self._duration_selection_cb) toolbar.insert(self._duration_button, -1) self._setup_duration_palette() self._quality_value = 0 self._quality_button = ToolButton('low-quality') self._quality_button.set_tooltip(_('Select quality')) self._quality_button.connect('clicked', self._quality_selection_cb) toolbar.insert(self._quality_button, -1) self._setup_quality_palette() def _timer_selection_cb(self, widget): if self._timer_palette: if not self._timer_palette.is_up(): self._timer_palette.popup(immediate=True, state=self._timer_palette.SECONDARY) else: self._timer_palette.popdown(immediate=True) return def _setup_timer_palette(self): self._timer_palette = self._timer_button.get_palette() for seconds in TIMER_VALUES: if seconds == 0: text = _('Immediate') else: text = ngettext('%s second', '%s seconds', seconds) % seconds menu_item = MenuItem(icon_name='timer-%d' % (seconds), text_label=text) menu_item.connect('activate', self._timer_selected_cb, seconds) self._timer_palette.menu.append(menu_item) menu_item.show() def _timer_selected_cb(self, button, seconds): self.set_timer_idx(TIMER_VALUES.index(seconds)) def _duration_selection_cb(self, widget): if self._duration_palette: if not self._duration_palette.is_up(): self._duration_palette.popup( immediate=True, state=self._duration_palette.SECONDARY) else: self._duration_palette.popdown(immediate=True) return def _setup_duration_palette(self): self._duration_palette = self._duration_button.get_palette() for minutes in DURATION_VALUES: if minutes == 0: text = gtk.Label(_('Immediate')) else: text = ngettext('%s minute', '%s minutes', minutes) % minutes menu_item = MenuItem(icon_name='duration-%d' % (minutes), text_label=text) menu_item.connect('activate', self._duration_selected_cb, minutes) self._duration_palette.menu.append(menu_item) menu_item.show() def _duration_selected_cb(self, button, minutes): self.set_duration_idx(DURATION_VALUES.index(minutes)) def _quality_selection_cb(self, widget): if self._quality_palette: if not self._quality_palette.is_up(): self._quality_palette.popup( immediate=True, state=self._quality_palette.SECONDARY) else: self._quality_palette.popdown(immediate=True) return def _setup_quality_palette(self): self._quality_palette = self._quality_button.get_palette() for quality in QUALITY_VALUES: text = _('%s quality') % (quality) menu_item = MenuItem(icon_name=quality + '-quality', text_label=text) menu_item.connect('activate', self._quality_selected_cb, quality) self._quality_palette.menu.append(menu_item) menu_item.show() def _quality_selected_cb(self, button, quality): self.set_quality(QUALITY_VALUES.index(quality)) def set_mode(self, mode): if mode == constants.MODE_PHOTO: self._quality_button.set_sensitive(False) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(False) if mode == constants.MODE_VIDEO: self._quality_button.set_sensitive(True) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(True) if mode == constants.MODE_AUDIO: self._quality_button.set_sensitive(False) self._timer_button.set_sensitive(True) self._duration_button.set_sensitive(True) def get_timer(self): return self._timer_value def get_timer_idx(self): if self._timer_value in TIMER_VALUES: return TIMER_VALUES.index(self._timer_value) else: return TIMER_VALUES[0] def set_timer_idx(self, idx): self._timer_value = TIMER_VALUES[idx] if hasattr(self, '_timer_button'): self._timer_button.set_icon('timer-%d' % (self._timer_value)) def get_duration(self): return self._duration_value def get_duration_idx(self): if self._duration_value in DURATION_VALUES: return DURATION_VALUES.index(self._duration_value) else: return DURATION_VALUES[0] def set_duration_idx(self, idx): self._duration_value = DURATION_VALUES[idx] if hasattr(self, '_duration_button'): self._duration_button.set_icon('duration-%d' % (self._duration_value)) def get_quality(self): return self._quality_value def set_quality(self, idx): self._quality_value = idx if hasattr(self, '_quality_button'): self._quality_button.set_icon('%s-quality' % (QUALITY_VALUES[idx]))
class FreeFromMalariaActivity(activity.Activity): def __init__(self, handle): activity.Activity.__init__(self, handle) self.activity_state = {} self._name = handle self.set_title(_("Free From Malaria")) restartTitle = _("End User Licence"); restartText = _("The materials in this game are in no way intended to replace or supersede professional medical care, advice, diagnosis or treatment of a doctor. The game only provides general advice on Malaria. This advice may not apply to everyone in every locality. If you notice medical symptoms or feel ill, you should consult your doctor. Please seek further advice from your local health authority for further information about Malaria.All information provided in this activity has been produced using peer reviewed scientific and health documentation. By clicking OK you agree that this game should be used for general educational and information purposes only and is not intended to replace medical advice or act as a diagnosis tool. For more details please visit http://worldclassproject.org.uk/."); dialog = self.create_dialog_ok(restartTitle, restartText) result = dialog.run() dialog.destroy() #init the controller #game controller if handle.object_id == None: print "Launched from home." else: print "Journal resume." # Set title for our Activity self.set_title('Free From Malaria') # Attach sugar toolbox (Share, ...) # Use old <= 0.84 toolbar design toolbox = activity.ActivityToolbox(self) view_tool_bar = toolbox.get_activity_toolbar();#gtk.Toolbar() #for debug only # self.previous_chapter = ToolButton('gtk-media-forward-rtl') # self.previous_chapter.set_tooltip("Previous Chapter") # self.previous_chapter_id = self.previous_chapter.connect('clicked', self.previous_chapter_clicked) # view_tool_bar.insert(self.previous_chapter, 0) # self.previous_chapter.show() ######################################## self.previous_scene_button = ToolButton('previous') self.previous_scene_button.set_tooltip("Previous Scene") self.previous_scene_id = self.previous_scene_button.connect('clicked', self.previous_scene_clicked) view_tool_bar.insert(self.previous_scene_button, 1) self.previous_scene_button.show() ###########print "CHANGING" self.next_scene = ToolButton('next') self.next_scene.set_tooltip("Next Scene") self.next_scene_id = self.next_scene.connect('clicked', self.next_scene_clicked) view_tool_bar.insert(self.next_scene, 2) self.next_scene.show() ########### #disable comic buttons in the main menu self.set_navigation(False) ###################### self.sound = ToolButton('audio-volume-high') homeString = _("Enable/Disable Sound"); self.sound.set_tooltip(homeString) self.sound_id = self.sound.connect('clicked', self.sound_clicked) view_tool_bar.insert(self.sound, 3) self.sound.show() ############################# ########### self.reload = ToolButton('reload') restart = _("Restart"); self.reload.set_tooltip(restart) self.reload_id = self.reload.connect('clicked', self.reload_clicked) view_tool_bar.insert(self.reload, 4) self.reload.show() ###################### ###################### self.home = ToolButton('go-home') homeString = _("Go to main menu"); self.home.set_tooltip(homeString) self.home_id = self.home.connect('clicked', self.home_clicked) view_tool_bar.insert(self.home, 5) self.home.show() ############################# view_tool_bar.show() # toolbox.add_toolbar('Game Control', view_tool_bar) self.set_toolbox(toolbox) toolbox.show() activity_toolbar = toolbox.get_activity_toolbar() activity_toolbar.share.props.visible = False #global game state ##restore previous session self.controller = controller.GameController.GlobalGameController(self) self.read_and_parse_prefs(os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults') #welcomeview = WelcomeScreen.GameWelcomeScreen(self.controller); #self.create_new_window(welcomeview) # self.mywindow = welcomeview.get_window() # self.w_child = self.mywindow.get_child() # self.widget = self.w_child # self.pack_and_show() def next_scene_clicked(self, event): self.controller.next_scene(); def previous_scene_clicked(self, event): self.controller.previous_scene(); def reload_clicked(self, event): restartTitle = _("Restart The Story?"); restartText = _("Are you sure you want to restart the story?"); dialog = self.create_dialog(restartTitle, restartText) result = dialog.run() dialog.destroy() if result == gtk.RESPONSE_YES: self.controller.reload(); def home_clicked(self, event): restartTitle = _("Restart The Main Menu?"); restartText = _("Are you sure you want to return to the main menu?"); dialog = self.create_dialog(restartTitle, restartText) result = dialog.run() dialog.destroy() if result == gtk.RESPONSE_YES: self.controller.play_game("Welcome", None); def sound_clicked(self, event): if(self.controller.get_sound() == True): self.sound.set_icon("audio-volume-muted") self.controller.set_sound(False); else: self.controller.set_sound(True); self.sound.set_icon("audio-volume-high") def create_dialog(self, title, message): dialog = gtk.MessageDialog(parent=None, buttons=gtk.BUTTONS_YES_NO, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, message_format=message); dialog.set_title(title) return dialog; def create_dialog_ok(self, title, message): dialog = gtk.MessageDialog(parent=None, buttons=gtk.BUTTONS_OK, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, message_format=message); dialog.set_title(title) return dialog; ##disables the nav buttons when comic is not being shown def set_navigation(self, switch): self.previous_scene_button.set_sensitive(switch); self.next_scene.set_sensitive(switch); def create_new_window(self, view): #self.view = view; self.mywindow = view.get_window() self.w_child = self.mywindow.get_child() self.widget = self.w_child # if(self.widget==None or self.w_child==None): # raise RuntimeError("No widget available") self.pack_and_show() def pack_and_show(self): # Create the main container self._main_view = gtk.VBox() # Import our class gtktest(): # Step 1: Load class, which creates gtktest.widget #self.gtktest = devtest2(self) # Step 2: Remove the widget's parent if self.widget.parent: self.widget.parent.remove(self.widget) # Step 3: We attach that widget to our window self._main_view.pack_start(self.widget) # Display everything self.widget.show() self._main_view.show() self.set_canvas(self._main_view) self.show_all() def read_and_parse_prefs(self, file_path): #Parse and set preference data from a given file. #file_path=os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults' #file_path=os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults'; print "Restoring ", file_path try: read_file = open(file_path, 'r') self.activity_state = json.loads(read_file.read()) if self.activity_state.has_key('comic_index'): comic_index = self.activity_state['comic_index'] # print "Restoring with index ",comic_index self.controller.set_comic_index(comic_index) print "Restored COMIC SCENE from ", file_path if self.activity_state.has_key('current_language_code'): current_language = self.activity_state['current_language_code'] self.controller.load_language_by_code(current_language) print "Restored LANGUAGE from ", file_path self.controller.update_scene(); read_file.close(); except IOError:# as (errno, strerror): print "Error: Preferences error" except AttributeError:# as (errno): print "Warning: controller not initialised and prefs called. {0}" except: raise; def read_file(self, file_path): #Read state from datastore. self.read_and_parse_prefs(file_path) def write_file(self, file_path): # #"""Write state to journal datastore and to persistent file system. # #""" #file_path=os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults'; # print "WRITING FILE TO JOURNAL : "+os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults' # BUG [ID: 3334629] try: print "WRITING FILE TO JOURNAL : " + file_path self.activity_state['comic_index'] = self.controller.get_comic_index(); self.activity_state['current_language_code'] = self.controller.get_current_language_code(); serialised_data = json.dumps(self.activity_state) to_journal = file(file_path, 'w') try: to_journal.write(serialised_data) except: raise finally: to_journal.close() to_persistent_fs = file(os.environ['SUGAR_ACTIVITY_ROOT'] + '/data/defaults', 'w') try: to_persistent_fs.write(serialised_data) except: raise; finally: to_persistent_fs.close() except AttributeError:# BUG [ID: 3334629] print "Warning: controller not initialised and trying to write. {0}"
class WebToolbar(gtk.Toolbar): __gtype_name__ = 'WebToolbar' __gsignals__ = { 'add-link': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])) } def __init__(self, activity): gtk.Toolbar.__init__(self) self._activity = activity self._browser = activity._browser self._loading = False self._back = ToolButton('go-previous-paired') self._back.set_tooltip(_('Back')) self._back.props.sensitive = False self._back.connect('clicked', self._go_back_cb) self.insert(self._back, -1) self._back.show() self._forward = ToolButton('go-next-paired') self._forward.set_tooltip(_('Forward')) self._forward.props.sensitive = False self._forward.connect('clicked', self._go_forward_cb) self.insert(self._forward, -1) self._forward.show() self._stop_and_reload = ToolButton('media-playback-stop') self._stop_and_reload.connect('clicked', self._stop_and_reload_cb) self.insert(self._stop_and_reload, -1) self._stop_and_reload.show() self.entry = WebEntry() self.entry.connect('activate', self._entry_activate_cb) entry_item = gtk.ToolItem() entry_item.set_expand(True) entry_item.add(self.entry) self.entry.show() self.insert(entry_item, -1) entry_item.show() self._link_add = ToolButton('emblem-favorite') self._link_add.set_tooltip(_('Bookmark')) self._link_add.connect('clicked', self._link_add_clicked_cb) self.insert(self._link_add, -1) self._link_add.show() progress_listener = self._browser.progress progress_listener.connect('location-changed', self._location_changed_cb) progress_listener.connect('loading-start', self._loading_start_cb) progress_listener.connect('loading-stop', self._loading_stop_cb) progress_listener.connect('loading-progress', self._loading_progress_cb) self._browser.history.connect('session-history-changed', self._session_history_changed_cb) self._browser.connect("notify::title", self._title_changed_cb) self._create_ssb = ToolButton('activity-ssb') self._create_ssb.set_tooltip(_('Create SSB')) self._create_ssb.connect('clicked', self._create_ssb_clicked_cb) self.insert(self._create_ssb, -1) self._create_ssb.show() self._save_document = ToolButton('save') self._save_document.set_tooltip(_('Save Document')) self._save_document.connect('clicked', self._save_document_clicked_cb) self.insert(self._save_document, -1) self._save_document.show() def _session_history_changed_cb(self, session_history, current_page_index): # We have to wait until the history info is updated. gobject.idle_add(self._reload_session_history, current_page_index) def _location_changed_cb(self, progress_listener, uri): cls = components.classes['@mozilla.org/intl/texttosuburi;1'] texttosuburi = cls.getService(interfaces.nsITextToSubURI) ui_uri = texttosuburi.unEscapeURIForUI(uri.originCharset, uri.spec) self._set_address(ui_uri) self._update_navigation_buttons() filepicker.cleanup_temp_files() def _loading_start_cb(self, progress_listener): self._set_title(None) self._set_loading(True) self._update_navigation_buttons() def _loading_stop_cb(self, progress_listener): self._set_loading(False) self._update_navigation_buttons() def _loading_progress_cb(self, progress_listener, progress): self._set_progress(progress) def _set_progress(self, progress): self.entry.props.progress = progress def _set_address(self, address): self.entry.props.address = address def _set_title(self, title): self.entry.props.title = title def _show_stop_icon(self): self._stop_and_reload.set_icon('media-playback-stop') def _show_reload_icon(self): self._stop_and_reload.set_icon('view-refresh') def _update_navigation_buttons(self): can_go_back = self._browser.web_navigation.canGoBack self._back.props.sensitive = can_go_back can_go_forward = self._browser.web_navigation.canGoForward self._forward.props.sensitive = can_go_forward def _entry_activate_cb(self, entry): self._browser.load_uri(entry.props.text) self._browser.grab_focus() def _go_back_cb(self, button): self._browser.web_navigation.goBack() def _go_forward_cb(self, button): self._browser.web_navigation.goForward() def _title_changed_cb(self, embed, spec): self._set_title(embed.props.title) def _stop_and_reload_cb(self, button): if self._loading: self._browser.web_navigation.stop( \ interfaces.nsIWebNavigation.STOP_ALL) else: flags = interfaces.nsIWebNavigation.LOAD_FLAGS_NONE self._browser.web_navigation.reload(flags) def _set_loading(self, loading): self._loading = loading if self._loading: self._show_stop_icon() self._stop_and_reload.set_tooltip(_('Stop')) else: self._show_reload_icon() self._stop_and_reload.set_tooltip(_('Reload')) def _reload_session_history(self, current_page_index=None): session_history = self._browser.web_navigation.sessionHistory if current_page_index is None: current_page_index = session_history.index for palette in (self._back.get_palette(), self._forward.get_palette()): for menu_item in palette.menu.get_children(): palette.menu.remove(menu_item) if current_page_index > _MAX_HISTORY_ENTRIES: bottom = current_page_index - _MAX_HISTORY_ENTRIES else: bottom = 0 if (session_history.count - current_page_index) > \ _MAX_HISTORY_ENTRIES: top = current_page_index + _MAX_HISTORY_ENTRIES + 1 else: top = session_history.count for i in range(bottom, top): if i == current_page_index: continue entry = session_history.getEntryAtIndex(i, False) menu_item = MenuItem(entry.title, text_maxlen=60) menu_item.connect('activate', self._history_item_activated_cb, i) if i < current_page_index: palette = self._back.get_palette() palette.menu.prepend(menu_item) elif i > current_page_index: palette = self._forward.get_palette() palette.menu.append(menu_item) menu_item.show() def _history_item_activated_cb(self, menu_item, index): self._browser.web_navigation.gotoIndex(index) def _link_add_clicked_cb(self, button): self.emit('add-link') def _create_ssb_clicked_cb(self, button): title = self._activity.webtitle uri = self._activity.current #favicon = self._activity.get_favicon() pattern = re.compile(r''' (\w+) # first word [ _-]* # any amount and type of spacing (\w+)? # second word, may be absent ''', re.VERBOSE) first, second = re.search(pattern, title).groups() # CamelCase the two words first = first.capitalize() if second is not None: second = second.capitalize() name = first + ' ' + second else: name = first self._ssb = ssb.SSBCreator(name, uri) # alert to show after creation alert = Alert() alert.props.title = _('SSB Creation') cancel_icon = Icon(icon_name='dialog-cancel') alert.add_button(gtk.RESPONSE_CANCEL, _('Cancel'), cancel_icon) cancel_icon.show() open_icon = Icon(icon_name='filesave') alert.add_button(gtk.RESPONSE_APPLY, _('Show in Journal'), open_icon) open_icon.show() ok_icon = Icon(icon_name='dialog-ok') alert.add_button(gtk.RESPONSE_OK, _('Install'), ok_icon) ok_icon.show() self._activity.add_alert(alert) alert.connect('response', self._create_ssb_alert_cb) try: self._ssb.create() except Exception, e: # DEBUG: alert shows exception message alert.props.msg = _('Failed: ') + str(e) else:
class SensorToolbar(gtk.Toolbar): """ The toolbar for resitance and voltage sensors """ __gsignals__ = { 'add-media': (gobject.SIGNAL_RUN_FIRST, None, [object]), 'add-opened': (gobject.SIGNAL_RUN_FIRST, None, [object]) } def __init__(self, activity): """ By default, start with resistance mode """ gtk.Toolbar.__init__(self) self.mode = 'resistance' self._STR_BASIC = \ _("Sensors, DC (connect sensor to pink 'Mic In' on left side of XO)") \ + ' ' self._STR_R = _('Bias/Offset Enabled') + ' ' + _('Ohms') + ' ' self._STR_V = _('Bias/Offset Disabled') + ' ' + _('Volts') + ' ' self._STR_I = ' ' + _('Invert') + ' ' self.string_for_textbox = "" self.activity = activity self.activity.audiograb.set_sensor(self) # Set up Resistance Button if self.activity.has_toolbarbox: self.resistance = ToolButton('bias-on') else: self.resistance = ToolButton('bias-on2') self.insert(self.resistance, -1) self.resistance.show() self.resistance.set_tooltip(_('Resistance Sensor')) self.resistance.connect('clicked', self.set_resistance_voltage_mode, 'resistance') # Set up Voltage Button self.voltage = ToolButton('bias-off') self.insert(self.voltage, -1) self.voltage.set_tooltip(_('Voltage Sensor')) self.voltage.connect('clicked', self.set_resistance_voltage_mode, 'voltage') # Set up Invert Button self._invert = ToolButton('invert') self.insert(self._invert, -1) self._invert.set_tooltip(_('Invert')) self._invert.connect('clicked', self._invert_control_cb) self.activity.wave.set_invert_state(False) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self.audiobutton = ToolButton('add-icon') self.insert(self.audiobutton, -1) self.audiobutton.show() self.audiobutton.set_tooltip('Close Sound') self.audiobutton.connect('clicked', self.addAudio) self.connect('add-media', self.addThisAudio) self.insert(separator, -1) self.insert(separator, -1) self.openedbutton = ToolButton('delete-icon') self.insert(self.openedbutton, -1) self.openedbutton.show() self.openedbutton.set_tooltip('Open Sound') self.openedbutton.connect('clicked', self.addOpenedAudio) self.connect('add-opened', self.addThisOpenedAudio) self.insert(separator, -1) self.insert(separator, -1) # Set up Logging Interval combo box self.loginterval_img = gtk.Image() self.loginterval_img.set_from_file(ICONS_DIR + '/sample_rate.svg') self.loginterval_img_tool = gtk.ToolItem() self.loginterval_img_tool.add(self.loginterval_img) self.insert(self.loginterval_img_tool, -1) self._loginterval_combo = ComboBox() self.interval = [ _('1/10 second'), _('1 second'), _('30 seconds'), _('5 minutes'), _('30 minutes') ] if hasattr(self._loginterval_combo, 'set_tooltip_text'): self._loginterval_combo.set_tooltip_text(_('Sampling interval')) self._interval_changed_id = self._loginterval_combo.connect( "changed", self.loginterval_control) for i, s in enumerate(self.interval): self._loginterval_combo.append_item(i, s, None) if s == _('1 second'): self._loginterval_combo.set_active(i) self._loginterval_tool = ToolComboBox(self._loginterval_combo) self.insert(self._loginterval_tool, -1) self.logginginterval_status = '1 second' # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start Recording')) self._record.connect('clicked', self.record_control) self.show_all() def addAudio(self, button): #self.activity.showFileLoadBlocker(True) fp = FilePicker() dOb = fp.show() if (dOb != None): if (dOb.file_path != None): self.emit('add-media', dOb) #self.activity.showFileLoadBlocker(False) def addOpenedAudio(self, button): fp = FilePicker() dOb = fp.show() if (dOb != None): if (dOb.file_path != None): self.emit('add-opened', dOb) def addThisAudio(self, ot, datastoreOb): self.activity.closedSound = datastoreOb #self.activity.playsound.setLocation("file://"+datastoreOb.file_path) #self.activity.playsound.play() def addThisOpenedAudio(self, ot, datastoreOb): self.activity.openedSound = datastoreOb def set_sample_value(self, label=None): """ Write a sample value to the textbox """ gtk.threads_enter() self._update_string_for_textbox(label) gtk.threads_leave() return def record_control(self, data=None): """Depending upon the selected interval, does either a logging session, or just logs the current buffer""" if not self.activity.LOGGING_IN_SESSION: Xscale = (1.00 / self.activity.audiograb.get_sampling_rate()) Yscale = 0.0 interval = self.interval_convert() username = self.activity.nick print "calling start new session" self.activity.ji.start_new_session(username, Xscale, Yscale, _(self.logginginterval_status)) self.activity.audiograb.set_logging_params(True, interval, False) self.activity.LOGGING_IN_SESSION = True self._record.set_icon('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) else: self.activity.audiograb.set_logging_params(False) self.activity.LOGGING_IN_SESSION = False self._record.set_icon('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) def interval_convert(self): """Converts interval string to an integer that denotes the number of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written""" interval_dictionary = { '1/10 second': 0.1, '1 second': 1, '30 seconds': 30, '5 minutes': 300, '30 minutes': 1800 } try: return interval_dictionary[self.logginginterval_status] except ValueError: logging.error('logging interval status = %s' %\ (str(self.logginginterval_status))) return 0 def loginterval_control(self, combobox): """ Callback from the Logging Interval Combo box: sets status """ if self._loginterval_combo.get_active() != -1: intervals = [ '1/10 second', '1 second', '30 seconds', '5 minutes', '30 minutes' ] self.logginginterval_status = \ intervals[self._loginterval_combo.get_active()] def set_resistance_voltage_mode(self, data=None, mode_to_set='resistance'): """ Callback for Resistance/Voltage Buttons """ # Make sure the current context is for sensor capture. if self.activity.CONTEXT != 'sensor': self.activity.set_sensor_context() self.set_mode(mode_to_set) if mode_to_set == 'resistance': self.resistance.set_icon('bias-on2') self.voltage.set_icon('bias-off') self.resistance.show() self.voltage.show() self._update_string_for_textbox() if self.activity.has_toolbarbox: self.activity.label_button.set_icon('bias-on2') self.activity.label_button.set_tooltip(_('Resistance Sensor')) elif mode_to_set == 'voltage': self.resistance.set_icon('bias-on') self.voltage.set_icon('bias-off2') self.resistance.show() self.voltage.show() self._update_string_for_textbox() if self.activity.has_toolbarbox: self.activity.label_button.set_icon('bias-off2') self.activity.label_button.set_tooltip(_('Voltage Sensor')) else: logging.error('unknown mode %s' % (mode_to_set)) if self.activity.has_toolbarbox: self.activity.sound_toolbar.time.set_icon('domain-time') self.activity.sound_toolbar.freq.set_icon('domain-freq') return False def _invert_control_cb(self, data=None): """ Callback for Invert Button """ if self.activity.wave.get_invert_state(): self.activity.wave.set_invert_state(False) self._invert.set_icon('invert') self._invert.show() else: self.activity.wave.set_invert_state(True) self._invert.set_icon('invert2') self._invert.show() self._update_string_for_textbox() return False def set_mode(self, mode='resistance'): """ Set the mixer settings to match the current mode. """ self.mode = mode self.activity.audiograb.set_sensor_type(self.mode) return def context_off(self): """ Called when sensor toolbar is no longer selected. """ self.activity.audiograb.pause_grabbing() def context_on(self): """ Called when sensor toolbar is selected. """ self.activity.audiograb.resume_grabbing() self.activity.audiograb.set_sensor_type(self.mode) self._update_string_for_textbox() self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE) return False def _update_string_for_textbox(self, value=None): """ Update the status field at the bottom of the canvas. """ self.string_for_textbox = "" self.string_for_textbox += (self._STR_BASIC + "\n") if self.mode == 'resistance': self.string_for_textbox += self._STR_R else: self.string_for_textbox += self._STR_V if self.activity.wave.get_invert_state(): self.string_for_textbox += self._STR_I if value is not None: self.string_for_textbox += '\t(%s)' % (str(value)) self.activity.text_box.set_data_params(0, self.string_for_textbox)
class ButiaToolbar(gtk.Toolbar): ''' The toolbar for specifiying the sensor: temp, distance, light or gray ''' def __init__(self, activity, channels): #Se utiliza para contralar que no se ejecute dos veces self._butia_context_id = None gtk.Toolbar.__init__(self) self.activity = activity self._channels = channels self.mode = 'butia' # Set up Sensores Button self.time = RadioToolButton(group=None) # Mantiene la lista de botones (de sensores) # agregados a la ButiaToolbar self.lista_sensores_button = [] self.we_are_logging = False self._log_this_sample = False self._logging_timer = None self._logging_counter = 0 self._image_counter = 0 self._logging_interval = 0 self._channels_logged = [] self._busy = False self._take_screenshot = True # BUTIA Se detectan sensores log.debug('se agrega el boton refrescar') self.refrescar_button = RadioToolButton(group=None) self.refrescar_button.set_named_icon('recargar') self.refrescar_button.connect('clicked', self.update_buttons) self.insert(self.refrescar_button, -1) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self.detect_sensors() self.load_buttons() separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_interval_combo = ComboBox() self.interval = [ _('1/10 second'), _('1 second'), _('30 seconds'), _('5 minutes'), _('30 minutes') ] if hasattr(self._log_interval_combo, 'set_tooltip_text'): self._log_interval_combo.set_tooltip_text(_('Sampling interval')) self._interval_changed_id = self._log_interval_combo.connect( 'changed', self.log_interval_cb) for i, s in enumerate(self.interval): self._log_interval_combo.append_item(i, s, None) if s == _('1 second'): self._log_interval_combo.set_active(i) self._log_interval_tool = ToolComboBox(self._log_interval_combo) self.insert(self._log_interval_tool, -1) self.logging_interval_status = '1 second' # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start Recording')) self._record.connect('clicked', self.record_control_cb) self.show_all() # BUTIA Busca modulos conectados y pregunta si son sensores def detect_sensors(self): self.robot = butiaAPI.robot() log.debug('listando modulos detectados:') modules = self.robot.get_modules_list() self.sensores = [] log.debug(modules) for i in range(len(modules)): if self.is_sensor(modules[i]): log.debug(modules[i] + ' es sensor!') self.sensores.append(modules[i]) else: log.debug(modules[i] + ' no es sensor!') self.sensores.sort() log.debug('sensores: ') log.debug(self.sensores) # BUTIA determina si el modulo que le pasan es sensor! ! def is_sensor(self, module): is_sensor = 0 descripcion = 'A' #log.debug('DESCRIBIENDO: '+ module) descripcion = self.robot.doCommand('DESCRIBE ' + module) if descripcion == -1: return 0 #log.debug(descripcion) is_sensor = descripcion.count( 'returns={[1]') and module != 'display' and module != 'butia' return is_sensor #BUTIA Cargo los botones para cada sensor detectado def load_buttons(self): self.lista_sensores_button = [] for i in range(len(self.sensores)): self.sensor = self.sensores[i] log.debug('agregando boton para : ' + self.sensor) #radio_tool_button = 0 radio_tool_button = RadioToolButton(group=self.time) icono = self.sensor.strip('0123456789:') radio_tool_button.set_named_icon(icono) radio_tool_button.set_tooltip(_(self.sensor)) if self.sensor.count('temp'): #determino el numero de sensor y lo paso por parametro. #log.debug('el sensor '+ self.sensor + 'es el numero '+ self.get_sensor_number(self.sensor) ) radio_tool_button.connect('clicked', self.click_temp_button, self.get_sensor_number(self.sensor)) elif self.sensor.count('dist'): #log.debug('el sensor '+ self.sensor + 'es el numero '+ self.get_sensor_number(self.sensor) ) radio_tool_button.connect('clicked', self.click_dist_button, self.get_sensor_number(self.sensor)) elif self.sensor.count('grey'): #log.debug('el sensor '+ self.sensor + 'es el numero '+ self.get_sensor_number(self.sensor) ) radio_tool_button.connect('clicked', self.click_grises_button, self.get_sensor_number(self.sensor)) elif self.sensor.count('light'): #log.debug('el sensor '+ self.sensor + 'es el numero '+ self.get_sensor_number(self.sensor) ) radio_tool_button.connect('clicked', self.click_luz_button, self.get_sensor_number(self.sensor)) self.insert(radio_tool_button, 2) self.lista_sensores_button.append(radio_tool_button) def update_buttons(self, button=None): for s in self.lista_sensores_button: self.remove(s) self.detect_sensors() self.load_buttons() self.show_all() def get_sensor_number(self, sensor): number = 0 sensor_trunked = sensor.strip('0123456789') number = sensor.strip(sensor_trunked) log.debug('sensor number :' + sensor.strip(sensor)) return number # BUTIA metodos para leen sensores def read_temp_from_bobot_server(self, num=0): #log.debug('**********Sensando temperature' + str(num)+ '***********') value = 0 value = self.robot.callModule('temp:' + str(num), 'getValue') #log.debug('temperature : ' + value) return value def read_dist_from_bobot_server(self, num=0): #log.debug('**********Sensando distance'+ str(num) + '******************') value = 0 #value = self.robot.getDistance(num) value = self.robot.callModule('distanc:' + str(num), 'getValue') #log.debug('distance = ' + str(value)) return value def read_grises_from_bobot_server(self, num=0): #log.debug('**********Sensando grises'+ str(num) + '******************') value = '0' value = self.robot.callModule('grey:' + str(num), 'getValue') #log.debug('grey = ' + str(value)) return value def read_luz_from_bobot_server(self, num=0): #log.debug('**********Sensando luz '+ str(num) + '******************') value = '0' value = self.robot.callModule('ligth:' + str(num), 'getValue') #log.debug('grey = ' + str(value)) return value def read_sensor_from_bobot_server(self, num): log.debug('**********Read Sensor ***********') return 0 def click_button(self, button=None): log.debug('********** clicka botton ***********') self.set_butia_context() return False def click_temp_button(self, button=None, num='0'): log.debug('********** clickea botton temp ***********') self.mode = 'temperatura' self.read_sensor_from_bobot_server = self.read_temp_from_bobot_server self.set_butia_context(num) return False def click_dist_button(self, button=None, num='0'): log.debug('********** clickea botton dist ***********') self.mode = 'distancia' self.read_sensor_from_bobot_server = self.read_dist_from_bobot_server self.activity.limpiar_canales() self.set_butia_context(num) return False def click_grises_button(self, button=None, num='0'): log.debug('********** clickea botton grises ***********') self.mode = 'grises' self.read_sensor_from_bobot_server = self.read_grises_from_bobot_server self.activity.limpiar_canales() self.set_butia_context(num) return False def click_luz_button(self, button=None, num='0'): log.debug('********** clickea botton luz ***********') self.mode = 'luz' self.read_sensor_from_bobot_server = self.read_luz_from_bobot_server self.activity.limpiar_canales() self.set_butia_context(num) return False def set_butia_context(self, num='0'): self.activity.audiograb.stop_grabbing() if self._butia_context_id: gobject.source_remove(self._butia_context_id) self._butia_context_id =\ gobject.timeout_add(50,self.butia_context_on,num) def butia_context_on(self, num='0'): bufChannelTmp = [] #Si esta el boton de pause activada no se agregar el nuevo valor if self.activity.audiograb.get_freeze_the_display(): bufChannelTmp.append(self.read_sensor_from_bobot_server(num)) for i in range(self.activity.audiograb.channels): self.activity.wave.new_buffer(bufChannelTmp, i) if self.we_are_logging: self.logging_to_file(bufChannelTmp, i) if self.activity.CONTEXT == 'butia': return True else: return False def logging_to_file(self, data_buffer, channel): if self.we_are_logging: if self._logging_counter == MAX_LOG_ENTRIES: self._logging_counter = 0 self.we_are_logging = False self.activity.data_logger.stop_session() else: if self._logging_interval == 0: self._emit_for_logging(data_buffer, channel=channel) self._log_this_sample = False self.we_are_logging = False self.activity.data_logger.stop_session() elif self._log_this_sample: # Sample channels in order if self.activity.audiograb._channels_logged.index( False) == channel: self.activity.audiograb._channels_logged[ channel] = True self._emit_for_logging(data_buffer, channel=channel) # Have we logged every channel? if self.activity.audiograb._channels_logged.count( True) == self.activity.audiograb.channels: self._log_this_sample = False for i in range(self.activity.audiograb.channels): self.activity.audiograb._channels_logged[ i] = False self._logging_counter += 1 def _emit_for_logging(self, data_buffer, channel=0): '''Sends the data for logging''' if not self._busy: self._busy = True if self._take_screenshot: if self.activity.data_logger.take_screenshot( self._image_counter): self._image_counter += 1 else: log.debug('failed to take screenshot %d' % (self._logging_counter)) self._busy = False return value_string = data_buffer[0] if self.activity.audiograb.channels > 1: self.activity.data_logger.write_value( value_string, channel=channel, sample=self._logging_counter) else: self.activity.data_logger.write_value( value_string, sample=self._logging_counter) self._busy = False else: log.debug('skipping sample %d.%d' % (self._logging_counter, channel)) def _sample_now(self): ''' Log the current sample now. This method is called from the _logging_timer object when the interval expires. ''' self._log_this_sample = True self._make_timer() def _make_timer(self): ''' Create the next timer that will trigger data logging. ''' self._logging_timer = Timer(self._logging_interval, self._sample_now) self._logging_timer.start() def record_control_cb(self, button=None): ''' Depending upon the selected interval, does either a logging session, or just logs the current buffer. ''' if self.we_are_logging: self.set_logging_params(start_stop=False) self._record.set_icon('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) else: Xscale = 0.0 Yscale = 0.0 interval = self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, _(self.logging_interval_status), channels=self._channels, mode='frequency') else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, _(self.logging_interval_status), channels=self._channels, mode=self.mode) self.set_logging_params(start_stop=True, interval=interval, screenshot=False) self._record.set_icon('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) self.activity.new_recording = True def set_logging_params(self, start_stop=False, interval=0, screenshot=True): ''' Configures for logging of data: starts or stops a session; sets the logging interval; and flags if screenshot is taken. ''' self.we_are_logging = start_stop self._logging_interval = interval if not start_stop: if self._logging_timer: self._logging_timer.cancel() self._logging_timer = None self._log_this_sample = False self._logging_counter = 0 elif interval != 0: self._make_timer() self._take_screenshot = screenshot self._busy = False def interval_convert(self): ''' Converts interval string to an integer that denotes the number of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written. ''' interval_dictionary = { '1/10 second': 0.1, '1 second': 1, '30 seconds': 30, '5 minutes': 300, '30 minutes': 1800 } try: return interval_dictionary[self.logging_interval_status] except ValueError: logging.error('logging interval status = %s' %\ (str(self.logging_interval_status))) return 0 def log_interval_cb(self, combobox): ''' Callback from the Logging Interval Combo box: sets status ''' if self._log_interval_combo.get_active() != -1: intervals = [ '1/10 second', '1 second', '30 seconds', '5 minutes', '30 minutes' ] self.logging_interval_status = \ intervals[self._log_interval_combo.get_active()] def take_screenshot(self): ''' Capture the current screen to the Journal ''' log.debug('taking a screenshot %d' % (self._logging_counter)) self.set_logging_params(start_stop=True, interval=0, screenshot=True)
class TuningToolbar(gtk.Toolbar): ''' The toolbar for tuning instruments ''' def __init__(self, activity): gtk.Toolbar.__init__(self) self.activity = activity self._show_tuning_line = False self._updating_note = True self._tuning_tool = None self._instrument_button = ToolButton('instruments') self._instrument_button.set_tooltip(_('Tune an instrument.')) self._instrument_button.connect('clicked', self._button_selection_cb) self.insert(self._instrument_button, -1) self._setup_instrument_palette() separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._note = 'A' self._notes_button = ToolButton('notes') self._notes_button.set_tooltip(_('Notes')) self._notes_button.connect('clicked', self._button_selection_cb) self.insert(self._notes_button, -1) self._setup_notes_palette() self._octave = 4 self._octaves_button = ToolButton('octaves') self._octaves_button.set_tooltip(_('Octaves')) self._octaves_button.connect('clicked', self._button_selection_cb) self.insert(self._octaves_button, -1) self._setup_octaves_palette() # The entry is used to display a note or for direct user input self._freq_entry = gtk.Entry() self._freq_entry.set_text('440') # A self._freq_entry_changed_id = self._freq_entry.connect( 'changed', self._update_freq_entry) if hasattr(self._freq_entry, 'set_tooltip_text'): self._freq_entry.set_tooltip_text( _('Enter a frequency to display.')) self._freq_entry.set_width_chars(8) self._freq_entry.show() toolitem = gtk.ToolItem() toolitem.add(self._freq_entry) self.insert(toolitem, -1) toolitem.show() self._new_tuning_line = ToolButton('tuning-tools') self._new_tuning_line.show() self.insert(self._new_tuning_line, -1) self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._new_tuning_line.connect('clicked', self.tuning_line_cb) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._harmonic = ToolButton('harmonics') self._harmonic.show() self.insert(self._harmonic, -1) self._harmonic.set_tooltip(_('Show harmonics.')) self._harmonic.connect('clicked', self.harmonic_cb) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._play_tone = ToolButton('media-playback-start') self._play_tone.show() self.insert(self._play_tone, -1) self._play_tone.set_tooltip(_('Play a note.')) self._play_tone.connect('clicked', self.play_cb) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) self.label = gtk.Label('') self.label.set_use_markup(True) self.label.show() toolitem = gtk.ToolItem() toolitem.add(self.label) self.insert(toolitem, -1) toolitem.show() self.show_all() def _update_note(self): ''' Calculate the frequency based on note and octave ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar return i = self._octave * 12 + NOTES.index(self._note) freq = A0 * pow(TWELTHROOT2, i) self._updating_note = True self._freq_entry.set_text('%0.3f' % (freq)) self.label.set_markup(SPAN % (style.COLOR_WHITE.get_html(), self._note + str(self._octave))) if self._show_tuning_line: self.activity.wave.tuning_line = freq return def _update_freq_entry(self, widget): # Calculate a note from a frequency if not self._updating_note: # Only if user types in a freq. try: freq = float(self._freq_entry.get_text()) # Only consider notes in piano range if freq < A0 * 0.97: self.label.set_text('< A0') return if freq > C8 * 1.03: self.label.set_text('> C8') return self.label.set_markup(freq_note(freq, flatsharp=True)) except ValueError: return self._updating_note = False def _button_selection_cb(self, widget): palette = widget.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True, state=palette.SECONDARY) else: palette.popdown(immediate=True) return def _setup_notes_palette(self): self._notes_palette = self._notes_button.get_palette() for note in NOTES: menu_item = MenuItem(icon_name='', text_label=note) menu_item.connect('activate', self._note_selected_cb, note) self._notes_palette.menu.append(menu_item) menu_item.show() def _note_selected_cb(self, widget, note): self._note = note self._update_note() def _setup_octaves_palette(self): self._octaves_palette = self._octaves_button.get_palette() for octave in range(9): menu_item = MenuItem(icon_name='', text_label=str(octave)) menu_item.connect('activate', self._octave_selected_cb, octave) self._octaves_palette.menu.append(menu_item) menu_item.show() def _octave_selected_cb(self, widget, octave): self._octave = octave self._update_note() def _setup_instrument_palette(self): self.instrument_palette = self._instrument_button.get_palette() self.instrument = [] for k in INSTRUMENT_DICT.keys(): self.instrument.append(k) menu_item = MenuItem(icon_name='', text_label=k) menu_item.connect('activate', self.instrument_selected_cb, k) self.instrument_palette.menu.append(menu_item) menu_item.show() def instrument_selected_cb(self, button, instrument): ''' Callback for instrument control ''' logging.debug(instrument) if self._tuning_tool is not None: self.remove(self._tuning_tool) if instrument == _('None'): self.activity.wave.instrument = None # Remove any previous tuning button if hasattr(self, '_tuning_button'): self._tuning_button.destroy() # Restore the notes, octaves buttons if hasattr(self, '_notes_button'): self.insert(self._notes_button, 2) self.insert(self._octaves_button, 3) return self.remove(self._notes_button) self.remove(self._octaves_button) self.activity.wave.instrument = instrument # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Add a Tuning palette for this instrument self._tuning_button = ToolButton('notes') self._tuning_button.set_tooltip(instrument) self._tuning_button.connect('clicked', self._button_selection_cb) self.insert(self._tuning_button, 1) self._setup_tuning_palette(instrument) def _setup_tuning_palette(self, instrument): self._tuning_palette = self._tuning_button.get_palette() self.tuning = [] self.tuning.append(_('All notes')) menu_item = MenuItem(icon_name='', text_label=_('All notes')) menu_item.connect('activate', self._tuning_selected_cb, instrument, -1) self._tuning_palette.menu.append(menu_item) menu_item.show() for i, f in enumerate(INSTRUMENT_DICT[instrument]): self.tuning.append(freq_note(f)) menu_item = MenuItem(icon_name='', text_label=freq_note(f)) menu_item.connect('activate', self._tuning_selected_cb, instrument, i) self._tuning_palette.menu.append(menu_item) menu_item.show() self.show_all() def _tuning_selected_cb(self, widget, instrument, fidx): ''' Update note ''' if not hasattr(self, '_freq_entry'): # Still setting up toolbar? return if not instrument in INSTRUMENT_DICT: return if fidx == -1: # All notes self.activity.wave.instrument = instrument self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: freq = INSTRUMENT_DICT[instrument][fidx] self.activity.wave.instrument = None self.activity.wave.tuning_line = freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True self._updating_note = False def harmonic_cb(self, *args): ''' Callback for harmonics control ''' self.activity.wave.harmonics = not self.activity.wave.harmonics if self.activity.wave.harmonics: self._harmonic.set_icon('harmonics-off') self._harmonic.set_tooltip(_('Hide harmonics.')) if self.activity.wave.instrument is None and \ self.activity.wave.tuning_line == 0.0: self._load_tuning_line() else: self._harmonic.set_icon('harmonics') self._harmonic.set_tooltip(_('Show harmonics.')) def tuning_line_cb(self, *args): ''' Callback for tuning insert ''' if self._show_tuning_line: self.activity.wave.tuning_line = 0.0 self._new_tuning_line.set_icon('tuning-tools') self._new_tuning_line.set_tooltip(_('Show tuning line.')) self._show_tuning_line = False else: self._load_tuning_line() def _load_tuning_line(self): ''' Read the freq entry and use value to set tuning line ''' freq = self._freq_entry.get_text() try: self.activity.wave.tuning_line = float(freq) if freq < 0: freq = -freq self._new_tuning_line.set_icon('tuning-tools-off') self._new_tuning_line.set_tooltip(_('Hide tuning line.')) self._show_tuning_line = True except ValueError: self.activity.wave.tuning_line = 0.0 self._freq_entry.set_text('0') # If we are not already in freq. base, switch. if not self.activity.wave.get_fft_mode(): self.activity.timefreq_control() def play_cb(self, *args): ''' Save settings, turn off display, and then play a tone at the current frequency ''' channels = [] for c in range(self.activity.audiograb.channels): channels.append(self.activity.wave.get_visibility(channel=c)) self.activity.wave.set_visibility(False, channel=c) wave_status = self.activity.wave.get_active() self.activity.wave.set_context_off() self.activity.wave.set_active(False) if self.activity.hw in [XO4, XO175]: self.activity.audiograb.stop_grabbing() freq = float(self._freq_entry.get_text()) gobject.timeout_add(200, self.play_sound, freq, channels, wave_status) def play_sound(self, freq, channels, wave_status): ''' Play the sound and then restore wave settings ''' self._play_sinewave(freq, 5000, 1) if self.activity.hw in [XO4, XO175]: self.activity.sensor_toolbar.set_mode('sound') self.activity.sensor_toolbar.set_sound_context() self.activity.audiograb.start_grabbing() for c in range(self.activity.audiograb.channels): self.activity.wave.set_visibility(channels[c], channel=c) self.activity.wave.set_context_on() self.activity.wave.set_active(wave_status) def _play_sinewave(self, pitch, amplitude=5000, duration=1): """ Create a Csound score to play a sine wave. """ self.orchlines = [] self.scorelines = [] self.instrlist = [] try: pitch = abs(float(pitch)) amplitude = abs(float(amplitude)) duration = abs(float(duration)) except ValueError: logging.error('bad args to _play_sinewave') return self._prepare_sinewave(pitch, amplitude, duration) path = os.path.join(self.activity.get_activity_root(), 'instance', 'tmp.csd') # Create a csound file from the score. self._audio_write(path) # Play the csound file. output = check_output(['csound', path], 'call to csound failed?') # os.system('csound ' + path + ' > /dev/null 2>&1') def _prepare_sinewave(self, pitch, amplitude, duration, starttime=0, pitch_envelope=99, amplitude_envelope=100, instrument=1): pitenv = pitch_envelope ampenv = amplitude_envelope if not 1 in self.instrlist: self.orchlines.append("instr 1\n") self.orchlines.append("kpitenv oscil 1, 1/p3, p6\n") self.orchlines.append("aenv oscil 1, 1/p3, p7\n") self.orchlines.append("asig oscil p5*aenv, p4*kpitenv, p8\n") self.orchlines.append("out asig\n") self.orchlines.append("endin\n\n") self.instrlist.append(1) self.scorelines.append("i1 %s %s %s %s %s %s %s\n" % (str(starttime), str(duration), str(pitch), str(amplitude), str(pitenv), str(ampenv), str(instrument))) def _audio_write(self, file): """ Compile a .csd file. """ csd = open(file, "w") csd.write("<CsoundSynthesizer>\n\n") csd.write("<CsOptions>\n") csd.write("-+rtaudio=alsa -odevaudio -m0 -d -b256 -B512\n") csd.write("</CsOptions>\n\n") csd.write("<CsInstruments>\n\n") csd.write("sr=16000\n") csd.write("ksmps=50\n") csd.write("nchnls=1\n\n") for line in self.orchlines: csd.write(line) csd.write("\n</CsInstruments>\n\n") csd.write("<CsScore>\n\n") csd.write("f1 0 2048 10 1\n") csd.write("f2 0 2048 10 1 0 .33 0 .2 0 .143 0 .111\n") csd.write("f3 0 2048 10 1 .5 .33 .25 .2 .175 .143 .125 .111 .1\n") csd.write("f10 0 2048 10 1 0 0 .3 0 .2 0 0 .1\n") csd.write("f99 0 2048 7 1 2048 1\n") csd.write("f100 0 2048 7 0. 10 1. 1900 1. 132 0.\n") csd.write(self.scorelines.pop()) csd.write("e\n") csd.write("\n</CsScore>\n") csd.write("\n</CsoundSynthesizer>") csd.close()
class SensorToolbar(gtk.Toolbar): ''' The toolbar for specifiying the sensor: sound, resitance, or voltage ''' LOWER = 0.0 UPPER = 1.0 STR_DC_R = \ _("Resistive sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + ' ' STR_DC_V = \ _("Voltage sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + ' ' STR_AC = _('Sound') + ' ' STR_RESISTANCE = _('Resistance') + ' (' + _('Ohms') + ') ' STR_VOLTAGE = _('Voltage') + ' (' + _('Volts') + ') ' STR_TIME = _('Time Base') + ' ' STR_FREQUENCY = _('Frequency Base') + ' ' STR_INVERT = ' ' + _('Invert') + ' ' STR_XAXIS_TEXT = _('X Axis Scale: 1 division = %(division)s %(unit)s') # TRANSLATORS: This is milli seconds. MS = _('ms') # TRANSLATORS: This is Hertz, so 1/second. HZ = _('Hz') def __init__(self, activity, channels): ''' By default, start with resistance mode ''' gtk.Toolbar.__init__(self) self.activity = activity self._channels = channels self._lock_radio_buttons = False self._radio_button_pushed = False self.values = [] for i in range(self._channels): self.values.append('') self.string_for_textbox = '' self.gain = 1.0 self.y_mag = 3.0 self.capture_gain = CAPTURE_GAIN self.mic_boost = MIC_BOOST self.mode = 'sound' # Set up Time-domain Button self.time = RadioToolButton(group=None) self.time.set_named_icon('media-audio') self.insert(self.time, -1) self.time.set_tooltip(_('Sound')) self.time.connect('clicked', self.analog_resistance_voltage_mode_cb, 'sound') # Set up Resistance Button self.resistance = RadioToolButton(group=self.time) self.resistance.set_named_icon('resistance') if _is_xo(self.activity.hw): self.insert(self.resistance, -1) self.resistance.show() self.resistance.set_tooltip(_('Resistance Sensor')) self.resistance.connect('clicked', self.analog_resistance_voltage_mode_cb, 'resistance') # Set up Voltage Button self.voltage = RadioToolButton(group=self.time) self.voltage.set_named_icon('voltage') if _is_xo(self.activity.hw): self.insert(self.voltage, -1) self.voltage.set_tooltip(_('Voltage Sensor')) self.voltage.connect('clicked', self.analog_resistance_voltage_mode_cb, 'voltage') separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_value = LOG_TIMER_VALUES[1] self.log_label = gtk.Label(self._log_to_string(self._log_value)) toolitem = gtk.ToolItem() toolitem.add(self.log_label) self.insert(toolitem, -1) self._log_button = ToolButton('timer-10') self._log_button.set_tooltip(_('Select logging interval')) self._log_button.connect('clicked', self._log_selection_cb) self.insert(self._log_button, -1) self._setup_log_palette() # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start logging')) self._record.connect('clicked', self.record_control_cb) separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) toolitem = gtk.ToolItem() self.trigger_label = gtk.Label(_('Trigger')) toolitem.add(self.trigger_label) self.insert(toolitem, -1) # Set up Trigger Combo box self.trigger_none = RadioToolButton() self.trigger_none.set_named_icon('trigger-none') self.insert(self.trigger_none, -1) self.trigger_none.set_tooltip(_('None')) self.trigger_none.connect('clicked', self.update_trigger_control_cb, self.activity.wave.TRIGGER_NONE) self.trigger_rise = RadioToolButton(group=self.trigger_none) self.trigger_rise.set_named_icon('trigger-rise') self.insert(self.trigger_rise, -1) self.trigger_rise.set_tooltip(_('Rising Edge')) self.trigger_rise.connect('clicked', self.update_trigger_control_cb, self.activity.wave.TRIGGER_POS) self.trigger_fall = RadioToolButton(group=self.trigger_none) self.trigger_fall.set_named_icon('trigger-fall') self.insert(self.trigger_fall, -1) self.trigger_fall.set_tooltip(_('Falling Edge')) self.trigger_fall.connect('clicked', self.update_trigger_control_cb, self.activity.wave.TRIGGER_NEG) self.show_all() def get_log(self): return self._log_value def get_log_idx(self): if self._log_value in LOG_TIMER_VALUES: return LOG_TIMER_VALUES.index(self._log_value) else: return LOG_TIMER_VALUES[0] def set_log_idx(self, idx): self._log_value = LOG_TIMER_VALUES[idx] self.log_label.set_text(self._log_to_string(self._log_value)) if hasattr(self, '_log_button'): self._log_button.set_icon('timer-%d' % (self._log_value)) def _log_selection_cb(self, widget): if self._log_palette: if not self._log_palette.is_up(): self._log_palette.popup(immediate=True, state=self._log_palette.SECONDARY) else: self._log_palette.popdown(immediate=True) return def _log_to_seconds(self, tenth_seconds): return tenth_seconds / 10. def _log_to_string(self, tenth_seconds): if tenth_seconds in LOG_TIMER_LABELS: return LOG_TIMER_LABELS[tenth_seconds] else: return _('1 second') def _setup_log_palette(self): self._log_palette = self._log_button.get_palette() for tenth_seconds in LOG_TIMER_VALUES: text = self._log_to_string(tenth_seconds) menu_item = MenuItem(icon_name='timer-%d' % (tenth_seconds), text_label=self._log_to_string(tenth_seconds)) menu_item.connect('activate', self._log_selected_cb, tenth_seconds) self._log_palette.menu.append(menu_item) menu_item.show() def _log_selected_cb(self, button, seconds): self.set_log_idx(LOG_TIMER_VALUES.index(seconds)) def add_frequency_slider(self, toolbox): ''' Either on the Sound toolbar or the Main toolbar ''' self._freq_stepper_up = ToolButton('freq-high') self._freq_stepper_up.set_tooltip(_('Zoom out')) self._freq_stepper_up.connect('clicked', self._freq_stepper_up_cb) self._freq_stepper_up.show() self.activity.adjustmentf = gtk.Adjustment(0.5, self.LOWER, self.UPPER, 0.01, 0.1, 0) self.activity.adjustmentf.connect('value_changed', self.cb_page_sizef) self._freq_range = gtk.HScale(self.activity.adjustmentf) self._freq_range.set_inverted(True) self._freq_range.set_draw_value(False) self._freq_range.set_update_policy(gtk.UPDATE_CONTINUOUS) self._freq_range.set_size_request(120, 15) self._freq_range.show() self._freq_stepper_down = ToolButton('freq-low') self._freq_stepper_down.set_tooltip(_('Zoom in')) self._freq_stepper_down.connect('clicked', self._freq_stepper_down_cb) self._freq_stepper_down.show() self._freq_range_tool = gtk.ToolItem() self._freq_range_tool.add(self._freq_range) self._freq_range_tool.show() toolbox.add(self._freq_stepper_up) toolbox.add(self._freq_range_tool) toolbox.add(self._freq_stepper_down) return def update_trigger_control_cb(self, button, value): if button is None: value = self.activity.wave.TRIGGER_NONE if self.activity.wave.get_fft_mode(): self.trigger_none.set_active(True) else: self.activity.wave.set_trigger(value) def analog_resistance_voltage_mode_cb(self, button=None, mode_to_set='sound'): ''' Callback for Analog/Resistance/Voltage Buttons ''' if self._lock_radio_buttons: logging.debug('mode selector locked') self._radio_button_pushed = True return if self.mode == mode_to_set: logging.debug('mode already set to %s' % mode_to_set) return self._lock_radio_buttons = True if self.activity.CONTEXT == 'sound': self.sound_context_off() else: self.sensor_context_off() # Force time domain when switching modes if self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Turn off logging when switching modes if self.activity.audiograb.we_are_logging: self.record_control_cb() self.set_mode(mode_to_set) if mode_to_set == 'sound': self.set_sound_context() elif mode_to_set == 'resistance': self.set_sensor_context() elif mode_to_set == 'voltage': self.set_sensor_context() self.update_string_for_textbox() return False def unlock_radio_buttons(self): ''' Enable radio button selection ''' logging.debug('unlocking radio buttons') if self._radio_button_pushed: if self.mode == 'sound': self.time.set_active(True) elif self.mode == 'resistance': self.resistance.set_active(True) elif self.mode == 'voltage': self.voltage.set_active(True) self._lock_radio_buttons = False self._radio_button_pushed = False def set_mode(self, mode='sound'): ''' Set the mixer settings to match the current mode. ''' self.mode = mode self.activity.audiograb.set_sensor_type(self.mode) for i in range(self._channels): self.values[i] = 0.0 return def get_mode(self): ''' Get the mixer settings. ''' return self.mode def _freq_stepper_up_cb(self, button=None): ''' Moves the horizontal zoom slider to the left one notch, where one notch is 1/100 of the total range. This correspond to zooming out as a larger number of Hertz or milliseconds will be represented by the same space on the screen. ''' new_value = self._freq_range.get_value() +\ (self.UPPER - self.LOWER) / 100.0 if new_value <= self.UPPER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.UPPER) def _freq_stepper_down_cb(self, button=None): ''' Moves the horizontal zoom slider to the right one notch, where one notch is 1/100 of the total range. This corresponds to zooming in. ''' new_value = self._freq_range.get_value() -\ (self.UPPER - self.LOWER) / 100.0 if new_value >= self.LOWER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.LOWER) def cb_page_sizef(self, button=None): ''' Callback to scale the frequency range (zoom in and out) ''' if self._update_page_size_id: gobject.source_remove(self._update_page_size_id) self._update_page_size_id =\ gobject.timeout_add(250, self.update_page_size) return True def update_page_size(self): ''' Set up the scaling of the display. ''' self._update_page_size_id = None new_value = round(self.activity.adjustmentf.value * 100.0) / 100.0 if self.activity.adjustmentf.value != new_value: self.activity.adjustmentf.value = new_value return False time_div = 0.001 * max(self.activity.adjustmentf.value, 0.05) freq_div = 1000 * max(self.activity.adjustmentf.value, 0.01) self.activity.wave.set_div(time_div, freq_div) self.update_string_for_textbox() return False def set_sound_context(self): ''' Called when analog sensing is selected ''' self.set_show_hide_windows(mode='sound') gobject.timeout_add(500, self.sound_context_on) self.activity.CONTEXT = 'sound' def set_sensor_context(self): ''' Called when digital sensing is selected ''' self.set_show_hide_windows(mode='sensor') gobject.timeout_add(500, self.sensor_context_on) self.activity.CONTEXT = 'sensor' def set_show_hide_windows(self, mode='sound'): ''' Shows the appropriate window identified by the mode ''' self.activity.wave.set_context_on() for i in range(self._channels): self.activity.side_toolbars[i].set_show_hide(True, mode) def sensor_context_off(self): ''' Called when a DC sensor is no longer selected ''' # self.activity.audiograb.pause_grabbing() self.activity.audiograb.stop_grabbing() def sensor_context_on(self): ''' Called when a DC sensor is selected ''' self.update_string_for_textbox() self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE) # self.activity.audiograb.resume_grabbing() self.activity.audiograb.start_grabbing() return False def sound_context_off(self): ''' Called when an analog sensor is no longer selected ''' self.gain, self.y_mag = self.activity.wave.get_mag_params() self.capture_gain = self.activity.audiograb.get_capture_gain() self.mic_boost = self.activity.audiograb.get_mic_boost() self.activity.audiograb.stop_grabbing() def sound_context_on(self): ''' Called when an analog sensor is selected ''' self.activity.wave.set_mag_params(self.gain, self.y_mag) self.update_string_for_textbox() self.update_trigger_control_cb(None, self.activity.wave.TRIGGER_NONE) self.activity.audiograb.start_grabbing() return False def set_sample_value(self, value='', channel=0): ''' Write a sample value to the textbox. ''' gtk.threads_enter() self.values[channel] = value self.update_string_for_textbox() gtk.threads_leave() return def record_control_cb(self, button=None): ''' Depending upon the selected interval, does either a logging session, or just logs the current buffer. ''' if self.activity.audiograb.we_are_logging: self.activity.audiograb.set_logging_params(start_stop=False) self._record.set_icon('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) else: Xscale = (1.00 / self.activity.audiograb.get_sampling_rate()) Yscale = 0.0 interval = self._log_value / 10. # self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode='frequency') else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, self._log_to_string(self._log_value), channels=self._channels, mode=self.mode) self.activity.audiograb.set_logging_params(start_stop=True, interval=interval, screenshot=False) self._record.set_icon('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) self.activity.new_recording = True def update_string_for_textbox(self): ''' Update the status field at the bottom of the canvas. ''' if self.mode == 'resistance': string_for_textbox = (self.STR_DC_R + '\n') string_for_textbox += self.STR_RESISTANCE elif self.mode == 'voltage': string_for_textbox = (self.STR_DC_V + '\n') string_for_textbox += self.STR_VOLTAGE else: string_for_textbox = (self.STR_AC + '\t') if self.activity.wave.get_fft_mode(): scalex = self.STR_XAXIS_TEXT % { 'unit': self.HZ, 'division': self.activity.wave.freq_div } string_for_textbox += self.STR_FREQUENCY string_for_textbox += ('\n' + scalex) elif self.mode == 'sound': scalex = self.STR_XAXIS_TEXT % { 'unit': self.MS, 'division': self.activity.wave.time_div * 1000 } string_for_textbox += self.STR_TIME string_for_textbox += ('\n' + scalex) else: for i in range(self._channels): string_for_textbox += '\t(%s)' % (self.values[i]) invert = False for i in range(self._channels): if self.activity.wave.get_invert_state(channel=i): invert = True if invert: string_for_textbox += self.STR_INVERT self.activity.text_box.set_label(string_for_textbox)
class MeasureActivity(activity.Activity): ''' Oscilloscope Sugar activity ''' def __init__(self, handle): ''' Init canvas, toolbars, etc. The toolbars are in sensor_toolbar.py and toolbar_side.py The audio controls are in audiograb.py The rendering happens in drawwaveform.py Logging is in journal.py ''' activity.Activity.__init__(self, handle) self.mode_images = {} self.mode_images['sound'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'media-audio.svg'), 45, 45) self.mode_images['resistance'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'resistance.svg'), 45, 45) self.mode_images['voltage'] = gtk.gdk.pixbuf_new_from_file_at_size( os.path.join(ICONS_DIR, 'voltage.svg'), 45, 45) self.icon_colors = self.get_icon_colors_from_sugar() self.stroke_color, self.fill_color = self.icon_colors.split(',') self.nick = self.get_nick_from_sugar() self.CONTEXT = '' self.adjustmentf = None # Freq. slider control self.new_recording = False self.session_id = 0 self.read_metadata() self._active = True self._dsobject = None self.connect('notify::active', self._notify_active_cb) self.connect('destroy', self.on_quit) self.data_logger = DataLogger(self) self.hw = _get_hardware() log.debug('running on %s hardware' % (self.hw)) self.wave = DrawWaveform(self) if self.hw == XO15: self.audiograb = AudioGrab_XO15(self.wave.new_buffer, self) elif self.hw == XO175: self.audiograb = AudioGrab_XO175(self.wave.new_buffer, self) elif self.hw == XO4: self.audiograb = AudioGrab_XO4(self.wave.new_buffer, self) elif self.hw == XO1: self.audiograb = AudioGrab_XO1(self.wave.new_buffer, self) else: self.audiograb = AudioGrab_Unknown(self.wave.new_buffer, self) # no sharing self.max_participants = 1 box3 = gtk.HBox(False, 0) box3.pack_start(self.wave, True, True, 0) # We need event boxes in order to set the background color. side_eventboxes = [] self.side_toolbars = [] for i in range(self.audiograb.channels): side_eventboxes.append(gtk.EventBox()) side_eventboxes[i].modify_bg( gtk.STATE_NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) self.side_toolbars.append(SideToolbar(self, channel=i)) side_eventboxes[i].add(self.side_toolbars[i].box1) box3.pack_start(side_eventboxes[i], False, True, 0) event_box = gtk.EventBox() self.text_box = gtk.Label() self.text_box.set_justify(gtk.JUSTIFY_LEFT) alist = pango.AttrList() alist.insert(pango.AttrForeground(65535, 65535, 65535, 0, -1)) self.text_box.set_attributes(alist) event_box.add(self.text_box) event_box.modify_bg(gtk.STATE_NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) box1 = gtk.VBox(False, 0) box1.pack_start(box3, True, True, 0) box1.pack_start(event_box, False, True, 0) self.set_canvas(box1) toolbox = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbox.toolbar.insert(activity_button, 0) activity_button.show() self.sensor_toolbar = SensorToolbar(self, self.audiograb.channels) #Added by Lego # Turn on bobot Server log.debug('Starting Server...') self.bobot = subprocess.Popen(['python', 'pybot_server.py'], cwd='./pybot') log.debug("Start : %s" % time.ctime()) time.sleep(bobot_delay_start) log.debug("Started : %s" % time.ctime()) self.lego_toolbar = LegoToolbar(self, self.audiograb.channels) #Lego end # Added by Butia self.butia_toolbar = ButiaToolbar(self, self.audiograb.channels) #Butia end #Added by Arduino self.arduino_toolbar = ArduinoToolbar(self, self.audiograb.channels) #Arduino end self.tuning_toolbar = TuningToolbar(self) self.new_instrument_toolbar = InstrumentToolbar(self) self._extras_toolbar = gtk.Toolbar() self.control_toolbar = gtk.Toolbar() sensor_button = ToolbarButton(label=_('Sensors'), page=self.sensor_toolbar, icon_name='sensor-tools') toolbox.toolbar.insert(sensor_button, -1) #Added by Lego sensor_button.connect('clicked', self._sensor_toolbar_cb) #Lego end sensor_button.show() lego_button = ToolbarButton(label=_('Lego'), page=self.lego_toolbar, icon_name='LEGO-tools') toolbox.toolbar.insert(lego_button, -1) lego_button.connect('clicked', self._lego_toolbar_cb) lego_button.show() #Lego end #Added by Butia sensor_button.connect('clicked', self._sensor_toolbar_cb) #Butia end sensor_button.show() #Added by Butia butia_button = ToolbarButton(label=_('Butia'), page=self.butia_toolbar, icon_name='butia-tools') toolbox.toolbar.insert(butia_button, -1) butia_button.connect('clicked', self._butia_toolbar_cb) butia_button.show() #Butia end #Added by Arduino sensor_button.connect('clicked', self._sensor_toolbar_cb) #Arduino end sensor_button.show() #Added by Arduino arduino_button = ToolbarButton(label=_('Arduino'), page=self.arduino_toolbar, icon_name='arduino-tools') toolbox.toolbar.insert(arduino_button, -1) arduino_button.connect('clicked', self._arduino_toolbar_cb) arduino_button.show() #Arduino end tuning_button = ToolbarButton( # TRANS: Tuning insruments label=_('Tuning'), page=self.tuning_toolbar, icon_name='tuning-tools') toolbox.toolbar.insert(tuning_button, -1) tuning_button.show() new_instrument_button = ToolbarButton(label=_('Add instrument'), page=self.new_instrument_toolbar, icon_name='view-source') toolbox.toolbar.insert(new_instrument_button, -1) new_instrument_button.show() #Added by butia self.butia_toolbar.show() #Butia end self._extras_button = ToolbarButton(page=self._extras_toolbar, icon_name='domain-time') toolbox.toolbar.insert(self._extras_button, -1) self._extras_toolbar_item = gtk.ToolItem() self._extras_toolbar.insert(self._extras_toolbar_item, -1) self._extras_button.hide() self.sensor_toolbar.show() self._extra_tools = gtk.HBox() # Set up Frequency-domain Button self.freq = ToolButton('domain-time') self.freq.set_tooltip(_('Time Base')) self.freq.connect('clicked', self.timefreq_control) self.freq.show() self._extra_tools.add(self.freq) self.sensor_toolbar.add_frequency_slider(self._extra_tools) self._extra_item = gtk.ToolItem() self._extra_item.add(self._extra_tools) self._extra_tools.show() toolbox.toolbar.insert(self._extra_item, -1) self._extra_item.show() self._pause = ToolButton('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.connect('clicked', self._pause_play_cb) self._pause.show() toolbox.toolbar.insert(self._pause, -1) self._capture = ToolButton('image-saveoff') self._capture.set_tooltip(_('Capture sample now')) self._capture.connect('clicked', self._capture_cb) self._capture.show() toolbox.toolbar.insert(self._capture, -1) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) toolbox.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') toolbox.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbox(toolbox) sensor_button.set_expanded(True) toolbox.show() self.sensor_toolbar.update_page_size() self.show_all() self._first = True # Always start in 'sound' mode. self.sensor_toolbar.set_mode('sound') self.sensor_toolbar.set_sound_context() self.sensor_toolbar.set_show_hide_windows() self.wave.set_active(True) self.wave.set_context_on() gtk.gdk.screen_get_default().connect('size-changed', self._configure_cb) self._configure_cb(None) def _configure_cb(self, event): ''' Screen size has changed, so check to see if the toolbar elements still fit.''' self.width = gtk.gdk.screen_width() if self.width < style.GRID_CELL_SIZE * 14: self._extras_button.show() if self._extra_tools in self._extra_item: self._extra_item.remove(self._extra_tools) if not self._extra_tools in self._extras_toolbar_item: self._extras_toolbar_item.add(self._extra_tools) self._extras_toolbar_item.show() self.sensor_toolbar.log_label.hide() self.sensor_toolbar.trigger_label.hide() else: self._extras_button.hide() if self._extra_tools in self._extras_toolbar_item: self._extras_toolbar_item.remove(self._extra_tools) if not self._extra_tools in self._extra_item: self._extra_item.add(self._extra_tools) if self._extras_button.is_expanded(): self._extras_button.set_expanded(False) self._extras_toolbar_item.hide() self.sensor_toolbar.log_label.show() self.sensor_toolbar.trigger_label.show() self._extra_tools.show() #Added by Lego def _sensor_toolbar_cb(self, button=None): '''Callback al hacer clic en sensor toolbar''' log.debug('Click en sensor toolbar') self.sensor_toolbar.set_mode('sound') self.sensor_toolbar.set_sound_context() self.sensor_toolbar.set_show_hide_windows() self.limpiar_canales() self.CONTEXT = 'sound' #Added by Lego def _lego_toolbar_cb(self, button=None): '''Callback al hacer clic en lego toolbar''' log.debug('Click en lego toolbar') self.audiograb.stop_grabbing() self.limpiar_canales() log.debug('CONTEXTO ANTERIOR: %s' % self.CONTEXT) self.CONTEXT = 'lego' self.sensor_toolbar.update_string_for_textbox() #Added by Butia def _butia_toolbar_cb(self, button=None): '''Callback al hacer clic en butia toolbar''' log.debug('Click en butia toolbar') self.audiograb.stop_grabbing() self.limpiar_canales() log.debug('CONTEXTO ANTERIOR: %s' % self.CONTEXT) self.CONTEXT = 'butia' self.sensor_toolbar.update_string_for_textbox() #Added by Arduino def _arduino_toolbar_cb(self, button=None): '''Callback al hacer clic en arduino toolbar''' log.debug('Click en arduino toolbar') self.audiograb.stop_grabbing() self.limpiar_canales() log.debug('CONTEXTO ANTERIOR: %s' % self.CONTEXT) log.debug('***** ARDUINO CONTEXT ******') self.CONTEXT = 'arduino' self.sensor_toolbar.update_string_for_textbox() #Added by lego def limpiar_canales(self): for i in range(self.audiograb.channels): self.wave.ringbuffer[i] = RingBuffer1d(self.wave.max_samples, dtype='int16') self.wave.new_buffer([0], i) def on_quit(self, data=None): '''Clean up, close journal on quit''' self.audiograb.on_activity_quit() def _notify_active_cb(self, widget, pspec): ''' Callback to handle starting/pausing capture when active/idle ''' if self._first: log.debug('_notify_active_cb: start grabbing') self.audiograb.start_grabbing() self._first = False elif not self.props.active: log.debug('_notify_active_cb: pause grabbing') self.audiograb.pause_grabbing() elif self.props.active: log.debug('_notify_active_cb: resume grabbing') self.audiograb.resume_grabbing() self._active = self.props.active self.wave.set_active(self._active) def read_metadata(self): ''' Any saved instruments? ''' for data in self.metadata.keys(): if data[0] == PREFIX: # instrument log.debug('found an instrument: %s' % (data[1:])) instrument = data[1:] log.debug(self.metadata[data]) INSTRUMENT_DICT[instrument] = [] for note in self.metadata[data].split(' '): INSTRUMENT_DICT[instrument].append(float(note)) def write_file(self, file_path): ''' Write data to journal, if there is any data to write ''' # Check to see if there are any new instruments to save if hasattr(self, 'new_instrument_toolbar'): for i, instrument in enumerate( self.new_instrument_toolbar.new_instruments): log.debug('saving %s' % (instrument)) notes = '' for i, note in enumerate(INSTRUMENT_DICT[instrument]): notes += '%0.3f' % note if i < len(INSTRUMENT_DICT[instrument]) - 1: notes += ' ' self.metadata['%s%s' % (PREFIX, instrument)] = notes # FIXME: Don't use ""s around data if hasattr(self, 'data_logger') and \ self.new_recording and \ len(self.data_logger.data_buffer) > 0: # Append new data to Journal entry fd = open(file_path, 'ab') writer = csv.writer(fd) # Also output to a separate file as a workaround to Ticket 2127 # (the assumption being that this file will be opened by the user) tmp_data_file = os.path.join(os.environ['SUGAR_ACTIVITY_ROOT'], 'instance', 'sensor_data' + '.csv') log.debug('saving sensor data to %s' % (tmp_data_file)) if self._dsobject is None: # first time, so create fd2 = open(tmp_data_file, 'wb') else: # we've been here before, so append fd2 = open(tmp_data_file, 'ab') writer2 = csv.writer(fd2) # Pop data off start of buffer until it is empty for i in range(len(self.data_logger.data_buffer)): datum = self.data_logger.data_buffer.pop(0) writer.writerow([datum]) writer2.writerow([datum]) fd.close() fd2.close() # Set the proper mimetype self.metadata['mime_type'] = 'text/csv' if os.path.exists(tmp_data_file): if self._dsobject is None: self._dsobject = datastore.create() self._dsobject.metadata['title'] = _('Measure Log') self._dsobject.metadata['icon-color'] = self.icon_colors self._dsobject.metadata['mime_type'] = 'text/csv' self._dsobject.set_file_path(tmp_data_file) datastore.write(self._dsobject) # remove(tmp_data_file) def read_file(self, file_path): ''' Read csv data from journal on start ''' reader = csv.reader(open(file_path, "rb")) # Count the number of sessions. for row in reader: if len(row) > 0: if row[0].find(_('Session')) != -1: # log.debug('found a previously recorded session') self.session_id += 1 elif row[0].find('abiword') != -1: # File has been opened by Write cannot be read by Measure # See Ticket 2127 log.error('File was opened by Write: Measure cannot read') self.data_logger.data_buffer = [] return self.data_logger.data_buffer.append(row[0]) if self.session_id == 0: # log.debug('setting data_logger buffer to []') self.data_logger.data_buffer = [] def _pause_play_cb(self, button=None): ''' Callback for Pause Button ''' if self.audiograb.get_freeze_the_display(): self.audiograb.set_freeze_the_display(False) self._pause.set_icon('media-playback-start') self._pause.set_tooltip(_('Unfreeze the display')) self._pause.show() else: self.audiograb.set_freeze_the_display(True) self._pause.set_icon('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.show() return False def _capture_cb(self, button=None): ''' Callback for screen capture ''' if self.CONTEXT == 'butia': self.butia_toolbar.take_screenshot() self.audiograb.take_screenshot() def timefreq_control(self, button=None): ''' Callback for Freq. Button ''' # Turn off logging when switching modes if self.audiograb.we_are_logging: self.sensor_toolbar.record_control_cb() #Added by Lego self.lego_toolbar.set_sound_context() #Lego end #Added by Butia self.butia_toolbar.set_sound_context() #Butia end #Added by Arduino self.arduino_toolbar.set_sound_context() #Arduino end if self.wave.get_fft_mode(): self.wave.set_fft_mode(False) self.freq.set_icon('domain-time') self.freq.set_tooltip(_('Time Base')) else: self.wave.set_fft_mode(True) self.freq.set_icon('domain-freq') self.freq.set_tooltip(_('Frequency Base')) # Turn off triggering in Frequencey Base self.sensor_toolbar.trigger_none.set_active(True) self.wave.set_trigger(self.wave.TRIGGER_NONE) # Turn off invert in Frequencey Base for i in range(self.audiograb.channels): if self.wave.get_invert_state(channel=i): self.side_toolbars[i].invert_control_cb() self.sensor_toolbar.update_string_for_textbox() return False def get_icon_colors_from_sugar(self): ''' Returns the icon colors from the Sugar profile ''' return profile.get_color().to_string() def get_nick_from_sugar(self): ''' Returns nick from Sugar ''' return profile.get_nick_name()
class PhysicsActivity(olpcgames.PyGameActivity): game_name = 'physics' game_title = _('Physics') game_size = None # Olpcgame will choose size def __init__(self, handle): super(PhysicsActivity, self).__init__(handle) self.metadata['mime_type'] = 'application/x-physics-activity' self.add_events(gtk.gdk.ALL_EVENTS_MASK | gtk.gdk.VISIBILITY_NOTIFY_MASK) self.connect('visibility-notify-event', self._focus_event) self.connect('window-state-event', self._window_event) def get_preview(self): """Custom preview code to get image from pygame. """ surface = pygame.display.get_surface() width, height = surface.get_width(), surface.get_height() pixbuf = gtk.gdk.pixbuf_new_from_data( pygame.image.tostring(surface, "RGB"), gtk.gdk.COLORSPACE_RGB, 0, 8, width, height, 3 * width) pixbuf = pixbuf.scale_simple(300, 225, gtk.gdk.INTERP_BILINEAR) preview_data = [] def save_func(buf, data): data.append(buf) pixbuf.save_to_callback(save_func, 'png', user_data=preview_data) preview_data = ''.join(preview_data) return preview_data def write_file(self, file_path): """Over-ride olpcgames write_file so that title keeps working. """ event = olpcgames.eventwrap.Event(type=pygame.USEREVENT, code=olpcgames.FILE_WRITE_REQUEST, filename=file_path, metadata=self.metadata) olpcgames.eventwrap.post(event) event.block() event.retire() # <- Without this, title editing stops updating # Setup the toolbar def build_toolbar(self): try: # Use new >= 0.86 toolbar self.max_participants = 1 toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() separator = gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) separator.show() self._insert_create_tools(toolbar_box.toolbar) separator = gtk.SeparatorToolItem() separator.props.draw = False separator.set_size_request(0, -1) separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show() return toolbar_box except NameError: # Use old <= 0.84 toolbar design toolbox = activity.ActivityToolbox(self) activity_toolbar = toolbox.get_activity_toolbar() activity_toolbar.share.props.visible = False create_toolbar = gtk.Toolbar() self._insert_create_tools(create_toolbar) toolbox.add_toolbar(_("Create"), create_toolbar) create_toolbar.show() toolbox.set_current_toolbar(1) toolbox.show() self.set_toolbox(toolbox) return activity_toolbar def _insert_create_tools(self, create_toolbar): # Stop/play button self.stop_play_state = True self.stop_play = ToolButton('media-playback-stop') self.stop_play.set_tooltip(_("Stop")) self.stop_play.set_accelerator(_('<ctrl>space')) self.stop_play.connect('clicked', self.stop_play_cb) create_toolbar.insert(self.stop_play, -1) self.stop_play.show() separator = gtk.SeparatorToolItem() create_toolbar.insert(separator, -1) separator.show() # Make + add the component buttons self.radioList = {} firstButton = None for c in tools.allTools: button = RadioToolButton(named_icon=c.icon) if firstButton: button.set_group(firstButton) else: button.set_group(None) firstButton = button button.set_tooltip(c.toolTip) button.set_accelerator(c.toolAccelerator) button.connect('clicked', self.radioClicked) create_toolbar.insert(button, -1) button.show() self.radioList[button] = c.name def stop_play_cb(self, button): pygame.event.post( olpcgames.eventwrap.Event(pygame.USEREVENT, action="stop_start_toggle")) self.stop_play_state = not self.stop_play_state # Update button if self.stop_play_state: self.stop_play.set_icon('media-playback-stop') self.stop_play.set_tooltip(_("Stop")) else: self.stop_play.set_icon('media-playback-start') self.stop_play.set_tooltip(_("Start")) def radioClicked(self, button): pygame.event.post( olpcgames.eventwrap.Event(pygame.USEREVENT, action=self.radioList[button])) def _focus_event(self, event, data=None): """Send focus events to pygame to allow it to idle when in background. """ if data.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED: pygame.event.post( olpcgames.eventwrap.Event(pygame.USEREVENT, action="focus_out")) else: pygame.event.post( olpcgames.eventwrap.Event(pygame.USEREVENT, action="focus_in")) def _window_event(self, window, event): """Send focus out event to pygame when switching to a desktop view. """ if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED: pygame.event.post( olpcgames.eventwrap.Event(pygame.USEREVENT, action="focus_out"))
class SoundToolbar(gtk.Toolbar): """ Set up the toolbar for audio (analog) capture mode """ SAMPLE_NOW = _('Capture now') SAMPLE_30_SEC = _('Every 30 sec.') SAMPLE_2_MIN = _('Every 2 min.') SAMPLE_10_MIN = _('Every 10 min.') SAMPLE_30_MIN = _('Every 30 min.') LOWER = 0.0 UPPER = 1.0 def __init__(self, activity): """ Initialize the toolbar controls. """ gtk.Toolbar.__init__(self) self.activity = activity self._STR_BASIC = _('Sound') + ' ' self._STR1 = _('Time Base') + ' ' self._STR2 = _('Frequency Base') + ' ' self._STR3 = ' ' + _('Invert') + ' ' self._STR_SCALEX = "" self._STR_XAXIS_TEXT = \ _('X Axis Scale: 1 division = %(division)s %(unit)s') # TRANSLATORS: This is milli seconds. self._ms = _('ms') # TRANSLATORS: This is Hertz, so 1/second. self._Hz = _('Hz') self._update_page_size_id = None self.string_for_textbox = "" self.gain = 1.0 self.y_mag = 3.0 self.capture_gain = CAPTURE_GAIN self.mic_boost = MIC_BOOST # self.logging_status = False self._record = None # Set up Time-domain Button self.time = ToolButton('domain-time2') self.insert(self.time, -1) self.time.set_tooltip(_('Time Base')) self.time.connect('clicked', self._timefreq_control_cb, True) # Set up Frequency-domain Button self.freq = ToolButton('domain-freq') self.insert(self.freq, -1) self.freq.show() self.freq.set_tooltip(_('Frequency Base')) self.freq.connect('clicked', self._timefreq_control_cb, False) # Set up Frequency-control Slider and corresponding buttons if not self.activity.has_toolbarbox: self.add_frequency_slider(self) # Set up the Pause Button self._pause = ToolButton('media-playback-pause') self.insert(self._pause, -1) self._pause.set_tooltip(_('Freeze the display')) self._pause.connect('clicked', self._pauseplay_control_cb) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) separator.show() self.loginterval_img = gtk.Image() self.loginterval_img.set_from_file(ICONS_DIR + 'sample_rate.svg') self.loginterval_img_tool = gtk.ToolItem() self.loginterval_img_tool.add(self.loginterval_img) self.insert(self.loginterval_img_tool, -1) # Set up the Logging-interval Combo box self._loginterval_combo = ComboBox() self.interval = [ _(self.SAMPLE_NOW), _(self.SAMPLE_30_SEC), _(self.SAMPLE_2_MIN), _(self.SAMPLE_10_MIN), _(self.SAMPLE_30_MIN) ] if hasattr(self._loginterval_combo, 'set_tooltip_text'): self._loginterval_combo.set_tooltip_text(_('Sampling interval')) self._interval_changed_id = self._loginterval_combo.connect( 'changed', self.loginterval_control) for i, s in enumerate(self.interval): self._loginterval_combo.append_item(i, s, None) if s == self.SAMPLE_NOW: self._loginterval_combo.set_active(i) self._loginterval_tool = ToolComboBox(self._loginterval_combo) self.insert(self._loginterval_tool, -1) self.logginginterval_status = 'picture' # Set up Start/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Capture sample now')) self._record.connect('clicked', self.record_control) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) # Set up Trigger Combo box self._trigger_combo = ComboBox() self.trigger = [_('None'), _('Rising Edge'), _('Falling Edge')] self.trigger_conf = [ self.activity.wave.TRIGGER_NONE, self.activity.wave.TRIGGER_POS, self.activity.wave.TRIGGER_NEG ] self._trigger_changed_id = self._trigger_combo.connect( 'changed', self.update_trigger_control) for i, s in enumerate(self.trigger): self._trigger_combo.append_item(i, s, None) self._trigger_combo.set_active(0) if hasattr(self._trigger_combo, 'set_tooltip_text'): self._trigger_combo.set_tooltip_text(_('Create a trigger')) self._trigger_tool = ToolComboBox(self._trigger_combo) self.insert(self._trigger_tool, -1) self.show_all() return def add_frequency_slider(self, toolbar): """ Either on the Sound toolbar or the Main toolbar """ self._freq_stepper_up = ToolButton('freq-high') self._freq_stepper_up.set_tooltip(_('Zoom out')) self._freq_stepper_up.connect('clicked', self._freq_stepper_up_cb) self.activity.adjustmentf = gtk.Adjustment(0.5, self.LOWER, self.UPPER, 0.01, 0.1, 0) self.activity.adjustmentf.connect('value_changed', self.cb_page_sizef) self._freq_range = gtk.HScale(self.activity.adjustmentf) self._freq_range.set_inverted(True) self._freq_range.set_draw_value(False) self._freq_range.set_update_policy(gtk.UPDATE_CONTINUOUS) self._freq_range.set_size_request(120, 15) self._freq_stepper_down = ToolButton('freq-low') self._freq_stepper_down.set_tooltip(_('Zoom in')) self._freq_stepper_down.connect('clicked', self._freq_stepper_down_cb) self._freq_range_tool = gtk.ToolItem() self._freq_range_tool.add(self._freq_range) toolbar.insert(self._freq_stepper_up, -1) toolbar.insert(self._freq_range_tool, -1) toolbar.insert(self._freq_stepper_down, -1) return def _set_icon_ready(self): self._record.set_icon('media-record') self._record.show() return False def _set_icon_stop(self): self._record.set_icon('record-stop') self._record.show() return False def record_control_delayed(self, data=None): """Depending upon the selected interval, either starts/stops a logging session, or just logs the current buffer""" if not self.activity.LOGGING_IN_SESSION: Xscale = (1.00 / self.activity.audiograb.get_sampling_rate()) Yscale = 0.0 interval = self.interval_convert() username = self.activity.nick self.activity.ji.start_new_session(username, Xscale, Yscale, self.logginginterval_status) self.activity.audiograb.set_logging_params(True, interval, True) self.activity.LOGGING_IN_SESSION = True self._set_icon_stop() if interval == 0: # Flash the stop button when grabbing just one image gobject.timeout_add(250, self._set_icon_ready) self.record_state = False self.activity.LOGGING_IN_SESSION = False self.logging_status = False else: self.activity.audiograb.set_logging_params(False) self.activity.LOGGING_IN_SESSION = False self._set_icon_ready() self._set_record_button_tooltip() return False def record_control(self, data=None): self._record.palette.popdown() gtk.gdk.flush() gobject.timeout_add(10, self.record_control_delayed, data) def interval_convert(self): """Converts picture/time interval to an integer that denotes the number of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written 1second= about 66 ticks at 48khz sampling""" if self.logginginterval_status == 'picture': return 0 elif self.logginginterval_status == '30second': return 30 #2667 elif self.logginginterval_status == '2minute': return 120 #10668 elif self.logginginterval_status == '10minute': return 600 #53340 elif self.logginginterval_status == '30minute': return 1800 #160000 def loginterval_control(self, combobox): """ The combo box has changed. Set the logging interval status correctly and then set the tooltip on the record button properly depending upon whether logging is currently in progress or not. """ if (self._loginterval_combo.get_active() != -1): if (self._loginterval_combo.get_active() == 0): self.logginginterval_status = 'picture' elif (self._loginterval_combo.get_active() == 1): self.logginginterval_status = '30second' elif (self._loginterval_combo.get_active() == 2): self.logginginterval_status = '2minute' elif (self._loginterval_combo.get_active() == 3): self.logginginterval_status = '10minute' elif (self._loginterval_combo.get_active() == 4): self.logginginterval_status = '30minute' self._set_record_button_tooltip() return def _set_record_button_tooltip(self): """ Determines the tool tip for the record button. The tool tip text depends upon whether sampling is currently on and whether the sampling interval > 0. """ if self._record == None: return if self.activity.LOGGING_IN_SESSION: self._record.set_tooltip(_('Stop sampling')) else: # No sampling in progress if (self._loginterval_combo.get_active() == 0): self._record.set_tooltip(_('Capture sample now')) else: self._record.set_tooltip(_('Start sampling')) return def update_trigger_control(self, *args): """ Callback for trigger control """ active = self._trigger_combo.get_active() if active == -1: return self.activity.wave.set_trigger(self.trigger_conf[active]) return def _pauseplay_control_cb(self, data=None): """ Callback for Pause Button """ if self.activity.audiograb.get_freeze_the_display(): self.activity.audiograb.set_freeze_the_display(False) self._pause.set_icon('media-playback-pause-insensitive') self._pause.set_tooltip(_('Unfreeze the display')) self._pause.show() else: self.activity.audiograb.set_freeze_the_display(True) self._pause.set_icon('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.show() return False def _timefreq_control_cb(self, data=None, time_state=True): """ Callback for Time and Freq. Buttons """ # Make sure the current context is for sound capture. if self.activity.CONTEXT != 'sound': self.activity.set_sound_context() if time_state: self.activity.wave.set_fft_mode(False) self.time.set_icon('domain-time2') self.freq.set_icon('domain-freq') self.time.show() self.freq.show() self._update_string_for_textbox() if self.activity.has_toolbarbox: self.activity.label_button.set_icon('domain-time2') self.activity.label_button.set_tooltip(_('Time Base')) else: self.activity.wave.set_fft_mode(True) self.time.set_icon('domain-time') self.freq.set_icon('domain-freq2') self.time.show() self.freq.show() self._update_string_for_textbox() if self.activity.has_toolbarbox: self.activity.label_button.set_icon('domain-freq2') self.activity.label_button.set_tooltip(_('Frequency Base')) if self.activity.has_toolbarbox and \ hasattr(self.activity, 'sensor_toolbar'): self.activity.sensor_toolbar.resistance.set_icon('bias-on') self.activity.sensor_toolbar.voltage.set_icon('bias-off') return False def _freq_stepper_up_cb(self, data=None): """Moves the horizontal zoom slider to the left one notch, where one notch is 1/100 of the total range. This correspond to zooming out as a larger number of Hertz or milliseconds will be represented by the same space on the screen.""" new_value = self._freq_range.get_value() +\ (self.UPPER - self.LOWER) / 100.0 if new_value <= self.UPPER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.UPPER) def _freq_stepper_down_cb(self, data=None): """Moves the horizontal zoom slider to the right one notch, where one notch is 1/100 of the total range. This corresponds to zooming in.""" new_value = self._freq_range.get_value() -\ (self.UPPER - self.LOWER) / 100.0 if new_value >= self.LOWER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.LOWER) def cb_page_sizef(self, data=None): """ Callback to scale the frequency range (zoom in and out) """ if self._update_page_size_id: gobject.source_remove(self._update_page_size_id) self._update_page_size_id =\ gobject.timeout_add(250, self.update_page_size) return True def update_page_size(self): """ Set up the scaling of the display """ self._update_page_size_id = None new_value = round(self.activity.adjustmentf.value * 100.0) / 100.0 if self.activity.adjustmentf.value != new_value: self.activity.adjustmentf.value = new_value return False time_div = 0.001 * max(self.activity.adjustmentf.value, 0.05) freq_div = 1000 * max(self.activity.adjustmentf.value, 0.01) self.activity.wave.set_div(time_div, freq_div) self._update_string_for_textbox() return False def context_off(self): """When some other context is switched to and the sound context is switched off""" print "context off: gain and y_mag were %f and %f" %\ (self.gain, self.y_mag) self.gain, self.y_mag = self.activity.wave.get_mag_params() print "context off: gain and y_mag are %f and %f" %\ (self.gain, self.y_mag) self.capture_gain = self.activity.audiograb.get_capture_gain() self.mic_boost = self.activity.audiograb.get_mic_boost() print "context off: capture gain %s and mic boost %s" %\ (str(self.capture_gain), str(self.mic_boost)) self.activity.audiograb.stop_sound_device() self.activity.wave.set_fft_mode(False) def context_on(self): """When the sound context is switched on""" self.activity.audiograb.start_sound_device() self.activity.audiograb.set_sensor_type('sound') self.activity.wave.set_fft_mode(False) print "context on: gain and y_mag are %f and %f" %\ (self.gain, self.y_mag) self.activity.wave.set_mag_params(self.gain, self.y_mag) self._update_string_for_textbox() self.update_trigger_control() return False def _update_string_for_textbox(self): """ Update the text at the bottom of the canvas """ if not self.activity.wave.get_fft_mode(): self._STR_SCALEX = self._STR_XAXIS_TEXT % \ {'unit': self._ms, 'division': self.activity.wave.time_div*1000} else: self._STR_SCALEX = self._STR_XAXIS_TEXT % \ {'unit': self._Hz, 'division': self.activity.wave.freq_div} self.string_for_textbox = "" self.string_for_textbox += (self._STR_BASIC + '\t') if not self.activity.wave.get_fft_mode(): self.string_for_textbox += self._STR1 else: self.string_for_textbox += self._STR2 if self.activity.wave.get_invert_state(): self.string_for_textbox += self._STR3 self.string_for_textbox += ('\n' + self._STR_SCALEX) self.activity.text_box.set_data_params(0, self.string_for_textbox)
class SideToolbar(gtk.Toolbar): """ A toolbar on the side of the canvas for adjusting gain/bias """ LOWER = 0.0 UPPER = 4.0 def __init__(self, activity): """ Set up initial toolbars """ gtk.Toolbar.__init__(self) self.activity = activity self.show_toolbar = True self.mode = 'sound' self.mode_values = {'sound': 3, 'sensor': 2} self.button_up = ToolButton('amp-high') self.button_up.set_tooltip(_('Increase amplitude')) self.button_up.connect('clicked', self._button_up_cb) self.button_up.show() self.adjustmenty = gtk.Adjustment(self.mode_values[self.mode], self.LOWER, self.UPPER, 0.1, 0.1, 0.0) self.adjustmenty.connect('value_changed', self._yscrollbar_cb, self.adjustmenty) self.yscrollbar = gtk.VScale(self.adjustmenty) self.yscrollbar.set_draw_value(False) self.yscrollbar.set_inverted(True) self.yscrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS) self.button_down = ToolButton('amp-low') self.button_down.set_tooltip(_('Decrease amplitude')) self.button_down.connect('clicked', self._button_down_cb) self.button_down.show() self.box1 = gtk.VBox(False, 0) self.box1.pack_start(self.button_up, False, True, 0) self.box1.pack_start(self.yscrollbar, True, True, 0) self.box1.pack_start(self.button_down, False, True, 0) self.set_show_hide(False) def _yscrollbar_cb(self, adjy, data=None): """ Callback for scrollbar """ if self.mode == 'sound': print "toolbar side: setting mag to 1.0, %f" % (adjy.value) self.activity.wave.set_mag_params(1.0, adjy.value) print "toolbar side: setting capture gain to %f" %\ (adjy.value * 100 / (self.UPPER - self.LOWER)) self.activity.audiograb.set_capture_gain(adjy.value * 100 / (self.UPPER - self.LOWER)) self.activity.wave.set_bias_param(0) elif self.mode == 'sensor': print "toolbar side: setting bias param to %f" %\ (300 * (adjy.value - (self.UPPER - self.LOWER) / 2)) self.activity.wave.set_bias_param( int(300 * (adjy.value - (self.UPPER - self.LOWER) / 2))) self.mode_values[self.mode] = adjy.value return True def _button_up_cb(self, data=None): """Moves slider up""" new_value = self.yscrollbar.get_value() + (self.UPPER - self.LOWER)\ / 100.0 if new_value <= self.UPPER: self.yscrollbar.set_value(new_value) else: self.yscrollbar.set_value(self.UPPER) return True def _button_down_cb(self, data=None): """Moves slider down""" new_value = self.yscrollbar.get_value() - (self.UPPER - self.LOWER)\ / 100.0 if new_value >= self.LOWER: self.yscrollbar.set_value(new_value) else: self.yscrollbar.set_value(self.LOWER) return True def set_show_hide(self, show=True, mode='sound'): """ Show or hide the toolbar """ self.show_toolbar = show self.set_mode(mode) def set_mode(self, mode='sound'): """ Set the toolbar to either 'sound' or 'sensor' """ self.mode = mode if self.mode == 'sound': self.button_up.set_icon('amp-high') self.button_up.set_tooltip(_('Increase amplitude')) self.button_down.set_icon('amp-low') self.button_down.set_tooltip(_('Decrease amplitude')) elif self.mode == 'sensor': self.button_up.set_icon('bias-high') self.button_up.set_tooltip(_('Increase bias')) self.button_down.set_icon('bias-low') self.button_down.set_tooltip(_('Decrease bias')) self.yscrollbar.set_value(self.mode_values[self.mode]) return
class SensorToolbar(gtk.Toolbar): ''' The toolbar for specifiying the sensor: sound, resitance, or voltage ''' LOWER = 0.0 UPPER = 1.0 STR_DC_R = \ _("Resistive sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + ' ' STR_DC_V = \ _("Voltage sensor (connect sensor to pink 'Mic In' on left side \ of XO)" ) + ' ' STR_AC = _('Sound') + ' ' STR_RESISTANCE = _('Resistance') + ' (' + _('Ohms') + ') ' STR_VOLTAGE = _('Voltage') + ' (' + _('Volts') + ') ' STR_TIME = _('Time Base') + ' ' STR_FREQUENCY = _('Frequency Base') + ' ' STR_INVERT = ' ' + _('Invert') + ' ' STR_XAXIS_TEXT = _('X Axis Scale: 1 division = %(division)s %(unit)s') # TRANSLATORS: This is milli seconds. MS = _('ms') # TRANSLATORS: This is Hertz, so 1/second. HZ = _('Hz') def __init__(self, activity, channels): ''' By default, start with resistance mode ''' gtk.Toolbar.__init__(self) self.activity = activity self._channels = channels self._lock_radio_buttons = False self._radio_button_pushed = False self.values = [] for i in range(self._channels): self.values.append('') self.string_for_textbox = '' self.gain = 1.0 self.y_mag = 3.0 self.capture_gain = CAPTURE_GAIN self.mic_boost = MIC_BOOST self.mode = 'sound' # Set up Time-domain Button self.time = RadioToolButton(group=None) self.time.set_named_icon('media-audio') self.insert(self.time, -1) self.time.set_tooltip(_('Sound')) self.time.connect('clicked', self.analog_resistance_voltage_mode_cb, 'sound') # Set up Resistance Button self.resistance = RadioToolButton(group=self.time) self.resistance.set_named_icon('resistance') if _is_xo(self.activity.hw): self.insert(self.resistance, -1) self.resistance.show() self.resistance.set_tooltip(_('Resistance Sensor')) self.resistance.connect('clicked', self.analog_resistance_voltage_mode_cb, 'resistance') # Set up Voltage Button self.voltage = RadioToolButton(group=self.time) self.voltage.set_named_icon('voltage') if _is_xo(self.activity.hw): self.insert(self.voltage, -1) self.voltage.set_tooltip(_('Voltage Sensor')) self.voltage.connect('clicked', self.analog_resistance_voltage_mode_cb, 'voltage') separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) self._log_interval_combo = ComboBox() self.interval = [ _('1/10 second'), _('1 second'), _('30 seconds'), _('5 minutes'), _('30 minutes') ] if hasattr(self._log_interval_combo, 'set_tooltip_text'): self._log_interval_combo.set_tooltip_text(_('Sampling interval')) self._interval_changed_id = self._log_interval_combo.connect( 'changed', self.log_interval_cb) for i, s in enumerate(self.interval): self._log_interval_combo.append_item(i, s, None) if s == _('1 second'): self._log_interval_combo.set_active(i) self._log_interval_tool = ToolComboBox(self._log_interval_combo) self.insert(self._log_interval_tool, -1) self.logging_interval_status = '1 second' # Set up Logging/Stop Logging Button self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.set_tooltip(_('Start Recording')) self._record.connect('clicked', self.record_control_cb) if self.activity.has_toolbarbox: separator = gtk.SeparatorToolItem() separator.props.draw = True self.insert(separator, -1) # Set up Trigger Combo box self.trigger_combo = ComboBox() self.trigger = [_('None'), _('Rising Edge'), _('Falling Edge')] self.trigger_conf = [ self.activity.wave.TRIGGER_NONE, self.activity.wave.TRIGGER_POS, self.activity.wave.TRIGGER_NEG ] self._trigger_changed_id = self.trigger_combo.connect( 'changed', self.update_trigger_control) for i, s in enumerate(self.trigger): self.trigger_combo.append_item(i, s, None) self.trigger_combo.set_active(0) if hasattr(self.trigger_combo, 'set_tooltip_text'): self.trigger_combo.set_tooltip_text(_('Create a trigger')) self._trigger_tool = ToolComboBox(self.trigger_combo) self.insert(self._trigger_tool, -1) self.show_all() def add_frequency_slider(self, toolbar): ''' Either on the Sound toolbar or the Main toolbar ''' self._freq_stepper_up = ToolButton('freq-high') self._freq_stepper_up.set_tooltip(_('Zoom out')) self._freq_stepper_up.connect('clicked', self._freq_stepper_up_cb) self.activity.adjustmentf = gtk.Adjustment(0.5, self.LOWER, self.UPPER, 0.01, 0.1, 0) self.activity.adjustmentf.connect('value_changed', self.cb_page_sizef) self._freq_range = gtk.HScale(self.activity.adjustmentf) self._freq_range.set_inverted(True) self._freq_range.set_draw_value(False) self._freq_range.set_update_policy(gtk.UPDATE_CONTINUOUS) self._freq_range.set_size_request(120, 15) self._freq_stepper_down = ToolButton('freq-low') self._freq_stepper_down.set_tooltip(_('Zoom in')) self._freq_stepper_down.connect('clicked', self._freq_stepper_down_cb) self._freq_range_tool = gtk.ToolItem() self._freq_range_tool.add(self._freq_range) toolbar.insert(self._freq_stepper_up, -1) toolbar.insert(self._freq_range_tool, -1) toolbar.insert(self._freq_stepper_down, -1) return def update_trigger_control(self, *args): ''' Callback for trigger control ''' if self.activity.wave.get_fft_mode(): self.trigger_combo.set_active(self.activity.wave.TRIGGER_NONE) active = self.trigger_combo.get_active() if active == -1: return self.activity.wave.set_trigger(self.trigger_conf[active]) return def analog_resistance_voltage_mode_cb(self, button=None, mode_to_set='sound'): ''' Callback for Analog/Resistance/Voltage Buttons ''' if self._lock_radio_buttons: logging.debug('mode selector locked') self._radio_button_pushed = True return if self.mode == mode_to_set: logging.debug('mode already set to %s' % mode_to_set) return self._lock_radio_buttons = True if self.activity.CONTEXT == 'sound': self.sound_context_off() else: self.sensor_context_off() # Force time domain when switching modes if self.activity.wave.get_fft_mode(): self.activity.timefreq_control() # Turn off logging when switching modes if self.activity.audiograb.we_are_logging: self.record_control_cb() self.set_mode(mode_to_set) if mode_to_set == 'sound': self.set_sound_context() elif mode_to_set == 'resistance': self.set_sensor_context() elif mode_to_set == 'voltage': self.set_sensor_context() self.update_string_for_textbox() return False def unlock_radio_buttons(self): ''' Enable radio button selection ''' logging.debug('unlocking radio buttons') if self._radio_button_pushed: if self.mode == 'sound': self.time.set_active(True) elif self.mode == 'resistance': self.resistance.set_active(True) elif self.mode == 'voltage': self.voltage.set_active(True) self._lock_radio_buttons = False self._radio_button_pushed = False def set_mode(self, mode='sound'): ''' Set the mixer settings to match the current mode. ''' self.mode = mode self.activity.audiograb.set_sensor_type(self.mode) for i in range(self._channels): self.values[i] = 0.0 return def get_mode(self): ''' Get the mixer settings. ''' return self.mode def _freq_stepper_up_cb(self, button=None): ''' Moves the horizontal zoom slider to the left one notch, where one notch is 1/100 of the total range. This correspond to zooming out as a larger number of Hertz or milliseconds will be represented by the same space on the screen. ''' new_value = self._freq_range.get_value() +\ (self.UPPER - self.LOWER) / 100.0 if new_value <= self.UPPER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.UPPER) def _freq_stepper_down_cb(self, button=None): ''' Moves the horizontal zoom slider to the right one notch, where one notch is 1/100 of the total range. This corresponds to zooming in. ''' new_value = self._freq_range.get_value() -\ (self.UPPER - self.LOWER) / 100.0 if new_value >= self.LOWER: self._freq_range.set_value(new_value) else: self._freq_range.set_value(self.LOWER) def cb_page_sizef(self, button=None): ''' Callback to scale the frequency range (zoom in and out) ''' if self._update_page_size_id: gobject.source_remove(self._update_page_size_id) self._update_page_size_id =\ gobject.timeout_add(250, self.update_page_size) return True def update_page_size(self): ''' Set up the scaling of the display. ''' self._update_page_size_id = None new_value = round(self.activity.adjustmentf.value * 100.0) / 100.0 if self.activity.adjustmentf.value != new_value: self.activity.adjustmentf.value = new_value return False time_div = 0.001 * max(self.activity.adjustmentf.value, 0.05) freq_div = 1000 * max(self.activity.adjustmentf.value, 0.01) self.activity.wave.set_div(time_div, freq_div) self.update_string_for_textbox() return False def set_sound_context(self): ''' Called when analog sensing is selected ''' self.set_show_hide_windows(mode='sound') gobject.timeout_add(500, self.sound_context_on) self.activity.CONTEXT = 'sound' def set_sensor_context(self): ''' Called when digital sensing is selected ''' self.set_show_hide_windows(mode='sensor') gobject.timeout_add(500, self.sensor_context_on) self.activity.CONTEXT = 'sensor' def set_show_hide_windows(self, mode='sound'): ''' Shows the appropriate window identified by the mode ''' self.activity.wave.set_context_on() for i in range(self._channels): self.activity.side_toolbars[i].set_show_hide(True, mode) def sensor_context_off(self): ''' Called when a DC sensor is no longer selected ''' # self.activity.audiograb.pause_grabbing() self.activity.audiograb.stop_grabbing() def sensor_context_on(self): ''' Called when a DC sensor is selected ''' self.update_string_for_textbox() self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE) # self.activity.audiograb.resume_grabbing() self.activity.audiograb.start_grabbing() return False def sound_context_off(self): ''' Called when an analog sensor is no longer selected ''' self.gain, self.y_mag = self.activity.wave.get_mag_params() self.capture_gain = self.activity.audiograb.get_capture_gain() self.mic_boost = self.activity.audiograb.get_mic_boost() self.activity.audiograb.stop_grabbing() def sound_context_on(self): ''' Called when an analog sensor is selected ''' self.activity.wave.set_mag_params(self.gain, self.y_mag) self.update_string_for_textbox() self.update_trigger_control() self.activity.audiograb.start_grabbing() return False def set_sample_value(self, value='', channel=0): ''' Write a sample value to the textbox. ''' gtk.threads_enter() self.values[channel] = value self.update_string_for_textbox() gtk.threads_leave() return def record_control_cb(self, button=None): ''' Depending upon the selected interval, does either a logging session, or just logs the current buffer. ''' if self.activity.audiograb.we_are_logging: self.activity.audiograb.set_logging_params(start_stop=False) self._record.set_icon('media-record') self._record.show() self._record.set_tooltip(_('Start Recording')) else: Xscale = (1.00 / self.activity.audiograb.get_sampling_rate()) Yscale = 0.0 interval = self.interval_convert() username = self.activity.nick if self.activity.wave.get_fft_mode(): self.activity.data_logger.start_new_session( username, Xscale, Yscale, _(self.logging_interval_status), channels=self._channels, mode='frequency') else: self.activity.data_logger.start_new_session( username, Xscale, Yscale, _(self.logging_interval_status), channels=self._channels, mode=self.mode) self.activity.audiograb.set_logging_params(start_stop=True, interval=interval, screenshot=False) self._record.set_icon('record-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) self.activity.new_recording = True def interval_convert(self): ''' Converts interval string to an integer that denotes the number of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written. ''' interval_dictionary = { '1/10 second': 0.1, '1 second': 1, '30 seconds': 30, '5 minutes': 300, '30 minutes': 1800 } try: return interval_dictionary[self.logging_interval_status] except ValueError: logging.error('logging interval status = %s' %\ (str(self.logging_interval_status))) return 0 def log_interval_cb(self, combobox): ''' Callback from the Logging Interval Combo box: sets status ''' if self._log_interval_combo.get_active() != -1: intervals = [ '1/10 second', '1 second', '30 seconds', '5 minutes', '30 minutes' ] self.logging_interval_status = \ intervals[self._log_interval_combo.get_active()] def update_string_for_textbox(self): ''' Update the status field at the bottom of the canvas. ''' if self.activity.CONTEXT == 'butia': string_for_textbox = '' else: if self.mode == 'resistance': string_for_textbox = (self.STR_DC_R + '\n') string_for_textbox += self.STR_RESISTANCE elif self.mode == 'voltage': string_for_textbox = (self.STR_DC_V + '\n') string_for_textbox += self.STR_VOLTAGE else: string_for_textbox = (self.STR_AC + '\t') if self.activity.wave.get_fft_mode(): scalex = self.STR_XAXIS_TEXT % { 'unit': self.HZ, 'division': self.activity.wave.freq_div } string_for_textbox += self.STR_FREQUENCY string_for_textbox += ('\n' + scalex) elif self.mode == 'sound': scalex = self.STR_XAXIS_TEXT % { 'unit': self.MS, 'division': self.activity.wave.time_div * 1000 } string_for_textbox += self.STR_TIME string_for_textbox += ('\n' + scalex) else: for i in range(self._channels): string_for_textbox += '\t(%s)' % (self.values[i]) invert = False for i in range(self._channels): if self.activity.wave.get_invert_state(channel=i): invert = True if invert: string_for_textbox += self.STR_INVERT self.activity.text_box.set_label(string_for_textbox)
class ViewToolbar(gtk.Toolbar): def __init__(self, activity): gtk.Toolbar.__init__(self) self._activity = activity self._activity.tray.connect('unmap', self.__unmap_cb) self._activity.tray.connect('map', self.__map_cb) self._browser = self._activity._browser self.zoomout = ToolButton('zoom-out') self.zoomout.set_tooltip(_('Zoom out')) self.zoomout.connect('clicked', self.__zoomout_clicked_cb) self.insert(self.zoomout, -1) self.zoomout.show() self.zoomin = ToolButton('zoom-in') self.zoomin.set_tooltip(_('Zoom in')) self.zoomin.connect('clicked', self.__zoomin_clicked_cb) self.insert(self.zoomin, -1) self.zoomin.show() self.separator = gtk.SeparatorToolItem() self.separator.set_draw(True) self.insert(self.separator, -1) self.separator.show() self.fullscreen = ToolButton('view-fullscreen') self.fullscreen.set_tooltip(_('Fullscreen')) self.fullscreen.connect('clicked', self.__fullscreen_clicked_cb) self.insert(self.fullscreen, -1) self.fullscreen.show() self.traybutton = ToolButton('tray-hide') self.traybutton.connect('clicked', self.__tray_clicked_cb) self.traybutton.props.sensitive = False self.insert(self.traybutton, -1) self.traybutton.show() def __zoomin_clicked_cb(self, button): self._browser.zoom_in() def __zoomout_clicked_cb(self, button): self._browser.zoom_out() def __fullscreen_clicked_cb(self, button): self._activity.fullscreen() def __tray_clicked_cb(self, button): if self._activity.tray.props.visible is False: self._activity.tray.show() else: self._activity.tray.hide() def __map_cb(self, tray): if len(self._activity.tray.get_children()) > 0: self.tray_set_hide() def __unmap_cb(self, tray): if len(self._activity.tray.get_children()) > 0: self.tray_set_show() def tray_set_show(self): self.traybutton.set_icon('tray-show') self.traybutton.set_tooltip(_('Show Tray')) def tray_set_hide(self): self.traybutton.set_icon('tray-hide') self.traybutton.set_tooltip(_('Hide Tray'))