Initialize mmi-voice-touch-app 34/282034/1
author이다예 <dyamy.lee@samsung.com>
Tue, 20 Sep 2022 07:36:57 +0000 (16:36 +0900)
committerdyamy-lee <dyamy.lee@samsung.com>
Mon, 26 Sep 2022 08:44:49 +0000 (17:44 +0900)
Change-Id: If42ee7614de342d9731dfe945d542bbd484b8f90

22 files changed:
VoiceTouch.sln [new file with mode: 0644]
voice-touch/ClickableObject.cs [new file with mode: 0644]
voice-touch/GridLayer.cs [new file with mode: 0644]
voice-touch/Interop/Interop.Libraries.cs [new file with mode: 0644]
voice-touch/Interop/Interop.Mmi.cs [new file with mode: 0644]
voice-touch/LottieAnimationLayer.cs [new file with mode: 0644]
voice-touch/TextBubbleLayer.cs [new file with mode: 0644]
voice-touch/TooltipLayer.cs [new file with mode: 0644]
voice-touch/VoiceTouch.cs [new file with mode: 0644]
voice-touch/VoiceTouch.csproj [new file with mode: 0644]
voice-touch/VoiceTouchEventManager.cs [new file with mode: 0644]
voice-touch/VoiceTouchMmi/ExceptionFactory.cs [new file with mode: 0644]
voice-touch/VoiceTouchMmi/SetResultEventArgs.cs [new file with mode: 0644]
voice-touch/VoiceTouchMmi/VoiceTouchMmiManager.cs [new file with mode: 0644]
voice-touch/VoiceTouchMmi/VoiceTouchResult.cs [new file with mode: 0644]
voice-touch/VoiceTouchViewManager.cs [new file with mode: 0644]
voice-touch/nuget.config [new file with mode: 0644]
voice-touch/res/images/tizen.png [new file with mode: 0644]
voice-touch/res/lottie.json [new file with mode: 0644]
voice-touch/res/theme/theme.xaml [new file with mode: 0644]
voice-touch/shared/res/VoiceTouch.png [new file with mode: 0644]
voice-touch/tizen-manifest.xml [new file with mode: 0644]

diff --git a/VoiceTouch.sln b/VoiceTouch.sln
new file mode 100644 (file)
index 0000000..57f1e8d
--- /dev/null
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31026.100
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VoiceTouch", "voice-touch\VoiceTouch.csproj", "{EE457A88-D143-4C62-A477-AA46D212C54F}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|Any CPU = Debug|Any CPU
+               Release|Any CPU = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {EE457A88-D143-4C62-A477-AA46D212C54F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+               {EE457A88-D143-4C62-A477-AA46D212C54F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+               {EE457A88-D143-4C62-A477-AA46D212C54F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+               {EE457A88-D143-4C62-A477-AA46D212C54F}.Release|Any CPU.Build.0 = Release|Any CPU
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {F48C7EF8-7CDC-44E8-9C68-A357BE805DB0}
+       EndGlobalSection
+EndGlobal
diff --git a/voice-touch/ClickableObject.cs b/voice-touch/ClickableObject.cs
new file mode 100644 (file)
index 0000000..45fc62f
--- /dev/null
@@ -0,0 +1,24 @@
+using System;
+
+namespace VoiceTouch
+{
+    public class ClickableObject
+    {
+        public int idx;
+        public int x;
+        public int y;
+        public int width;
+        public int height;
+        public string uiObjectText;
+
+        public ClickableObject (int idx, int x, int y, int w, int h, String text)
+        {
+            this.idx = idx;
+            this.x = x;
+            this.y = y;
+            this.width = w;
+            this.height = h;
+            this.uiObjectText = text;
+        }
+    }
+}
\ No newline at end of file
diff --git a/voice-touch/GridLayer.cs b/voice-touch/GridLayer.cs
new file mode 100644 (file)
index 0000000..6639196
--- /dev/null
@@ -0,0 +1,255 @@
+using System;
+using System.Collections.Generic;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using System.Threading.Tasks;
+
+namespace VoiceTouch
+{
+    public class GridLayer
+    {
+        View gridView = null;
+        View labelView = null;
+        List<View> firstLayerGridView;
+        List<View> secondLayerGridView;
+
+        List<View> firstLayerTextLabelView;
+        List<View> secondLayerTextLabelView;
+
+        View highlightGridView = null;
+        View highlightLabelView = null;
+        Timer highlightGridTimer = null;
+
+        static int textLabelMinWidth = 40;
+        static int textLabelMinHeight = 40;
+        static int firstLayerTextLabelWidthPad = 8;
+        static int firstLayerTextLabelHeightPad = 12;
+        static int secondLayerTextLabelPad = 4;
+
+
+        public GridLayer()
+        {
+            firstLayerGridView = new List<View>();
+            secondLayerGridView = new List<View>();
+            firstLayerTextLabelView = new List<View>();
+            secondLayerTextLabelView = new List<View>();
+        }
+
+        public void ClearGrid()
+        {
+            foreach (var view in secondLayerTextLabelView)
+            {
+                view.Unparent();
+                view.Dispose();
+            }
+            secondLayerTextLabelView.Clear();
+
+            foreach (var view in firstLayerTextLabelView)
+            {
+                view.Unparent();
+                view.Dispose();
+            }
+            firstLayerTextLabelView.Clear();
+
+            foreach (var view in secondLayerGridView)
+            {
+                view.Unparent();
+                view.Dispose();
+            }
+            secondLayerGridView.Clear();
+
+            foreach (var view in firstLayerGridView)
+            {
+                view.Unparent();
+                view.Dispose();
+            }
+            firstLayerGridView.Clear();
+
+            if (labelView != null)
+            {
+                labelView.Unparent();
+                labelView.Dispose();
+                labelView = null;
+            }
+
+            if (gridView != null)
+            {
+                gridView.Unparent();
+                gridView.Dispose();
+                gridView = null;
+            }
+        }
+
+        public void CreateFirstLevelGrid(List<ClickableObject> grids)
+        {
+            ClearGrid();
+            gridView = new View()
+            {
+                BackgroundColor = Color.Transparent,
+                Size = Window.Instance.WindowSize,
+            };
+
+            Window.Instance.Add(gridView);
+
+            labelView = new View();
+            Window.Instance.Add(labelView);
+
+            foreach (var grid in grids)
+            {
+                int col = (grid.idx - 1) % 7 + 1;
+                int row = (grid.idx - 1) / 7;
+                View boxView = new View()
+                {
+                    BorderlineColor = Color.LightGray, // TODO: Change to white when Default Headed UI changed
+                    BorderlineWidth = 1.5f,
+                    BorderlineOffset = -1f,
+                    BackgroundColor = Color.Transparent,
+                    Size = new Size(grid.width, grid.height),
+                    Position = new Position(grid.x, grid.y)
+                };
+                firstLayerGridView.Add(boxView);
+                gridView.Add(boxView);
+
+                TextLabel indexTextLabel = new TextLabel()
+                {
+                    Text = grid.idx.ToString(),
+                    BackgroundColor = new Color("#181E36"),
+                    MinimumSize = new Size(textLabelMinWidth, textLabelMinHeight),
+                    WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                    TextColor = new Color("#FAFAFA"),
+                    HorizontalAlignment = HorizontalAlignment.Center,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    CornerRadius = new Vector4(0, 12, 0, 12),
+                    Padding = new Extents(10, 10, 4, 4),
+                };
+
+                View indexView = new View()
+                {
+                    WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                };
+                float stride = (indexTextLabel.NaturalSize.Width < textLabelMinWidth) ? textLabelMinWidth : indexTextLabel.NaturalSize.Width;
+                indexTextLabel.Position = new Position(col * grid.width - stride - firstLayerTextLabelWidthPad, row * grid.height + firstLayerTextLabelHeightPad);
+                indexView.Add(indexTextLabel);
+                firstLayerTextLabelView.Add(indexView);
+                labelView.Add(indexView);
+            }
+        }
+
+        public void CreateSecondLevelGrid(List<ClickableObject> grids)
+        {
+            if(firstLayerTextLabelView.Count == 0)
+            {
+                return;
+            }
+            foreach (var view in firstLayerTextLabelView)
+            {
+                view.Unparent();
+                view.Dispose();
+            }
+            firstLayerTextLabelView.Clear();
+
+            float basePositionX = grids[0].x;
+            float basePositionY = grids[0].y;
+            foreach (var grid in grids)
+            {
+                int col = (grid.idx - 1) % 4 + 1;
+                int row = (grid.idx - 1) / 4;
+                
+
+                TextLabel indexTextLabel = new TextLabel()
+                {
+                    Text = grid.idx.ToString(),
+                    BackgroundColor = new Color("#181E36"),
+                    MinimumSize = new Size2D(textLabelMinWidth, textLabelMinHeight),
+                    WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                    TextColor = new Color("#FAFAFA"),
+                    HorizontalAlignment = HorizontalAlignment.Center,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    CornerRadius = new Vector4(0, 12, 0, 12),
+                    Padding = new Extents(10, 10, 4, 4),
+                };
+
+                View indexView = new View()
+                {
+                    WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                };
+                float stride = (indexTextLabel.NaturalSize.Width < textLabelMinWidth) ? textLabelMinWidth : indexTextLabel.NaturalSize.Width;
+                indexTextLabel.Position = new Position(basePositionX + col * grid.width - stride - secondLayerTextLabelPad, basePositionY + row * grid.height + secondLayerTextLabelPad);
+                indexView.Add(indexTextLabel);
+                secondLayerTextLabelView.Add(indexView);
+                labelView.Add(indexView);
+
+                View boxView = new View()
+                {
+                    BorderlineColor = Color.LightGray, // TODO: Change to white when Default Headed UI changed
+                    BorderlineWidth = 1.5f,
+                    BorderlineOffset = -1f,
+                    BackgroundColor = Color.Transparent,
+                    Size = new Size(grid.width, grid.height),
+                    Position = new Position(grid.x, grid.y)
+                };
+                secondLayerGridView.Add(boxView);
+                gridView.Add(boxView);
+                boxView.RaiseToTop();
+            }
+        }
+
+        public void ClearHighlightedGrid()
+        {
+            if (highlightGridView != null)
+            {
+                highlightGridView.Unparent();
+                highlightGridView.Dispose();
+                highlightGridView = null;
+            }
+
+            if (highlightLabelView != null)
+            {
+                highlightLabelView.Unparent();
+                highlightLabelView.Dispose();
+                highlightLabelView = null;
+            }
+        }
+
+        public void HighlightGrid(ClickableObject obj, int selected)
+        {
+            if (highlightGridView != null)
+            {
+                return;
+            }
+            View targetGridView = secondLayerGridView[selected - 1];
+            View targetLabelView = secondLayerTextLabelView[selected - 1].GetChildAt(0);
+            highlightGridView = new View()
+            {
+                BorderlineColor = new Color("#FF6200"),
+                BorderlineWidth = 2.0f,
+                BorderlineOffset = -1f,
+                BackgroundColor = Color.Transparent,
+                Size = new Size(obj.width, obj.height),
+                Position = new Position(obj.x, obj.y),
+            };
+            TextLabel indexTextLabel = new TextLabel()
+            {
+                Text = selected.ToString(),
+                BackgroundColor = new Color("#FF6200"),
+                MinimumSize = new Size2D(textLabelMinWidth, textLabelMinHeight),
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                TextColor = new Color("#FAFAFA"),
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center,
+                CornerRadius = new Vector4(0, 12, 0, 12),
+                Padding = new Extents(10, 10, 4, 4),
+                Position = new Position(targetLabelView.Position.X, targetLabelView.Position.Y),
+            };
+            highlightLabelView = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+            };
+            highlightLabelView.Add(indexTextLabel);
+            ClearGrid();
+            Window.Instance.Add(highlightGridView);
+            Window.Instance.Add(highlightLabelView);
+        }
+    }
+}
diff --git a/voice-touch/Interop/Interop.Libraries.cs b/voice-touch/Interop/Interop.Libraries.cs
new file mode 100644 (file)
index 0000000..385da53
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 2022 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.
+*/
+
+/// <summary>
+/// Partial Interop Class
+/// </summary>
+
+internal static partial class Interop
+{
+    /// <summary>
+    /// Partial libraries class.
+    /// </summary>
+    internal static partial class Libraries
+    {
+        internal const string Mmi = "libmmi.so";
+    }
+}
\ No newline at end of file
diff --git a/voice-touch/Interop/Interop.Mmi.cs b/voice-touch/Interop/Interop.Mmi.cs
new file mode 100644 (file)
index 0000000..331cd23
--- /dev/null
@@ -0,0 +1,39 @@
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Mmi
+    {
+        internal static string LogTag = "Tizen.Mmi";
+
+        private const int ErrorMmi = -0x030F0000;
+
+        internal enum MmiError
+        {
+            None = Tizen.Internals.Errors.ErrorCode.None,                           /* Successful */
+            OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,             /* Out of Memory */
+            IoError = Tizen.Internals.Errors.ErrorCode.IoError,                     /* I/O error */
+            InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,   /* Invalid parameter */
+            TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,                   /* No answer from service */
+            PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,   /* Permission denied */
+            NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,           /* MMI NOT supported */
+            OperationFailed = ErrorMmi | 0x01,                                      /* Operation failed */
+        };
+
+        [DllImport(Libraries.Mmi, EntryPoint = "mmi_initialize")]
+        internal static extern MmiError MmiInitialize();
+
+        [DllImport(Libraries.Mmi, EntryPoint = "mmi_deinitialize")]
+        internal static extern MmiError MmiDeinitialize();
+
+        [DllImport(Libraries.Mmi, EntryPoint = "mmi_set_result_cb")]
+        internal static extern MmiError MmiSetResultCb(int input_event_type, MMIResult callback, IntPtr user_data);
+
+        [DllImport(Libraries.Mmi, EntryPoint = "mmi_activate_input_event")]
+        internal static extern MmiError MmiActivateInputEvent(int input_event_type);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        internal delegate void MMIResult(IntPtr user_data, int input_event_type, IntPtr result_out);
+    }
+}
\ No newline at end of file
diff --git a/voice-touch/LottieAnimationLayer.cs b/voice-touch/LottieAnimationLayer.cs
new file mode 100644 (file)
index 0000000..21558d1
--- /dev/null
@@ -0,0 +1,165 @@
+using System;
+using System.Collections.Generic;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace VoiceTouch
+{
+    public class LottieAnimationLayer
+    {
+        LottieAnimationView mLottie = null;
+        internal static string lottieURL = Tizen.Applications.Application.Current.DirectoryInfo.Resource + "lottie.json";
+
+        internal static int lottieSize = 124;
+        internal static int lottieRightPad = 82;
+        internal static int lottieAbovePad = 71;
+
+        // move
+        Animation moveAnimation;
+        KeyFrames keyFrames;
+        // Scale
+        Animation scaleAnimation;
+        //KeyFrames keyFrames;
+        // Opacity
+        Animation opacityAnimation;
+        // Size
+        Animation sizeAnimation;
+        public LottieAnimationLayer()
+        {
+
+        }
+
+        public void CreateLottie()
+        {
+            if (mLottie != null)
+            {
+                return;
+            }
+            mLottie = new LottieAnimationView();
+            mLottie.URL = lottieURL;
+            Window.Instance.Add(mLottie);
+            mLottie.Size2D = new Size2D(lottieSize, lottieSize);
+            mLottie.Position2D = new Position2D(Window.Instance.Size.Width - lottieSize - lottieRightPad, lottieAbovePad);
+            mLottie.LoopCount = -1;
+            mLottie.ScaleX = 0.0f;
+            mLottie.ScaleY = 0.0f;
+            mLottie.ScaleZ = 0.0f;
+            mLottie.Opacity = 0.0f;
+            mLottie.DrawMode = DrawModeType.Overlay2D;
+            mLottie.Play();
+            ApplyScaleAnimation(1.0f, 1.0f, 1.0f, 500, AlphaFunction.BuiltinFunctions.EaseIn);
+            ApplyOpacityAnimation(1.0f, 333, AlphaFunction.BuiltinFunctions.EaseIn);
+        }
+
+        public bool ClearLottie(object target, Timer.TickEventArgs args)
+        {
+            if (mLottie != null)
+            {
+                mLottie.Unparent();
+                mLottie.Dispose();
+                mLottie = null;
+            }
+            return false;
+        }
+
+        public void Clear()
+        {
+            ApplyScaleAnimation(1.2f, 1.2f, 1.2f, 500, AlphaFunction.BuiltinFunctions.EaseOut);
+            ApplyOpacityAnimation(0.0f, 333, AlphaFunction.BuiltinFunctions.EaseOut);
+            Timer timer = new Timer(500);
+            timer.Tick += ClearLottie;
+            timer.Start();
+        }
+
+        // move
+
+        void moveAnimationFinished(object sender, EventArgs e)
+        {
+            mLottie.Size2D = new Size2D(lottieSize, lottieSize);
+            mLottie.Position2D = new Position2D(Window.Instance.Size.Width - lottieSize - lottieRightPad, lottieAbovePad);
+        }
+
+        void ResetMoveAnimation(int X, int Y)
+        {
+            //Reset previous moving animation
+            if (moveAnimation)
+            {
+                moveAnimation.Stop();
+                moveAnimation.Dispose();
+            }
+
+            moveAnimation = new Animation(1000);
+
+            //Apply EaseInOut AlphaFunction for Acceleration
+            moveAnimation.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseInOutSine);
+            moveAnimation.Finished += moveAnimationFinished;
+
+            //Scale Keyframe Animation for Acceleration
+            keyFrames = new KeyFrames();
+            keyFrames.Add(0.0f, new Position(1.0f, 1.0f));
+            keyFrames.Add(0.5f, new Position(0.85f, 0.85f));
+            keyFrames.Add(1.0f, new Position(1.0f, 1.0f));
+            moveAnimation.AnimateBetween(mLottie, "Scale", keyFrames);
+        }
+
+        public void ApplyMoveAnimation(int X, int Y)
+        {
+            ResetMoveAnimation(X, Y);
+            Vector2 pos = new Vector2(X, Y);
+
+            moveAnimation.AnimateTo(mLottie, "PositionX", pos.X);
+            moveAnimation.AnimateTo(mLottie, "PositionY", pos.Y);
+            moveAnimation.Play();
+        }
+
+        private void ScaleAnimationFinished(object sender, EventArgs e)
+        {
+            mLottie.Play();
+        }
+
+        public void ApplyScaleAnimation(float x, float y, float z, int milliseconds, AlphaFunction.BuiltinFunctions func)
+        {
+            scaleAnimation = new Animation(milliseconds);
+            scaleAnimation.DefaultAlphaFunction = new AlphaFunction(func);
+            scaleAnimation.Finished += ScaleAnimationFinished;
+            Vector3 scale = new Vector3(x, y, z);
+
+            scaleAnimation.AnimateTo(mLottie, "ScaleX", scale.X);
+            scaleAnimation.AnimateTo(mLottie, "ScaleY", scale.Y);
+            scaleAnimation.AnimateTo(mLottie, "ScaleZ", scale.Z);
+            scaleAnimation.Play();
+        }
+
+        private void OpacityAnimationFinished(object sender, EventArgs e)
+        {
+            mLottie.Play();
+        }
+
+        public void ApplyOpacityAnimation(float value, int milliseconds, AlphaFunction.BuiltinFunctions func)
+        {
+            opacityAnimation = new Animation(milliseconds);
+            opacityAnimation.DefaultAlphaFunction = new AlphaFunction(func);
+            opacityAnimation.Finished += OpacityAnimationFinished;
+
+            opacityAnimation.AnimateTo(mLottie, "Opacity", value);
+            opacityAnimation.Play();
+        }
+
+        private void SizeAnimationFinished(object sender, EventArgs e)
+        {
+            mLottie.Play();
+        }
+
+        public void ApplySizeAnimation(int height, int pos, int milliseconds, AlphaFunction.BuiltinFunctions func)
+        {
+            sizeAnimation = new Animation(milliseconds);
+            sizeAnimation.DefaultAlphaFunction = new AlphaFunction(func);
+            sizeAnimation.Finished += SizeAnimationFinished;
+
+            sizeAnimation.AnimateTo(mLottie, "SizeHeight", height);
+            sizeAnimation.AnimateTo(mLottie, "PositionY", pos);
+            sizeAnimation.Play();
+        }
+    }
+}
\ No newline at end of file
diff --git a/voice-touch/TextBubbleLayer.cs b/voice-touch/TextBubbleLayer.cs
new file mode 100644 (file)
index 0000000..4223f80
--- /dev/null
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace VoiceTouch
+{
+    public class TextBubbleLayer
+    {
+        View mView = null;
+        TextLabel mTextBubble = null;
+        static readonly int minWidth = 88;
+        static readonly int minHeight = 80;
+        static readonly int maxWidth = 788;
+        static readonly int maxHeight = 144;
+        static Position2D rightTop;
+
+        public TextBubbleLayer()
+        {
+            rightTop = new Position2D(1920 - 208, 93);
+        }
+
+        public void CleartextBubbles()
+        {
+            if(mView)
+            {
+                mView.Unparent();
+                mView.Dispose();
+                mView = null;
+            }
+        }
+
+        public void CreateTextBubble(string text, Color color)
+        {
+            if (mView)
+            {
+                CleartextBubbles();
+            }
+
+            mTextBubble = new TextLabel()
+            {
+                Text = text,
+                BackgroundColor = new Color("#DBE3FF"),
+                MinimumSize = new Size2D(minWidth, minHeight),
+                MaximumSize = new Size2D(maxWidth, maxHeight),
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                TextColor = color,
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center,
+                CornerRadius = new Vector4(40, 40, 40, 40),
+                Padding = new Extents(24, 24, 24, 24),
+            };
+            mView = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+            };
+            float stride = (mTextBubble.NaturalSize.Width > minWidth) ? mTextBubble.NaturalSize.Width : minWidth;
+            mTextBubble.Position = new Position(rightTop.X - stride, rightTop.Y);
+
+            // TODO: Needs to be adjusted width, height according to proper length. After Integration.
+            if (mTextBubble.NaturalSize.Width > maxWidth)
+            {
+                mTextBubble = new TextLabel()
+                {
+                    Text = text,
+                    BackgroundColor = new Color("#DBE3FF"),
+                    Size = new Size(maxWidth, maxHeight),
+                    TextColor = color,
+                    HorizontalAlignment = HorizontalAlignment.Center,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    CornerRadius = new Vector4(40, 40, 40, 40),
+                    Padding = new Extents(24, 24, 24, 24),
+                    MultiLine = true,
+                };
+                mView = new View()
+                {
+                    Size2D = new Size2D(maxWidth, maxHeight),
+                };
+                mTextBubble.Position = new Position(rightTop.X - maxWidth, rightTop.Y);
+            }
+
+            mView.Add(mTextBubble);
+            Window.Instance.Add(mView);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/voice-touch/TooltipLayer.cs b/voice-touch/TooltipLayer.cs
new file mode 100644 (file)
index 0000000..544049b
--- /dev/null
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace VoiceTouch
+{
+    public class TooltipLayer
+    {
+        List<View> tooltips;
+
+        Timer highlightObjectTimer = null;
+        View highlightObjectView = null;
+
+        View highlightTooltipView = null;
+        Timer highlightTooltipTimer = null;
+
+        static readonly int minWidth = 40;
+        static readonly int tooltipHeight = 40;
+
+        public TooltipLayer()
+        {
+            tooltips = new List<View>();
+        }
+
+        public void ClearTooltips()
+        {
+            foreach (var tooltip in tooltips)
+            {
+                tooltip.Unparent();
+                tooltip.Dispose();
+            }
+            tooltips.Clear();
+        }
+
+        public void CreateNumberTooltips(List<ClickableObject> elements)
+        {
+            if (tooltips.Count > 0)
+            {
+                ClearTooltips();
+            }
+            foreach (var element in elements)
+            {
+                CreateTooltip(element.idx.ToString(), element.x, element.y, element.width, element.height);
+            }
+        }
+
+        public void CreateNameTooltips(List<ClickableObject> elements)
+        {
+            if (tooltips.Count > 0)
+            {
+                ClearTooltips();
+            }
+            foreach (var element in elements)
+            {
+                CreateTooltip(element.uiObjectText, element.x, element.y, element.width, element.height);
+            }
+        }
+
+        private void CreateTooltip(string text, int x, int y, int w, int h)
+        {
+            TextLabel tooltipTextLabel = new TextLabel()
+            {
+                Text = text,
+                BackgroundColor = new Color("#181E36"),
+                MinimumSize = new Size2D(minWidth, tooltipHeight),
+                MaximumSize = new Size2D(w, tooltipHeight),
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                TextColor = new Color("#FAFAFA"),
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center,
+                CornerRadius = new Vector4(0, 12, 0, 12),
+                Padding = new Extents(10, 10, 4, 4),
+            };
+
+            View tooltipView = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+            };
+            float stride = (tooltipTextLabel.NaturalSize.Width < minWidth) ? minWidth : tooltipTextLabel.NaturalSize.Width;
+            tooltipTextLabel.Position = new Position(x + w - stride, y);
+
+            if (tooltipTextLabel.NaturalSize.Width > w)
+            {
+                tooltipTextLabel = new TextLabel()
+                {
+                    Text = text,
+                    BackgroundColor = new Color("#181E36"),
+                    Size = new Size(w, tooltipHeight),
+                    TextColor = new Color("#FAFAFA"),
+                    HorizontalAlignment = HorizontalAlignment.Center,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    CornerRadius = new Vector4(0, 12, 0, 12),
+                    Padding = new Extents(10, 10, 4, 4),
+                };
+
+                tooltipView = new View()
+                {
+                    Size2D = new Size2D(w, tooltipHeight),
+                };
+                tooltipTextLabel.Position = new Position(x + w - tooltipTextLabel.NaturalSize.Width, y);
+            }
+
+            tooltipView.Add(tooltipTextLabel);
+            tooltips.Add(tooltipView);
+            Window.Instance.Add(tooltipView);
+        }
+
+        public void ClearHighlightedTooltip()
+        {
+            if(highlightTooltipView != null)
+            {
+                highlightTooltipView.Unparent();
+                highlightTooltipView.Dispose();
+                highlightTooltipView = null;
+            }
+        }
+
+        public void HighlightTooltip(ClickableObject obj, string tooltipType)
+        {
+            if (highlightTooltipView != null)
+            {
+                return;
+            }
+            ClearTooltips();
+            string text = obj.idx.ToString();
+            if (tooltipType == "tooltipNumber")
+            {
+                text = obj.idx.ToString();
+            }
+            else if (tooltipType == "tooltipText")
+            {
+                text = obj.uiObjectText;
+            }
+            TextLabel tooltipTextLabel = new TextLabel()
+            {
+                Text = text,
+                BackgroundColor = new Color("#FF6200"),
+                MinimumSize = new Size2D(minWidth, tooltipHeight),
+                MaximumSize = new Size2D(obj.width, tooltipHeight),
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+                TextColor = new Color("#FAFAFA"),
+                HorizontalAlignment = HorizontalAlignment.Center,
+                VerticalAlignment = VerticalAlignment.Center,
+                CornerRadius = new Vector4(0, 12, 0, 12),
+                Padding = new Extents(10, 10, 4, 4),
+            };
+
+            highlightTooltipView = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.UseNaturalSize,
+            };
+            float stride = (tooltipTextLabel.NaturalSize.Width < (minWidth)) ? (minWidth) : tooltipTextLabel.NaturalSize.Width;
+            tooltipTextLabel.Position = new Position(obj.x + obj.width - stride, obj.y);
+
+            if (tooltipTextLabel.NaturalSize.Width > obj.width)
+            {
+                tooltipTextLabel = new TextLabel()
+                {
+                    Text = text,
+                    BackgroundColor = new Color("#FF6200"),
+                    Size = new Size(obj.width, tooltipHeight),
+                    TextColor = new Color("#FAFAFA"),
+                    HorizontalAlignment = HorizontalAlignment.Center,
+                    VerticalAlignment = VerticalAlignment.Center,
+                    CornerRadius = new Vector4(0, 12, 0, 12),
+                    Padding = new Extents(10, 10, 4, 4),
+                };
+
+                highlightTooltipView = new View()
+                {
+                    Size2D = new Size2D(obj.width, tooltipHeight),
+                };
+                tooltipTextLabel.Position = new Position(obj.x + obj.width - tooltipTextLabel.NaturalSize.Width, obj.y);
+            }
+
+            highlightTooltipView.Add(tooltipTextLabel);
+            Window.Instance.Add(highlightTooltipView);
+        }
+    }
+}
diff --git a/voice-touch/VoiceTouch.cs b/voice-touch/VoiceTouch.cs
new file mode 100644 (file)
index 0000000..e608273
--- /dev/null
@@ -0,0 +1,70 @@
+using Tizen.Applications;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using VoiceTouch.VoiceTouchMmi;
+using static VoiceTouch.VoiceTouchMmi.VoiceTouchMmiManager;
+
+using Tizen.NUI.Components;
+using System;
+using System.Collections.Generic;
+
+namespace VoiceTouch
+{
+    public class VoiceTouch : NUIApplication
+    {
+        internal static string LogTag = "Tizen.Mmi";
+
+        protected VoiceTouchMmiManager mVoiceTouchMmiManager = null;
+        protected VoiceTouchEventManager mVtObject = null;
+        protected VoiceTouchViewManager mVoiceTouchViewManager = null;
+
+        override protected void OnCreate()
+        {
+            base.OnCreate();
+
+            Window window = Window.Instance;
+            window.Type = WindowType.Notification;
+            window.SetNotificationLevel(NotificationLevel.Top);
+            window.SetTransparency(true);
+            window.BackgroundColor = Color.Transparent;
+            window.SetAcceptFocus(true);
+            window.SetInputRegion(new Rectangle(0, 0, 0, 0));
+
+            mVoiceTouchMmiManager = new VoiceTouchMmiManager();
+            mVtObject = new VoiceTouchEventManager();
+            mVoiceTouchViewManager = VoiceTouchViewManager.Instance;
+
+            mVoiceTouchMmiManager.VoiceTouchMmiIinitialize();
+            mVoiceTouchMmiManager.VoiceTouchMmiSetResultCb(InputEventTypeEnum.MMI_INPUT_EVENT_TYPE_VOICE_TOUCH, mVtObject.VoiceTouchResult);
+
+            int state = mVoiceTouchMmiManager.VoiceTouchActivate((int)InputEventTypeEnum.MMI_INPUT_EVENT_TYPE_VOICE_TOUCH);
+
+            mVoiceTouchViewManager.ShowVoiceTouchLottie(); // show when mmi manager connected/activated?
+        }
+        override protected void OnPause()
+        {
+            base.OnPause();
+        }
+
+        override protected void OnResume()
+        {
+            base.OnResume();
+        }
+
+        override protected void OnTerminate()
+        {
+            base.OnTerminate();
+        }
+
+        override protected void OnAppControlReceived(AppControlReceivedEventArgs e)
+        {
+            base.OnAppControlReceived(e);
+        }
+
+        static void Main(string[] args)
+        {
+            VoiceTouch Instance = new VoiceTouch();
+            Instance.Run(args);
+        }
+    }
+}
diff --git a/voice-touch/VoiceTouch.csproj b/voice-touch/VoiceTouch.csproj
new file mode 100644 (file)
index 0000000..6c6bb3f
--- /dev/null
@@ -0,0 +1,35 @@
+<Project Sdk="Tizen.NET.Sdk/1.1.8">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>tizen10.0</TargetFramework>
+    <DisableImplicitTizenReferences>True</DisableImplicitTizenReferences>
+  </PropertyGroup>
+
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugType>portable</DebugType>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>None</DebugType>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="*.xaml">
+      <Generator>MSBuild:Compile</Generator>
+    </EmbeddedResource>
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+    <PackageReference Include="Tizen.NET" Version="10.0.0.17319" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="res\layout\" />
+  </ItemGroup>
+
+  <PropertyGroup>
+    <XamlOptimization>1</XamlOptimization>
+  </PropertyGroup>
+
+</Project>
diff --git a/voice-touch/VoiceTouchEventManager.cs b/voice-touch/VoiceTouchEventManager.cs
new file mode 100644 (file)
index 0000000..3ccf4f7
--- /dev/null
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using VoiceTouch.VoiceTouchMmi;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace VoiceTouch
+{
+    public class VoiceTouchEventManager
+    {
+        internal static string LogTag = "Tizen.Mmi.EventManager";
+        protected VoiceTouchViewManager mVoiceTouchViewManager = VoiceTouchViewManager.Instance;
+
+        public void VoiceTouchResult(object sender, SetResultEventArgs e)
+        {
+            Tizen.Log.Debug(LogTag, "VoiceTouchResult | type : " + e.InputEventType + ", stirng : " + e.ResultOut);
+            
+            VoiceTouchResult voiceTouchResult = JsonConvert.DeserializeObject<VoiceTouchResult>(e.ResultOut);
+
+            mVoiceTouchViewManager.ShowTooltip(voiceTouchResult.uiClickableObject.infoOfClickableObjects, voiceTouchResult.uiClickableObject.tooltipType);
+        }
+    }
+}
diff --git a/voice-touch/VoiceTouchMmi/ExceptionFactory.cs b/voice-touch/VoiceTouchMmi/ExceptionFactory.cs
new file mode 100644 (file)
index 0000000..82a34c4
--- /dev/null
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using static Interop.Mmi;
+
+namespace VoiceTouch.VoiceTouchMmi
+{
+    internal static class ExceptionFactory
+    {
+        internal static Exception CreationException(MmiError err)
+        {
+            Tizen.Log.Error(LogTag, "Error" + err);
+            Exception exp;
+            switch (err)
+            {
+                case MmiError.OutOfMemory:
+                    {
+                        exp = new OutOfMemoryException("Out Of Memory");
+                        break;
+                    }
+
+                case MmiError.IoError:
+                    {
+                        exp = new InvalidOperationException("I/O Error Occurred");
+                        break;
+                    }
+
+                case MmiError.InvalidParameter:
+                    {
+                        exp = new ArgumentException("Invalid Parameters Provided");
+                        break;
+                    }
+
+                case MmiError.TimedOut:
+                    {
+                        exp = new TimeoutException("No answer from the MMI service");
+                        break;
+                    }
+
+                case MmiError.PermissionDenied:
+                    {
+                        exp = new UnauthorizedAccessException("Permission Denied");
+                        break;
+                    }
+
+                case MmiError.NotSupported:
+                    {
+                        exp = new NotSupportedException("MMI NOT supported");
+                        break;
+                    }
+
+                case MmiError.OperationFailed:
+                    {
+                        exp = new NotSupportedException("MMI OperationFailed");
+                        break;
+                    }
+                default:
+                    {
+                        exp = new Exception("");
+                        break;
+                    }
+            }
+            return exp;
+        }
+    }
+}
diff --git a/voice-touch/VoiceTouchMmi/SetResultEventArgs.cs b/voice-touch/VoiceTouchMmi/SetResultEventArgs.cs
new file mode 100644 (file)
index 0000000..3f7e243
--- /dev/null
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+
+namespace VoiceTouch.VoiceTouchMmi
+{
+    public class SetResultEventArgs
+    {
+        internal SetResultEventArgs(int input_event_type, string result_out)
+        {
+            this.InputEventType = input_event_type;
+            this.ResultOut = result_out;
+        }
+
+        public int InputEventType
+        {
+            get;
+            internal set;
+        }
+        public string ResultOut
+        {
+            get;
+            internal set;
+        }
+    }
+}
diff --git a/voice-touch/VoiceTouchMmi/VoiceTouchMmiManager.cs b/voice-touch/VoiceTouchMmi/VoiceTouchMmiManager.cs
new file mode 100644 (file)
index 0000000..0c12995
--- /dev/null
@@ -0,0 +1,146 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+using static Interop.Mmi;
+
+namespace VoiceTouch.VoiceTouchMmi
+{
+    public class VoiceTouchMmiManager
+    {
+        /// <summary>
+        /// Enumeration for error values that can occur.
+        /// </summary>
+        /// <since_tizen> 7 </since_tizen>
+        public enum Error
+        {
+            /// <summary>
+            /// Successful, no error.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            None,
+            /// <summary>
+            /// Out of memory.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            OutOfMemory,
+            /// <summary>
+            /// I/O error.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            IoError,
+            /// <summary>
+            /// Invalid parameter.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            InvalidParameter,
+            /// <summary>
+            /// No answer from the MMI service.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            TimedOut,
+            /// <summary>
+            /// Network is down.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            OutOfNetwork,
+            /// <summary>
+            /// Permission denied.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            PermissionDenied,
+            /// <summary>
+            /// MMI not supported.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            NotSupported,
+            /// <summary>
+            /// MMI operation failed.
+            /// </summary>
+            /// <since_tizen> 7 </since_tizen>
+            OperationFailed,
+        };
+
+        public enum InputEventTypeEnum
+        {
+            MMI_INPUT_EVENT_TYPE_NONE,
+            MMI_INPUT_EVENT_TYPE_VOICE_TOUCH,
+            MMI_INPUT_EVENT_TYPE_VOICE_RECOGNITION
+        };
+
+        private MMIResult _resultDelegate;
+        private event EventHandler<SetResultEventArgs> _mmiResultVoiceTouch;
+
+        public void VoiceTouchMmiIinitialize()
+        {
+            Tizen.Log.Debug(LogTag, "Enter Init");
+            MmiError error = MmiInitialize();
+            if (error != MmiError.None)
+            {
+                Tizen.Log.Error(LogTag, "Initialize Failed with error " + error);
+                throw ExceptionFactory.CreationException(error);
+            }
+            Tizen.Log.Debug(LogTag, "End Init");
+        }
+
+        public void VoiceTouchMmiDeinitialize()
+        {
+            Tizen.Log.Debug(LogTag, "Enter DeInit");
+            MmiError error = MmiDeinitialize();
+            if (error != MmiError.None)
+            {
+                Tizen.Log.Error(LogTag, "DeInitialize Failed with error " + error);
+                throw ExceptionFactory.CreationException(error);
+            }
+            Tizen.Log.Debug(LogTag, "End DeInit");
+        }
+
+        public void VoiceTouchMmiSetResultCb(InputEventTypeEnum input_event_type, EventHandler<SetResultEventArgs> handler)
+        {
+            Tizen.Log.Debug(LogTag, "Enter VoiceTouchMmiSetResultCb");
+            if (input_event_type == InputEventTypeEnum.MMI_INPUT_EVENT_TYPE_VOICE_TOUCH)
+                MmiResultVoiceTouch += handler;
+        }
+
+        public int VoiceTouchActivate(int input_event_type)
+        {
+            MmiError error = MmiActivateInputEvent(input_event_type);
+            if (error != MmiError.None)
+            {
+                Tizen.Log.Error(LogTag, "Activate InputEvent with error " + error);
+                //throw ExceptionFactory.CreationException(error);
+            }
+            return 0;
+        }
+
+        public event EventHandler<SetResultEventArgs> MmiResultVoiceTouch
+        {
+            add
+            {
+                if (_mmiResultVoiceTouch == null)
+                {
+                    _resultDelegate = (IntPtr userData, int input_event_type, IntPtr result_out) =>
+                    {
+                        string resultOutString = Marshal.PtrToStringAnsi(result_out);
+                        SetResultEventArgs args = new SetResultEventArgs(input_event_type, resultOutString);
+                        _mmiResultVoiceTouch?.Invoke(null, args);
+                    };
+                    MmiError error = MmiSetResultCb((int)InputEventTypeEnum.MMI_INPUT_EVENT_TYPE_VOICE_TOUCH, _resultDelegate, IntPtr.Zero);
+                    if (error != MmiError.None)
+                    {
+                        Tizen.Log.Error(LogTag, "Add MmiResultVoiceTouch EventHandler Failed with Error " + error);
+                    }
+                }
+                _mmiResultVoiceTouch += value;
+            }
+            remove
+            {
+                _mmiResultVoiceTouch -= value;
+                if(_mmiResultVoiceTouch == null)
+                {
+                    Tizen.Log.Debug(LogTag, "Remove MmiResultVoiceTouch EventHandler");
+                }
+            }
+        }
+    }
+}
diff --git a/voice-touch/VoiceTouchMmi/VoiceTouchResult.cs b/voice-touch/VoiceTouchMmi/VoiceTouchResult.cs
new file mode 100644 (file)
index 0000000..2b7bdb3
--- /dev/null
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace VoiceTouch.VoiceTouchMmi
+{
+    class VoiceTouchResult
+    {
+        public string inputEvent;
+        public List<string> outputEvent;
+        public UiClickableObject uiClickableObject;
+        public ASRResult asrPartialResult;
+        public ASRResult asrFinalResult;
+    }
+    class UiClickableObject
+    {
+        public string uiObjectResultType;
+        public string foregroundApp;
+        public string tooltipType;
+        public int numOfClickableObjects;
+        public List<ClickableObject> infoOfClickableObjects;
+        public int timestamp;
+    }
+    class ASRResult
+    {
+        public string result;
+        public int timestamp;
+    }
+}
\ No newline at end of file
diff --git a/voice-touch/VoiceTouchViewManager.cs b/voice-touch/VoiceTouchViewManager.cs
new file mode 100644 (file)
index 0000000..152ea88
--- /dev/null
@@ -0,0 +1,282 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using VoiceTouch.VoiceTouchMmi;
+using System.Collections.Generic;
+using Tizen.NUI;
+
+namespace VoiceTouch
+{
+    public class VoiceTouchViewManager
+    {
+        private static VoiceTouchViewManager instance = null;
+
+        protected TooltipLayer mTooltipLayer = null;
+        protected LottieAnimationLayer mLottieAnimationLayer = null;
+        protected TextBubbleLayer mTextBubbleLayer = null;
+        protected GridLayer mGridLayer = null;
+
+        internal uint responseMilliseconds = 5000;
+        internal uint successMilliseconds = 1000;
+        protected TimerState currentTimerState;
+        public enum TimerState
+        {
+            Inactive = 0,
+            Active = 1
+        }
+
+        // need to move another place
+        protected VoiceTouchState currentVoiceTouchState;
+        public enum VoiceTouchState
+        {
+            Idle = 0,
+            Active = 1
+        }
+
+        private VoiceTouchViewManager()
+        {
+            mLottieAnimationLayer = new LottieAnimationLayer();
+            mTextBubbleLayer = new TextBubbleLayer();
+            mTooltipLayer = new TooltipLayer();
+            mGridLayer = new GridLayer();
+            currentTimerState = TimerState.Inactive;
+            currentVoiceTouchState = VoiceTouchState.Idle;
+        }
+
+        public static VoiceTouchViewManager Instance
+        {
+            get
+            {
+                if (instance == null)
+                {
+                    instance = new VoiceTouchViewManager();
+                }
+                return instance;
+            }
+        }
+
+        ~VoiceTouchViewManager()
+        {
+            ClearVoiceTouchLottie();
+            ClearAll();
+        }
+
+        /// <summary>
+        /// Show voice touch lottie animation
+        /// Call when mmi manager connected
+        /// </summary>
+        public void ShowVoiceTouchLottie()
+        {
+            mLottieAnimationLayer.CreateLottie();
+        }
+
+        /// <summary>
+        /// Clear voice touch lottie animation
+        /// </summary>
+        public void ClearVoiceTouchLottie()
+        {
+            mLottieAnimationLayer.Clear();
+        }
+
+
+        /// <summary>
+        /// Callback for voice touch state change
+        /// </summary>
+        /// <param name="previousState"></param>
+        /// <param name="currentVoiceTouchState"></param>
+        public void VoiceTouchStateChange(VoiceTouchState previousState, VoiceTouchState currentVoiceTouchState)
+        {
+            if (previousState == VoiceTouchState.Idle && currentVoiceTouchState == VoiceTouchState.Active)
+            {
+                mLottieAnimationLayer.ApplyScaleAnimation(1.2f, 1.2f, 1.2f, 500, Tizen.NUI.AlphaFunction.BuiltinFunctions.EaseOut);
+            }
+            else if (previousState == VoiceTouchState.Active && currentVoiceTouchState == VoiceTouchState.Idle)
+            {
+                mLottieAnimationLayer.ApplyScaleAnimation(1.0f, 1.0f, 1.0f, 500, Tizen.NUI.AlphaFunction.BuiltinFunctions.EaseIn);
+            }
+        }
+
+        /// <summary>
+        /// show asr partial result on a text bubble
+        /// if current state is idle, lottie scale increase to 120%
+        /// </summary>
+        /// <param name="asrPartialResult"></param>
+        public void ShowAsrPartialResult(string asrPartialResult)
+        {
+            if (currentTimerState == TimerState.Active)
+            {
+                return;
+            }
+
+            if (currentVoiceTouchState == VoiceTouchState.Idle)
+            {
+                currentVoiceTouchState = VoiceTouchState.Active;
+                mLottieAnimationLayer.ApplyScaleAnimation(1.2f, 1.2f, 1.2f, 500, Tizen.NUI.AlphaFunction.BuiltinFunctions.EaseOut);
+            }
+
+            mTextBubbleLayer.CreateTextBubble(asrPartialResult, new Color("#17234D"));
+        }
+
+        /// <summary>
+        /// show asr final result on a text bubble
+        /// if current state is idle, lottie scale increase to 100%
+        /// </summary>
+        /// <param name="asrFinalResult"></param>
+        public void ShowAsrFinalResult(string asrFinalResult)
+        {
+            if (currentTimerState == TimerState.Active)
+            {
+                currentTimerState = TimerState.Inactive;
+                mGridLayer.ClearHighlightedGrid();
+                mTooltipLayer.ClearHighlightedTooltip();
+            }
+
+            if (currentVoiceTouchState == VoiceTouchState.Active)
+            {
+                currentVoiceTouchState = VoiceTouchState.Idle;
+                mLottieAnimationLayer.ApplyScaleAnimation(1.0f, 1.0f, 1.0f, 500, Tizen.NUI.AlphaFunction.BuiltinFunctions.EaseIn);
+            }
+
+            mTextBubbleLayer.CreateTextBubble(asrFinalResult, new Color("#17234D"));
+        }
+
+        /// <summary>
+        /// show response on a text bubble
+        /// </summary>
+        /// <param name="asrFinalResult"></param>
+        public void ShowResponse(string response)
+        {
+            mTextBubbleLayer.CreateTextBubble(response, new Color("#666666"));
+            Timer timer = new Timer(responseMilliseconds);
+            timer.Tick += ClearTextBubble;
+            timer.Start();
+            currentTimerState = TimerState.Active;
+        }
+
+        /// <summary>
+        /// Show tooltip
+        /// </summary>
+        /// <param name="objs">list of ClickableObject</param>
+        /// <param name="tooltipMode">number, name</param>
+        public void ShowTooltip(List<ClickableObject> objs, string tooltipMode)
+        {
+            Tizen.Log.Error("Tizen.Mmi", "show tooltip");
+            mGridLayer.ClearGrid();
+            if (tooltipMode == "tooltipNumber")
+            {
+                mTooltipLayer.CreateNumberTooltips(objs);
+            }
+            else if (tooltipMode == "tooltipText")
+            {
+                mTooltipLayer.CreateNameTooltips(objs);
+            }
+            Tizen.Log.Error("Tizen.Mmi", "show tooltip");
+            // add timer for remove final result text bubble
+            Timer timer = new Timer(successMilliseconds);
+            timer.Tick += ClearTextBubble;
+            timer.Start();
+            currentTimerState = TimerState.Active;
+        }
+
+        /// <summary>
+        /// Highlight tooltip
+        /// Called when click tooltip occur
+        /// </summary>
+        /// <param name="obj">Clicked object</param>
+        /// <param name="tooltipMode">number, name</param>
+        public void HighlightTooltip(ClickableObject obj, string tooltipMode)
+        {
+            mTooltipLayer.HighlightTooltip(obj, tooltipMode);
+            // add timer for remove final result text bubble, highlighted tooltip
+            Timer timer = new Timer(successMilliseconds);
+            timer.Tick += ClearHighlightedTooltip;
+            timer.Start();
+            currentTimerState = TimerState.Active;
+        }
+
+        /// <summary>
+        /// Show grid
+        /// </summary>
+        /// <param name="objs">List of grid info</param>
+        /// <param name="depth">1, 2</param>
+        public void ShowGrid(List<ClickableObject> objs, int depth)
+        {
+            mTooltipLayer.ClearTooltips();
+            if (depth == 1)
+            {
+                mGridLayer.CreateFirstLevelGrid(objs);
+            }
+            else if (depth == 2)
+            {
+                mGridLayer.CreateSecondLevelGrid(objs);
+            }
+            // add timer for remove final result text bubble
+
+            Timer timer = new Timer(successMilliseconds);
+            timer.Tick += ClearHighlightedGrid;
+            timer.Start();
+            currentTimerState = TimerState.Active;
+        }
+
+        /// <summary>
+        /// Hilight Grid
+        /// Called when click grid in second depth
+        /// </summary>
+        /// <param name="obj">Clicked grid info</param>
+        /// <param name="idx">index of grid info</param>
+        public void HighlightGrid(ClickableObject obj, int idx)
+        {
+            mGridLayer.HighlightGrid(obj, idx);
+            // add timer for remove final result text bubble, highlighted tooltip
+            Timer timer = new Timer(successMilliseconds);
+            timer.Tick += ClearHighlightedGrid;
+            timer.Start();
+            currentTimerState = TimerState.Active;
+        }
+
+        /// <summary>
+        /// Clear all ui component except lottie animation
+        /// </summary>
+        public void ClearAll()
+        {
+            mTextBubbleLayer.CleartextBubbles();
+            mTooltipLayer.ClearTooltips();
+            mGridLayer.ClearGrid();
+        }
+
+        private bool ClearTextBubble(object target, Timer.TickEventArgs args)
+        {
+            if (currentTimerState == TimerState.Inactive)
+            {
+                return false;
+            }
+            mTextBubbleLayer.CleartextBubbles();
+            currentTimerState = TimerState.Inactive;
+            return false;
+        }
+
+        private bool ClearHighlightedTooltip(object target, Timer.TickEventArgs args)
+        {
+            if (currentTimerState == TimerState.Inactive)
+            {
+                return false;
+            }
+            mTooltipLayer.ClearHighlightedTooltip();
+            mTextBubbleLayer.CleartextBubbles();
+            currentTimerState = TimerState.Inactive;
+            return false;
+        }
+
+        private bool ClearHighlightedGrid(object target, Timer.TickEventArgs args)
+        {
+            if (currentTimerState == TimerState.Inactive)
+            {
+                return false;
+            }
+            mGridLayer.ClearHighlightedGrid();
+            mTextBubbleLayer.CleartextBubbles();
+            currentTimerState = TimerState.Inactive;
+            return false;
+        }
+    }
+}
diff --git a/voice-touch/nuget.config b/voice-touch/nuget.config
new file mode 100644 (file)
index 0000000..1cde40d
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <packageSources>
+    <add key="NuGet official package source" value="https://nuget.org/api/v2/" />
+    <add key="Tizen" value="https://tizen.myget.org/F/dotnet/api/v3/index.json" />
+  </packageSources>
+  <activePackageSource>
+    <add key="All" value="(Aggregate source)" />
+  </activePackageSource>
+</configuration>
diff --git a/voice-touch/res/images/tizen.png b/voice-touch/res/images/tizen.png
new file mode 100644 (file)
index 0000000..9765b1b
Binary files /dev/null and b/voice-touch/res/images/tizen.png differ
diff --git a/voice-touch/res/lottie.json b/voice-touch/res/lottie.json
new file mode 100644 (file)
index 0000000..8e4b594
--- /dev/null
@@ -0,0 +1 @@
+{"v":"4.8.0","meta":{"g":"LottieFiles AE 2.0.4","a":"","k":"","d":"","tc":""},"fr":30,"ip":0,"op":300,"w":1200,"h":1200,"nm":"Voice_Touch_Animation","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-45]},{"t":300,"s":[-405]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.649,0.649,0.649],"y":[1,1,1]},"o":{"x":[0.302,0.302,0.302],"y":[0,0,0]},"t":0,"s":[60,70,100]},{"i":{"x":[0.688,0.688,0.688],"y":[-0.023,0.898,1]},"o":{"x":[0.342,0.342,0.342],"y":[0,0,0]},"t":60,"s":[80,90,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0.141,-0.283,0]},"t":120,"s":[80,70,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0,0,0]},"t":180,"s":[90,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0,0,0]},"t":240,"s":[100,90,100]},{"t":300,"s":[60,70,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,1,1,1,1,1,1,1,0,0.19,0.802,0.365,0.845,0.54,0.897,0.77,0.95,1,0.972,0.635,0.994,0.27],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":300,"s":[360]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.649,0.649,0.649],"y":[1,1,1]},"o":{"x":[0.302,0.302,0.302],"y":[0,0,0]},"t":0,"s":[70,90,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1.205,0.795,1]},"o":{"x":[0.342,0.342,0.342],"y":[0,0,0]},"t":60,"s":[70,80,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0.094,-0.283,0]},"t":120,"s":[65,70,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0,0,0]},"t":180,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0,0,0]},"t":240,"s":[80,90,100]},{"t":300,"s":[70,90,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,1,1,1,1,1,1,1,0,0.19,0.802,0.365,0.845,0.54,0.897,0.77,0.95,1,0.972,0.635,0.994,0.27],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Shape Layer 18","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":300,"s":[360]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.649,0.649,0.649],"y":[1,1,1]},"o":{"x":[0.302,0.302,0.302],"y":[0,0,0]},"t":0,"s":[80,70,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1.102,0.898,1]},"o":{"x":[0.342,0.342,0.342],"y":[0,0,0]},"t":60,"s":[90,80,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[-0.141,-0.141,0]},"t":120,"s":[80,60,100]},{"i":{"x":[0.688,0.688,0.688],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0,0,0]},"t":180,"s":[70,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.431,0.431,0.431],"y":[0,0,0]},"t":240,"s":[70,80,100]},{"t":300,"s":[80,70,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,1,1,1,1,1,1,1,0,0.19,0.802,0.365,0.845,0.54,0.897,0.77,0.95,1,0.972,0.635,0.994,0.27],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 17","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[60]},{"t":300,"s":[420]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[80,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[70,70,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":120,"s":[90,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":180,"s":[80,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":240,"s":[90,70,100]},{"t":300,"s":[80,90,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,1,1,1,1,1,1,1,0,0.19,0.802,0.365,0.845,0.54,0.897,0.77,0.95,1,0.972,0.635,0.994,0.27],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-120]},{"t":300,"s":[-480]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[70,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.875,0.875,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[90,70,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.063,-0.25,0]},"t":120,"s":[80,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":180,"s":[100,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":240,"s":[80,90,100]},{"t":300,"s":[70,80,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,1,1,1,1,1,1,1,0,0.19,0.802,0.365,0.845,0.54,0.897,0.77,0.95,1,0.972,0.635,0.994,0.27],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Shape Layer 22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[180]},{"t":300,"s":[540]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[70,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1.125,0.875,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[80,70,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0.063,-0.25,0]},"t":120,"s":[90,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":180,"s":[70,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":240,"s":[80,90,100]},{"t":300,"s":[70,90,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,0.5,0.547,0.749,1,0,0.094,0.498,0,0.19,0.669,0.365,0.705,0.54,0.775,0.77,0.845,1,0.901,0.5,0.956,0],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Shape Layer 20","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[120]},{"t":300,"s":[480]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[75,85,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.75,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[80,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.083,0,0]},"t":120,"s":[75,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":180,"s":[90,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":240,"s":[70,70,100]},{"t":300,"s":[75,85,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,0.5,0.547,0.749,1,0,0.094,0.498,0,0.19,0.669,0.365,0.705,0.54,0.775,0.77,0.845,1,0.901,0.5,0.956,0],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Shape Layer 14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[240]},{"t":300,"s":[600]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1.125,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[70,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-1.25,0,0]},"t":120,"s":[80,70,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":180,"s":[80,90,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":240,"s":[90,70,100]},{"t":300,"s":[80,80,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,0.5,0.547,0.749,1,0,0.094,0.498,0,0.19,0.669,0.365,0.705,0.54,0.775,0.77,0.845,1,0.901,0.5,0.956,0],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Shape Layer 13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-300]},{"t":300,"s":[-660]}],"ix":10},"p":{"a":0,"k":[600,600,0],"ix":2},"a":{"a":0,"k":[236,220,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[90,70,100]},{"i":{"x":[0.667,0.667,0.667],"y":[0.75,2.25,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[-0.125,-1.25,0]},"t":120,"s":[90,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":180,"s":[70,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":240,"s":[90,90,100]},{"t":300,"s":[90,70,100]}],"ix":6}},"ao":0,"ef":[{"ty":5,"nm":"Noise","np":5,"mn":"ADBE Noise2","ix":1,"en":1,"ef":[{"ty":0,"nm":"Amount of Noise","mn":"ADBE Noise2-0001","ix":1,"v":{"a":0,"k":7,"ix":1}},{"ty":7,"nm":"Noise Type","mn":"ADBE Noise2-0002","ix":2,"v":{"a":0,"k":0,"ix":2}},{"ty":7,"nm":"Clipping","mn":"ADBE Noise2-0003","ix":3,"v":{"a":0,"k":1,"ix":3}}]}],"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[508,508],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":60,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0.12,1,1,1,0.518,0.5,0.547,0.749,1,0,0.094,0.498,0,0.19,0.669,0.365,0.705,0.54,0.775,0.77,0.845,1,0.901,0.5,0.956,0],"ix":9}},"s":{"a":0,"k":[0,0],"ix":5},"e":{"a":0,"k":[255.659,0],"ix":6},"t":2,"h":{"a":0,"k":0,"ix":7},"a":{"a":0,"k":0,"ix":8},"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[236,220],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[177.953,177.953],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}],"markers":[{"tm":0,"cm":"Voice_Touch_Animation_Base","dr":300}]}
\ No newline at end of file
diff --git a/voice-touch/res/theme/theme.xaml b/voice-touch/res/theme/theme.xaml
new file mode 100644 (file)
index 0000000..10978f5
--- /dev/null
@@ -0,0 +1,9 @@
+<Theme
+  xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
+  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+  xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
+  Id="sampleTheme" >
+
+  <!-- Put styles with x:Key here -->
+
+</Theme>
\ No newline at end of file
diff --git a/voice-touch/shared/res/VoiceTouch.png b/voice-touch/shared/res/VoiceTouch.png
new file mode 100644 (file)
index 0000000..9765b1b
Binary files /dev/null and b/voice-touch/shared/res/VoiceTouch.png differ
diff --git a/voice-touch/tizen-manifest.xml b/voice-touch/tizen-manifest.xml
new file mode 100644 (file)
index 0000000..5678b1d
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="7" package="org.tizen.voice-touch" version="1.0.0">
+  <profile name="common" />
+  <ui-application appid="org.tizen.voice-touch" exec="VoiceTouch.dll" type="dotnet" multiple="false" taskmanage="true" nodisplay="false" launch_mode="single">
+    <icon>VoiceTouch.png</icon>
+    <label>voice-touch</label>
+    <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+  </ui-application>
+<privileges>
+  <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+  <privilege>http://tizen.org/privilege/datasharing</privilege>
+  <privilege>http://tizen.org/privilege/window.priority.set</privilege>
+</privileges>
+</manifest>