[the-board] [things] Add voice recording support to SoundThing
- From: Lucas Rocha <lucasr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [the-board] [things] Add voice recording support to SoundThing
- Date: Thu, 6 Jan 2011 23:03:37 +0000 (UTC)
commit d5b367b01d0d3526f821cf022fa7861f08b81398
Author: Lucas Rocha <lucasr gnome org>
Date: Thu Jan 6 21:29:39 2011 +0000
[things] Add voice recording support to SoundThing
data/things/Makefile.am | 2 +
data/things/sound/caption-border-recording.png | Bin 0 -> 251 bytes
data/things/sound/stop-border.png | Bin 0 -> 634 bytes
data/things/sound/style.css | 17 +++
src/js/ui/things/sound.js | 164 +++++++++++++++++++++++-
5 files changed, 178 insertions(+), 5 deletions(-)
---
diff --git a/data/things/Makefile.am b/data/things/Makefile.am
index 9d7b763..d923681 100644
--- a/data/things/Makefile.am
+++ b/data/things/Makefile.am
@@ -23,11 +23,13 @@ sounddir = $(thingsdir)/sound
dist_sound_DATA = \
sound/caption-border.png \
+ sound/caption-border-recording.png \
sound/cassete.png \
sound/cassete-spool.png \
sound/sound-controls-bg.png \
sound/sound-progress-bar-bar.png \
sound/sound-progress-bar-bg.png \
+ sound/stop-border.png \
sound/style.css
videodir = $(thingsdir)/video
diff --git a/data/things/sound/caption-border-recording.png b/data/things/sound/caption-border-recording.png
new file mode 100644
index 0000000..afedf53
Binary files /dev/null and b/data/things/sound/caption-border-recording.png differ
diff --git a/data/things/sound/stop-border.png b/data/things/sound/stop-border.png
new file mode 100644
index 0000000..bdcadbc
Binary files /dev/null and b/data/things/sound/stop-border.png differ
diff --git a/data/things/sound/style.css b/data/things/sound/style.css
index 89b2704..081c416 100644
--- a/data/things/sound/style.css
+++ b/data/things/sound/style.css
@@ -31,6 +31,15 @@ MxButton#sound-thing-play-button:checked {
-mx-icon-name: pause;
}
+MxButton#sound-thing-stop-button {
+ background-color: none;
+ border-image: url('stop-border.png') 4 4 4 4;
+ padding: 7px 14px 3px 14px;
+ font-family: "Action Man";
+ font-size: 16;
+ color: white;
+}
+
TbBox#sound-thing-sound-border-box {
border-image: none;
background-color: none;
@@ -38,6 +47,14 @@ TbBox#sound-thing-sound-border-box {
TbBox#sound-thing-caption-box {
border-image: url('caption-border.png') 4 4 4 4;
+}
+
+TbBox#sound-thing-caption-box-recording {
+ border-image: url('caption-border-recording.png') 4 4 4 4;
+}
+
+TbBox#sound-thing-caption-box,
+TbBox#sound-thing-caption-box-recording {
padding: 8px 5px 3px 5px;
}
diff --git a/src/js/ui/things/sound.js b/src/js/ui/things/sound.js
index dc3c37c..7de7893 100644
--- a/src/js/ui/things/sound.js
+++ b/src/js/ui/things/sound.js
@@ -7,6 +7,7 @@ const Tweener = imports.tweener.tweener;
// gi imports
const Tb = imports.gi.Tb;
const Clutter = imports.gi.Clutter;
+const GIO = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Gtk = imports.gi.Gtk;
const Mx = imports.gi.Mx;
@@ -30,6 +31,9 @@ const _CASSETE_IMAGE = Path.THINGS_DATA_DIR + "sound/cassete.png";
const _SHOW_BUTTON_BOX_TIME = 0.5;
+const _CAPTION_BOX_STYLE_NORMAL = "sound-thing-caption-box";
+const _CAPTION_BOX_STYLE_RECORDING = "sound-thing-caption-box-recording";
+
function SoundThing(args) {
this._init(args);
}
@@ -43,6 +47,11 @@ SoundThing.prototype = {
args.content = this;
args.canResize = false;
+ // Storing voice messages in the music directory for now as, apparently,
+ // there's no standard location for sound files
+ let musicDir = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_MUSIC);
+ this._targetVoicePath = musicDir + "/The Board/";
+
this._style = new Mx.Style();
this._style.load_from_file(STYLE);
@@ -190,7 +199,7 @@ SoundThing.prototype = {
new Tb.Box({ orientation: Tb.BoxOrientation.HORIZONTAL,
xAlign: Tb.BoxAlignment.FILL,
yAlign: Tb.BoxAlignment.FILL,
- name: "sound-thing-caption-box" });
+ name: _CAPTION_BOX_STYLE_NORMAL });
this._captionBox.set_style(this._style);
@@ -256,6 +265,8 @@ SoundThing.prototype = {
return;
}
+ this._maybeDeleteVoiceFile();
+
this._soundFilename = soundFilename;
if (this._soundFilename) {
@@ -332,6 +343,131 @@ SoundThing.prototype = {
false /* not from state*/);
},
+ _ensureTargetVoiceDir : function() {
+ try {
+ let targetDir = GIO.file_new_for_path(this._targetVoicePath);
+
+ // FIXME: we should not be creating this directory
+ // synchronously
+ targetDir.make_directory_with_parents(null);
+ } catch(e) {
+ }
+ },
+
+ _generateVoiceFilename : function() {
+ this._ensureTargetVoiceDir();
+
+ let now = new Date();
+
+ let filename = "VoiceMessage-" +
+ now.getFullYear() + "-" +
+ (now.getMonth() + 1) + "-" +
+ now.getDate() + "-" +
+ now.getHours() +
+ now.getMinutes() +
+ now.getSeconds() +
+ now.getMilliseconds() +
+ ".wav";
+
+ return this._targetVoicePath + filename;
+ },
+
+ _startVoiceRecording : function() {
+ if (this._recorder) {
+ return;
+ }
+
+ let filename = this._generateVoiceFilename();
+
+ if (!filename) {
+ return;
+ }
+
+ this._recorder =
+ new Tb.SoundRecorder({ filename: filename });
+
+ this._stopButton =
+ new Mx.Button({ label: Gettext.gettext("Stop"),
+ name: "sound-thing-stop-button" });
+
+ this._stopButton.connect("clicked",
+ Lang.bind(this,
+ this._onStopButtonClicked));
+
+ this._stopButton.set_style(this._style);
+
+ this._contentBox.append(this._stopButton,
+ Tb.BoxPackFlags.FIXED);
+
+ this._contentBox.set_fixed_child_align(this._stopButton,
+ Tb.BoxAlignment.CENTER,
+ Tb.BoxAlignment.END);
+
+ this._recorder.start();
+
+ this._setSpoolsAnimating(true);
+
+ this._captionBox.name = _CAPTION_BOX_STYLE_RECORDING;
+
+ this._stopEditingCaption();
+ this._textBeforeRecording = this._captionLabel.text;
+ this._captionLabel.text = Gettext.gettext("Recording");
+
+ this._updateControlsVisibility();
+ },
+
+ _stopVoiceRecording : function() {
+ if (!this._recorder) {
+ return;
+ }
+
+ this._setSpoolsAnimating(false);
+
+ let soundFilename = this._recorder.filename;
+
+ this._recorder.stop();
+ delete this._recorder;
+
+ this._stopButton.destroy();
+ delete this._stopButton;
+
+ this._captionBox.name = _CAPTION_BOX_STYLE_NORMAL;
+
+ this._captionLabel.text = this._textBeforeRecording;
+ delete this._textBeforeRecording;
+
+ this._updateSoundFilename(soundFilename,
+ true /* avoid autoplaying */);
+
+ this._updateControlsVisibility();
+ },
+
+ _startEditingCaption : function() {
+ this._captionLabel.clutterText.editable = true;
+ this._captionLabel.clutterText.grab_key_focus();
+ },
+
+ _stopEditingCaption : function() {
+ this._captionLabel.clutterText.editable = false;
+ },
+
+ _maybeDeleteVoiceFile : function() {
+ if (!this._soundFilename) {
+ return;
+ }
+
+ let targetDir = GIO.file_new_for_path(this._targetVoicePath);
+
+ let soundFile = GIO.file_new_for_path(this._soundFilename);
+ let parentDir = soundFile.get_parent();
+
+ if (targetDir.equal(parentDir)) {
+ Tb.g_file_delete_async(soundFile, null,
+ function() {},
+ null);
+ }
+ },
+
_updateForSoundLoaded : function() {
this._updateSpinner();
},
@@ -364,7 +500,8 @@ SoundThing.prototype = {
},
_updateControlsVisibility : function() {
- let visible = this._soundFilename &&
+ let visible = !this._recorder &&
+ this._soundFilename &&
(this.hover || this.active);
if (visible) {
@@ -399,6 +536,10 @@ SoundThing.prototype = {
},
_onCaptionTextChanged : function() {
+ if (this._recorder) {
+ return;
+ }
+
this.emit('save');
},
@@ -407,6 +548,11 @@ SoundThing.prototype = {
this._setSpoolsAnimating(this._playButton.toggled);
},
+ _onStopButtonClicked : function() {
+ this._stopVoiceRecording();
+ this._startEditingCaption();
+ },
+
_onProgressBarButtonPressEvent : function(progressBar, event) {
let [eventX, eventY] = event.get_coords();
@@ -451,13 +597,13 @@ SoundThing.prototype = {
},
activate : function() {
- this._captionLabel.clutterText.editable = true;
- this._captionLabel.clutterText.grab_key_focus();
+ this._startEditingCaption();
this._updateControlsVisibility();
},
deactivate : function() {
- this._captionLabel.clutterText.editable = false;
+ this._stopVoiceRecording();
+ this._stopEditingCaption();
this._updateControlsVisibility();
},
@@ -483,6 +629,8 @@ SoundThing.prototype = {
doAction : function(actionName, actionArgs) {
if (actionName == "chooseFile") {
this._updateSoundWithFileChooser();
+ } else if (actionName == "recordVoice") {
+ this._startVoiceRecording();
}
},
@@ -501,6 +649,9 @@ SoundThing.prototype = {
},
destroy : function() {
+ this._maybeDeleteVoiceFile();
+ this._stopVoiceRecording();
+
if (this._soundBox) {
this._soundBox.destroy();
delete this._soundBox;
@@ -544,6 +695,9 @@ function createToolbar(args) {
toolBox.addButton({ label: Gettext.gettext("File"),
actionName: "chooseFile" });
+ toolBox.addButton({ label: Gettext.gettext("Mic"),
+ actionName: "recordVoice" });
+
toolbar.addToolBox(toolBox);
return toolbar;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]