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)
Beispiel #4
0
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
Beispiel #6
0
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)
Beispiel #9
0
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)
Beispiel #10
0
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
Beispiel #12
0
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()
Beispiel #14
0
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)
Beispiel #15
0
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)
Beispiel #17
0
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]))
Beispiel #18
0
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}"
Beispiel #19
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)
Beispiel #22
0
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()
Beispiel #23
0
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)
Beispiel #24
0
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
Beispiel #28
0
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)
Beispiel #29
0
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'))