diff --git a/Mobile/NUI/SpeechToText/LICENSE b/Mobile/NUI/SpeechToText/LICENSE new file mode 100644 index 00000000..4d4d2443 --- /dev/null +++ b/Mobile/NUI/SpeechToText/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Samsung + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/Mobile/NUI/SpeechToText/README.md b/Mobile/NUI/SpeechToText/README.md new file mode 100644 index 00000000..562977f5 --- /dev/null +++ b/Mobile/NUI/SpeechToText/README.md @@ -0,0 +1,29 @@ +# SpeechToText +SpeechToText is a sample application which demonstrates how to record and recognize +sound data using [Tizen STT API](https://docs.tizen.org/application/dotnet/guides/uix/stt/) in NUI. + +### Verified Version +* Tizen.NET : 10.0.0.17614 +* Tizen.NET.SDK : 5.0 + +![Main page](./ScreenShots/mainpage.png) +![Recording](./ScreenShots/recording.png) +![Processing](./ScreenShots/processing.png) +![Result](./ScreenShots/result.png) +![Application Settings](./ScreenShots/settings.png) + +### Features +* Starting/Pausing/Stopping Recognition +* Clearing results +* Settings - Language +* Settings - Recognition type +* Settings - Silence detection +* Settings - Sounds (start, end) + +### Prerequisites +* [Visual Studio](https://www.visualstudio.com/) - Buildtool, IDE +* [Tizen Studio](https://developer.tizen.org/development/tizen-studio/) - Tizen Studio +* [Visual Studio Tools for Tizen](https://docs.tizen.org/application/vstools/install) - Visual Studio plugin for Tizen .NET application development + +### Author +* Feras Hamam (f.hamam@partner.samsung.com) diff --git a/Mobile/NUI/SpeechToText/ScreenShots/mainpage.png b/Mobile/NUI/SpeechToText/ScreenShots/mainpage.png new file mode 100644 index 00000000..3bb6be6d Binary files /dev/null and b/Mobile/NUI/SpeechToText/ScreenShots/mainpage.png differ diff --git a/Mobile/NUI/SpeechToText/ScreenShots/processing.png b/Mobile/NUI/SpeechToText/ScreenShots/processing.png new file mode 100644 index 00000000..cdaec56c Binary files /dev/null and b/Mobile/NUI/SpeechToText/ScreenShots/processing.png differ diff --git a/Mobile/NUI/SpeechToText/ScreenShots/recording.png b/Mobile/NUI/SpeechToText/ScreenShots/recording.png new file mode 100644 index 00000000..80be923f Binary files /dev/null and b/Mobile/NUI/SpeechToText/ScreenShots/recording.png differ diff --git a/Mobile/NUI/SpeechToText/ScreenShots/result.png b/Mobile/NUI/SpeechToText/ScreenShots/result.png new file mode 100644 index 00000000..e2fe9a5a Binary files /dev/null and b/Mobile/NUI/SpeechToText/ScreenShots/result.png differ diff --git a/Mobile/NUI/SpeechToText/ScreenShots/settings.png b/Mobile/NUI/SpeechToText/ScreenShots/settings.png new file mode 100644 index 00000000..b887502b Binary files /dev/null and b/Mobile/NUI/SpeechToText/ScreenShots/settings.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/Controllers/MediaController.cs b/Mobile/NUI/SpeechToText/SpeechToText/Controllers/MediaController.cs new file mode 100644 index 00000000..1ea8749a --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/Controllers/MediaController.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using MediaContent = Tizen.Content.MediaContent; + + +namespace SpeechToText.Controllers +{ + public class MediaController + { + private MediaContent.MediaDatabase _mediaDatabase; + + public MediaController() + { + _mediaDatabase = new MediaContent.MediaDatabase(); + _mediaDatabase.Connect(); + } + + /// + /// Returns a list of sound files (paths) which can be used + /// as start and end sounds for STT client. + /// + /// A list of file names and file paths. + public List GetAvailableStartEndSounds() + { + var result = new List(); + var command = new MediaContent.MediaInfoCommand(_mediaDatabase); + var reader = command.SelectMedia(new MediaContent.SelectArguments() + { + FilterExpression = string.Format( + "{0} IN ('audio/wav', 'audio/x-wav')", + MediaContent.MediaInfoColumns.MimeType), + SortOrder = MediaContent.MediaInfoColumns.DisplayName + " ASC" + }); + result.Add("None"); + while (reader.Read()) + { + MediaContent.AudioInfo info = reader.Current as MediaContent.AudioInfo; + if (info == null) + { + continue; + } + result.Add(info.Path); + } + return result; + } + ~MediaController() + { + _mediaDatabase.Disconnect(); + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/Controllers/SttController.cs b/Mobile/NUI/SpeechToText/SpeechToText/Controllers/SttController.cs new file mode 100644 index 00000000..0695bae6 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/Controllers/SttController.cs @@ -0,0 +1,517 @@ +using System; +using System.Collections.Generic; +using Tizen.Uix.Stt; +using Tizen.Security; +using System.Linq; +using Tizen.Applications; +using System.Threading; +using System.Threading.Tasks; +using ElmSharp; +using Tizen.NUI.Components; + +namespace SpeechToText.Controllers +{ + public class SttController + { + private SttClient _sttClient; + private string _language = null; + private State _state; + private Action _onResultChange; + private Action _onRecordingState; + private Action _onReadyState; + private Action _onCreateState; + private Action _onProcessingState; + private Action _onErrorAlert; + private RecognitionType _recognitionType; + private SilenceDetection _silenceDetection = SilenceDetection.Auto; + private bool _sounds = false; + private string _endSound = null; + private string _startSound = null; + + /// + /// Current STT model state (created, ready, recording, processing). + /// + public State State + { + get => _state; + } + + /// + /// Current STT model recognition type. + /// + public RecognitionType RecognitionType + { + get => _recognitionType; + set => _recognitionType = value; + } + + /// + /// Current STT model silence detection mode. + /// + public SilenceDetection SilenceDetection + { + get => _silenceDetection; + set + { + _silenceDetection = value; + SetSilenceDetection(_silenceDetection); + } + } + + /// + /// Flag indicating if model sounds are on. + /// + public bool Sounds + { + get => _sounds; + set + { + _sounds = value; + } + } + + /// + /// Sound path to start recording. + /// + public string StartSound + { + get => _startSound; + set + { + _startSound = value; + } + } + + /// + /// Sound path to end recording. + /// + public string EndSound + { + get => _endSound; + set + { + _endSound = value; + } + } + + public Action OnProcessingState + { + get => _onProcessingState; + set + { + _onProcessingState = value; + } + } + + public Action OnResultChange + { + set => _onResultChange = value; + } + + public Action OnErrorAlert + { + set => _onErrorAlert = value; + } + + public Action OnReadyState + { + set => _onReadyState = value; + } + + public Action OnCreateState + { + set => _onCreateState = value; + } + + public Action OnRecordingState + { + set => _onRecordingState = value; + } + + /// + /// STT model + /// + private SttClient SttClient + { + get + { + if (_sttClient == null) + CreateSttClient(); + return _sttClient; + } + } + + /// + /// Current STT model language (code). + /// + public string Language + { + get => _language; + set => _language = value; + } + + public SttController() + { + //Initializing the Language to the first on the list + CreateSttClient(); + } + + /// + /// Event when state changes + /// + void SttStateChanged(object sender, StateChangedEventArgs e) + { + _state = e.Current; + switch (_state) + { + case State.Unavailable: + _onCreateState(); + break; + case State.Created: + _onCreateState(); + break; + case State.Ready: + if (Sounds && EndSound != null) + { + SetStopSound(EndSound); + } + _onReadyState(); + _onResultChange(null); + break; + case State.Recording: + _onRecordingState(); + break; + case State.Processing: + _onProcessingState(); + break; + default: + _onCreateState(); + break; + } + } + + /// Event handler + void SttEngineChanged(object sender, EngineChangedEventArgs args) + { + try + { + Language = SttClient.GetSupportedLanguages().FirstOrDefault(""); + } + catch (Exception e) + { + _onErrorAlert("Note", "The engine has been changed, you have to restart the application in order to use it.", true); + Console.WriteLine(e.ToString()); + } + } + + /// + /// Event to recieve the result when it is done. + /// + private void SttRecognitionResult(object sender, RecognitionResultEventArgs e) + { + string result = ""; + foreach (string data in e.Data) + { + result += data; + } + string trimmedResult = result.Trim(); + _onResultChange(trimmedResult); + } + + /// + /// Initializes and prepares the model. + /// + public void CreateSttClient() + { + try + { + if (PrivacyPrivilegeManager.CheckPermission("http://tizen.org/privilege/recorder") == CheckResult.Allow) + { + if (_sttClient == null) + { + _sttClient = new SttClient(); + _sttClient.StateChanged += SttStateChanged; + _sttClient.RecognitionResult += SttRecognitionResult; + _sttClient.EngineChanged += SttEngineChanged; + _sttClient.ErrorOccurred += SttErrorOccured; + } + Language = GetSupportedLanguages().First(); + PrepareSttClient(); + } + } + catch (Exception e) + { + ReleaseResources(); + _onErrorAlert("Something Went Wrong", "The application did not find any supported languages, Please try again.", false); + } + } + + /// + /// Gets a list of the supported languages to check whether the language you want is supported. + /// + public List GetSupportedLanguages() + { + List list = new(); + if (SttClient == null) + return list; + try + { + list = (List)SttClient.GetSupportedLanguages(); + } + catch (Exception e) + { + ReleaseResources(); + _onErrorAlert("Something Went Wrong", "The application did not find any supported languages, Please try again.", false); + } + return list; + } + + /// + /// Gets a list of the supported engines and the selection of current engines. + /// Additional features, such as silence detection and partial result, + /// are provided by specific engines. + /// + public void GetSupportedEngines() + { + if (SttClient == null) + return; + try + { + List supportedEngines = (List)SttClient.GetSupportedEngines(); + } + catch (Exception e) + { + ReleaseResources(); + _onErrorAlert("Something Went Wrong", "The application did not find any supported engines, Please try again.", false); + } + } + + /// + /// Connects the background STT daemon. + /// The state will become ready. + /// + public void PrepareSttClient() + { + try + { + if (State == State.Created && SttClient != null) + { + SttClient.Prepare(); + } + } + catch (Exception e) + { + ReleaseResources(); + _onErrorAlert("An Error Occured", "Something Went Wrong, Please try again!", false); + } + } + + /// + /// Disconnects the background STT daemon. + /// The state will become created. + /// + public void UnprepareSttClient() + { + try + { + if (SttClient != null && State != State.Recording && State != State.Processing) + { + SttClient.Unprepare(); + } + } + catch (Exception e) + { + ReleaseResources(); + _onErrorAlert("An Error Occured", "Something Went Wrong, Please try again!", false); + } + } + + /// + /// Starts the recognition. + /// The state will become recording. + /// + public void Start() + { + try + { + if (State == State.Recording || State == State.Processing) + { + _onErrorAlert("NOTE", "The Application is Currently Processing or Recording your voice!", false); + return; + } + else if (State == State.Created) + { + PrepareSttClient(); + } + if (StartSound != null) + { + SttClient.UnsetStartSound(); + } + + if (EndSound != null) + { + SttClient.UnsetStopSound(); + } + + if (Sounds == true && StartSound != null) + { + SetStartSound(StartSound); + } + SttClient.Start(_language, _recognitionType); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + if (State == State.Processing || State == State.Recording) + return; + _onErrorAlert("An Error Occured", "Something Went Wrong, Please try again!", false); + } + } + + /// + /// Stops the recognition. + /// Locks recognition start untill result are done and + /// the state will become processing, + /// after processing the state will become ready again. + /// + public void Stop() + { + try + { + if (State == State.Recording) + { + SttClient.Stop(); + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + _onErrorAlert("An Error Occured", "Something Went Wrong, the application could not stop the recording.", false); + } + } + + /// + /// Clears recognition result. + /// Unlocks recognition start. + /// The state will become ready again. + /// + public void Cancel() + { + try + { + if (State == State.Recording) + { + SttClient.Cancel(); + } + if (_onResultChange != null && State != State.Processing) + _onResultChange(""); + } + catch (Exception e) + { + _onErrorAlert("Something Went Wrong", "The application could not cancel the recording.", false); + } + } + + /// + /// Detects silence when the sound input from the user ends. + /// If the silence detection is enabled, + /// the STT library stops recognition automatically and sends the result. + /// + private void SetSilenceDetection(SilenceDetection type) + { + try + { + /// Default type is SilenceDetection.Auto + SttClient.SetSilenceDetection(type); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + } + + /// + /// Sets the sound to start recording. Sound file type should be .wav type. + /// If null value is specified, the sound is unset. + /// + /// File path to set. + public void SetStartSound(string filePath) + { + try + { + Console.WriteLine(filePath ?? "null"); + if (filePath == null) + { + SttClient.UnsetStartSound(); + } + else + { + SttClient.SetStartSound(filePath); + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + _onErrorAlert("Something Went Wrong", "Unable to change start sound!", false); + } + } + + /// + /// Sets the sound to stop recording. Sound file type should be .wav type. + /// If null value is specified, the sound is unset. + /// + /// File path to set. + public void SetStopSound(string filePath) + { + try + { + Console.WriteLine(filePath ?? "null"); + if (filePath == null) + { + SttClient.UnsetStopSound(); + } + else + { + SttClient.SetStopSound(filePath); + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + _onErrorAlert("Something Went Wrong", "Unable to change stop sound!", false); + } + } + + /// + /// Event to handle errors(string). + /// + void SttErrorOccured(object sender, ErrorOccurredEventArgs e) + { + Console.WriteLine(e); + _onErrorAlert("Something Went Wrong", "Please try again.", false); + } + + /// + /// Destroys the STT client instance. + /// + public void ReleaseResources() + { + try + { + _sttClient?.Dispose(); + } + catch (Exception e) + { + _onErrorAlert("Something Went Wrong", "The Application could not release the resources!", false); + } + } + + /// + /// Destructor of the SttController. + /// + ~SttController() + { + ReleaseResources(); + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/Converters/LanguageCodeToStringConverter.cs b/Mobile/NUI/SpeechToText/SpeechToText/Converters/LanguageCodeToStringConverter.cs new file mode 100644 index 00000000..a0238cee --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/Converters/LanguageCodeToStringConverter.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SpeechToText.Converters +{ + /// + /// Converter class to convert STT supported language code to corresponding display name. + /// + public class SupportedLanguageToDisplayNameConverter + { + #region methods + + /// + /// Converts STT supported language code to corresponding display name. + /// + /// Value to be converted. + /// Converted value. + public string Convert(string value) + { + switch (value) + { + case "en_US": + return "English US"; + case "es_US": + return "Spanish US"; + case "fr_FR": + return "French"; + case "ja_JP": + return "Japanese"; + case "ko_KR": + return "Korean"; + case "zh_CN": + return "Chinese"; + case "zh_TW": + return "Chinese Taiwan"; + case "zh_SG": + return "Chinese Singapore"; + case "zh_HK": + return "Chinese Hong Kong"; + case "de_DE": + return "German"; + case "ru_RU": + return "Russian"; + case "pt_BR": + return "Portuguese Brasil"; + case "es_ES": + return "Spanish"; + case "en_GB": + return "English GB"; + case "it_IT": + return "Italian"; + default: + return value; + } + } + + /// + /// Converts back STT supported language display name to corresponding code (string). + /// + /// Not required by the application (not implemented). + /// + /// Value to be converted back. + /// Converted value. + public string ConvertBack(string value) + { + switch (value) + { + case "English US": + return "en_US"; + case "Spanish US": + return "es_US"; + case "French": + return "fr_FR"; + case "Japanese": + return "ja_JP"; + case "Korean": + return "ko_KR"; + case "Chinese": + return "zh_CN"; + case "Chinese Taiwan": + return "zh_TW"; + case "Chinese Singapore": + return "zh_SG"; + case "Chinese Hong Kong": + return "zh_HK"; + case "German": + return "de_DE"; + case "Russian": + return "ru_RU"; + case "Portuguese Brasil": + return "pt_BR"; + case "Spanish": + return "es_ES"; + case "English GB": + return "en_GB"; + case "Italian": + return "it_IT"; + default: + return value; + } + } + #endregion + } +} \ No newline at end of file diff --git a/Mobile/NUI/SpeechToText/SpeechToText/Converters/RecognitionTypeToDisplayNameConverter.cs b/Mobile/NUI/SpeechToText/SpeechToText/Converters/RecognitionTypeToDisplayNameConverter.cs new file mode 100644 index 00000000..cab4d138 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/Converters/RecognitionTypeToDisplayNameConverter.cs @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Tizen.Uix.Stt; + +namespace SpeechToText.Converters +{ + /// + /// Converter class to convert STT recognition type (enum) to display name. + /// + public class RecognitionTypeToDisplayNameConverter + { + #region methods + + /// + /// Converts recognition type (enum) to corresponding display name. + /// + /// Value to be converted. + /// Converted value. + public string Convert(RecognitionType value) + { + switch (value) + { + case RecognitionType.Free: + return "Free"; + case RecognitionType.Partial: + return "Partial"; + case RecognitionType.Map: + return "Map"; + case RecognitionType.Search: + return "Search"; + case RecognitionType.WebSearch: + return "Web search"; + default: + return "Unknown"; + } + } + + /// + /// Converts back recognition type display name to corresponding enum value. + /// + /// Not required by the application (not implemented). + /// + /// Value to be converted back. + /// Converted value. + public RecognitionType ConvertBack(string value) + { + switch (value) + { + case "Free": + return RecognitionType.Free; + case "Partial": + return RecognitionType.Partial; + case "Map": + return RecognitionType.Map; + case "Search": + return RecognitionType.Search; + case "Web search": + return RecognitionType.WebSearch; + default: + return RecognitionType.Free; + } + } + #endregion + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/Converters/SilenceDetectionToDisplayNameConverter.cs b/Mobile/NUI/SpeechToText/SpeechToText/Converters/SilenceDetectionToDisplayNameConverter.cs new file mode 100644 index 00000000..cb054b34 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/Converters/SilenceDetectionToDisplayNameConverter.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Tizen.Uix.Stt; + +namespace SpeechToText.Converters +{ + /// + /// Converter class to convert STT silence detection (enum) to its display name. + /// + public class SilenceDetectionToDisplayNameConverter + { + #region methods + + /// + /// Converts STT silence detection (enum) to corresponding display name. + /// + /// Value that need to be converted. + /// Converted value. + public string Convert(SilenceDetection value) + { + switch (value) + { + case SilenceDetection.Auto: + return "Auto"; + case SilenceDetection.False: + return "Off"; + case SilenceDetection.True: + return "On"; + default: + return "Auto"; + } + } + + /// + /// Converts back STT silence detection display name to corresponding enum value. + /// + /// Not required by the application (not implemented). + /// + /// Value to be converted back. + /// Converted value. + public SilenceDetection ConvertBack(string value) + { + switch (value) + { + case "Auto": + return SilenceDetection.Auto; + case "Off": + return SilenceDetection.False; + case "On": + return SilenceDetection.True; + default: + return SilenceDetection.Auto; + } + } + #endregion + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/Main.cs b/Mobile/NUI/SpeechToText/SpeechToText/Main.cs new file mode 100644 index 00000000..ea4985e8 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/Main.cs @@ -0,0 +1,154 @@ +using SpeechToText.Controllers; +using SpeechToText.MainPageViews.MainPage; +using System; +using System.Collections.Generic; +using System.Linq; +using Tizen.NUI; +using Tizen.NUI.Components; +using Tizen.Security; + +namespace SpeechToText +{ + internal class Program : NUIApplication + { + private Window window; + private Navigator navigator; + private ContentPage mainPage; + private SttController sttController; + private readonly Color color = new("#40ACC6"); + + private void showDialog(string titleMessage, string message, Action action) + { + Button okButton = new() { BackgroundColor = color, Text = "Ok", SizeHeight = 100, SizeWidth = 150 }; + okButton.Clicked += (sender, e) => + { + action(); + }; + DialogPage.ShowAlertDialog(titleMessage, message, okButton); + } + + /// + /// Handles record permission request and response. + /// + /// If allowed the application will run normally, + /// if denied the application will close. + /// + /// + private async void checkPermissions() + { + string[] privileges = new[] {"http://tizen.org/privilege/recorder", + "http://tizen.org/privilege/content.write", + "http://tizen.org/privilege/mediastorage" + }; + CheckResult[] results = PrivacyPrivilegeManager.CheckPermissions(privileges).ToArray(); + List privilegesWithAskStatus = new List(); + try + { + for (int iterator = 0; iterator < results.Length; ++iterator) + { + switch (results[iterator]) + { + case CheckResult.Allow: + // Privilege can be used + break; + case CheckResult.Deny: + case CheckResult.Ask: + // User permission request required + privilegesWithAskStatus.Add(privileges[iterator]); + break; + } + } + + RequestMultipleResponseEventArgs request; + if (privilegesWithAskStatus.Count < 1) + { + sttController.CreateSttClient(); + return; + } + request = await PrivacyPrivilegeManager.RequestPermissions(privilegesWithAskStatus); + + if (request.Cause == CallCause.Error) + { + showDialog("Permission Not Granted", "We have to close the Application", delegate () { Current.Exit(); }); + } + foreach (PermissionRequestResponse response in request.Responses) + { + // PermissionRequestResponse contains privilege name and request result + switch (response.Result) + { + case RequestResult.AllowForever: + sttController.CreateSttClient(); + Console.WriteLine("User allowed usage of privileges definitely"); + break; + case RequestResult.DenyForever: + case RequestResult.DenyOnce: + showDialog("Permission Not Granted", "We have to close the Application", delegate () { Current.Exit(); }); + break; + } + } + } + catch (Exception e) + { + showDialog("Permission Not Granted", "We have to close the Application", delegate () { Current.Exit(); }); + } + } + + protected override void OnCreate() + { + base.OnCreate(); + Initialize(); + sttController = new SttController(); + mainPage = new MainPage(window.Size.Height, window.Size.Width, sttController); + navigator.Push(mainPage); + checkPermissions(); + } + + protected override void OnPause() + { + base.OnPause(); + if (sttController != null) + { + sttController.UnprepareSttClient(); + } + } + + protected override void OnResume() + { + base.OnResume(); + if (sttController != null) + { + sttController.PrepareSttClient(); + } + } + + void Initialize() + { + window = GetDefaultWindow(); + window.Title = "Speech To Text"; + window.KeyEvent += OnKeyEvent; + navigator = window.GetDefaultNavigator(); + } + public void OnKeyEvent(object sender, Window.KeyEventArgs e) + { + if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == "XF86Back" || e.Key.KeyPressedName == "Escape")) + { + Exit(); + } + } + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } + + protected override void OnTerminate() + { + if (sttController != null) + { + sttController.ReleaseResources(); + } + base.OnTerminate(); + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/SpeechToText.csproj b/Mobile/NUI/SpeechToText/SpeechToText/SpeechToText.csproj new file mode 100644 index 00000000..a458a32c --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/SpeechToText.csproj @@ -0,0 +1,14 @@ + + + net6.0-tizen + Exe + + + + + + + + + + \ No newline at end of file diff --git a/Mobile/NUI/SpeechToText/SpeechToText/SpeechToText.sln b/Mobile/NUI/SpeechToText/SpeechToText/SpeechToText.sln new file mode 100644 index 00000000..59acb078 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/SpeechToText.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33122.133 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpeechToText", "SpeechToText.csproj", "{713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}.Release|Any CPU.Build.0 = Release|Any CPU + {713F9FA8-A2BC-4CEB-A62A-D681F8ACD07F}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4FB41A0F-E243-46AA-98FF-8BF4C94E22D1} + EndGlobalSection +EndGlobal diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/back.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/back.png new file mode 100644 index 00000000..868df508 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/back.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/bg.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/bg.png new file mode 100644 index 00000000..5d74b043 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/bg.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/clear_default.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/clear_default.png new file mode 100644 index 00000000..82fde3bb Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/clear_default.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/clear_pressed.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/clear_pressed.png new file mode 100644 index 00000000..1933da96 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/clear_pressed.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/language.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/language.png new file mode 100644 index 00000000..b97c31c7 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/language.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/language_pressed.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/language_pressed.png new file mode 100644 index 00000000..dd1def7a Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/language_pressed.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_1.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_1.png new file mode 100644 index 00000000..99a46ce1 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_1.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_2.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_2.png new file mode 100644 index 00000000..7d880329 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_2.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_3.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_3.png new file mode 100644 index 00000000..eb91c32e Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_3.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_4.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_4.png new file mode 100644 index 00000000..87eb6219 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_4.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_5.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_5.png new file mode 100644 index 00000000..99a46ce1 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_5.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_6.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_6.png new file mode 100644 index 00000000..99a46ce1 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/Iot_Loading_6.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_00.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_00.png new file mode 100644 index 00000000..ca1d5d98 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_00.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_01.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_01.png new file mode 100644 index 00000000..86b77c06 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_01.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_02.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_02.png new file mode 100644 index 00000000..0eeff640 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_02.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_03.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_03.png new file mode 100644 index 00000000..4442e238 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_03.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_04.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_04.png new file mode 100644 index 00000000..bbd389f9 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_04.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_05.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_05.png new file mode 100644 index 00000000..b4b4bb58 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_05.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_06.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_06.png new file mode 100644 index 00000000..a24c141f Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_06.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_07.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_07.png new file mode 100644 index 00000000..61e6d348 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_07.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_08.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_08.png new file mode 100644 index 00000000..da2cbbc5 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_08.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_09.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_09.png new file mode 100644 index 00000000..8f6c6152 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_09.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_10.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_10.png new file mode 100644 index 00000000..1249c951 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_10.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_11.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_11.png new file mode 100644 index 00000000..83c55046 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_11.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_12.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_12.png new file mode 100644 index 00000000..f269195a Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_12.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_13.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_13.png new file mode 100644 index 00000000..fbfc7cb8 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_13.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_14.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_14.png new file mode 100644 index 00000000..c102c7af Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_14.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_15.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_15.png new file mode 100644 index 00000000..86c58813 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_15.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_16.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_16.png new file mode 100644 index 00000000..c6eb5864 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_16.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_17.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_17.png new file mode 100644 index 00000000..bc0eb707 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_17.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_18.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_18.png new file mode 100644 index 00000000..7d327209 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_18.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_19.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_19.png new file mode 100644 index 00000000..53c86f13 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_19.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_20.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_20.png new file mode 100644 index 00000000..a834c14f Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_20.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_21.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_21.png new file mode 100644 index 00000000..fb617937 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_21.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_22.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_22.png new file mode 100644 index 00000000..652be89d Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_22.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_23.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_23.png new file mode 100644 index 00000000..ac1c231d Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_23.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_24.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_24.png new file mode 100644 index 00000000..978bad3b Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_24.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_25.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_25.png new file mode 100644 index 00000000..9616903a Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_25.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_26.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_26.png new file mode 100644 index 00000000..8e1e46d7 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_26.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_27.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_27.png new file mode 100644 index 00000000..86637e1d Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_27.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_28.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_28.png new file mode 100644 index 00000000..ef9a78dd Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_28.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_29.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_29.png new file mode 100644 index 00000000..91bcadf2 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_29.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_30.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_30.png new file mode 100644 index 00000000..201fb942 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_30.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_31.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_31.png new file mode 100644 index 00000000..91ff05e8 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_31.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_32.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_32.png new file mode 100644 index 00000000..24135911 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_32.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_33.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_33.png new file mode 100644 index 00000000..44c90158 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_33.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_34.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_34.png new file mode 100644 index 00000000..88eb10f6 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_34.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_35.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_35.png new file mode 100644 index 00000000..a950a3ac Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/loading/loading_35.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic1.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic1.png new file mode 100644 index 00000000..4a3f9f35 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic1.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic1_bg.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic1_bg.png new file mode 100644 index 00000000..817c2972 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic1_bg.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic2.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic2.png new file mode 100644 index 00000000..dada628e Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/mic2.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/recognition_type.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/recognition_type.png new file mode 100644 index 00000000..84f6e6c6 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/recognition_type.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/recognition_type_pressed.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/recognition_type_pressed.png new file mode 100644 index 00000000..aabf6320 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/recognition_type_pressed.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/settings.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/settings.png new file mode 100644 index 00000000..a0de60e4 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/settings.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/silence_detection.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/silence_detection.png new file mode 100644 index 00000000..d14e0a08 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/silence_detection.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/silence_detection_pressed.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/silence_detection_pressed.png new file mode 100644 index 00000000..d9d51806 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/silence_detection_pressed.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/sounds.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/sounds.png new file mode 100644 index 00000000..ceddb33f Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/sounds.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/sounds_pressed.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/sounds_pressed.png new file mode 100644 index 00000000..25a67417 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/sounds_pressed.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/stop_default.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/stop_default.png new file mode 100644 index 00000000..26840bb2 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/stop_default.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/stop_pressed.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/stop_pressed.png new file mode 100644 index 00000000..552703b4 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/stop_pressed.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_off.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_off.png new file mode 100644 index 00000000..93fd2c43 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_off.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_off_dim.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_off_dim.png new file mode 100644 index 00000000..5c62b946 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_off_dim.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_on.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_on.png new file mode 100644 index 00000000..128f236c Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_on.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_on_dim.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_on_dim.png new file mode 100644 index 00000000..427763b6 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_bg_on_dim.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_handler.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_handler.png new file mode 100644 index 00000000..edafdc1d Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_handler.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_handler_dim.png b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_handler_dim.png new file mode 100644 index 00000000..cc870485 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/res/images/switch/controller_switch_handler_dim.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/shared/res/SpeechToText.png b/Mobile/NUI/SpeechToText/SpeechToText/shared/res/SpeechToText.png new file mode 100644 index 00000000..9f3cb986 Binary files /dev/null and b/Mobile/NUI/SpeechToText/SpeechToText/shared/res/SpeechToText.png differ diff --git a/Mobile/NUI/SpeechToText/SpeechToText/tizen-manifest.xml b/Mobile/NUI/SpeechToText/SpeechToText/tizen-manifest.xml new file mode 100644 index 00000000..d80a5cd1 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/tizen-manifest.xml @@ -0,0 +1,20 @@ + + + + + + SpeechToText.png + + + + http://tizen.org/privilege/recorder + http://tizen.org/privilege/content.write + http://tizen.org/privilege/mediastorage + + diff --git a/Mobile/NUI/SpeechToText/SpeechToText/views/MainPageViews/LoadingIndicator.cs b/Mobile/NUI/SpeechToText/SpeechToText/views/MainPageViews/LoadingIndicator.cs new file mode 100644 index 00000000..8bcd617d --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/views/MainPageViews/LoadingIndicator.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tizen.Applications; +using Tizen.NUI; +using Tizen.NUI.Components; + +namespace SpeechToText.views.MainPageViews +{ + class LoadingIndicator : Loading + { + /// + /// Contains the loading images + /// + private readonly string[] imageArray; + + /// + /// Contains the absolute path to the application resource directory + /// + private readonly string directory; + + public LoadingIndicator() { + //Initial state for the loading indicator + Hide(); + Stop(); + directory = Application.Current.DirectoryInfo.Resource; + imageArray = new string[36]; + for (int i = 0; i < 36; i++) + { + imageArray[i] = directory + "images/loading/loading_" + i.ToString("00") + ".png"; + } + ImageArray = imageArray; + Size2D = new Size2D(150, 180); + //Centering the Loading indicator according to the absolute layout + PositionUsesPivotPoint = true; + ParentOrigin = Position.ParentOriginCenter; + PivotPoint = Position.PivotPointCenter; + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/views/MainPageViews/MainPage.cs b/Mobile/NUI/SpeechToText/SpeechToText/views/MainPageViews/MainPage.cs new file mode 100644 index 00000000..392d10d0 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/views/MainPageViews/MainPage.cs @@ -0,0 +1,348 @@ +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; +using Tizen.NUI; +using Tizen.Applications; +using System; +using SpeechToText.Controllers; +using SpeechToText.SettingsPageViews.SettingsPage; +using SpeechToText.views.MainPageViews; + +namespace SpeechToText.MainPageViews.MainPage +{ + + class MainPage : ContentPage + { + /// + /// Contains the absolute path to the application resource directory + /// + private readonly string directory = Application.Current.DirectoryInfo.Resource; + + /// + /// Speech to text controller. + /// + private readonly SttController sttController; + + /// + /// Text label to hold the result of Speech to text component. + /// + private readonly TextLabel resultText; + + /// + /// Microphone button to start recording. + /// + private readonly Button micButton; + + /// + /// Action that will be called inside the controller to change the UI according to the state. + /// This action will update the result text on the Main page when the result is done. + /// + private readonly Action onTextChange; + + /// + /// Action that will enable the mic button. + /// + private readonly Action onCreateState; + + /// + /// Action that will enable the mic button. + /// + private readonly Action onReadyState; + + /// + /// Action that changes the mic button while recording. + /// + private readonly Action onRecordingState; + + /// + /// Action that shows loading indicator while processing the data. + /// + private readonly Action onProcessingState; + + /// + /// Action that will show a dialog. + /// + private readonly Action showDialog; + + /// + /// Custom defined Color + /// + private readonly Color color = new("#40ACC6"); + + public MainPage(float height, float width, SttController sttController) + { + //Loading Indicator + LoadingIndicator loadingIndicator = new LoadingIndicator(); + + onTextChange = delegate (string text) + { + if (text != null) + resultText.Text = text; + loadingIndicator.Hide(); + loadingIndicator.Stop(); + }; + + onCreateState = delegate () + { + loadingIndicator.Show(); + loadingIndicator.Play(); + micButton.IsEnabled = false; + micButton.IconURL = directory + "/images/mic2.png"; + }; + + onReadyState = delegate () + { + micButton.IsEnabled = true; + loadingIndicator.Hide(); + loadingIndicator.Stop(); + micButton.IconURL = directory + "/images/mic2.png"; + }; + + onRecordingState = delegate () + { + micButton.IconURL = directory + "/images/mic1.png"; + }; + + onProcessingState = delegate () + { + micButton.IconURL = directory + "/images/mic2.png"; + loadingIndicator.Show(); + loadingIndicator.Play(); + }; + + showDialog = delegate (string titleMessage, string message, bool exit) + { + Button okButton = new() { BackgroundColor = color, Text = "Ok", SizeHeight = 100, SizeWidth = 150 }; + okButton.Clicked += (sender, e) => + { + if (!exit) + { + Navigator.Pop(); + return; + } + Application.Current.Exit(); + }; + DialogPage.ShowAlertDialog(titleMessage, message, okButton); + }; + + //Initializing the speech to text controller + this.sttController = sttController; + this.sttController.OnCreateState = onCreateState; + this.sttController.OnReadyState = onReadyState; + this.sttController.OnResultChange = onTextChange; + this.sttController.OnRecordingState = onRecordingState; + this.sttController.OnProcessingState = onProcessingState; + this.sttController.OnErrorAlert = showDialog; + + //UI For the main page + //Navigation button at the top left(settings) + Button settingsButton = new(new ButtonStyle() + { + BackgroundColor = new Selector() + { + Pressed = new(0, 0, 0, 0.2f), + Other = Color.Transparent + }, + }) + { + IconURL = directory + "/images/settings.png", + SizeWidth = 150, + SizeHeight = 100, + CornerRadius = 25, + }; + + //Assigning touch event for the settings button to naivgate to the Setting Page + settingsButton.Clicked += (object sender, ClickedEventArgs e) => + { + //Navigating to settings page if the state is not recording or processing + //Otherwise it will show a dialog + if (this.sttController.State == Tizen.Uix.Stt.State.Recording || this.sttController.State == Tizen.Uix.Stt.State.Processing) + { + showDialog("Notice", "You Can not go the settings while recording or processing", false); + } + else + { + settingsButton.IsEnabled = false; + Navigator.Push(page: new SettingsPage(SizeHeight, SizeWidth, this.sttController, delegate () { settingsButton.IsEnabled = true; })); + } + + }; + + //App Bar Title Text Style + var mainAppBarTextStyle = new PropertyMap(); + mainAppBarTextStyle.Add("slant", new PropertyValue(FontSlantType.Normal.ToString())); + mainAppBarTextStyle.Add("width", new PropertyValue(FontWidthType.Expanded.ToString())); + mainAppBarTextStyle.Add("weight", new PropertyValue(FontWeightType.DemiBold.ToString())); + + //Creating the AppBar with one navigation button and without any additional buttons + AppBar appBar = new() + { + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + VerticalAlignment = VerticalAlignment.Center, + + }, + SizeHeight = height / 12, + SizeWidth = width, + BackgroundColor = Color.Transparent, + AutoNavigationContent = false, + NavigationContent = settingsButton, + //Disable the action button + ActionContent = new View() { SizeWidth = width * 0.1f }, + TitleContent = new TextLabel() + { + Text = "Speech To Text", + PointSize = 10, + TextColor = Color.White, + Margin = new Extents((ushort)(width * 0.1f), (ushort)(width * 0.1f), 0, 0), + FontStyle = mainAppBarTextStyle, + }, + }; + + //The main view of the page, it will contain the text and the three buttons(cancel, mic, stop) + View mainView = new() + { + LayoutDirection = ViewLayoutDirectionType.LTR, + SizeHeight = height - (height / 12), + SizeWidth = width, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + }, + }; + + //Button view to hold the buttons horizontally + //It will be added to the main view + View buttonView = new() + { + SizeWidth = width, + SizeHeight = height * 0.15f, + BackgroundColor = Color.Transparent, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + CellPadding = new Size2D(30, 10), + }, + }; + + //Creating buttons + //Microphone button + micButton = new Button() + { + Size = new Size(130, 130), + BackgroundImage = directory + "/images/mic1_bg.png", + IconURL = directory + "/images/mic2.png", + WidthSpecification = LayoutParamPolicies.WrapContent, + HeightSpecification = LayoutParamPolicies.WrapContent, + }; + + //This button will work only if the _state is ready + //This button will change the _state to recording while you are speaking + micButton.Clicked += (object sender, ClickedEventArgs e) => + { + this.sttController.Start(); + }; + + //Cancel button to cancel the recording + //The _state will change from recording to ready + Button cancelButton = new(new ButtonStyle() + { + BackgroundImage = new Selector() + { + Pressed = directory + "images/clear_pressed.png", + Normal = directory + "images/clear_default.png", + } + }) + { + SizeWidth = 100, + SizeHeight = 100, + }; + cancelButton.Clicked += (object sender, ClickedEventArgs e) => + { + //Canceling the recording process + this.sttController.Cancel(); + }; + + //Stop button + Button stopButton = new(new ButtonStyle() + { + BackgroundImage = new Selector() + { + Pressed = directory + "images/stop_pressed.png", + Normal = directory + "/images/stop_default.png" + } + }) + { + SizeWidth = 100, + SizeHeight = 100, + }; + + //The _state will change from recording to processing + //When the processing is finished the _state will be ready again + stopButton.Clicked += (object sender, ClickedEventArgs e) => + { + this.sttController.Stop(); + }; + + //Text view to hold the text label when the result is ready + View textView = new() + { + SizeWidth = width, + SizeHeight = height * 0.75f, + BackgroundColor = Color.Transparent, + Layout = new AbsoluteLayout() + { + }, + Padding = new Extents(25, 25, 75, 25), + }; + + //Text style for the result text + var paragraphTextStyle = new PropertyMap(); + paragraphTextStyle.Add("slant", new PropertyValue(FontSlantType.Normal.ToString())); + paragraphTextStyle.Add("width", new PropertyValue(FontWidthType.Expanded.ToString())); + paragraphTextStyle.Add("weight", new PropertyValue(FontWeightType.DemiBold.ToString())); + + resultText = new() + { + SizeWidth = width * 0.9f, + SizeHeight = height * 0.7f, + PointSize = 8, + TextColor = new Color(1, 1, 1, 0.8f), + BackgroundColor = Color.Transparent, + FontStyle = paragraphTextStyle, + MultiLine = true, + Margin = new Extents(50, 50, 50, 50), + PositionUsesPivotPoint = true, + PivotPoint = Position.PivotPointCenter, + ParentOrigin = Position.ParentOriginCenter, + //Initial state + Text = "", + }; + textView.Add(resultText); + textView.Add(loadingIndicator); + + //Add buttons to button view + buttonView.Add(cancelButton); + buttonView.Add(micButton); + buttonView.Add(stopButton); + + //Add views to the main view + mainView.Add(textView); + mainView.Add(buttonView); + + //Adding Components to the content page + AppBar = appBar; + Content = mainView; + BackgroundImage = directory + "/images/bg.png"; + } + ~MainPage() + { + if (sttController != null) + { + sttController.ReleaseResources(); + } + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/views/PreferencePageViews/PreferencesPage.cs b/Mobile/NUI/SpeechToText/SpeechToText/views/PreferencePageViews/PreferencesPage.cs new file mode 100644 index 00000000..95ea774b --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/views/PreferencePageViews/PreferencesPage.cs @@ -0,0 +1,161 @@ +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; +using Tizen.NUI; +using Tizen.Applications; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SpeechToText.views.PreferencePageViews +{ + public class PreferencesPage : ContentPage + { + /// + /// Custom defined Color + /// + private readonly Color color = new("#40ACC6"); + + /// + /// Contains the absolute path to the application resource directory + /// + private readonly string directory = Application.Current.DirectoryInfo.Resource; + + /// + /// Holds the selected preference button + /// + private Button selectedButton; + + public PreferencesPage(string title, float height, float width, string currentPreferenceName, List preferences, Action preferenceAction, Action onPop) + { + //Back button used in the app bar to pop the current page + Button backButton = new(new ButtonStyle() + { + Opacity = new Selector + { + Pressed = 0.5f, + Other = 1f + } + }) + { + BackgroundImage = directory + "images/back.png", + SizeWidth = 50, + SizeHeight = 50, + Margin = new Extents(25, 0, 0, 0), + }; + + backButton.Clicked += (object sender, ClickedEventArgs e) => + { + onPop(); + Navigator.Pop(); + }; + + //Scrollable view that holds the preference buttons + ScrollableBase scrollableBase = new() + { + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical + }, + ScrollingDirection = ScrollableBase.Direction.Vertical, + SizeHeight = height - height / 12, + SizeWidth = width, + ScrollEnabled = true, + }; + + foreach (string preferenceName in preferences) + { + //Creating button for each preference + Button preferenceButton = new(new ButtonStyle() + { + BackgroundColor = new Selector + { + Pressed = new Color(color.R, color.G, color.B, 0.3f), + Selected = new Color(color.R, color.G, color.B, 0.5f), + Other = Color.Transparent, + }, + }) + { + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + }, + //BackgroundColor = currentPreferenceName == preferenceName ? new Color(color.R, color.G, color.B, 0.5f) : Color.Transparent, + PointSize = 8, + TextAlignment = HorizontalAlignment.Begin, + Text = preferenceName.Split('/').Last().Split(".wav").First(), + Padding = new Extents(25, 0, 25, 0), + TextColor = Color.Black, + SizeWidth = width, + SizeHeight = height / 10, + Margin = new Extents(0, 0, 10, 10), + IsSelectable = true, + }; + + //Selecting the Default button + if (currentPreferenceName == preferenceName) + { + selectedButton = preferenceButton; + selectedButton.IsSelected = true; + } + preferenceButton.TouchEvent += (object sender, TouchEventArgs e) => + { + if (e.Touch.GetState(0) == PointStateType.Started) + { + //Change the default background color to give an effect when pressed + //preferenceButton.BackgroundColor = new Color(color.R, color.G, color.B, 0.3f); + } + if (e.Touch.GetState(0) == PointStateType.Leave) + { + //Return the default background color + //preferenceButton.BackgroundColor = Color.Transparent; + } + if (e.Touch.GetState(0) == PointStateType.Finished) + { + //Return the default background color + //if (selectedButton != null) + //selectedButton.BackgroundColor = Color.Transparent; + //Changing the selected button to the pressed one + //preferenceButton.BackgroundColor = new Color(color.R, color.G, color.B, 0.5f); + selectedButton.IsSelected = false; + preferenceButton.IsSelected = true; + selectedButton = preferenceButton; + //To change the text value on the button of the settings page + preferenceAction(preferenceName); + } + return true; + }; + //Adding button the scrollable view + scrollableBase.Add(preferenceButton); + } + + //Creating AppBar and AppBar style + var mainAppBarTextStyle = new PropertyMap(); + mainAppBarTextStyle.Add("slant", new PropertyValue(FontSlantType.Normal.ToString())); + mainAppBarTextStyle.Add("width", new PropertyValue(FontWidthType.Expanded.ToString())); + mainAppBarTextStyle.Add("weight", new PropertyValue(FontWeightType.DemiBold.ToString())); + + //Creating the AppBar with one navigation button and without any additional buttons + AppBar appBar = new() + { + SizeHeight = height / 12, + SizeWidth = width, + BackgroundColor = color, + AutoNavigationContent = false, + ActionContent = new View() { SizeWidth = width * 0.1f }, + NavigationContent = backButton, + TitleContent = new TextLabel() + { + Text = title, + PointSize = 10, + TextColor = Color.White, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + FontStyle = mainAppBarTextStyle, + WidthSpecification = LayoutParamPolicies.MatchParent, + }, + }; + AppBar = appBar; + Content = scrollableBase; + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/views/SettingsPageViews/SettingsPage.cs b/Mobile/NUI/SpeechToText/SpeechToText/views/SettingsPageViews/SettingsPage.cs new file mode 100644 index 00000000..21f2ace8 --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/views/SettingsPageViews/SettingsPage.cs @@ -0,0 +1,600 @@ +using Tizen.NUI.BaseComponents; +using Tizen.NUI; +using Tizen.NUI.Components; +using Tizen.Applications; +using SpeechToText.Controllers; +using System; +using SpeechToText.views.PreferencePageViews; +using SpeechToText.Converters; +using System.Collections.Generic; +using Tizen.Uix.Stt; +using System.Linq; + +namespace SpeechToText.SettingsPageViews.SettingsPage +{ + class SettingsPage : ContentPage + { + /// + /// Contains the absolute path to the application resource directory + /// + private readonly string directory = Application.Current.DirectoryInfo.Resource; + + /// + /// Custom defined Color + /// + private readonly Color color = new("#40ACC6"); + + + public SettingsPage(float height, float width, SttController sttController, Action onPop) + { + //Back button used in the app bar to pop the current page + Button backButton = new(new ButtonStyle() + { + Opacity = new Selector + { + Pressed = 0.5f, + Other = 1f + } + }) + { + BackgroundImage = directory + "images/back.png", + SizeWidth = 50, + SizeHeight = 50, + Margin = new Extents(25, 0, 0, 0), + }; + + backButton.Clicked += (object sender, ClickedEventArgs e) => + { + //To enable the settings button in the main page + onPop(); + Navigator.Pop(); + }; + + //App bar title Text Style + var mainAppBarTextStyle = new PropertyMap(); + mainAppBarTextStyle.Add("slant", new PropertyValue(FontSlantType.Normal.ToString())); + mainAppBarTextStyle.Add("width", new PropertyValue(FontWidthType.Expanded.ToString())); + mainAppBarTextStyle.Add("weight", new PropertyValue(FontWeightType.DemiBold.ToString())); + + //Creating AppBar + AppBar appBar = new() + { + SizeHeight = height / 12, + SizeWidth = width, + BackgroundColor = color, + AutoNavigationContent = false, + ActionContent = new View() { SizeWidth = width * 0.1f }, + NavigationContent = backButton, + TitleContent = new TextLabel() + { + Text = "Settings", + PointSize = 10, + TextColor = Color.White, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + FontStyle = mainAppBarTextStyle, + WidthSpecification = LayoutParamPolicies.MatchParent, + }, + }; + + //View to hold the general buttons + View generalButtonList = new() + { + SizeWidth = width, + SizeHeight = height * 0.4f, + BackgroundColor = Color.Transparent, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + VerticalAlignment = VerticalAlignment.Top, + HorizontalAlignment = HorizontalAlignment.Center, + }, + }; + + //Adding title to the general list + generalButtonList.Add(new TextLabel() + { + Text = "General", + TextColor = color, + PointSize = 8, + WidthSpecification = LayoutParamPolicies.MatchParent, + SizeHeight = height * 0.05f, + BackgroundColor = Color.Transparent, + Margin = new Extents(20, 0, 0, 0), + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + + }); + + //Adding buttons to the view + //Language Button + Button languageButton = new(new ButtonStyle() + { + BackgroundColor = new Selector + { + Pressed = new Color(0, 0, 0, 0.2f), + Normal = Color.Transparent, + }, + Icon = new ImageViewStyle() + { + ResourceUrl = new Selector + { + Pressed = directory + "/images/language_pressed.png", + Other = directory + "/images/language.png", + }, + }, + IsEnabled = true, + }) + { + PointSize = 6, + ItemSpacing = new Size2D((int)(width * 0.08f), 0), + TextColor = Color.Black, + TextAlignment = HorizontalAlignment.Center, + SizeHeight = height * 0.1f, + Padding = new Extents(40, 0, 0, 0), + WidthSpecification = LayoutParamPolicies.MatchParent, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + }; + + //Displays the currently selected language + TextLabel languageValueLabel = new() + { + Text = sttController.Language.ToString(), + PointSize = 6, + TextColor = new Color(0, 0, 0, 0.6f), + }; + + //Title for the language button + TextLabel languageTitleLabel = new() + { + Text = "Language", + PointSize = 7, + TextColor = Color.Black, + }; + + //View that will hold the title and the currently selected language + View languageButtonView = new() + { + Layout = new LinearLayout + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + Padding = new Extents(40, 0, 0, 0), + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + }; + + //Adding the text labels to the view + languageButtonView.Add(languageTitleLabel); + languageButtonView.Add(languageValueLabel); + + //Adding the view to the button + languageButton.Add(languageButtonView); + + //Assigning event to the language button + languageButton.Clicked += (object sender, ClickedEventArgs e) => + { + //To prevent double clicks + languageButton.IsEnabled = false; + + //Converts the language code to language name + var languageConverter = new SupportedLanguageToDisplayNameConverter(); + + //Getting the currently selected language code, and converting it to the language name + string currentLanguageName = languageConverter.Convert(sttController.Language); + + //Initializing empty list that will hold the languages name + List languageNames = new(); + + //Getting languages code + List languageCodes = sttController.GetSupportedLanguages(); + + foreach (string languageCode in languageCodes) + { + //Adding language name to the language list + string languageName = languageConverter.Convert(languageCode); + languageNames.Add(languageName); + } + + //Action that will be used to update the value label from the preference page when a new language is selected + void languageAction(string languageName) + { + string languageCode = languageConverter.ConvertBack(languageName); + sttController.Language = languageCode; + languageValueLabel.Text = languageCode; + } + + Navigator.Push(new PreferencesPage( + "Language", + height: height, + width: width, + currentPreferenceName: currentLanguageName, + preferences: languageNames, + preferenceAction: languageAction, + delegate () { languageButton.IsEnabled = true; }) + ); + }; + + //Adding the language button to the general list + generalButtonList.Add(languageButton); + + //Recognition type button + var recognitionButton = new Button(new ButtonStyle() + { + BackgroundColor = new Selector + { + Pressed = new Color(0, 0, 0, 0.2f), + Other = Color.Transparent, + }, + Icon = new ImageViewStyle() + { + ResourceUrl = new Selector + { + Pressed = directory + "/images/recognition_type_pressed.png", + Other = directory + "/images/recognition_type.png", + }, + }, + IsEnabled = true, + }) + { + ItemSpacing = new Size2D((int)(width * 0.08f), 0), + PointSize = 6, + TextColor = Color.Black, + TextAlignment = HorizontalAlignment.Center, + SizeHeight = height * 0.1f, + TooltipText = "English US", + WidthSpecification = LayoutParamPolicies.MatchParent, + Padding = new Extents(40, 0, 0, 0), + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + }; + + //Displays the currently selected recognition type + TextLabel recognitionButtonValue = new() + { + Text = sttController.RecognitionType.ToString(), + PointSize = 6, + TextColor = new Color(0, 0, 0, 0.6f), + }; + + //Title for the recognition button + TextLabel recognitionButtonTitle = new() + { + Text = "Recognition Type", + PointSize = 7, + TextColor = Color.Black, + }; + + //View that will hold the title and the currently selected recognition type + View recognitionButtonView = new() + { + Layout = new LinearLayout + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + Padding = new Extents(40, 0, 0, 0), + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + }; + + //Adding the text labels to the view + recognitionButtonView.Add(recognitionButtonTitle); + recognitionButtonView.Add(recognitionButtonValue); + + //Adding the view to the button + recognitionButton.Add(recognitionButtonView); + + //Assign events to the recognition button + recognitionButton.Clicked += (object sender, ClickedEventArgs e) => + { + //To prevent double clicks + recognitionButton.IsEnabled = false; + + //Converts the recognition type code to recognition type name + var recognitionTypeToDisplayNameConverter = new RecognitionTypeToDisplayNameConverter(); + + //Initializing empty list that will hold the recognition types name + List recognitionTypeNames = new(); + + //Getting the currently selected recognition type code, and converting it to the recognition type name + string currentRecognitionTypeName = recognitionTypeToDisplayNameConverter.Convert(sttController.RecognitionType); + + //Getting recognition types code + List recognitionTypeCodes = Enum.GetValues().ToList(); + + foreach (RecognitionType recognitionTypeCode in recognitionTypeCodes) + { + //Adding recognition type name to the recognition types list + string recognitionTypeName = recognitionTypeToDisplayNameConverter.Convert(recognitionTypeCode); + recognitionTypeNames.Add(recognitionTypeName); + } + + //Action that will be used to update the value label from the preference page when a new recognition type is selected + void recognitionTypeAction(string languageName) + { + RecognitionType recognitionType = recognitionTypeToDisplayNameConverter.ConvertBack(languageName); + sttController.RecognitionType = recognitionType; + recognitionButtonValue.Text = recognitionType.ToString(); + } + + Navigator.Push(new PreferencesPage( + "Recognition Type", + height: height, + width: width, + currentPreferenceName: currentRecognitionTypeName, + preferences: recognitionTypeNames, + preferenceAction: recognitionTypeAction, + delegate () { recognitionButton.IsEnabled = true; } + )); + }; + + //Adding the recognition button to the general list + generalButtonList.Add(recognitionButton); + + //Silence detection button + var silenceDetectionButton = new Button(new ButtonStyle() + { + BackgroundColor = new Selector + { + Pressed = new Color(0, 0, 0, 0.2f), + Other = Color.Transparent, + }, + Icon = new ImageViewStyle() + { + ResourceUrl = new Selector + { + Pressed = directory + "/images/silence_detection_pressed.png", + Other = directory + "/images/silence_detection.png" + }, + }, + IsEnabled = true, + }) + { + ItemSpacing = new Size2D((int)(width * 0.08f), 0), + TextColor = Color.Black, + TextAlignment = HorizontalAlignment.Center, + SizeHeight = height * 0.1f, + TooltipText = "English US", + WidthSpecification = LayoutParamPolicies.MatchParent, + Padding = new Extents(40, 0, 0, 0), + PointSize = 6, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + }; + + //Title for the silence detection button + TextLabel silenceDetectionButtonTitle = new() + { + Text = "Silence Detection", + PointSize = 7, + TextColor = Color.Black, + }; + + //Displays the currently selected silence detection type + TextLabel silenceDetectionButtonValue = new() + { + Text = sttController.SilenceDetection.ToString(), + PointSize = 6, + TextColor = new Color(0, 0, 0, 0.6f), + }; + + //View that will hold the title and the currently selected language + View silenceDetectionButtonView = new() + { + Layout = new LinearLayout + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + Padding = new Extents(40, 0, 0, 0), + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + }; + + //Adding the text labels to the view + silenceDetectionButtonView.Add(silenceDetectionButtonTitle); + silenceDetectionButtonView.Add(silenceDetectionButtonValue); + + //Adding the view to the button + silenceDetectionButton.Add(silenceDetectionButtonView); + + //Assign events to the silence detection button + silenceDetectionButton.Clicked += (object sender, ClickedEventArgs e) => + { + //To prevent double clicks + silenceDetectionButton.IsEnabled = false; + + //Converts the silence detection type code to silence detection type name + var silenceDetectionToDisplayNameConverter = new SilenceDetectionToDisplayNameConverter(); + + //Initializing empty list that will hold the recognition types name + List silenceDetectionNames = new(); + + //Getting the currently selected silence detection type code, and converting it to the silence detection type name + string currentSilenceDetectionName = silenceDetectionToDisplayNameConverter.Convert(sttController.SilenceDetection); + + //Getting silence detection types code + List silenceDetectionCodes = Enum.GetValues().ToList(); + + foreach (SilenceDetection silenceDetectionCode in silenceDetectionCodes) + { + //Adding silence detection type name to the silence detection types list + silenceDetectionNames.Add(silenceDetectionToDisplayNameConverter.Convert(silenceDetectionCode)); + } + + //Action that will be used to update the value label from the preference page when a new Silence Detection type is selected + void silenceDetectionAction(string silenceDetectionName) + { + SilenceDetection silenceDetectionType = silenceDetectionToDisplayNameConverter.ConvertBack(silenceDetectionName); + sttController.SilenceDetection = silenceDetectionType; + silenceDetectionButtonValue.Text = silenceDetectionName; + } + + Navigator.Push(new PreferencesPage( + "Silence Detection", + height: height, width: width, + currentPreferenceName: currentSilenceDetectionName, + preferences: silenceDetectionNames, + preferenceAction: silenceDetectionAction, delegate () { silenceDetectionButton.IsEnabled = true; }) + ); + }; + + //Adding the silence detection button to the general list + generalButtonList.Add(silenceDetectionButton); + + //View to hold the personal buttons + View personalButtonList = new() + { + SizeWidth = width, + SizeHeight = height * 0.3f, + BackgroundColor = Color.Transparent, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + VerticalAlignment = VerticalAlignment.Top, + HorizontalAlignment = HorizontalAlignment.Center, + }, + }; + + //Adding title to the persnoal list + personalButtonList.Add(new TextLabel() + { + Text = "Personal", + TextColor = color, + PointSize = 8, + WidthSpecification = LayoutParamPolicies.MatchParent, + SizeHeight = height * 0.05f, + BackgroundColor = Color.Transparent, + Margin = new Extents(20, 0, 0, 0), + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }); + + //Sound button + var soundsButton = new Button(new ButtonStyle() + { + BackgroundColor = new Selector + { + Pressed = new Color(0, 0, 0, 0.2f), + Other = Color.Transparent, + }, + Icon = new ImageViewStyle() + { + ResourceUrl = new Selector + { + Pressed = directory + "/images/sounds_pressed.png", + Other = directory + "/images/sounds.png" + }, + }, + IsEnabled = true, + }) + { + ItemSpacing = new Size2D((int)(width * 0.08f), 0), + TextColor = Color.Black, + TextAlignment = HorizontalAlignment.Center, + SizeHeight = height * 0.1f, + WidthSpecification = LayoutParamPolicies.MatchParent, + Padding = new Extents(40, 0, 0, 0), + PointSize = 6, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + }; + + //Displays the currently selected language + TextLabel soundsValueLabel = new() + { + Text = sttController.Sounds.ToString(), + PointSize = 6, + TextColor = new Color(0, 0, 0, 0.6f), + }; + + //Title for the language button + TextLabel soundsTitleLabel = new() + { + Text = "Sounds", + PointSize = 7, + TextColor = Color.Black, + }; + + //View that will hold the title and the state of the sound's settings + View soundsButtonView = new() + { + Layout = new LinearLayout + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + Padding = new Extents(40, 0, 0, 0), + WidthSpecification = LayoutParamPolicies.MatchParent, + HeightSpecification = LayoutParamPolicies.MatchParent, + }; + + //Adding the text labels to the view + soundsButtonView.Add(soundsTitleLabel); + soundsButtonView.Add(soundsValueLabel); + + //Adding the view to the button + soundsButton.Add(soundsButtonView); + + //Assign events to the sound button + soundsButton.Clicked += (object sender, ClickedEventArgs e) => + { + //To prevent double clicks + soundsButton.IsEnabled = false; + + Navigator.Push( + new SoundsPage(height: height, + width: width, + sttController, + delegate (bool value) { soundsValueLabel.Text = value.ToString(); }, + delegate () { soundsButton.IsEnabled = true; })); + }; + + //Adding the sound button to the personal list + personalButtonList.Add(soundsButton); + + //The view that will hold the general and personal lists + View mainView = new() + { + LayoutDirection = ViewLayoutDirectionType.LTR, + SizeHeight = height - (height / 12), + SizeWidth = width, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + }, + }; + + //Adding the general and personal lists to the main view + mainView.Add(generalButtonList); + mainView.Add(personalButtonList); + + AppBar = appBar; + Content = mainView; + BackgroundColor = Color.White; + } + } +} diff --git a/Mobile/NUI/SpeechToText/SpeechToText/views/SoundsPageView/SoundsPage.cs b/Mobile/NUI/SpeechToText/SpeechToText/views/SoundsPageView/SoundsPage.cs new file mode 100644 index 00000000..4e55c8bf --- /dev/null +++ b/Mobile/NUI/SpeechToText/SpeechToText/views/SoundsPageView/SoundsPage.cs @@ -0,0 +1,323 @@ +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; +using Tizen.NUI; +using Tizen.Applications; +using System; +using SpeechToText.Controllers; +using System.Collections.Generic; +using System.Linq; + +namespace SpeechToText.views.PreferencePageViews +{ + public class SoundsPage : ContentPage + { + /// + /// Custom defined color + /// + private readonly Color color = new("#40ACC6"); + + /// + /// Contains the absolute path to the application resource directory + /// + private readonly string directory = Application.Current.DirectoryInfo.Resource; + + public SoundsPage(float height, float width, SttController sttController, Action toggleSound, Action onPop) + { + //Back button used in the AppBar to pop the current page + Button backButton = new(new ButtonStyle() + { + Opacity = new Selector + { + Pressed = 0.5f, + Other = 1f + } + }) + { + BackgroundImage = directory + "images/back.png", + SizeWidth = 50, + SizeHeight = 50, + Margin = new Extents(25, 0, 0, 0), + }; + + backButton.Clicked += (object sender, ClickedEventArgs e) => + { + onPop(); + Navigator.Pop(); + }; + + //Creating AppBar and AppBar style + var mainAppBarTextStyle = new PropertyMap(); + mainAppBarTextStyle.Add("slant", new PropertyValue(FontSlantType.Normal.ToString())); + mainAppBarTextStyle.Add("width", new PropertyValue(FontWidthType.Expanded.ToString())); + mainAppBarTextStyle.Add("weight", new PropertyValue(FontWeightType.DemiBold.ToString())); + + //Creating the AppBar with one navigation button and without any additional buttons + AppBar appBar = new() + { + SizeHeight = height / 12, + SizeWidth = width, + BackgroundColor = color, + AutoNavigationContent = false, + ActionContent = new View() { SizeWidth = width * 0.1f }, + NavigationContent = backButton, + TitleContent = new TextLabel() + { + Text = "Sounds", + PointSize = 10, + TextColor = Color.White, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + FontStyle = mainAppBarTextStyle, + WidthSpecification = LayoutParamPolicies.MatchParent, + }, + }; + + //Scrollable view that holds the buttons + ScrollableBase scrollableBase = new() + { + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical + }, + ScrollingDirection = ScrollableBase.Direction.Vertical, + SizeHeight = height - height / 12, + SizeWidth = width, + ScrollEnabled = true, + }; + + //Sound button + //View that holdes switch and label for sound toggle + View soundView = new() + { + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Horizontal, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + Padding = new Extents(25, 0, 0, 0), + SizeWidth = width, + + }; + + //Text label that holds the sound button title + TextLabel soundTitle = new() + { + Text = "Sound", + PointSize = 7, + TextColor = Color.Black, + }; + + //Switch that enables and disables start and end sounds + Switch soundSwitch = new() + { + SizeWidth = width, + SizeHeight = height / 10, + SwitchBackgroundImageURLSelector = new StringSelector + { + Normal = directory + "images/switch/controller_switch_bg_off.png", + Selected = directory + "images/switch/controller_switch_bg_on.png", + Disabled = directory + "images/switch/controller_switch_bg_off_dim.png", + DisabledSelected = directory + "images/switch/controller_switch_bg_on_dim.png" + }, + SwitchHandlerImageURLSelector = new StringSelector + { + Normal = directory + "images/switch/controller_switch_handler.png", + Selected = directory + "images/switch/controller_switch_handler.png", + Disabled = directory + "images/switch/controller_switch_handler_dim.png", + DisabledSelected = directory + "images/switch/controller_switch_handler_dim.png", + }, + Margin = new Extents((ushort)(width * 0.7f), 0, 10, 10), + IsEnabled = true, + IsSelectable = true, + IsSelected = sttController.Sounds, + }; + + //Assigning event to switch + soundSwitch.SelectedChanged += (object sender, SelectedChangedEventArgs e) => + { + if (e.IsSelected) + { + sttController.Sounds = true; + toggleSound(true); + } + else + { + sttController.Sounds = false; + toggleSound(false); + }; + }; + + //Adding the title and value to the sound toggle + soundView.Add(soundTitle); + soundView.Add(soundSwitch); + + //Start sound button + //Button for selecting start sound + var startSoundButton = new Button() + { + ItemSpacing = new Size2D((int)(width * 0.08f), 0), + BackgroundColor = Color.Transparent, + TextColor = Color.Black, + TextAlignment = HorizontalAlignment.Center, + SizeHeight = height * 0.1f, + WidthSpecification = LayoutParamPolicies.MatchParent, + Padding = new Extents(25, 0, 0, 0), + PointSize = 6, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + }; + + //Displays the state of the start sound file + TextLabel startSoundValue = new() + { + Text = sttController.StartSound == null ? "None" : sttController.StartSound.Split('/').Last().Split(".wav").First(), + PointSize = 6, + TextColor = new Color(0, 0, 0, 0.6f), + }; + + //Title for the start sound button + TextLabel startSoundTitle = new() + { + Text = "Start Sound", + PointSize = 7, + TextColor = Color.Black, + }; + + //Assigning event to the start sound button + startSoundButton.TouchEvent += (object sender, TouchEventArgs e) => + { + if (e.Touch.GetState(0) == PointStateType.Started) + { + //Change the background color to give an efffect when pressed + startSoundButton.BackgroundColor = new Color(0, 0, 0, 0.2f); + } + if (e.Touch.GetState(0) == PointStateType.Leave) + { + //Return the background color to default + startSoundButton.BackgroundColor = Color.Transparent; + } + if (e.Touch.GetState(0) == PointStateType.Finished) + { + //To prevent double clicks + startSoundButton.IsEnabled = false; + + //Return the background color to default + startSoundButton.BackgroundColor = Color.Transparent; + MediaController mediaController = new(); + List sounds = mediaController.GetAvailableStartEndSounds(); + Navigator.Push(new PreferencesPage( + "Sounds", + height: height, + width: width, + currentPreferenceName: sttController.StartSound ?? "None", + preferences: sounds, + preferenceAction: delegate (string value) + { + sttController.StartSound = value == "None" ? null : value; + startSoundValue.Text = value.Split('/').Last().Split(".wav").First(); + }, + onPop: delegate () { startSoundButton.IsEnabled = true; } + ) + ); + } + return true; + }; + + //Adding the title and value to the start sound button + startSoundButton.Add(startSoundTitle); + startSoundButton.Add(startSoundValue); + + //End sound + //Button for selecting end sound + var endSoundButton = new Button() + { + ItemSpacing = new Size2D((int)(width * 0.08f), 0), + BackgroundColor = Color.Transparent, + TextColor = Color.Black, + TextAlignment = HorizontalAlignment.Center, + SizeHeight = height * 0.1f, + WidthSpecification = LayoutParamPolicies.MatchParent, + Padding = new Extents(25, 0, 0, 0), + PointSize = 6, + Layout = new LinearLayout() + { + LinearOrientation = LinearLayout.Orientation.Vertical, + HorizontalAlignment = HorizontalAlignment.Begin, + VerticalAlignment = VerticalAlignment.Center, + }, + }; + + //Displays the state of the end sound file + TextLabel endSoundValue = new() + { + Text = sttController.EndSound == null ? "None" : sttController.EndSound.Split('/').Last().Split(".wav").First(), + PointSize = 6, + TextColor = new Color(0, 0, 0, 0.6f), + }; + + //Title for the end sound button + TextLabel endSoundTitle = new() + { + Text = "End Sound", + PointSize = 7, + TextColor = Color.Black, + }; + + //Assigning event to the start sound button + endSoundButton.TouchEvent += (object sender, TouchEventArgs e) => + { + if (e.Touch.GetState(0) == PointStateType.Started) + { + //Change the background color to give an effect when pressed + endSoundButton.BackgroundColor = new Color(0, 0, 0, 0.2f); + } + if (e.Touch.GetState(0) == PointStateType.Leave) + { + //Return the background color to default + endSoundButton.BackgroundColor = Color.Transparent; + } + if (e.Touch.GetState(0) == PointStateType.Finished) + { + //To prevent double clicks + endSoundButton.IsEnabled = false; + + //Return the background color to default + endSoundButton.BackgroundColor = Color.Transparent; + MediaController mediaController = new(); + List sounds = mediaController.GetAvailableStartEndSounds(); + Navigator.Push(new PreferencesPage( + "Sounds", + height: height, + width: width, + currentPreferenceName: sttController.EndSound ?? "None", + preferences: sounds, + preferenceAction: delegate (string value) + { + sttController.EndSound = value == "None" ? null : value; + endSoundValue.Text = value.Split('/').Last().Split(".wav").First(); + }, + onPop : delegate () { endSoundButton.IsEnabled = true; } + )); + } + return true; + }; + + //Adding the title and value to the end sound button + endSoundButton.Add(endSoundTitle); + endSoundButton.Add(endSoundValue); + + //Adding button to the list + scrollableBase.Add(soundView); + scrollableBase.Add(startSoundButton); + scrollableBase.Add(endSoundButton); + + AppBar = appBar; + Content = scrollableBase; + } + } +}