From 3e5ee5c748d751ff1a3ffc346389bd1c454aebea Mon Sep 17 00:00:00 2001 From: flavio Date: Tue, 31 Jul 2012 12:57:19 +0000 Subject: Repairing cairo and removing the network --- diff --git a/activity.py b/activity.py index e3cae54..b9d78b5 100644 --- a/activity.py +++ b/activity.py @@ -35,7 +35,8 @@ from sugar3.graphics.toolbarbox import ToolbarBox from sugar3.activity.widgets import ActivityToolbarButton from sugar3.activity.widgets import StopButton -from shared_activity import SharedActivity +#from shared_activity import SharedActivity +from sugar3.activity import activity from combobox import ComboBox from toolitem import ToolWidget from messenger import Messenger, SERVICE @@ -79,12 +80,15 @@ class CursorFactory: return self.cursors[cur_type] -class SpeakActivity(SharedActivity): +class SpeakActivity(activity.Activity): + def __init__(self, handle): + activity.Activity.__init__(self, handle) + self.notebook = Gtk.Notebook() self.notebook.connect_after('map', self.__map_canvasactivity_cb) - SharedActivity.__init__(self, self.notebook, SERVICE, handle) + #SharedActivity.__init__(self, self.notebook, SERVICE, handle) self._cursor = None self.set_cursor(Gdk.CursorType.LEFT_PTR) @@ -208,6 +212,7 @@ class SpeakActivity(SharedActivity): toolbox.toolbar.insert(StopButton(self), -1) + self.set_canvas(self.notebook) toolbox.show_all() self.toolbar_box = toolbox diff --git a/eye.py b/eye.py index fdb4a4f..2729388 100644 --- a/eye.py +++ b/eye.py @@ -27,55 +27,49 @@ from gi.repository import Gdk from gi.repository import GObject import math - class Eye(Gtk.DrawingArea): + """Eye.""" + def __init__(self, fill_color): Gtk.DrawingArea.__init__(self) - self.frame = 0 - self.blink = False + self.x, self.y = 0, 0 self.fill_color = fill_color - - # listen for clicks - self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK) - self.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK) - self.connect("button_press_event", self._mouse_pressed_cb) - self.connect("button_release_event", self._mouse_released_cb) - - def _mouse_pressed_cb(self, widget, event): - self.blink = True - self.queue_draw() - - def _mouse_released_cb(self, widget, event): - self.blink = False - self.queue_draw() + + self.show_all() def look_at(self, x, y): + """ Look. . .""" + self.x = x self.y = y self.queue_draw() def look_ahead(self): + """ Look. . .""" + self.x = None self.y = None self.queue_draw() # Thanks to xeyes :) def computePupil(self): - a = self.get_allocation() + """pupil.""" + + rect = self.get_allocation() if self.x is None or self.y is None: # look ahead, but not *directly* in the middle - if a.x + a.width / 2 < self.get_allocation().width / 2: - cx = a.width * 0.6 + if rect.x + rect.width / 2 < rect.width / 2: + cx = rect.width * 0.6 else: - cx = a.width * 0.4 - return cx, a.height * 0.6 + cx = rect.width * 0.4 + return cx, rect.height * 0.6 EYE_X, EYE_Y = self.translate_coordinates( - self.get_toplevel(), a.width / 2, a.height / 2) - EYE_HWIDTH = a.width - EYE_HHEIGHT = a.height + self.get_toplevel(), rect.width / 2, rect.height / 2) + EYE_HWIDTH = rect.width + EYE_HHEIGHT = rect.height BALL_DIST = EYE_HWIDTH / 4 dx = self.x - EYE_X @@ -94,64 +88,49 @@ class Eye(Gtk.DrawingArea): dx = dist * cosa dy = dist * sina - return a.width / 2 + dx, a.height / 2 + dy + return rect.width / 2 + dx, rect.height / 2 + dy def do_draw(self, context): - self.frame += 1 - bounds = self.get_allocation() - - eyeSize = min(bounds.width, bounds.height) + rect = self.get_allocation() + + eyeSize = min(rect.width, rect.height) + outlineWidth = eyeSize / 20.0 pupilSize = eyeSize / 10.0 pupilX, pupilY = self.computePupil() - dX = pupilX - bounds.width / 2. - dY = pupilY - bounds.height / 2. + dX = pupilX - rect.width / 2. + dY = pupilY - rect.height / 2. distance = math.sqrt(dX * dX + dY * dY) limit = eyeSize / 2 - outlineWidth * 2 - pupilSize if distance > limit: - pupilX = bounds.width / 2 + dX * limit / distance - pupilY = bounds.height / 2 + dY * limit / distance - - self.context = context - #self.context.set_antialias(cairo.ANTIALIAS_NONE) - - #set a clip region for the expose event. - #This reduces redrawing work (and time) - self.context.rectangle(bounds.x, - bounds.y, - bounds.width, - bounds.height) - self.context.clip() - - # background - self.context.set_source_rgba(*self.fill_color.get_rgba()) - self.context.rectangle(0, 0, bounds.width, bounds.height) - self.context.fill() - + pupilX = rect.width / 2 + dX * limit / distance + pupilY = rect.height / 2 + dY * limit / distance + + context.set_source_rgba(*self.fill_color.get_rgba()) + context.rectangle(0, 0, rect.width, rect.height) + context.fill() + # eye ball - self.context.arc(bounds.width / 2, - bounds.height / 2, - eyeSize / 2 - outlineWidth / 2, - 0, - 360) - self.context.set_source_rgb(1, 1, 1) - self.context.fill() - + context.set_source_rgb(1, 1, 1) + context.arc(rect.width / 2, + rect.height / 2, + eyeSize / 2 - outlineWidth / 2, + 0, 360) + context.fill() + # outline - self.context.set_line_width(outlineWidth) - self.context.arc(bounds.width / 2, - bounds.height / 2, - eyeSize / 2 - outlineWidth / 2, - 0, - 360) - self.context.set_source_rgb(0, 0, 0) - self.context.stroke() - + context.set_source_rgb(0, 0, 0) + context.set_line_width(outlineWidth) + context.arc(rect.width / 2, + rect.height / 2, + eyeSize / 2 - outlineWidth / 2, + 0, 360) + context.stroke() + # pupil - self.context.arc(pupilX, pupilY, pupilSize, 0, 360) - self.context.set_source_rgb(0, 0, 0) - self.context.fill() - - self.blink = False - + context.set_source_rgb(0, 0, 0) + context.arc(pupilX, pupilY, pupilSize, 0, 360) + context.fill() + return True + \ No newline at end of file diff --git a/face.py b/face.py index dec365e..9768157 100644 --- a/face.py +++ b/face.py @@ -42,7 +42,7 @@ logger = logging.getLogger('speak') FACE_PAD = 2 -class Status: +class Status(): def __init__(self): self.voice = voice.defaultVoice() self.pitch = espeak.PITCH_MAX / 2 @@ -52,26 +52,26 @@ class Status: self.mouth = mouth.Mouth def serialize(self): - eyes = {eye.Eye: 1, - glasses.Glasses: 2} + eyes = {eye.Eye: 1, glasses.Glasses: 2} + mouths = {mouth.Mouth: 1, - fft_mouth.FFTMouth: 2, - waveform_mouth.WaveformMouth: 3} + fft_mouth.FFTMouth: 2, + waveform_mouth.WaveformMouth: 3} return cjson.encode({ 'voice': {'language': self.voice.language, - 'name': self.voice.name}, + 'name': self.voice.name}, 'pitch': self.pitch, 'rate': self.rate, 'eyes': [eyes[i] for i in self.eyes], 'mouth': mouths[self.mouth]}) def deserialize(self, buf): - eyes = {1: eye.Eye, - 2: glasses.Glasses} + eyes = {1: eye.Eye, 2: glasses.Glasses} + mouths = {1: mouth.Mouth, - 2: fft_mouth.FFTMouth, - 3: waveform_mouth.WaveformMouth} + 2: fft_mouth.FFTMouth, + 3: waveform_mouth.WaveformMouth} data = cjson.decode(buf) self.voice = voice.Voice(data['voice']['language'], @@ -94,49 +94,40 @@ class Status: class View(Gtk.EventBox): + """Face.""" + def __init__(self, fill_color=style.COLOR_BUTTON_GREY): Gtk.EventBox.__init__(self) + self.status = Status() self.fill_color = fill_color - - self.connect('size-allocate', self._size_allocate_cb) - + self.modify_bg(0, self.fill_color.get_gdk_color()) + self._audio = espeak.AudioGrab() - - # make an empty box for some eyes - self._eyes = None + + self._eyes = [] self._eyebox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) - self._eyebox.show() - - # make an empty box to put the mouth in + self._mouth = None self._mouthbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) - self._mouthbox.show() - - # layout the screen + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) - box.set_homogeneous(False) - box.pack_start(self._eyebox, expand=True, fill=True, padding=0) - box.pack_start(self._mouthbox, expand=True, fill=True, padding=100) - box.set_border_width(0) - self.modify_bg(0, self.fill_color.get_gdk_color()) + + box.pack_start(self._eyebox, True, True, 0) + box.pack_start(self._mouthbox, True, True, 0) + self.add(box) - - self._peding = None - self.connect('map', self.__map_cb) - - self.update() - - def __map_cb(self, widget): - if self._peding: - self.update(self._peding) - self._peding = None + self.show_all() def look_ahead(self): + """ Look. . .""" + if self._eyes: map(lambda e: e.look_ahead(), self._eyes) - + def look_at(self, pos=None): + """ Look. . .""" + if self._eyes: if pos is None: display = Gdk.Display.get_default() @@ -144,54 +135,42 @@ class View(Gtk.EventBox): else: x, y = pos map(lambda e, x=x, y=y: e.look_at(x, y), self._eyes) - + def update(self, status=None): - if not status: - status = self.status - else: - # FIXME: view object has no attribute flags - #if not self.flags() & Gtk.MAPPED: - # self._peding = status - # return - self.status = status - - if self._eyes: - for eye in self._eyes: - self._eyebox.remove(eye) - if self._mouth: - self._mouthbox.remove(self._mouth) - + """ Re packaged the mouth and eyes according to quantity.""" + + if status: self.status = status + + for eye in self._eyes: + self._eyebox.remove(eye) + + for child in self._mouthbox.get_children(): + self._mouthbox.remove(child) + self._eyes = [] - - for i in status.eyes: + for i in self.status.eyes: eye = i(self.fill_color) self._eyes.append(eye) + + for eye in self._eyes: self._eyebox.pack_start(eye, True, True, 0) - eye.show() - self._mouth = status.mouth(self._audio, self.fill_color) - self._mouth.show() - self._mouthbox.add(self._mouth) - - # enable mouse move events so we can track - # the eyes while the mouse is over the mouth - #self._mouth.add_events(gtk.gdk.POINTER_MOTION_MASK) + self._mouth = self.status.mouth(self._audio, self.fill_color) + self._mouthbox.pack_start(self._mouth, True, True, 0) + + self.show_all() def set_voice(self, voice): self.status.voice = voice self.say_notification(voice.friendlyname) def say(self, something): - self._audio.speak(self._peding or self.status, something) + self._audio.speak(self.status, something) def say_notification(self, something): - status = (self._peding or self.status).clone() + status = self.status.clone() status.voice = voice.defaultVoice() self._audio.speak(status, something) def shut_up(self): self._audio.stop_sound_device() - - def _size_allocate_cb(self, widget, allocation): - self._mouthbox.set_size_request(-1, - int(allocation.height / 2.5)) diff --git a/fft_mouth.py b/fft_mouth.py index f91d900..1fae0cf 100644 --- a/fft_mouth.py +++ b/fft_mouth.py @@ -56,9 +56,9 @@ class FFTMouth(Mouth): self.scaleX = "10" self.scaleY = "10" - def processBuffer(self, bounds): - self.param1 = bounds.height / 65536.0 - self.param2 = bounds.height / 2.0 + def processBuffer(self, rect): + self.param1 = rect.height / 65536.0 + self.param2 = rect.height / 2.0 if(self.stop == False): @@ -68,7 +68,7 @@ class FFTMouth(Mouth): self.fftx = fft(self.newest_buffer, 256, -1) self.fftx = self.fftx[0:self.freq_range * 2] - self.draw_interval = bounds.width / (self.freq_range * 2.) + self.draw_interval = rect.width / (self.freq_range * 2.) NumUniquePts = ceil((nfft + 1) / 2) self.buffers = abs(self.fftx) * 0.02 @@ -85,8 +85,8 @@ class FFTMouth(Mouth): temp_val_float = float(self.param1 * i * self.y_mag) +\ self.y_mag_bias_multiplier * self.param2 - if(temp_val_float >= bounds.height): - temp_val_float = bounds.height - 25 + if(temp_val_float >= rect.height): + temp_val_float = rect.height - 25 if(temp_val_float <= 0): temp_val_float = 25 val.append(temp_val_float) @@ -94,44 +94,28 @@ class FFTMouth(Mouth): self.peaks = val def do_draw(self, context): - """This function is the "expose" event - handler and does all the drawing.""" - - bounds = self.get_allocation() - - self.processBuffer(bounds) - - #Create context, disable antialiasing - self.context = context - #self.context.set_antialias(cairo.ANTIALIAS_NONE) - - #set a clip region for the expose event. - #This reduces redrawing work (and time) - self.context.rectangle(bounds.x, - bounds.y, - bounds.width, - bounds.height) - self.context.clip() - + rect = self.get_allocation() + + self.processBuffer(rect) + # background - self.context.set_source_rgba(*self.fill_color.get_rgba()) - self.context.rectangle(0, 0, bounds.width, bounds.height) - self.context.fill() - + context.set_source_rgba(*self.fill_color.get_rgba()) + context.paint() + # Draw the waveform - self.context.set_line_width(min(bounds.height / 10.0, 10)) - self.context.set_source_rgb(0, 0, 0) + context.set_line_width(min(rect.height / 10.0, 10)) + context.set_source_rgb(0, 0, 0) count = 0 for peak in self.peaks: - self.context.line_to(bounds.width / 2 + count, - bounds.height / 2 - peak) + context.line_to(rect.width / 2 + count, + rect.height / 2 - peak) count += self.draw_interval - self.context.stroke() + context.stroke() count = 0 for peak in self.peaks: - self.context.line_to(bounds.width / 2 - count, - bounds.height / 2 - peak) + context.line_to(rect.width / 2 - count, + rect.height / 2 - peak) count += self.draw_interval - self.context.stroke() - + context.stroke() + return True diff --git a/mouth.py b/mouth.py index 1155bb0..693d0ca 100644 --- a/mouth.py +++ b/mouth.py @@ -24,13 +24,14 @@ # This code is a super-stripped down version of the waveform view from Measure from gi.repository import Gtk +from gi.repository import Gdk from struct import unpack import numpy.core class Mouth(Gtk.DrawingArea): + def __init__(self, audioSource, fill_color): - Gtk.DrawingArea.__init__(self) self.buffers = [] @@ -38,7 +39,9 @@ class Mouth(Gtk.DrawingArea): self.main_buffers = [] self.newest_buffer = [] self.fill_color = fill_color - + + self.show_all() + audioSource.connect("new-buffer", self._new_buffer) def _new_buffer(self, obj, buf): @@ -55,7 +58,7 @@ class Mouth(Gtk.DrawingArea): self.queue_draw() return True - def processBuffer(self, bounds): + def processBuffer(self): if len(self.main_buffers) == 0 or len(self.newest_buffer) == 0: self.volume = 0 else: @@ -63,46 +66,31 @@ class Mouth(Gtk.DrawingArea): # numpy.core.min(self.main_buffers) def do_draw(self, context): - """This function is the "expose" event - handler and does all the drawing.""" - bounds = self.get_allocation() - - self.processBuffer(bounds) - - #Create context, disable antialiasing - self.context = context - #self.context.set_antialias(cairo.ANTIALIAS_NONE) - - # set a clip region for the expose event. - # This reduces redrawing work (and time) - self.context.rectangle(bounds.x, - bounds.y, - bounds.width, - bounds.height) - self.context.clip() - + rect = self.get_allocation() + + self.processBuffer() + # background - self.context.set_source_rgba(*self.fill_color.get_rgba()) - self.context.rectangle(0, 0, bounds.width, bounds.height) - self.context.fill() + context.set_source_rgba(*self.fill_color.get_rgba()) + context.paint() # Draw the mouth volume = self.volume / 30000. - mouthH = volume * bounds.height - mouthW = volume ** 2 * (bounds.width / 2.) + bounds.width / 2. + mouthH = volume * rect.height + mouthW = volume ** 2 * (rect.width / 2.) + rect.width / 2. # T # L R # B - Lx, Ly = bounds.width / 2 - mouthW / 2, bounds.height / 2 - Tx, Ty = bounds.width / 2, bounds.height / 2 - mouthH / 2 - Rx, Ry = bounds.width / 2 + mouthW / 2, bounds.height / 2 - Bx, By = bounds.width / 2, bounds.height / 2 + mouthH / 2 - self.context.set_line_width(min(bounds.height / 10.0, 10)) - self.context.move_to(Lx, Ly) - self.context.curve_to(Tx, Ty, Tx, Ty, Rx, Ry) - self.context.curve_to(Bx, By, Bx, By, Lx, Ly) - self.context.set_source_rgb(0, 0, 0) - self.context.close_path() - self.context.stroke() - + Lx, Ly = rect.width / 2 - mouthW / 2, rect.height / 2 + Tx, Ty = rect.width / 2, rect.height / 2 - mouthH / 2 + Rx, Ry = rect.width / 2 + mouthW / 2, rect.height / 2 + Bx, By = rect.width / 2, rect.height / 2 + mouthH / 2 + context.set_line_width(min(rect.height / 10.0, 10)) + context.move_to(Lx, Ly) + context.curve_to(Tx, Ty, Tx, Ty, Rx, Ry) + context.curve_to(Bx, By, Bx, By, Lx, Ly) + context.set_source_rgb(0, 0, 0) + context.close_path() + context.stroke() + return True diff --git a/waveform_mouth.py b/waveform_mouth.py index 51c47f4..04d2c45 100644 --- a/waveform_mouth.py +++ b/waveform_mouth.py @@ -40,48 +40,32 @@ class WaveformMouth(Mouth): self.y_mag = 0.7 def do_draw(self, context): - """This function is the "expose" - event handler and does all the drawing.""" - - bounds = self.get_allocation() - self.param1 = bounds.height / 65536.0 - self.param2 = bounds.height / 2.0 - - #Create context, disable antialiasing - self.context = context - #self.context.set_antialias(cairo.ANTIALIAS_NONE) - - #set a clip region for the expose event. - #This reduces redrawing work (and time) - self.context.rectangle(bounds.x, - bounds.y, - bounds.width, - bounds.height) - self.context.clip() - + rect = self.get_allocation() + self.param1 = rect.height / 65536.0 + self.param2 = rect.height / 2.0 + # background - self.context.set_source_rgba(*self.fill_color.get_rgba()) - self.context.rectangle(0, 0, bounds.width, bounds.height) - self.context.fill() - + context.set_source_rgba(*self.fill_color.get_rgba()) + context.paint() + # Draw the waveform - self.context.set_line_width(min(bounds.height / 10.0, 10)) + context.set_line_width(min(rect.height / 10.0, 10)) count = 0 buflen = float(len(self.main_buffers)) for value in self.main_buffers: peak = float(self.param1 * value * self.y_mag) +\ self.y_mag_bias_multiplier * self.param2 - - if peak >= bounds.height: - peak = bounds.height + + if peak >= rect.height: + peak = rect.height if peak <= 0: peak = 0 - - x = count / buflen * bounds.width - self.context.line_to(x, bounds.height - peak) - + + x = count / buflen * rect.width + context.line_to(x, rect.height - peak) + count += 1 - self.context.set_source_rgb(0, 0, 0) - self.context.stroke() - + context.set_source_rgb(0, 0, 0) + context.stroke() + return True -- cgit v0.9.1