Exemple #1
0
 def get_toolbar(self):
     toolbar = gtk.Toolbar()
     
     radio_adv = RadioToolButton()
     radio_adv.set_active(True)
     radio_adv.set_label("Avanzada")
     radio_adv.set_tooltip("Mostrar biblioteca avanzada")
     radio_adv.connect("clicked", self.switch, "advanced")
     toolbar.insert(radio_adv, -1)
     radio_adv.show()
     
     radio_bas = RadioToolButton(group=radio_adv)
     radio_bas.set_label("Simple")
     radio_bas.set_tooltip("Mostrar biblioteca sencilla")
     radio_bas.connect("clicked", self.switch, "basic")
     toolbar.insert(radio_bas, -1)
     
     toolbar.show_all()
     
     return toolbar
Exemple #2
0
class RadioItem(ToggleItem):
    def __init__(self,
                 group,
                 default_value=True,
                 stock_id=None,
                 important=False):
        ToggleItem.__init__(self, default_value, stock_id, important)
        self.group = group

    def get_tool_item(self):
        self.toolitem = RadioToolButton()
        if self.group:
            self.toolitem.set_group(self.group.toolitem)
        self.toolitem.set_named_icon(
            stock.icons[self._stock_id] if self._stock_id in
            stock.icons else self._stock_id)
        self.toolitem.set_active(self.default_value)
        self.toolitem.connect('toggled', self.toggled_cb)
        self.setup_tooltip()
        return self.toolitem
Exemple #3
0
    def __init__(self):
        RadioToolButton.__init__(self)

        self.props.tooltip = _('Favorites view')
        self.props.accelerator = _('<Ctrl>1')
        self.props.group = None

        favorites_settings = favoritesview.get_settings()
        self._layout = favorites_settings.layout
        self._update_icon()

        # someday, this will be a gtk.Table()
        layouts_grid = gtk.HBox()
        layout_item = None
        for layoutid, layoutclass in sorted(favoritesview.LAYOUT_MAP.items()):
            layout_item = RadioToolButton(icon_name=layoutclass.icon_name,
                                          group=layout_item,
                                          active=False)
            if layoutid == self._layout:
                layout_item.set_active(True)
            layouts_grid.pack_start(layout_item, fill=False)
            layout_item.connect('toggled', self.__layout_activate_cb, layoutid)
        layouts_grid.show_all()
        self.props.palette.set_content(layouts_grid)
Exemple #4
0
    def __init__(self):
        RadioToolButton.__init__(self)

        self.props.tooltip = _('Pathway view')
        self.props.accelerator = _('<Ctrl>3')
        self.props.group = None

        favorites_settings = favoritesview.get_settings()
        self._layout = favorites_settings.layout
        self._update_icon()

        # someday, this will be a gtk.Table()
        layouts_grid = gtk.HBox()
        layout_item = None
        for layoutid, layoutclass in sorted(favoritesview.LAYOUT_MAP.items()):
            layout_item = RadioToolButton(icon_name=layoutclass.icon_name,
                                          group=layout_item, active=False)
            if layoutid == self._layout:
                layout_item.set_active(True)
            layouts_grid.pack_start(layout_item, fill=False)
            layout_item.connect('toggled', self.__layout_activate_cb,
                                layoutid)
        layouts_grid.show_all()
        self.props.palette.set_content(layouts_grid)
class Activity(sugar.activity.activity.Activity):
    def __init__(self, handle):
        super(Activity, self).__init__(handle)
        self.paused = False

        watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
        self.window.set_cursor(watch)

        self.p = gtk.VPaned()
        self.p.connect("notify::position", self.redraw)
        self.box = gtk.Notebook()
        self.p.pack2(self.box)
        self.p.show()
        self.box.set_show_tabs(False)

        self.splash = gtk.Image()
        pixbuf = gtk.gdk.pixbuf_new_from_file("images/splash_comodo.png")
        screen = self.window.get_screen()
        width, height = screen.get_width(), screen.get_height() - style.GRID_CELL_SIZE
        pixbuf = pixbuf.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
        self.splash.set_from_pixbuf(pixbuf)
        self.splash.show()
        eb = gtk.EventBox()
        eb.add(self.splash)
        eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("white"))
        eb.show()
        self.box.append_page(eb, gtk.Label("Inicio"))

        self._pygamecanvas = sugargame2.canvas.PygameCanvas(self)
        self._pygamecanvas.set_flags(gtk.EXPAND)
        self._pygamecanvas.set_flags(gtk.FILL)

        self.connect("visibility-notify-event", self.redraw)
        self._pygamecanvas.set_events(gtk.gdk.BUTTON_PRESS_MASK)
        self._pygamecanvas.connect("button-press-event", self._pygamecanvas.grab_focus)
        self.box.append_page(self._pygamecanvas, gtk.Label("Juego"))

        self.box.show()
        self.set_canvas(self.p)

        gobject.timeout_add(300, self.pump)
        gobject.timeout_add(2000, self.init_interpreter)
        #gobject.timeout_add(1000, self.build_editor)
        gobject.timeout_add(1500, self.check_modified)

        self.build_toolbar()
        self.credits = None
        self.editor = None
        #self.reader = None
        self._pygamecanvas.run_pygame(self.run_game)

    def redraw(self, widget=None, b=None, c=None):
        scene = spyral.director.get_scene()
        if scene:
            scene.redraw()

    def alert(self, title=None, text=None, delay=5):
        alert = NotifyAlert(delay)
        alert.props.title = title
        alert.props.msg = text
        self.add_alert(alert)
        alert.connect('response', self._alert_ok)
        alert.show()

    def _alert_ok(self, alert, *args):
        self.remove_alert(alert)

    def check_modified(self):
        if self.box.current_page()==2:
            if not self.save_button.get_sensitive():
                if self.editor.modificado():
                    self.save_button.set_sensitive(True)
                    return False
        return True

    def pump(self):
        # Esto es necesario porque sino pygame acumula demasiados eventos.
        pygame.event.pump()

    def focus_interpreter(self, widget, event):
        self._interpreter.text.grab_focus()
        return True

    def init_interpreter(self):
        # diferido unos segundos para evitar ver errores superfluos al iniciar
        self._interpreter = GTKInterpreterConsole(self.redraw)
        self._interpreter.text.connect('button-press-event', self.focus_interpreter)
        self.p.pack1(self._interpreter)
        return False

    def open_file(self, widget, path):
        if path:
            if not os.path.isdir(path):
                self.editor.open_file(widget, path)

    def save_file(self, widget):
        if self.editor.modificado():
            self.save_button.set_sensitive(False)
            self.editor.save_file()
            filename = self.editor.current_file()
            self.alert(filename, "Archivo guardado.")
            gobject.timeout_add(1500, self.check_modified)

    def build_editor(self):
        dir_real = os.getcwd()
        f = os.path.realpath(JUEGO.__file__)
        f = "." + f.replace(dir_real ,"") # todo esto para obtener una ruta relativa
        f = f.rstrip("c")  # en caso que sea .pyc compilado

        self.h = gtk.HPaned()
        self.tree = FileViewer(".", os.path.basename(f))
        self.tree.connect("file-selected", self.open_file)
        self.tree.show()
        self.h.pack1(self.tree)
        self.box.append_page(self.h, gtk.Label("Editor"))

        if False: #os.path.isfile("/usr/bin/gvim"):
            # Si podemos, lo hacemos
            self.socket = gtk.Socket()
            self.socket.show()
            self.h.pack2(self.socket)
            sock_id = str(self.socket.get_id())
            self.editor = VimSourceView(sock_id)

            if not self.editor.bufInfo.bufferList:
                f = JUEGO.__file__
                if f.endswith("pyc"):
                    f = f[:-1]
                self.open_file(None, f)
        else:
            self.editor = SourceView()

            scroller = gtk.ScrolledWindow()
            scroller.set_policy(gtk.POLICY_AUTOMATIC,
                          gtk.POLICY_AUTOMATIC)
            scroller.add(self.editor)
            scroller.show()
            self.h.pack2(scroller)
            self.editor.show()

        self.h.show()
        self.open_file(None, f)

    def build_reader(self):
        self.reader = webkit.WebView()
        curdir = os.getcwd()
        self.reader.load_uri("file://%s/docs/index.html" % curdir)
        self.box.append_page(self.reader, gtk.Label("Lector"))
        self.reader.show()

    def build_toolbar(self):
        toolbar_box = ToolbarBox()
        self.set_toolbar_box(toolbar_box)
        toolbar_box.show()

        activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(activity_button, -1)
        activity_button.show()

        tool_group = None

        self.game_button = RadioToolButton()
        self.game_button.props.icon_name = 'gamecanvas'
        self.game_button.set_tooltip(_('Juego'))
        self.game_button.accelerator = "<Ctrl>1"
        self.game_button.props.group = tool_group
        self.game_button.connect('clicked', self.show_game)
        toolbar_box.toolbar.insert(self.game_button, -1)
        self.game_button.show()
        tool_group = self.game_button

        button = RadioToolButton()
        button.props.icon_name = 'view-source'
        button.set_tooltip(_('Editor'))
        button.accelerator = "<Ctrl>2"
        button.props.group = tool_group
        button.connect('clicked', self.show_editor)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        self.save_button = ToolButton('dialog-ok')
        self.save_button.set_tooltip(_('Guardar'))
        self.save_button.accelerator = "<Ctrl>s"
        self.save_button.connect('clicked', self.save_file)
        self.save_button.set_sensitive(False)
        toolbar_box.toolbar.insert(self.save_button, -1)
        self.save_button.show()

        separator = gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(separator, -1)
        separator.show()

        button = ToolButton('system-restart')
        button.set_tooltip(_('Reiniciar juego'))
        button.accelerator = "<Alt><Shift>r"
        button.connect('clicked', self.restart_game)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        self.editor_button = ToolButton('sources')
        self.editor_button.set_tooltip(_('Consola'))
        self.editor_button.accelerator = "<Ctrl>grave"
        self.editor_button.connect('clicked', self.toggle_console)
        toolbar_box.toolbar.insert(self.editor_button, -1)
        self.editor_button.show()

        separator = gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(separator, -1)
        separator.show()

        button = helpbutton.HelpButton(self)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        button = ToolButton()
        button.props.icon_name = 'activity-about'
        button.set_tooltip(_('Acerca de'))
        button.accelerator = "<Ctrl>i"
        button.connect('clicked', self.run_credits)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        # Blank space (separator) and Stop button at the end:

        separator = gtk.SeparatorToolItem()
        separator.props.draw = False
        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()

    def run_game(self):
        spyral.director.init((0,0), fullscreen=False, max_fps=30)
        self.game = JUEGO.Juego(self, callback=self.game_ready)
        self.box.connect("switch-page", self.redraw)
        spyral.director.push(self.game)
        self.start()

    def run_credits(self, widget):
        if not (spyral.director.get_scene()==self.credits):
            self.credits = game.credits.Creditos(self.game.size)
            spyral.director.push(self.credits)

    def start(self):
        try:
            spyral.director.run(sugar = True)
        except AttributeError as detail:
            detail2 = traceback.format_exc()
            self.box.set_page(0)
            self.alert( detail2, "Spyral se ha detenido abruptamente.", 60)

    def show_game(self, widget):
        self.box.set_page(1)
        self.redraw()

    def show_editor(self, widget):
        if not self.editor:
            self.build_editor()
        self.box.set_page(2)
        self.redraw()

    def show_reader(self, widget):
        if not self.reader:
            self.build_reader()
        self.box.set_page(3)
        self.redraw()

    def restart_game(self, widget):
        global JUEGO
        import objetos
        try:
            objetos.reset()
        except AttributeError:
            pass
        self.box.set_page(0)
        watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
        self.window.set_cursor(watch)
        JUEGO = reload(JUEGO)
        self.game = JUEGO.Juego(self, callback=self.game_ready)
        spyral.director.replace(self.game)
        self.start()

    def game_ready(self, widget = None):
        self.game_button.set_active(True)
        self.box.set_page(1)
        self._pygamecanvas.grab_focus()
        self.window.set_cursor(None)

    def read_file(self, file_path):
        pass

    def write_file(self, file_path):
        pass

    def can_close(self):
        if self.editor:
            self.editor.close()
        self.box.set_page(0)
        try:
            spyral.director.quit()
        except spyral.exceptions.GameEndException:
            pass
        finally:
            return True

    def toggle_console(self, e):
        if self._interpreter.props.visible:
            self._interpreter.hide()
            self._pygamecanvas.grab_focus()
        else:
            self.p.set_position(160)
            self._interpreter.show()
            self._interpreter.text.grab_focus()
        self.redraw()

    def animate_console(self):
        easing = spyral.easing.Linear(0,160)
        self.p.set_position(0)
Exemple #6
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)
class Activity(sugar.activity.activity.Activity):
    def __init__(self, handle):
        super(Activity, self).__init__(handle)
        self.paused = False

        watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
        self.window.set_cursor(watch)

        self.p = gtk.VPaned()
        self.p.connect("notify::position", self.redraw)
        self.box = gtk.Notebook()
        self.p.pack2(self.box)
        self.p.show()
        self.box.set_show_tabs(False)

        self.splash = gtk.Image()
        pixbuf = gtk.gdk.pixbuf_new_from_file("images/splash-colgadito.png")
        screen = self.window.get_screen()
        width, height = screen.get_width(), screen.get_height() - style.GRID_CELL_SIZE
        pixbuf = pixbuf.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
        self.splash.set_from_pixbuf(pixbuf)
        self.splash.show()
        eb = gtk.EventBox()
        eb.add(self.splash)
        eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("white"))
        eb.show()
        self.box.append_page(eb, gtk.Label("Inicio"))

        self._pygamecanvas = sugargame2.canvas.PygameCanvas(self)
        self._pygamecanvas.set_flags(gtk.EXPAND)
        self._pygamecanvas.set_flags(gtk.FILL)

        self.connect("visibility-notify-event", self.redraw)
        self._pygamecanvas.set_events(gtk.gdk.BUTTON_PRESS_MASK)
        self._pygamecanvas.connect("button-press-event", self._pygamecanvas.grab_focus)
        self.box.append_page(self._pygamecanvas, gtk.Label("Juego"))

        self.box.show()
        self.set_canvas(self.p)

        gobject.timeout_add(300, self.pump)
        gobject.timeout_add(2000, self.init_interpreter)
        #gobject.timeout_add(1000, self.build_editor)
        gobject.timeout_add(1500, self.check_modified)

        self.build_toolbar()
        self.credits = None
        self.editor = None
        self._pygamecanvas.run_pygame(self.run_game)

    def redraw(self, widget=None, b=None, c=None):
        scene = spyral.director.get_scene()
        if scene:
            scene.redraw()

    def alert(self, title=None, text=None, delay=5):
        alert = NotifyAlert(delay)
        alert.props.title = title
        alert.props.msg = text
        print text
        self.add_alert(alert)
        alert.connect('response', self._alert_ok)
        alert.show()

    def _alert_ok(self, alert, *args):
        self.remove_alert(alert)

    def check_modified(self):
        if self.box.current_page()==2:
            if not self.save_button.get_sensitive():
                if self.editor.modificado():
                    self.save_button.set_sensitive(True)
                    return False
        return True

    def pump(self):
        # Esto es necesario porque sino pygame acumula demasiados eventos.
        pygame.event.pump()

    def focus_interpreter(self, widget, event):
        self._interpreter.text.grab_focus()
        return True

    def init_interpreter(self):
        # diferido unos segundos para evitar ver errores superfluos al iniciar
        self._interpreter = GTKInterpreterConsole(self.redraw)
        self._interpreter.text.connect('button-press-event', self.focus_interpreter)
        self.p.pack1(self._interpreter)
        return False

    def open_file(self, widget, path):
        if path:
            if not os.path.isdir(path):
                self.editor.open_file(widget, path)

    def save_file(self, widget):
        if self.editor.modificado():
            self.save_button.set_sensitive(False)
            self.editor.save_file()
            filename = self.editor.current_file()
            self.alert(filename, "Archivo guardado.")
            gobject.timeout_add(1500, self.check_modified)

    def build_editor(self):
        dir_real = os.getcwd()
        f = os.path.realpath(JUEGO.__file__)
        f = "." + f.replace(dir_real ,"") # todo esto para obtener una ruta relativa
        f = f.rstrip("c")  # en caso que sea .pyc compilado

        self.h = gtk.HPaned()
        self.tree = FileViewer(".", os.path.basename(f))
        self.tree.connect("file-selected", self.open_file)
        self.tree.show()
        self.h.pack1(self.tree)
        self.box.append_page(self.h, gtk.Label("Editor"))

        if False: #os.path.isfile("/usr/bin/gvim"):
            # Si podemos, lo hacemos
            self.socket = gtk.Socket()
            self.socket.show()
            self.h.pack2(self.socket)
            sock_id = str(self.socket.get_id())
            self.editor = VimSourceView(sock_id)

            if not self.editor.bufInfo.bufferList:
                f = JUEGO.__file__
                if f.endswith("pyc"):
                    f = f[:-1]
                self.open_file(None, f)
        else:
            self.editor = SourceView()

            scroller = gtk.ScrolledWindow()
            scroller.set_policy(gtk.POLICY_AUTOMATIC,
                          gtk.POLICY_AUTOMATIC)
            scroller.add(self.editor)
            scroller.show()
            self.h.pack2(scroller)
            self.editor.show()

        self.h.show()
        self.open_file(None, f)

    def build_toolbar(self):
        toolbar_box = ToolbarBox()
        self.set_toolbar_box(toolbar_box)
        toolbar_box.show()

        activity_button = ActivityToolbarButton(self)
        toolbar_box.toolbar.insert(activity_button, -1)
        activity_button.show()

        tool_group = None

        self.game_button = RadioToolButton()
        self.game_button.props.icon_name = 'gamecanvas'
        self.game_button.set_tooltip(_('Juego'))
        self.game_button.accelerator = "<Ctrl>1"
        self.game_button.props.group = tool_group
        self.game_button.connect('clicked', self.show_game)
        toolbar_box.toolbar.insert(self.game_button, -1)
        self.game_button.show()
        tool_group = self.game_button

        button = RadioToolButton()
        button.props.icon_name = 'view-source'
        button.set_tooltip(_('Editor'))
        button.accelerator = "<Ctrl>2"
        button.props.group = tool_group
        button.connect('clicked', self.show_editor)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        self.save_button = ToolButton('dialog-ok')
        self.save_button.set_tooltip(_('Guardar'))
        self.save_button.accelerator = "<Ctrl>s"
        self.save_button.connect('clicked', self.save_file)
        self.save_button.set_sensitive(False)
        toolbar_box.toolbar.insert(self.save_button, -1)
        self.save_button.show()

        separator = gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(separator, -1)
        separator.show()

        button = ToolButton('system-restart')
        button.set_tooltip(_('Reiniciar juego'))
        button.accelerator = "<Alt><Shift>r"
        button.connect('clicked', self.restart_game)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        self.editor_button = ToolButton('sources')
        self.editor_button.set_tooltip(_('Consola'))
        self.editor_button.accelerator = "<Ctrl>grave"
        self.editor_button.connect('clicked', self.toggle_console)
        toolbar_box.toolbar.insert(self.editor_button, -1)
        self.editor_button.show()

        separator = gtk.SeparatorToolItem()
        toolbar_box.toolbar.insert(separator, -1)
        separator.show()

        button = helpbutton.HelpButton(self)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        button = ToolButton()
        button.props.icon_name = 'activity-about'
        button.set_tooltip(_('Acerca de'))
        button.accelerator = "<Ctrl>i"
        button.connect('clicked', self.run_credits)
        toolbar_box.toolbar.insert(button, -1)
        button.show()

        # Blank space (separator) and Stop button at the end:
        separator = gtk.SeparatorToolItem()
        separator.props.draw = False
        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()

    def run_game(self):
        spyral.director.init((0,0), fullscreen=False, max_fps=30)
        self.game = JUEGO.Game(activity=self)
        self.box.connect("switch-page", self.redraw)
        spyral.director.push(self.game)
        self.start()

    def run_credits(self, widget):
        if not (spyral.director.get_scene()==self.credits):
            self.credits = game.credits.Creditos(self.game.size)
            spyral.director.push(self.credits)

    def start(self):
        #try:
        spyral.director.run(sugar = True)
        #except AttributeError as detail:
        #    detail2 = traceback.format_exc()
        #    self.box.set_page(0)
        #    self.alert( detail2, "Spyral se ha detenido abruptamente.", 60)

    def show_game(self, widget):
        self.box.set_page(1)
        self.redraw()

    def show_editor(self, widget):
        if not self.editor:
            self.build_editor()
        self.box.set_page(2)
        self.redraw()

    def restart_game(self, widget):
        global JUEGO
        import objetos
        try:
            objetos.reset()
        except AttributeError:
            pass
        self.show_game(None)
        watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
        self.window.set_cursor(watch)
        JUEGO = reload(JUEGO)
        self.game = JUEGO.Game(activity=self)
        spyral.director.replace(self.game)
        self.start()

    def game_ready(self, widget = None):
        self.game_button.set_active(True)
        self.box.set_page(1)
        self._pygamecanvas.grab_focus()
        self.window.set_cursor(None)

    def read_file(self, file_path):
        pass

    def write_file(self, file_path):
        pass

    def can_close(self):
        if self.editor:
            self.editor.close()
        self.box.set_page(0)
        try:
            spyral.director.quit()
        except spyral.exceptions.GameEndException:
            pass
        finally:
            return True

    def toggle_console(self, e):
        if self._interpreter.props.visible:
            self._interpreter.hide()
            self._pygamecanvas.grab_focus()
        else:
            self.p.set_position(160)
            self._interpreter.show()
            self._interpreter.text.grab_focus()
        self.redraw()

    def animate_console(self):
        easing = spyral.easing.Linear(0,160)
        self.p.set_position(0)
Exemple #8
0
class TagStar(gtk.HBox):
    """
    A L{gtk.HBox} which arranges togglebuttons around the current position
    within a L{gtk.Fixed} widget.

    This is the central tag element, where a user can either tag his current
    position with a category specified in L{geotagplugin.ECategory}. If
    one of the user's already tagged features is selected in the tree, the
    made change action will be handled as an edit.
    """

    IMG_SIZE = (100, 100)
    BUTTON_SIZE = (100, 100)
    EMPTY_LIST_STORE = gtk.ListStore(gobject.TYPE_STRING)

    toggled = NONE_CATEGORY # selected category
    selected = None # gtk.Image displaying selected category

    def __init__(self, toolbar, control):
        gtk.HBox.__init__(self)
        self._logger = logging.getLogger('TagStar')
        self._logger.setLevel(constants.LOG_LEVEL)
        self.toolbar = toolbar
        self.control = control

        self.size_cb = self.connect('size_allocate', self.size_allocate_cb)

        self.fixed = gtk.Fixed()
        self.pack_start(self.fixed)
        self.show_all()

    def size_allocate_cb(self, widget, event):
        """
        Builds the tag star around the center where the selected
        category is shown.
        """
        self._logger.debug('size_allocate_cb()')
        x, y, width, height = self.fixed.get_allocation()
        self._logger.debug('x: %s, y: %s, w: %s, h: %s', x, y, width, height)
        self.set_size_request(width, height)

        ######################################################################
        # place togglebuttons around the current position in a radio group

        color_fill = profile.get_color().get_fill_color()
        color_stroke = profile.get_color().get_stroke_color()
        button_width, button_height = self.BUTTON_SIZE
        cat_names = get_categories()

        radius = 300 # px
        x_center = width / 2 - 40
        y_center = height / 2 - 40
        step_angle = math.radians(360 / (len(cat_names) + 1)) # plus reset btn

        # add a reset button
        self.reset_selected_btn = RadioToolButton()
        img_name = os.path.join(GeoTag.ICONS_PATH, 'reset.svg')
        icon = gtk.image_new_from_pixbuf(utils.load_svg_image(img_name,
                                                   color_stroke,
                                                   color_fill,
                                                   self.IMG_SIZE))
        self.reset_selected_btn.set_icon_widget(icon)
        self.reset_selected_btn.set_tooltip(_('Reset selected tag.'))
        self.reset_selected_btn.connect('clicked', self.reset_toggled)
        self.reset_selected_btn.show_all()
        self.reset_selected_btn.set_size_request(button_width, button_height)
        self.fixed.put(self.reset_selected_btn,
                       x_center,          # + int(radius * math.sin(i * step_angle)),
                       y_center + radius) # + int(radius * math.cos(i * step_angle)))
        self.reset_selected_btn.set_active(False)

        # read all available categories dynamically
        for i, category in enumerate(cat_names):
            button = RadioToolButton(group=self.reset_selected_btn)
            img_name = os.path.join(GeoTag.ICONS_PATH, category)
            icon = get_gtkimage_from_plugin(img_name, color_stroke, color_fill, self.IMG_SIZE)
            button.set_icon_widget(icon)
            button.set_tooltip(_('Tag some %s.' % category))            # XXX check translation here!!
            button.connect('clicked', self.set_toggled, category)
            button.show_all()
            button.set_size_request(button_width, button_height)
            self.fixed.put(button,
                           x_center + int(radius * math.sin((i + 1) * step_angle)),
                           y_center + int(radius * math.cos((i + 1) * step_angle)))
            button.set_active(False)

        img_name = os.path.join(GeoTag.ICONS_PATH, NONE_CATEGORY)
        self._set_selected(get_gtkimage_from_plugin(img_name, color_stroke,color_fill, self.IMG_SIZE))

        ###################################################################

        self._logger.debug("size_allocation done")
        self.disconnect(self.size_cb) ## use only once

    def reset_toggled(self, button):
        """
        Resets toggled property and combobox liststore.

        @param button: The reset button (can be omitted by passing None).
        @note: If a tag was selected within the L{geotagmodel.GeotagModel},
        the tag will be deleted.
        """
        self.toggled = NONE_CATEGORY

        # reset liststore
        combo = self.toolbar.combobox
        combo.set_model(self.EMPTY_LIST_STORE)

        # reset selected widget
        color_fill = profile.get_color().get_fill_color()
        color_stroke = profile.get_color().get_stroke_color()
        self._set_selected(get_gtkimage_from_plugin(NONE_CATEGORY,
                                                    color_stroke,
                                                    color_fill,
                                                    self.IMG_SIZE))

        self.reset_selected_btn.set_active(True)
        self.selected.queue_draw()
        combo.queue_draw()

    def set_toggled(self, button, category):
        """
        Switches the empty Button and the tagged category button clicked.
        Also, sets the appropriate liststore for the combobox.

        @param button: Toggled button (can be omittted).
        @param category: The corresponding category to set.
        """
        self._logger.debug("set_toggled()")

        self.toggled = category

        # set liststore
        combo = self.toolbar.combobox
        combo.set_model(self.toolbar.description_sets[category])

        color_fill = profile.get_color().get_fill_color()
        color_stroke = profile.get_color().get_stroke_color()

#        self._logger.debug("storage type: %s", self.selected.get_property("storage-type"))
        self._set_selected(get_gtkimage_from_plugin(category,
                                                    color_stroke,
                                                    color_fill,
                                                    self.IMG_SIZE))
        combo.queue_draw()

    def _set_selected(self, widget):
        """
        Sets the widget as the currently selected tag category.

        @param widget: The L{gtk.Image} to set.
        """
        x, y, width, height = self.fixed.get_allocation()
        x_center = width / 2 - 40
        y_center = height / 2 - 40

        if self.selected:
            self.selected.clear()
        button_width, button_height = self.BUTTON_SIZE
        widget.set_size_request(button_width, button_height)
        widget.show_all()
        self.selected = widget
        self.selected.queue_draw()

        self.fixed.put(self.selected, x_center, y_center)
Exemple #9
0
    def size_allocate_cb(self, widget, event):
        """
        Builds the tag star around the center where the selected
        category is shown.
        """
        self._logger.debug('size_allocate_cb()')
        x, y, width, height = self.fixed.get_allocation()
        self._logger.debug('x: %s, y: %s, w: %s, h: %s', x, y, width, height)
        self.set_size_request(width, height)

        ######################################################################
        # place togglebuttons around the current position in a radio group

        color_fill = profile.get_color().get_fill_color()
        color_stroke = profile.get_color().get_stroke_color()
        button_width, button_height = self.BUTTON_SIZE
        cat_names = get_categories()

        radius = 300 # px
        x_center = width / 2 - 40
        y_center = height / 2 - 40
        step_angle = math.radians(360 / (len(cat_names) + 1)) # plus reset btn

        # add a reset button
        self.reset_selected_btn = RadioToolButton()
        img_name = os.path.join(GeoTag.ICONS_PATH, 'reset.svg')
        icon = gtk.image_new_from_pixbuf(utils.load_svg_image(img_name,
                                                   color_stroke,
                                                   color_fill,
                                                   self.IMG_SIZE))
        self.reset_selected_btn.set_icon_widget(icon)
        self.reset_selected_btn.set_tooltip(_('Reset selected tag.'))
        self.reset_selected_btn.connect('clicked', self.reset_toggled)
        self.reset_selected_btn.show_all()
        self.reset_selected_btn.set_size_request(button_width, button_height)
        self.fixed.put(self.reset_selected_btn,
                       x_center,          # + int(radius * math.sin(i * step_angle)),
                       y_center + radius) # + int(radius * math.cos(i * step_angle)))
        self.reset_selected_btn.set_active(False)

        # read all available categories dynamically
        for i, category in enumerate(cat_names):
            button = RadioToolButton(group=self.reset_selected_btn)
            img_name = os.path.join(GeoTag.ICONS_PATH, category)
            icon = get_gtkimage_from_plugin(img_name, color_stroke, color_fill, self.IMG_SIZE)
            button.set_icon_widget(icon)
            button.set_tooltip(_('Tag some %s.' % category))            # XXX check translation here!!
            button.connect('clicked', self.set_toggled, category)
            button.show_all()
            button.set_size_request(button_width, button_height)
            self.fixed.put(button,
                           x_center + int(radius * math.sin((i + 1) * step_angle)),
                           y_center + int(radius * math.cos((i + 1) * step_angle)))
            button.set_active(False)

        img_name = os.path.join(GeoTag.ICONS_PATH, NONE_CATEGORY)
        self._set_selected(get_gtkimage_from_plugin(img_name, color_stroke,color_fill, self.IMG_SIZE))

        ###################################################################

        self._logger.debug("size_allocation done")
        self.disconnect(self.size_cb) ## use only once
Exemple #10
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)
Exemple #11
0
    def __init__(self, handle):

        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # CHART_OPTIONS

        self.x_label = ""
        self.y_label = ""
        self.chart_color = utils.get_user_fill_color('str')
        self.chart_line_color = utils.get_user_stroke_color('str')
        self.current_chart = None
        self.charts_area = None
        self.chart_data = []

        # TOOLBARS
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_btn_toolbar = activity_button.page

        activity_btn_toolbar.title.connect('changed', self._set_chart_title)

        save_as_image = ToolButton("save-as-image")
        save_as_image.connect("clicked", self._save_as_image)
        save_as_image.set_tooltip(_("Save as image"))
        activity_btn_toolbar.insert(save_as_image, -1)

        save_as_image.show()

        toolbarbox.toolbar.insert(activity_button, 0)

        import_freespace = ToolButton("import-freespace")
        import_freespace.connect("clicked", self.__import_freespace_cb)
        import_freespace.set_tooltip(_("Read Freespace data"))
        toolbarbox.toolbar.insert(import_freespace, -1)
        import_freespace.show()

        import_journal = ToolButton('import-journal')
        import_journal.connect('clicked', self.__import_journal_cb)
        import_journal.set_tooltip(_('Read Journal data'))
        toolbarbox.toolbar.insert(import_journal, -1)
        import_journal.show()

        import_turtle = ToolButton('import-turtle')
        import_turtle.connect('clicked', self.__import_turtle_cb)
        import_turtle.set_tooltip(_('Read Turtle data'))
        toolbarbox.toolbar.insert(import_turtle, -1)
        import_turtle.show()

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        add_vbar_chart = RadioToolButton()
        add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar")
        add_vbar_chart.set_tooltip(_("Vertical Bar Chart"))
        add_vbar_chart.props.icon_name = "vbar"
        charts_group = add_vbar_chart
        toolbarbox.toolbar.insert(add_vbar_chart, -1)

        add_hbar_chart = RadioToolButton()
        add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar")
        add_hbar_chart.set_tooltip(_("Horizontal Bar Chart"))
        add_hbar_chart.props.icon_name = "hbar"
        add_hbar_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_hbar_chart, -1)

        add_pie_chart = RadioToolButton()
        add_pie_chart.connect("clicked", self._add_chart_cb, "pie")
        add_pie_chart.set_tooltip(_("Pie Chart"))
        add_pie_chart.props.icon_name = "pie"
        add_pie_chart.props.group = charts_group
        add_pie_chart.set_active(True)
        toolbarbox.toolbar.insert(add_pie_chart, -1)

        self.chart_type_buttons = [
            add_vbar_chart, add_hbar_chart, add_pie_chart
        ]

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.connect("clicked", self.__fullscreen_cb)

        toolbarbox.toolbar.insert(fullscreen_btn, -1)

        charthelp.create_help(toolbarbox.toolbar)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)

        # CANVAS
        paned = gtk.HPaned()
        box = gtk.VBox()
        self.box = box

        # Set the info box width to 1/3 of the screen:
        def size_allocate_cb(widget, allocation):
            paned.disconnect(self._setup_handle)
            box_width = allocation.width / 3
            box.set_size_request(box_width, -1)

        self._setup_handle = paned.connect('size_allocate', size_allocate_cb)

        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.labels_and_values = ChartData(self)
        scroll.add(self.labels_and_values)

        self.labels_and_values.connect("label-changed", self._label_changed)
        self.labels_and_values.connect("value-changed", self._value_changed)

        box.pack_start(scroll, True, True, 0)

        paned.add1(box)

        # CHARTS AREA

        eventbox = gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size_allocate', self._chart_size_allocate)

        eventbox.modify_bg(gtk.STATE_NORMAL, _WHITE)

        eventbox.add(self.charts_area)
        paned.add2(eventbox)

        self.set_canvas(paned)

        self.show_all()
Exemple #12
0
class SpeakActivity(activity.Activity):
    def __init__(self, handle):
        super(SpeakActivity, self).__init__(handle)

        self._notebook = gtk.Notebook()
        self.set_canvas(self._notebook)
        self._notebook.show()

        self._colors = profile.get_color().to_string().split(',')
        lighter = style.Color(self._colors[
            _lighter_color(self._colors)])

        self._mode = MODE_TYPE
        self._tablet_mode = _is_tablet_mode()
        self._robot_idle_id = None
        self._active_eyes = None
        self._active_number_of_eyes = None
        self._current_voice = None

        # make an audio device for playing back and rendering audio
        self.connect('notify::active', self._active_cb)
        self._cfg = {}

        # make a box to type into
        hbox = gtk.HBox()

        if self._tablet_mode:
            self._entry = gtk.Entry()
            hbox.pack_start(self._entry, expand=True)
            talk_button = ToolButton('microphone')
            talk_button.set_tooltip(_('Speak'))
            talk_button.connect('clicked', self._talk_cb)
            hbox.pack_end(talk_button, expand=False)
        else:
            self._entrycombo = gtk.combo_box_entry_new_text()
            self._entrycombo.connect('changed', self._combo_changed_cb)
            self._entry = self._entrycombo.child
            self._entry.set_size_request(-1, style.GRID_CELL_SIZE)
            hbox.pack_start(self._entrycombo, expand=True)
        self._entry.set_editable(True)
        self._entry.connect('activate', self._entry_activate_cb)
        self._entry.connect('key-press-event', self._entry_key_press_cb)
        self._entry.modify_font(pango.FontDescription(str='sans bold 24'))
        hbox.show()

        self.face = face.View(fill_color=lighter)
        self.face.set_size_request(
            -1, gtk.gdk.screen_height() - 2 * style.GRID_CELL_SIZE)
        self.face.show()

        # layout the screen
        box = gtk.VBox(homogeneous=False)
        if self._tablet_mode:
            box.pack_start(hbox, expand=False)
            box.pack_start(self.face)
        else:
            box.pack_start(self.face, expand=True)
            box.pack_start(hbox)

        self.add_events(gtk.gdk.POINTER_MOTION_HINT_MASK
                        | gtk.gdk.POINTER_MOTION_MASK)
        self.connect('motion_notify_event', self._mouse_moved_cb)

        box.add_events(gtk.gdk.BUTTON_PRESS_MASK)
        box.connect('button_press_event', self._mouse_clicked_cb)

        # desktop
        self._notebook.show()
        self._notebook.props.show_border = False
        self._notebook.props.show_tabs = False

        box.show_all()
        self._notebook.append_page(box)

        self._chat = chat.View()
        self._chat.show_all()
        self._notebook.append_page(self._chat)

        # make the text box active right away
        if not self._tablet_mode:
            self._entry.grab_focus()

        self._entry.connect('move-cursor', self._cursor_moved_cb)
        self._entry.connect('changed', self._cursor_moved_cb)

        toolbox = ToolbarBox()
        self._activity_button = ActivityToolbarButton(self)
        self._activity_button.connect('clicked', self._configure_cb)

        toolbox.toolbar.insert(self._activity_button, -1)

        mode_type = RadioToolButton(
            named_icon='mode-type',
            tooltip=_('Type something to hear it'))
        mode_type.connect('toggled', self.__toggled_mode_type_cb)
        toolbox.toolbar.insert(mode_type, -1)

        mode_robot = RadioToolButton(
            named_icon='mode-robot',
            group=mode_type,
            tooltip=_('Ask robot any question'))
        mode_robot.connect('toggled', self.__toggled_mode_robot_cb)
        toolbox.toolbar.insert(mode_robot, -1)

        self._mode_chat = RadioToolButton(
            named_icon='mode-chat',
            group=mode_type,
            tooltip=_('Voice chat'))
        self._mode_chat.connect('toggled', self.__toggled_mode_chat_cb)
        toolbox.toolbar.insert(self._mode_chat, -1)

        self._voice_button = ToolbarButton(
            page=self._make_voice_bar(),
            label=_('Voice'),
            icon_name='voice')
        self._voice_button.connect('clicked', self._configure_cb)
        toolbox.toolbar.insert(self._voice_button, -1)

        self._face_button = ToolbarButton(
            page=self._make_face_bar(),
            label=_('Face'),
            icon_name='face')
        self._face_button.connect('clicked', self._configure_cb)
        toolbox.toolbar.insert(self._face_button, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbox.toolbar.insert(separator, -1)

        toolbox.toolbar.insert(StopButton(self), -1)

        toolbox.show_all()
        self.toolbar_box = toolbox

        gtk.gdk.screen_get_default().connect('size-changed',
                                             self._configure_cb)

        self._first_time = True
        self._new_instance()

        self._configure_cb()
        self._poll_accelerometer()

        if self.shared_activity:
            # we are joining the activity
            self.connect('joined', self._joined_cb)
            if self.get_shared():
                # we have already joined
                self._joined_cb(self)
            self._mode_chat.set_active(True)
            self._setup_chat_mode()
        elif handle.uri:
            # XMPP non-sugar3 incoming chat, not sharable
            self._activity_button.props.page.share.props.visible = \
                False
            self._one_to_one_connection(handle.uri)
        else:
            # we are creating the activity
            self.connect('shared', self._shared_cb)

    def _toolbar_expanded(self):
        if self._activity_button.is_expanded():
            return True
        if self._voice_button.is_expanded():
            return True
        if self._face_button.is_expanded():
            return True
        return False

    def _configure_cb(self, event=None):
        self._entry.set_size_request(-1, style.GRID_CELL_SIZE)
        if self._toolbar_expanded():
            self.face.set_size_request(
                -1, gtk.gdk.screen_height() - 3 * style.GRID_CELL_SIZE)
            self._chat.resize_chat_box(expanded=True)
            self._chat.resize_buddy_list()
        else:
            self.face.set_size_request(
                -1, gtk.gdk.screen_height() - 2 * style.GRID_CELL_SIZE)
            self._chat.resize_chat_box()
            self._chat.resize_buddy_list()

    def _new_instance(self):
        if self._first_time:
            # self.voices.connect('changed', self.__changed_voices_cb)
            self.pitchadj.connect('value_changed', self._pitch_adjusted_cb,
                                  self.pitchadj)
            self.rateadj.connect('value_changed', self._rate_adjusted_cb,
                                 self.rateadj)
        if self._active_number_of_eyes is None:
            self._number_of_eyes_changed_event_cb(None, None, 'two', True)
        if self._active_eyes is None:
            self._eyes_changed_event_cb(None, None, 'eyes', True)

        self._mouth_changed_cb(None, True)

        self.face.look_ahead()

        presenceService = presenceservice.get_instance()
        self.owner = presenceService.get_owner()
        if self._first_time:
            # say hello to the user
            if self._tablet_mode:
                self._entry.props.text = _('Hello %s.') \
                    % self.owner.props.nick.encode('utf-8', 'ignore')
            self.face.say_notification(_('Hello %s. Please Type something.')
                                       % self.owner.props.nick)
        else:
            if self._tablet_mode:
                self._entry.props.text = _('Welcome back %s.') \
                    % self.owner.props.nick.encode('utf-8', 'ignore')
            self.face.say_notification(_('Welcome back %s.')
                                       % self.owner.props.nick)
        self._set_idle_phrase(speak=False)
        self._first_time = False

    def read_file(self, file_path):
        self._cfg = json.loads(file(file_path, 'r').read())

        current_voice = self.face.status.voice

        status = self.face.status = \
            face.Status().deserialize(self._cfg['status'])

        found_my_voice = False
        for name in self._voice_evboxes.keys():
            if self._voice_evboxes[name][1] == current_voice:
                self._voice_evboxes[name][0].modify_bg(
                    0, style.COLOR_BLACK.get_gdk_color())
            if self._voice_evboxes[name][1] == status.voice and \
               not found_my_voice:
                self._voice_evboxes[name][0].modify_bg(
                    0, style.COLOR_BUTTON_GREY.get_gdk_color())
                self.face.set_voice(status.voice)
                if self._mode == MODE_BOT:
                    brain.load(self, status.voice)
                found_my_voice = True

        self.pitchadj.value = self.face.status.pitch
        self.rateadj.value = self.face.status.rate

        if status.mouth in MOUTHS:
            self._mouth_type[MOUTHS.index(status.mouth)].set_active(True)

        self._number_of_eyes_changed_event_cb(
            None, None, NUMBERS[len(status.eyes) - 1], True)
        for name in EYE_DICT.keys():
            if status.eyes[0] == EYE_DICT[name]['widget']:
                self._eye_type[name].set_icon(name + '-selected')
                self._eyes_changed_event_cb(None, None, name, True)
                break

        self._entry.props.text = self._cfg['text'].encode('utf-8', 'ignore')
        if not self._tablet_mode:
            for i in self._cfg['history']:
                self._entrycombo.append_text(i.encode('utf-8', 'ignore'))

        self._new_instance()

    def write_file(self, file_path):
        if self._tablet_mode:
            if 'history' in self._cfg:
                history = self._cfg['history']  # retain old history
            else:
                history = []
        else:
            history = [unicode(i[0], 'utf-8', 'ignore')
                       for i in self._entrycombo.get_model()]
        cfg = {'status': self.face.status.serialize(),
               'text': unicode(self._entry.props.text, 'utf-8', 'ignore'),
               'history': history, }
        file(file_path, 'w').write(json.dumps(cfg))

    def _cursor_moved_cb(self, entry, *ignored):
        # make the eyes track the motion of the text cursor
        index = entry.props.cursor_position
        layout = entry.get_layout()
        pos = layout.get_cursor_pos(index)
        x = pos[0][0] / pango.SCALE - entry.props.scroll_offset
        y = entry.get_allocation().y
        self.face.look_at(pos=(x, y))

    def _poll_accelerometer(self):
        if _has_accelerometer():
            idle_time = self._test_orientation()
            gobject.timeout_add(idle_time, self._poll_accelerometer)

    def _test_orientation(self):
        if _has_accelerometer():
            fh = open(ACCELEROMETER_DEVICE)
            string = fh.read()
            fh.close()
            xyz = string[1:-2].split(',')
            x = int(xyz[0])
            y = int(xyz[1])
            # DO SOMETHING HERE
            if ((gtk.gdk.screen_width() > gtk.gdk.screen_height() and
                 abs(x) > abs(y)) or
                (gtk.gdk.screen_width() < gtk.gdk.screen_height() and
                 abs(x) < abs(y))):
                sideways_phrase = SIDEWAYS_PHRASES[
                    random.randint(0, len(SIDEWAYS_PHRASES) - 1)]
                self.face.say(SIDEWAYS_PHRASES[sideways_phrase])
                return IDLE_DELAY  # Don't repeat the message for a while
            return 1000  # Test again soon

    def get_mouse(self):
        display = gtk.gdk.display_get_default()
        screen, mouseX, mouseY, modifiers = display.get_pointer()
        return mouseX, mouseY

    def _mouse_moved_cb(self, widget, event):
        # make the eyes track the motion of the mouse cursor
        self.face.look_at()
        self._chat.look_at()

    def _mouse_clicked_cb(self, widget, event):
        pass

    def _make_voice_bar(self):
        voicebar = gtk.Toolbar()

        all_voices = []
        for name in sorted(voice_model.allVoices().keys()):
            if len(name) < 26:
                friendly_name = name
            else:
                friendly_name = name[:26] + '...'
            all_voices.append([voice_model.allVoices()[name], friendly_name])

        # A palette for the voice selection
        logging.error(self.face.status.voice)

        self._voice_evboxes = {}
        self._voice_box = gtk.HBox()
        vboxes = [gtk.VBox(), gtk.VBox(), gtk.VBox()]
        count = len(voice_model.allVoices().keys())
        found_my_voice = False
        for i, voice in enumerate(sorted(all_voices)):
            label = gtk.Label()
            label.set_use_markup(True)
            label.set_justify(gtk.JUSTIFY_LEFT)
            label.set_markup('<span size="large">%s</span>' % voice[1])

            alignment = gtk.Alignment(0, 0, 0, 0)
            alignment.add(label)
            label.show()

            evbox = gtk.EventBox()
            self._voice_evboxes[voice[1]] = [evbox, voice[0]]
            self._voice_evboxes[voice[1]][0].connect(
                'button-press-event', self._voices_changed_event_cb, voice)
            if voice[0] == self.face.status.voice and not found_my_voice:
                self._current_voice = voice
                evbox.modify_bg(
                    0, style.COLOR_BUTTON_GREY.get_gdk_color())
                found_my_voice = True
            evbox.add(alignment)
            alignment.show()
            if i < count / 3:
                vboxes[0].pack_start(evbox)
            elif i < 2 * count / 3:
                vboxes[1].pack_start(evbox)
            else:
                vboxes[2].pack_start(evbox)
        self._voice_box.pack_start(vboxes[0], padding=style.DEFAULT_PADDING)
        self._voice_box.pack_start(vboxes[1], padding=style.DEFAULT_PADDING)
        self._voice_box.pack_start(vboxes[2], padding=style.DEFAULT_PADDING)

        voice_palette_button = ToolButton('module-language')
        voice_palette_button.set_tooltip(_('Choose voice:'))
        self._voice_palette = voice_palette_button.get_palette()
        self._voice_palette.set_content(self._voice_box)
        self._voice_box.show_all()
        voice_palette_button.connect('clicked', self._face_palette_cb)
        voicebar.insert(voice_palette_button, -1)
        voice_palette_button.show()

        brain_voices = []
        for name in sorted(brain.BOTS.keys()):
            brain_voices.append([voice_model.allVoices()[name], name])

        self._brain_evboxes = {}
        self._brain_box = gtk.HBox()
        vboxes = gtk.VBox()
        count = brain.BOTS.keys()
        found_my_voice = False
        for i, voice in enumerate(brain_voices):
            label = gtk.Label()
            label.set_use_markup(True)
            label.set_justify(gtk.JUSTIFY_LEFT)
            label.set_markup('<span size="large">%s</span>' % voice[1])

            alignment = gtk.Alignment(0, 0, 0, 0)
            alignment.add(label)
            label.show()

            evbox = gtk.EventBox()
            self._brain_evboxes[voice[1]] = [evbox, voice[0]]
            self._brain_evboxes[voice[1]][0].connect(
                'button-press-event', self._voices_changed_event_cb, voice)
            if voice[0] == self.face.status.voice and not found_my_voice:
                evbox.modify_bg(
                    0, style.COLOR_BUTTON_GREY.get_gdk_color())
                found_my_voice = True
            evbox.add(alignment)
            alignment.show()
            vboxes.pack_start(evbox)
        self._brain_box.pack_start(vboxes, padding=style.DEFAULT_PADDING)
        self._brain_box.show_all()

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        voicebar.insert(separator, -1)

        self.pitchadj = gtk.Adjustment(self.face.status.pitch, 0,
                                       espeak.PITCH_MAX, 1,
                                       espeak.PITCH_MAX/10, 0)
        pitchbar = gtk.HScale(self.pitchadj)
        pitchbar.set_draw_value(False)
        # pitchbar.set_inverted(True)
        pitchbar.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
        pitchbar.set_size_request(240, 15)

        pitchbar_toolitem = ToolWidget(widget=pitchbar, label_text=_('Pitch:'))
        voicebar.insert(pitchbar_toolitem, -1)

        self.rateadj = gtk.Adjustment(self.face.status.rate, 0,
                                      espeak.RATE_MAX,
                                      1, espeak.RATE_MAX / 10, 0)
        ratebar = gtk.HScale(self.rateadj)
        ratebar.set_draw_value(False)
        # ratebar.set_inverted(True)
        ratebar.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
        ratebar.set_size_request(240, 15)

        ratebar_toolitem = ToolWidget(widget=ratebar, label_text=_('Rate:'))
        voicebar.insert(ratebar_toolitem, -1)

        voicebar.show_all()
        return voicebar

    def _pitch_adjusted_cb(self, get, data=None):
        self.face.status.pitch = get.value
        self.face.say_notification(_('pitch adjusted'))

    def _rate_adjusted_cb(self, get, data=None):
        self.face.status.rate = get.value
        self.face.say_notification(_('rate adjusted'))

    def _make_face_bar(self):
        facebar = gtk.Toolbar()

        self._mouth_type = []
        self._mouth_type.append(RadioToolButton(
            named_icon='mouth',
            group=None,
            tooltip=_('Simple')))
        self._mouth_type[-1].connect('clicked', self._mouth_changed_cb, False)
        facebar.insert(self._mouth_type[-1], -1)

        self._mouth_type.append(RadioToolButton(
            named_icon='waveform',
            group=self._mouth_type[0],
            tooltip=_('Waveform')))
        self._mouth_type[-1].connect('clicked', self._mouth_changed_cb, False)
        facebar.insert(self._mouth_type[-1], -1)

        self._mouth_type.append(RadioToolButton(
            named_icon='frequency',
            group=self._mouth_type[0],
            tooltip=_('Frequency')))
        self._mouth_type[-1].connect('clicked', self._mouth_changed_cb, False)
        facebar.insert(self._mouth_type[-1], -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        facebar.insert(separator, -1)

        eye_box = gtk.VBox()
        self._eye_type = {}
        for name in EYE_DICT.keys():
            self._eye_type[name] = ToolButton(name)
            self._eye_type[name].connect('clicked',
                                         self._eyes_changed_event_cb,
                                         None, name, False)
            label = gtk.Label(EYE_DICT[name]['label'])
            hbox = gtk.HBox()
            hbox.pack_start(self._eye_type[name])
            self._eye_type[name].show()
            hbox.pack_start(label)
            label.show()
            evbox = gtk.EventBox()
            evbox.connect('button-press-event', self._eyes_changed_event_cb,
                          name, False)
            evbox.add(hbox)
            hbox.show()
            eye_box.pack_start(evbox)

        eye_palette_button = ToolButton('eyes')
        eye_palette_button.set_tooltip(_('Choose eyes:'))
        palette = eye_palette_button.get_palette()
        palette.set_content(eye_box)
        eye_box.show_all()
        eye_palette_button.connect('clicked', self._face_palette_cb)
        facebar.insert(eye_palette_button, -1)
        eye_palette_button.show()

        number_of_eyes_box = gtk.VBox()
        self._number_of_eyes_type = {}
        for name in NUMBERS:
            self._number_of_eyes_type[name] = ToolButton(name)
            self._number_of_eyes_type[name].connect(
                'clicked', self._number_of_eyes_changed_event_cb,
                None, name, False)
            label = gtk.Label(name)
            hbox = gtk.HBox()
            hbox.pack_start(self._number_of_eyes_type[name])
            self._number_of_eyes_type[name].show()
            hbox.pack_start(label)
            label.show()
            evbox = gtk.EventBox()
            evbox.connect('button-press-event',
                          self._number_of_eyes_changed_event_cb,
                          name, False)
            evbox.add(hbox)
            hbox.show()
            number_of_eyes_box.pack_start(evbox)

        number_of_eyes_palette_button = ToolButton('number')
        number_of_eyes_palette_button.set_tooltip(_('Eyes number:'))
        palette = number_of_eyes_palette_button.get_palette()
        palette.set_content(number_of_eyes_box)
        number_of_eyes_box.show_all()
        number_of_eyes_palette_button.connect('clicked', self._face_palette_cb)
        facebar.insert(number_of_eyes_palette_button, -1)
        number_of_eyes_palette_button.show()

        facebar.show_all()
        return facebar

    def _face_palette_cb(self, button):
        palette = button.get_palette()
        if palette:
            if not palette.is_up():
                palette.popup(immediate=True, state=palette.SECONDARY)
            else:
                palette.popdown(immediate=True)

    def _get_active_mouth(self):
        for i, button in enumerate(self._mouth_type):
            if button.get_active():
                return MOUTHS[i]

    def _mouth_changed_cb(self, ignored, quiet):
        value = self._get_active_mouth()
        if value is None:
            return

        self.face.status.mouth = value
        self._update_face()

        # this SegFaults: self.face.say(combo.get_active_text())
        if not quiet:
            self.face.say_notification(_('mouth changed'))

    def _voices_changed_event_cb(self, widget, event, voice):
        logging.error('voices_changed_event_cb %r %s' % (voice[0], voice[1]))
        if self._mode == MODE_BOT:
            evboxes = self._brain_evboxes
        else:
            evboxes = self._voice_evboxes
        for old_voice in evboxes.keys():
            if evboxes[old_voice][1] == self.face.status.voice:
                evboxes[old_voice][0].modify_bg(
                    0, style.COLOR_BLACK.get_gdk_color())
                break

        evboxes[voice[1]][0].modify_bg(
            0, style.COLOR_BUTTON_GREY.get_gdk_color())

        self.face.set_voice(voice[0])
        if self._mode == MODE_BOT:
            brain.load(self, voice[0])
        else:
            self._current_voice = voice

    def _get_active_eyes(self):
        for name in EYE_DICT.keys():
            if EYE_DICT[name]['index'] == self._active_eyes:
                return EYE_DICT[name]['widget']
        return None

    def _eyes_changed_event_cb(self, widget, event, name, quiet):
        if self._active_eyes is not None:
            for old_name in EYE_DICT.keys():
                if EYE_DICT[old_name]['index'] == self._active_eyes:
                    self._eye_type[old_name].set_icon(old_name)
                    break

        if self._active_number_of_eyes is None:
            self._active_number_of_eyes = 2

        if name is not None:
            self._active_eyes = EYE_DICT[name]['index']
            self._eye_type[name].set_icon(name + '-selected')
            value = EYE_DICT[name]['widget']
            self.face.status.eyes = [value] * self._active_number_of_eyes
            self._update_face()
            if not quiet:
                self.face.say_notification(_('eyes changed'))

    def _number_of_eyes_changed_event_cb(self, widget, event, name, quiet):
        if self._active_number_of_eyes is not None:
            old_name = NUMBERS[self._active_number_of_eyes - 1]
            self._number_of_eyes_type[old_name].set_icon(old_name)

        if name in NUMBERS:
            self._active_number_of_eyes = NUMBERS.index(name) + 1
            self._number_of_eyes_type[name].set_icon(name + '-selected')
            if self._active_eyes is not None:
                for eye_name in EYE_DICT.keys():
                    if EYE_DICT[eye_name]['index'] == self._active_eyes:
                        value = EYE_DICT[eye_name]['widget']
                        self.face.status.eyes = \
                            [value] * self._active_number_of_eyes
                        self._update_face()
                        if not quiet:
                            self.face.say_notification(_('eyes changed'))
                        break

    def _update_face(self):
        self.face.update()
        self._chat.update(self.face.status)

    def _combo_changed_cb(self, combo):
        # when a new item is chosen, make sure the text is selected
        if not self._entry.is_focus():
            if not self._tablet_mode:
                self._entry.grab_focus()
            self._entry.select_region(0, -1)

    def _entry_key_press_cb(self, combo, event):
        # make the up/down arrows navigate through our history
        if self._tablet_mode:
            return
        keyname = gtk.gdk.keyval_name(event.keyval)
        if keyname == 'Up':
            index = self._entrycombo.get_active()
            if index > 0:
                index -= 1
            self._entrycombo.set_active(index)
            self._entry.select_region(0, -1)
            return True
        elif keyname == 'Down':
            index = self._entrycombo.get_active()
            if index < len(self._entrycombo.get_model()) - 1:
                index += 1
            self._entrycombo.set_active(index)
            self._entry.select_region(0, -1)
            return True
        return False

    def _entry_activate_cb(self, entry):
        # the user pressed Return, say the text and clear it out
        text = entry.props.text
        if self._tablet_mode:
            self._dismiss_OSK(entry)
            timeout = DELAY_BEFORE_SPEAKING
        else:
            timeout = 100
        gobject.timeout_add(timeout, self._speak_the_text, entry, text)

    def _dismiss_OSK(self, entry):
        entry.hide()
        entry.show()

    def _talk_cb(self, button):
        text = self._entry.props.text
        self._speak_the_text(self._entry, text)

    def _speak_the_text(self, entry, text):
        self._remove_idle()

        if text:
            self.face.look_ahead()

            # speak the text
            if self._mode == MODE_BOT:
                self.face.say(brain.respond(text))
            else:
                self.face.say(text)

        if text and not self._tablet_mode:
            # add this text to our history unless it is the same as
            # the last item
            history = self._entrycombo.get_model()
            if len(history) == 0 or history[-1][0] != text:
                self._entrycombo.append_text(text)
                # don't let the history get too big
                while len(history) > 20:
                    self._entrycombo.remove_text(0)
                # select the new item
                self._entrycombo.set_active(len(history) - 1)
        if text:
            # select the whole text
            entry.select_region(0, -1)

        # Launch an robot idle phase after 2 minutes
        self._robot_idle_id = gobject.timeout_add(IDLE_DELAY,
                                                  self._set_idle_phrase)

    def _load_sleeping_face(self):
        current_eyes = self.face.status.eyes
        self.face.status.eyes = [SLEEPY_EYES] * self._active_number_of_eyes
        self._update_face()
        self.face.status.eyes = current_eyes

    def _set_idle_phrase(self, speak=True):
        if speak:
            self._load_sleeping_face()
            idle_phrase = IDLE_PHRASES[random.randint(
                0, len(IDLE_PHRASES) - 1)]
            if self.props.active:
                self.face.say(idle_phrase)

        self._robot_idle_id = gobject.timeout_add(IDLE_DELAY,
                                                  self._set_idle_phrase)

    def _active_cb(self, widget, pspec):
        # only generate sound when this activity is active
        if not self.props.active:
            self._load_sleeping_face()
            self.face.shut_up()
            self._chat.shut_up()

    def _set_voice(self, new_voice=None):
        if new_voice is not None:
            logging.error('set_voice %r' % new_voice)
            self.face.status.voice = new_voice
        else:
            logging.error('set_voice to current voice %s' %
                          self._current_voice[1])
            self.face.status.voice = self._current_voice[0]

    def __toggled_mode_type_cb(self, button):
        if not button.props.active:
            return

        self._mode = MODE_TYPE
        self._chat.shut_up()
        self.face.shut_up()
        self._notebook.set_current_page(0)

        self._voice_palette.set_content(self._voice_box)
        self._set_voice()

    def __toggled_mode_robot_cb(self, button):
        if not button.props.active:
            return

        self._remove_idle()

        self._mode = MODE_BOT
        self._chat.shut_up()
        self.face.shut_up()
        self._notebook.set_current_page(0)

        self._voice_palette.set_content(self._brain_box)

        new_voice = None
        for name in brain.BOTS.keys():
            if self._current_voice[0].short_name == name:
                new_voice == self._current_voice[0]
                break
        if new_voice is None:
            new_voice = brain.get_default_voice()
            if new_voice.friendlyname in self._current_voice[0].friendlyname:
                logging.debug('skipping sorry message for %s %s' %
                              (new_voice.friendlyname,
                               self._current_voice[0].friendlyname))
                sorry = None
            else:
                sorry = _("Sorry, I can't speak %(old_voice)s, "
                          "let's talk %(new_voice)s instead.") % {
                              'old_voice': self._current_voice[0].friendlyname,
                              'new_voice': new_voice.friendlyname}
        else:
            new_voice = new_voice[0]
            sorry = None

        self._set_voice(new_voice)

        evboxes = self._brain_evboxes
        for old_voice in evboxes.keys():
            evboxes[old_voice][0].modify_bg(
                0, style.COLOR_BLACK.get_gdk_color())

        if new_voice.short_name in evboxes:
            evboxes[new_voice.short_name][0].modify_bg(
                0, style.COLOR_BUTTON_GREY.get_gdk_color())

        if not brain.load(self, new_voice, sorry):
            if sorry:
                self.face.say_notification(sorry)

    def __toggled_mode_chat_cb(self, button):
        if not button.props.active:
            return

        self._remove_idle()

        is_first_session = not self.shared_activity

        self._setup_chat_mode()

        if is_first_session:
            self._chat.me.say_notification(
                _('You are in off-line mode, share and invite someone.'))

    def _remove_idle(self):
        if self._robot_idle_id is not None:
            gobject.source_remove(self._robot_idle_id)
            value = self._get_active_eyes()
            if value is not None:
                self.face.status.eyes = [value] * self._active_number_of_eyes
                self._update_face()

    def _setup_chat_mode(self):
        self._mode = MODE_CHAT
        self._remove_idle()
        self.face.shut_up()
        self._notebook.set_current_page(1)

        self._voice_palette.set_content(self._voice_box)
        self._set_voice()

    def _shared_cb(self, sender):
        logging.error('SHARED A CHAT')
        self._setup_text_channel()

    def _joined_cb(self, sender):
        '''Joined a shared activity.'''
        if not self.shared_activity:
            return
        logger.error('JOINED A SHARED CHAT')
        for buddy in self.shared_activity.get_joined_buddies():
            self._buddy_already_exists(buddy)
        self._setup_text_channel()

    def _one_to_one_connection(self, tp_channel):
        '''Handle a private invite from a non-sugar3 XMPP client.'''
        if self.shared_activity or self.text_channel:
            return
        bus_name, connection, channel = json.loads(tp_channel)
        logger.debug('GOT XMPP: %s %s %s', bus_name, connection, channel)
        Connection(bus_name, connection, ready_handler=lambda conn:
                   self._one_to_one_connection_ready_cb(
                       bus_name, channel, conn))

    def _one_to_one_connection_ready_cb(self, bus_name, channel, conn):
        '''Callback for Connection for one to one connection'''
        text_channel = Channel(bus_name, channel)
        self.text_channel = TextChannelWrapper(text_channel, conn)
        self.text_channel.set_received_callback(self._received_cb)
        self.text_channel.handle_pending_messages()
        self.text_channel.set_closed_callback(
            self._one_to_one_connection_closed_cb)

        # XXX How do we detect the sender going offline?
        self._chat.chat_post.set_sensitive(True)
        # self._chat.chat_post.props.placeholder_text = None
        self._chat.chat_post.grab_focus()

    def _one_to_one_connection_closed_cb(self):
        '''Callback for when the text channel closes.'''
        pass

    def _setup_text_channel(self):
        logging.error('_SETUP_TEXTCHANNEL')
        self.text_channel = TextChannelWrapper(
            self.shared_activity.telepathy_text_chan,
            self.shared_activity.telepathy_conn)
        self.text_channel.set_received_callback(self._received_cb)
        self.shared_activity.connect('buddy-joined', self._buddy_joined_cb)
        self.shared_activity.connect('buddy-left', self._buddy_left_cb)
        self._chat.messenger = self.text_channel
        self._chat.chat_post.set_sensitive(True)
        self._chat.chat_post.grab_focus()

    def _buddy_joined_cb(self, sender, buddy):
        '''Show a buddy who joined'''
        if buddy == self.owner:
            return
        logging.error('%s joined the chat (%r)' % (buddy.props.nick, buddy))
        self._chat.post(
            buddy, _('%s joined the chat') % buddy.props.nick,
            status_message=True)

    def _buddy_left_cb(self, sender, buddy):
        '''Show a buddy who joined'''
        if buddy == self.owner:
            return
        logging.error('%s left the chat (%r)' % (buddy.props.nick, buddy))
        self._chat.post(
            buddy, _('%s left the chat') % buddy.props.nick,
            status_message=True)
        self._chat.farewell(buddy)

    def _buddy_already_exists(self, buddy):
        '''Show a buddy already in the chat.'''
        if buddy == self.owner:
            return
        logging.error('%s is here (%r)' % (buddy.props.nick, buddy))
        self._chat.post(
            buddy, _('%s is here') % buddy.props.nick,
            status_message=True)

    def _received_cb(self, buddy, text):
        '''Show message that was received.'''
        if buddy:
            if type(buddy) is dict:
                nick = buddy['nick']
            else:
                nick = buddy.props.nick
        else:
            nick = '???'
        logger.debug('Received message from %s: %s', nick, text)
        self._chat.post(buddy, text)
class VncLauncherActivity(activity.Activity):
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        self.max_participants = 1

        self.toolbarbox = ToolbarBox()
        self.toolbar = self.toolbarbox.toolbar

        self.start_vnc = RadioToolButton(icon_name="start_vnc",
                                         tooltip=_("Start VNC Server"))

        self.stop_vnc = RadioToolButton(icon_name="stop_vnc",
                                        tooltip=_("Stop VNC Server"),
                                        group=self.start_vnc)

        self.stop_vnc.set_active(True)

        self.get_ipbutton = ToolButton(icon_name="get_ip",
                                       tooltip=_("Get the current IP"))

        ##
        self.messages = gtk.TreeView()
        self.messages.set_rules_hint(True)
        modelo = gtk.ListStore(str, str, gtk.gdk.Color)
        self.messages.set_model(modelo)
        render = gtk.CellRendererText()
        render1 = gtk.CellRendererText()

        column1 = gtk.TreeViewColumn(_("Hour"), render, markup=0)
        column2 = gtk.TreeViewColumn(_("Message"), render1, markup=1)
        column1.add_attribute(render, 'foreground-gdk', 2)
        column2.add_attribute(render1, 'foreground-gdk', 2)

        self.messages.append_column(column1)
        self.messages.append_column(column2)
        color = gtk.gdk.color_parse("dark blue")
        modelo.insert(0, [
            time.strftime("\n<b>%H:%M:%S</b>\n"),
            _("\n<b>Start of activity.</b>\n"), color
        ])

        self.showed_message_stop = True
        self.showed_message_start = False
        self.isrunning = True

        self.stop_vnc.connect("clicked", self.__stop_vnc)
        self.start_vnc.connect("clicked", self.__start_vnc)
        self.clear_model = ToolButton(icon_name="clear_console",
                                      tooltip=_("Delete messages"))
        self.clear_model.connect("clicked", lambda x: modelo.clear())
        self.get_ipbutton.connect("clicked", self.__get_ip)
        self.last_message = 1

        self.__get_x11vnc_path()
        ##
        separator = gtk.SeparatorToolItem()
        separator.props.draw = False
        separator.set_expand(True)

        self.stop_activity = StopButton(self)

        self.toolbar.insert(ActivityToolbarButton(self), -1)
        self.toolbar.insert(gtk.SeparatorToolItem(), -1)
        self.toolbar.insert(self.start_vnc, -1)
        self.toolbar.insert(self.stop_vnc, -1)
        self.toolbar.insert(gtk.SeparatorToolItem(), -1)
        self.toolbar.insert(self.get_ipbutton, -1)
        self.toolbar.insert(self.clear_model, -1)
        self.toolbar.insert(separator, -1)
        self.toolbar.insert(self.stop_activity, -1)

        self.messages_scroll = gtk.ScrolledWindow()
        self.messages_scroll.set_policy(gtk.POLICY_AUTOMATIC,
                                        gtk.POLICY_AUTOMATIC)
        self.messages_scroll.add_with_viewport(self.messages)

        self.set_toolbar_box(self.toolbarbox)
        self.set_canvas(self.messages_scroll)

        self.show_all()
        gobject.timeout_add(100, self.__check_is_on)

    def __check_is_on(self):
        pid = commands.getoutput("pidof x11vnc")
        if self.start_vnc.get_active() and pid == "" and self.isrunning:
            self.showed_message_stop = True
            self.stop_vnc.set_active(True)
            self.start_vnc.set_active(False)
            self.showed_message_start = False

            color = gtk.gdk.color_parse("dark red")
            self.messages.get_model().insert(self.last_message, [
                time.strftime("\n<b>%H:%M:%S</b>\n"),
                ("\n<b>It has stopped unexpectedly the server..</b>\n"), color
            ])
            self.last_message += 1

        return True

    def __get_x11vnc_path(self):
        system = platform.machine()
        color = gtk.gdk.color_parse("dark red")
        if os.path.exists("/usr/bin/x11vnc"):
            self.path = "/usr/bin/x11vnc"
            message = _("PATH: %s") % self.path
        else:
            if "arm" in system:
                self.path = os.path.join(activity.get_bundle_path(), "bin",
                                         "arm", "x11vnc")
            elif "64" in system:
                self.path = os.path.join(activity.get_bundle_path(), "bin",
                                         "x64", "x11vnc")
            else:
                self.path = os.path.join(activity.get_bundle_path(), "bin",
                                         "i586", "x11vnc")

            os.environ["LD_LIBRARY_PATH"] = self.path.replace("x11vnc", "lib/")
            message = _("PATH: %s") % self.path

        self.messages.get_model().insert(self.last_message, [
            time.strftime("\n<b>%H:%M:%S</b>\n"), "<b>" + message + "</b>",
            color
        ])
        self.last_message += 1

    def __start_vnc(self, widget):
        def servidor():
            commands.getoutput(self.path)

        Thread(target=servidor).start()

        if not self.showed_message_start:
            self.showed_message_start = True
            pass
        else:
            return

        self.showed_message_stop = False
        self.isrunning = True
        color = gtk.gdk.color_parse("green")
        self.messages.get_model().insert(self.last_message, [
            time.strftime("\n<b>%H:%M:%S</b>\n"),
            ("\n<b>VNC server is started</b>\n"), color
        ])
        self.last_message += 1

    def __stop_vnc(self, widget):

        if not self.showed_message_stop:
            self.showed_message_stop = True
            pass
        else:
            return

        self.showed_message_start = False
        self.pid_nuevo = commands.getoutput("pidof x11vnc")
        color = gtk.gdk.color_parse('red')

        os.system("kill " + self.pid_nuevo)

        self.messages.get_model().insert(self.last_message, [
            time.strftime("\n<b>%H:%M:%S</b>\n"),
            ("\n<b>The VNC server is now stopped.</b>\n"), color
        ])
        self.last_message += 1

    def close(self):
        self.isrunning = False
        pid = commands.getoutput("pidof x11vnc")
        os.system("kill " + pid)
        self.destroy()

    def __get_ip(self, widget):
        system = platform.platform()
        if "olpc" in system:
            target = "eth0"
        else:
            target = "wlan0"

        ifconfig = "/sbin/ifconfig"
        cmd = "%s %s" % (ifconfig, target)
        output = commands.getoutput(cmd)
        error = _("No wireless connection.")
        ip = error
        inet = output.find('inet')
        if inet >= 0:
            start = inet + len('inet')
            end = output.find(" ", start + 1)
            ip = output[start:end]
        else:
            ip = error

        if ip == _("No wireless connection."):
            mensaje = error
        else:
            ip = ip.replace(":", "")
            ip = ip.replace("addr", "")
            ip = ip.replace(" ", "")
            mensaje = "IP: " + ip
        color = gtk.gdk.color_parse("dark blue")
        self.messages.get_model().insert(self.last_message, [
            time.strftime("\n<b>%H:%M:%S</b>\n"), "\n<b>" + mensaje + "</b>\n",
            color
        ])

        self.last_message += 1
    def __init__(self, handle):
        activity.Activity.__init__(self, handle)

        self.max_participants = 1

        # Canvas
        canvas = Canvas(self)
        self.set_canvas(canvas)

        self._download_list = canvas.gtk_list.download_list

        # Toolbars
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        toolbarbox.toolbar.insert(activity_button, 0)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        # Switch
        store_list = RadioToolButton()
        store_list.set_active(True)
        store_list.props.icon_name = 'view-list'
        store_list.connect("clicked", canvas.switch_to_list)
        store_list.set_tooltip(_("Show the search list"))
        toolbarbox.toolbar.insert(store_list, -1)

        downloads_list = RadioToolButton()
        downloads_list.connect("clicked", canvas.switch_to_downloads_list)
        downloads_list.set_tooltip(_("Show the downloads list"))
        downloads_list.props.group = store_list

        self.downloads_icon = DownloadsIcon()
        downloads_list.set_icon_widget(self.downloads_icon)

        toolbarbox.toolbar.insert(downloads_list, -1)

        self.store_list = store_list
        self.downloads_list = downloads_list

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        # Search
        search_entry = iconentry.IconEntry()
        search_entry.set_size_request(gtk.gdk.screen_width() / 4, -1)
        search_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY,
                                        'system-search')
        search_entry.connect('activate', canvas.gtk_list.search)
        search_entry.connect('activate', lambda w: canvas.switch_to_list(None))
        search_entry.add_clear_button()
        search_item = gtk.ToolItem()
        search_item.add(search_entry)
        toolbarbox.toolbar.insert(search_item, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)
        self.show_all()

        canvas.set_page(0)
Exemple #15
0
    def __init__(self, handle):

        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # CHART_OPTIONS

        self.x_label = ""
        self.y_label = ""
        self.chart_color = utils.get_user_fill_color('str')
        self.chart_line_color = utils.get_user_stroke_color('str')
        self.current_chart = None
        self.charts_area = None
        self.chart_data = []

        # TOOLBARS
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_btn_toolbar = activity_button.page

        activity_btn_toolbar.title.connect('changed', self._set_chart_title)

        save_as_image = ToolButton("save-as-image")
        save_as_image.connect("clicked", self._save_as_image)
        save_as_image.set_tooltip(_("Save as image"))
        activity_btn_toolbar.insert(save_as_image, -1)

        save_as_image.show()

        toolbarbox.toolbar.insert(activity_button, 0)

        import_freespace = ToolButton("import-freespace")
        import_freespace.connect("clicked", self.__import_freespace_cb)
        import_freespace.set_tooltip(_("Read Freespace data"))
        toolbarbox.toolbar.insert(import_freespace, -1)
        import_freespace.show()

        import_journal = ToolButton('import-journal')
        import_journal.connect('clicked', self.__import_journal_cb)
        import_journal.set_tooltip(_('Read Journal data'))
        toolbarbox.toolbar.insert(import_journal, -1)
        import_journal.show()

        import_turtle = ToolButton('import-turtle')
        import_turtle.connect('clicked', self.__import_turtle_cb)
        import_turtle.set_tooltip(_('Read Turtle data'))
        toolbarbox.toolbar.insert(import_turtle, -1)
        import_turtle.show()

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        add_vbar_chart = RadioToolButton()
        add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar")
        add_vbar_chart.set_tooltip(_("Vertical Bar Chart"))
        add_vbar_chart.props.icon_name = "vbar"
        charts_group = add_vbar_chart
        toolbarbox.toolbar.insert(add_vbar_chart, -1)

        add_hbar_chart = RadioToolButton()
        add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar")
        add_hbar_chart.set_tooltip(_("Horizontal Bar Chart"))
        add_hbar_chart.props.icon_name = "hbar"
        add_hbar_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_hbar_chart, -1)

        add_pie_chart = RadioToolButton()
        add_pie_chart.connect("clicked", self._add_chart_cb, "pie")
        add_pie_chart.set_tooltip(_("Pie Chart"))
        add_pie_chart.props.icon_name = "pie"
        add_pie_chart.props.group = charts_group
        add_pie_chart.set_active(True)
        toolbarbox.toolbar.insert(add_pie_chart, -1)

        self.chart_type_buttons = [add_vbar_chart,
                                   add_hbar_chart,
                                   add_pie_chart]

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.connect("clicked", self.__fullscreen_cb)

        toolbarbox.toolbar.insert(fullscreen_btn, -1)

        charthelp.create_help(toolbarbox.toolbar)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)

        # CANVAS
        paned = gtk.HPaned()
        box = gtk.VBox()
        self.box = box

        # Set the info box width to 1/3 of the screen:
        def size_allocate_cb(widget, allocation):
            paned.disconnect(self._setup_handle)
            box_width = allocation.width / 3
            box.set_size_request(box_width, -1)

        self._setup_handle = paned.connect('size_allocate',
                    size_allocate_cb)

        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.labels_and_values = ChartData(self)
        scroll.add(self.labels_and_values)

        self.labels_and_values.connect("label-changed", self._label_changed)
        self.labels_and_values.connect("value-changed", self._value_changed)

        box.pack_start(scroll, True, True, 0)

        paned.add1(box)

        # CHARTS AREA

        eventbox = gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size_allocate', self._chart_size_allocate)

        eventbox.modify_bg(gtk.STATE_NORMAL, _WHITE)

        eventbox.add(self.charts_area)
        paned.add2(eventbox)

        self.set_canvas(paned)

        self.show_all()
Exemple #16
0
    def __init__(self, handle):

        activity.Activity.__init__(self, handle, True)

        self.max_participants = 1

        # CHART_OPTIONS

        self.x_label = ""
        self.y_label = ""
        self.chart_color = utils.get_user_fill_color('str')
        self.chart_line_color = utils.get_user_stroke_color('str')
        self.current_chart = None
        self.charts_area = None
        self.chart_data = []

        # TOOLBARS
        toolbarbox = ToolbarBox()

        activity_button = ActivityToolbarButton(self)
        activity_btn_toolbar = activity_button.page

        activity_btn_toolbar.title.connect('changed', self._set_chart_title)

        save_as_image = ToolButton("save-as-image")
        save_as_image.connect("clicked", self._save_as_image)
        save_as_image.set_tooltip(_("Save as image"))
        activity_btn_toolbar.insert(save_as_image, -1)

        save_as_image.show()

        import_stopwatch = ToolButton("import-stopwatch")
        import_stopwatch.connect("clicked", self.__import_stopwatch_cb)
        import_stopwatch.set_tooltip(_("Read StopWatch data"))
        activity_btn_toolbar.insert(import_stopwatch, -1)

        import_stopwatch.show()

        import_measure = ToolButton("import-measure")
        import_measure.set_tooltip(_("Read Measure data"))

        if utils.get_channels() == 1:
            import_measure.connect("clicked", self.__import_measure_cb, 1)

        else:
            import_measure.connect("clicked", self._measure_btn_clicked)
            self._create_measure_palette(import_measure)

        activity_btn_toolbar.insert(import_measure, -1)

        import_measure.show()

        activity_btn_toolbar.keep.hide()

        toolbarbox.toolbar.insert(activity_button, 0)

        add_v = ToolButton("row-insert")
        add_v.connect("clicked", self._add_value)
        add_v.set_tooltip(_("Add a value"))

        toolbarbox.toolbar.insert(add_v, -1)

        remove_v = ToolButton("row-remove")
        remove_v.connect("clicked", self._remove_value)
        remove_v.set_tooltip(_("Remove the selected value"))

        toolbarbox.toolbar.insert(remove_v, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        add_vbar_chart = RadioToolButton()
        add_vbar_chart.connect("clicked", self._add_chart_cb, "vbar")
        add_vbar_chart.set_tooltip(_("Vertical Bar Chart"))
        add_vbar_chart.props.icon_name = "vbar"
        charts_group = add_vbar_chart

        toolbarbox.toolbar.insert(add_vbar_chart, -1)

        add_hbar_chart = RadioToolButton()
        add_hbar_chart.connect("clicked", self._add_chart_cb, "hbar")
        add_hbar_chart.set_tooltip(_("Horizontal Bar Chart"))
        add_hbar_chart.props.icon_name = "hbar"
        add_hbar_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_hbar_chart, -1)

        add_line_chart = RadioToolButton()
        add_line_chart.connect("clicked", self._add_chart_cb, "line")
        add_line_chart.set_tooltip(_("Line Chart"))
        add_line_chart.props.icon_name = "line"
        add_line_chart.props.group = charts_group
        toolbarbox.toolbar.insert(add_line_chart, -1)

        add_pie_chart = RadioToolButton()
        add_pie_chart.connect("clicked", self._add_chart_cb, "pie")
        add_pie_chart.set_tooltip(_("Pie Chart"))
        add_pie_chart.props.icon_name = "pie"
        add_pie_chart.props.group = charts_group
        add_pie_chart.set_active(True)
        toolbarbox.toolbar.insert(add_pie_chart, -1)

        self.chart_type_buttons = [
            add_vbar_chart, add_hbar_chart, add_line_chart, add_pie_chart
        ]

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        options_button = ToolbarButton(icon_name='preferences-system')
        options_toolbar = gtk.Toolbar()

        self.chart_color_btn = ColorToolButton()
        self.chart_color_btn.set_color(_COLOR1)
        self.chart_color_btn.set_title(_("Chart Color"))
        self.chart_color_btn.connect('notify::color', self._set_chart_color)
        options_toolbar.insert(self.chart_color_btn, -1)

        self.line_color_btn = ColorToolButton()
        self.line_color_btn.set_color(_COLOR2)
        self.line_color_btn.set_title(_("Line Color"))
        self.line_color_btn.connect('notify::color',
                                    self._set_chart_line_color)
        options_toolbar.insert(self.line_color_btn, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        options_toolbar.insert(separator, -1)

        h_label_icon = Icon(icon_name="hlabel")
        h_label_tool_item = gtk.ToolItem()
        h_label_tool_item.add(h_label_icon)
        options_toolbar.insert(h_label_tool_item, -1)

        self.h_label = Entry(_("Horizontal label..."))
        self.h_label.entry.connect("changed", self._set_h_label)
        options_toolbar.insert(self.h_label, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(False)
        options_toolbar.insert(separator, -1)

        v_label_icon = Icon(icon_name="vlabel")
        v_label_tool_item = gtk.ToolItem()
        v_label_tool_item.add(v_label_icon)
        options_toolbar.insert(v_label_tool_item, -1)

        self.v_label = Entry(_("Vertical label..."))
        self.v_label.entry.connect("changed", self._set_v_label)
        options_toolbar.insert(self.v_label, -1)

        options_button.props.page = options_toolbar
        options_toolbar.show_all()

        toolbarbox.toolbar.insert(options_button, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(True)
        separator.set_expand(False)
        toolbarbox.toolbar.insert(separator, -1)

        fullscreen_btn = ToolButton('view-fullscreen')
        fullscreen_btn.set_tooltip(_('Fullscreen'))
        fullscreen_btn.connect("clicked", self.__fullscreen_cb)

        toolbarbox.toolbar.insert(fullscreen_btn, -1)

        separator = gtk.SeparatorToolItem()
        separator.set_draw(False)
        separator.set_expand(True)
        toolbarbox.toolbar.insert(separator, -1)

        simplegraphhelp.create_help(toolbarbox.toolbar)

        stopbtn = StopButton(self)
        toolbarbox.toolbar.insert(stopbtn, -1)

        self.set_toolbar_box(toolbarbox)

        # CANVAS
        paned = gtk.HPaned()
        box = gtk.VBox()
        self.box = box

        # Set the info box width to 1/3 of the screen:
        def size_allocate_cb(widget, allocation):
            paned.disconnect(self._setup_handle)
            box_width = allocation.width / 3
            box.set_size_request(box_width, -1)

        self._setup_handle = paned.connect('size_allocate', size_allocate_cb)

        scroll = gtk.ScrolledWindow()
        scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.labels_and_values = ChartData(self)
        scroll.add(self.labels_and_values)

        self.labels_and_values.connect("label-changed", self._label_changed)
        self.labels_and_values.connect("value-changed", self._value_changed)

        box.pack_start(scroll, True, True, 0)

        paned.add1(box)

        # CHARTS AREA

        eventbox = gtk.EventBox()
        self.charts_area = ChartArea(self)
        self.charts_area.connect('size_allocate', self._chart_size_allocate)

        eventbox.modify_bg(gtk.STATE_NORMAL, _WHITE)

        eventbox.add(self.charts_area)
        paned.add2(eventbox)

        self.set_canvas(paned)

        self.show_all()
Exemple #17
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)
Exemple #18
0
class GeoToolbar(gtk.Toolbar):
    """
    Tools which interacts with the currently chosen view.

    This toolbar is meant general: General map tools can be enabled. The
    toolbar serves as controller. Because you use a specific geo you have
    to wire specific functionality to the common tools offered by this toolbar.

    Tools you may want to enable:
    ===========     ==========================
    enable_goto_current_position
                                   User wants to center map over current
                                   position.

    toggle_crosslines
                                   User wants to show crosslines.

    navigation
                                   User wants to navigate the map. Includes
                                   buttons for NESW.

    zoom-in
                                   User wants to zoom-in the current map view.

    zoom-out
                                   User wants to zoom-out the current map view.

    zoom-bestfit
                                   User wants to zoom-in the current map view.
    ===========     ==========================

    Enable one of these tools by calling the appropriate method with your
    custom callback method before adding the toolbar to the toolbox.
    """
    title = _('Map tools')
    radio_show_own_pos_btn = None
    radio_show_all_pos_btn = None

    def __init__(self, view, name=None):
        """
        Creates general toolbar where general map tools can be enabled.

        @param name: The name of the toolbar.
        """
        gtk.Toolbar.__init__(self)
        self.set_property('can-focus', False)
        self.view = view
        if name:
            self.name = name
            self._logger = logging.getLogger(name)
        else:
            self._logger = logging.getLogger('geo.GeoToolbar')
        self._logger.setLevel(constants.LOG_LEVEL)

        # remove predefined key bindings
        gtk.binding_entry_remove(self, gtk.keysyms.Left, 0)
        gtk.binding_entry_remove(self, gtk.keysyms.Right, 0)
        gtk.binding_entry_remove(self, gtk.keysyms.Up, 0)
        gtk.binding_entry_remove(self, gtk.keysyms.Down, 0)
        gtk.binding_entry_remove(self, gtk.keysyms.plus, 0)
        gtk.binding_entry_remove(self, gtk.keysyms.minus, 0)

        self.callbacks = {}
        self.connect('key-press-event', self.key_pressed_cb, self.callbacks)

        self.show_no_positions = RadioToolButton()
        icon_name = os.path.join(constants.ICON_PATH, "show-no-positions.svg")
        icon = utils.load_svg_image(icon_name, None, None, BTN_ICON_SIZE)
        img = gtk.image_new_from_pixbuf(icon)
        self.show_no_positions.set_icon_widget(img)
        self.show_no_positions.set_tooltip(_('Show no players.'))

    def enable_show_own_position(self, view):
        """
        Shows the only the own position on the map.
        """
        self.radio_show_own_pos_btn = RadioToolButton(group=self.show_no_positions)
        (fill, stroke) = ('#ffffff', '#000000') # black/white explicit
        buddy_icon = utils.get_xo_icon(stroke, fill, BTN_ICON_SIZE)
        img = gtk.image_new_from_pixbuf(buddy_icon)
        self.radio_show_own_pos_btn.set_icon_widget(img)
        self.radio_show_own_pos_btn.set_tooltip(_('Show only me.'))
        self.radio_show_own_pos_btn.connect('clicked', view.radio_show_own_position_cb)
        self.insert(self.radio_show_own_pos_btn, -1)
        self.radio_show_own_pos_btn.show_all()
        if self.radio_show_all_pos_btn:
            self.show_no_positions.connect("clicked", view.radio_show_no_positions_cb)
            self.show_no_positions.show_all()
            self.insert(self.show_no_positions, -1)

    def enable_show_all_positions(self, view):
        """
        Shows the position of all players participating the game.
        """
        self.radio_show_all_pos_btn = RadioToolButton(group=self.show_no_positions)
        icon_name = os.path.join(constants.ICON_PATH , 'show-all-players.svg')
        icon = utils.load_svg_image(icon_name, None, None, BTN_ICON_SIZE)
        img = gtk.image_new_from_pixbuf(icon)
        self.radio_show_all_pos_btn.set_icon_widget(img)
        self.radio_show_all_pos_btn.set_tooltip(_('Show all players.'))
        self.radio_show_all_pos_btn.connect('clicked', view.radio_show_all_position_cb)
        self.insert(self.radio_show_all_pos_btn, -1)
        self.radio_show_all_pos_btn.show_all()
        if self.radio_show_own_pos_btn:
            self.show_no_positions.connect("clicked", view.radio_show_no_positions_cb)
            self.show_no_positions.show_all()
            self.insert(self.show_no_positions, -1)
            self.radio_show_all_pos_btn.set_active(True)

    def enable_center_current_position(self, on_center_on_current_position):
        """
        Enables tool to set the map center to current lon/lat position.

        @param on_goto_current_position: The callback function to be called when
        user wants to center the map to current position.
        """
        goto_current_pos_btn = ToggleToolButton('goto-current-pos')
        goto_current_pos_btn.set_tooltip(_('Center map on my position.'))
        goto_current_pos_btn.connect('clicked', on_center_on_current_position)
        goto_current_pos_btn.set_active(GeoCanvas._CENTER_MAP)
        goto_current_pos_btn.show()
        self.insert(goto_current_pos_btn, -1)

    def enable_toggle_crosslines(self, view):
        """
        Enables tool to toggle crosslines.

        @param view: The view for which the crosslines shall be displayed.
        """
        toggle_crossline_btn = ToggleToolButton('toggle-crosslines')
        toggle_crossline_btn.set_tooltip(_('Show crossline.'))
        toggle_crossline_btn.set_active(GeoCanvas._CROSSLINES)
        toggle_crossline_btn.connect('clicked', view.toggle_crossline_cb)
        toggle_crossline_btn.show()
        self.insert(toggle_crossline_btn, -1)

    def enable_zoom(self, zoom_callbacks):
        """
        Enables tools to zoom the map via buttons.

        @param zoom_callbacks: A dict containing zoom callbacks:
                ===========  =============
                zoom_callbacks['zoom_in']   A callback to zoom in

                zoom_callbacks['zoom_out']  A callback to zoom out
                ===========  =============
        """
        self.zoom_in_btn = ToolButton('zoom-in')
        self.zoom_in_btn.set_tooltip(_('Zoom in.'))
        self.zoom_in_btn.connect('clicked', zoom_callbacks['zoom_in'])
        self.zoom_in_btn.show()
        self.insert(self.zoom_in_btn, -1)

        self.zoom_out_btn = ToolButton('zoom-out')
        self.zoom_out_btn.set_tooltip(_('Zoom out.'))
        self.zoom_out_btn.connect('clicked',  zoom_callbacks['zoom_out'])
        self.zoom_out_btn.show()
        self.insert(self.zoom_out_btn, -1)

        self.callbacks.update(zoom_callbacks)

    def enable_zoom_bestfit(self, on_zoom_bestfit):
        """
        Enables zoom-to-best-fit support on this toolbar.

        @param on_zoom_bestfit: The callback function to be called when user
        wants to zoom to best extent.
        """
        zoom_best_fit_btn = ToolButton('zoom-best-fit')
        zoom_best_fit_btn.set_tooltip(_('Zoom best fitting extent.'))
        zoom_best_fit_btn.connect('clicked', on_zoom_bestfit)
        zoom_best_fit_btn.show()
        self.insert(zoom_best_fit_btn, -1)

    def enable_navigation(self, nav_callbacks):
        """
        Enables tools to navigate the map via buttons.

        @param nav_callbacks: A dict containing navigation callbacks:
                ===========  =============
                nav_callbacks['west']   A callback to step west

                nav_callbacks['north']   A callback to step north

                nav_callbacks['south']   A callback to step south

                nav_callbacks['east']   A callback to step east
                ===========  =============
        """
        self._enable_step_west(nav_callbacks['west'])
        self._enable_step_north(nav_callbacks['north'])
        self._enable_step_south(nav_callbacks['south'])
        self._enable_step_east(nav_callbacks['east'])
        self.callbacks.update(nav_callbacks)

    def enable_custom_Button(self, button):
        """
        Inserts a custom button to the map toolbar.

        Consider to use it only, if it does not make much sense to place
        the button in its own toolbar (e.g. if there will be only one
        button, which might an extra toolbar dispensable).
        """
        self.insert(button, -1)

    def key_pressed_cb(self, widget, event, callbacks):
        """
        Callback handles all incoming keyevents and calls the appropriate
        callback-method.
        """
        keyname = gtk.gdk.keyval_name(event.keyval)
        #self._logger.debug('\'%s\' key pressed' % keyname)
        if(keyname in ['KP_Up']): # up
            self.set_focus_child(self.step_north_btn)
            callbacks['north'](None)
        elif(keyname in ['KP_Down']): # down
            self.set_focus_child(self.step_south_btn)
            callbacks['south'](None)
        elif(keyname in ['KP_Left']): #left
            self.set_focus_child(self.step_west_btn)
            callbacks['west'](None)
        elif(keyname in ['KP_Right']): #right
            self.set_focus_child(self.step_east_btn)
            callbacks['east'](None)
        elif(keyname in ['plus', 'KP_Add', 'KP_Page_Up']): # zoom in
            self.set_focus_child(self.zoom_in_btn)
            callbacks['zoom_in'](None)
        elif(keyname in ['minus', 'KP_Substract', 'KP_Page_Down']): # zoom out
            self.set_focus_child(self.zoom_out_btn)
            callbacks['zoom_out'](None)
        if self.view._CROSSLINES:
            self.view.motion_crosslines(self.view.fixed)

    def _enable_step_north(self, on_step_north):
        """
        Enables button to step north.

        @param on_step_north: The callback function to be called when the user
        wants to step north.
        """
        self.step_north_btn = ToolButton('step-north')
        self.step_north_btn.set_tooltip(_('Move North.'))
        self.step_north_btn.connect('clicked', on_step_north)
        self.step_north_btn.show()
        self.insert(self.step_north_btn, -1)

    def _enable_step_east(self, on_step_east):
        """
        Enables button to step east.

        @param on_step_east: The callback function to be called when the user
        wants to step east.
        """
        self.step_east_btn = ToolButton('step-east')
        self.step_east_btn.set_tooltip(_('Move East.'))
        self.step_east_btn.connect('clicked', on_step_east)
        self.step_east_btn.show()
        self.insert(self.step_east_btn, -1)

    def _enable_step_south(self, on_step_south):
        """
        Enables button to step south.

        @param on_step_south: The callback function to be called when the user
        wants to step south.
        """
        self.step_south_btn = ToolButton('step-south')
        self.step_south_btn.set_tooltip(_('Move South.'))
        self.step_south_btn.connect('clicked', on_step_south)
        self.step_south_btn.show()
        self.insert(self.step_south_btn, -1)

    def _enable_step_west(self, on_step_west):
        """
        Enables button to step west.

        @param on_step_west: The callback function to be called when the user
        wants to step west.
        """
        self.step_west_btn = ToolButton('step-west')
        self.step_west_btn.set_tooltip(_('Move West.'))
        self.step_west_btn.connect('clicked', on_step_west)
        self.step_west_btn.show()
        self.insert(self.step_west_btn, -1)