--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using Tizen;\r
+using Tizen.Applications;\r
+using Tizen.NUI;\r
+using Tizen.NUI.BaseComponents;\r
+using Tizen.NUI.Components;\r
+using static Interop.SclNuiCSharp;\r
+\r
+namespace ISEDefaultNUI\r
+{\r
+ public class CandidateView\r
+ {\r
+ private static CandidateView instance;\r
+ private Timer timer;\r
+ private View parentView;\r
+ private ScrollableBase candidateView;\r
+ private bool visible;\r
+ private bool candidateExpanded;\r
+ private List<string> candidateStrings;\r
+ private List<TextLabel> labelList;\r
+ private List<ImageView> popupLineList;\r
+ private Button moreButton;\r
+ private Size imeSize;\r
+ private string selectedCandidate;\r
+ private int index = 0;\r
+ private int pointSize = 15;\r
+ private int itemWidth = 120;\r
+ private int viewHeight = 84;\r
+ private int moreButtonWidth = 89;\r
+ private int moreButtonHeight = 64;\r
+ private ushort margin = 5;\r
+ private static string ImageURL = Application.Current.DirectoryInfo.Resource + "image/soft_candidate/";\r
+\r
+ private CandidateView()\r
+ {\r
+ timer = new Timer(ResourceManager.CandidateHideTimerInterval);\r
+ timer.Tick += TimerTick;\r
+\r
+ candidateView = new ScrollableBase()\r
+ {\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = LayoutParamPolicies.MatchParent,\r
+ BackgroundColor = Color.Black,\r
+ Padding = new Extents(margin, margin, margin, margin),\r
+ };\r
+\r
+ candidateStrings = new List<string>();\r
+ labelList = new List<TextLabel>();\r
+ popupLineList = new List<ImageView>();\r
+ visible = false;\r
+ candidateExpanded = false;\r
+ }\r
+\r
+ public static CandidateView Instance\r
+ {\r
+ get\r
+ {\r
+ if (instance == null)\r
+ instance = new CandidateView();\r
+\r
+ return instance;\r
+ }\r
+ }\r
+\r
+ public List<string> CandidateStrings\r
+ {\r
+ get => candidateStrings;\r
+ set\r
+ {\r
+ if (value == null)\r
+ throw new ArgumentException("Invalid parameter");\r
+\r
+ candidateStrings = value;\r
+ }\r
+ }\r
+\r
+ public bool IsVisible\r
+ {\r
+ get => visible;\r
+ }\r
+\r
+ public int ViewHeight\r
+ {\r
+ get => viewHeight;\r
+ }\r
+\r
+ private bool TimerTick(object source, Timer.TickEventArgs e)\r
+ {\r
+ Log.Info("NUIIME", "Hide candidate view");\r
+ parentView.Remove(candidateView);\r
+ visible = false;\r
+ candidateExpanded = false;\r
+ return false;\r
+ }\r
+\r
+ private bool NeedEngineLoader()\r
+ {\r
+ bool loadInIme = false;\r
+ string currentLanguage = LanguageManager.Instance.GetCurrentLanguage();\r
+ if (currentLanguage != null)\r
+ {\r
+ LanguageInfo languageInfo = LanguageManager.Instance.GetLanguageInfo(currentLanguage);\r
+ if (languageInfo != null)\r
+ loadInIme = languageInfo.LoadInIME;\r
+ }\r
+\r
+ return !loadInIme;\r
+ }\r
+\r
+ private bool OnTouchEvent(object source, View.TouchEventArgs e)\r
+ {\r
+ TextLabel candidate = source as TextLabel;\r
+ if (e.Touch.GetState(0) == PointStateType.Down)\r
+ {\r
+ selectedCandidate = candidate.Text;\r
+ }\r
+ else if (e.Touch.GetState(0) == PointStateType.Up)\r
+ {\r
+ if (candidate.Text.Equals(selectedCandidate))\r
+ {\r
+ string candidateString = candidate.Text;\r
+ uint idx = (uint)candidateStrings.IndexOf(candidateString);\r
+\r
+ if (NeedEngineLoader())\r
+ {\r
+ SclDbusSelectCandidate(idx);\r
+ }\r
+ else\r
+ {\r
+ SclSelectCandidate(idx);\r
+ }\r
+ }\r
+ selectedCandidate = null;\r
+ }\r
+\r
+ return true;\r
+ }\r
+\r
+ private void CreateCandidateText(string text)\r
+ {\r
+ PropertyMap candidateStyle = new PropertyMap();\r
+ candidateStyle.Add("weight", new PropertyValue("semibold"));\r
+ candidateStyle.Add("slant", new PropertyValue("dejavu"));\r
+\r
+ TextLabel candidate = new TextLabel()\r
+ {\r
+ Margin = new Extents(0, margin, margin, margin),\r
+ Text = text,\r
+ PointSize = pointSize,\r
+ FontStyle = candidateStyle,\r
+ TextColor = Color.White,\r
+ HorizontalAlignment = HorizontalAlignment.Center,\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ Size = new Size(itemWidth, viewHeight - (margin * 3)),\r
+ BackgroundColor = Color.Black,\r
+ };\r
+\r
+ candidate.TouchEvent += OnTouchEvent;\r
+ candidateView.Add(candidate);\r
+ labelList.Add(candidate);\r
+ }\r
+\r
+ private void moreButtonClicked(object sender, ClickedEventArgs e)\r
+ {\r
+ if (candidateExpanded)\r
+ {\r
+ candidateView.Size = new Size(imeSize.Width, viewHeight);\r
+ candidateExpanded = false;\r
+ }\r
+ else\r
+ {\r
+ candidateView.Size = new Size(imeSize.Width, imeSize.Height + viewHeight);\r
+ candidateExpanded = true;\r
+\r
+ for (int i = index + 1; i < candidateStrings.Count; i++)\r
+ {\r
+ CreateCandidateText(candidateStrings[i]);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void CreateMoreButton()\r
+ {\r
+ ButtonStyle Style = new ButtonStyle\r
+ {\r
+ IsSelectable = true,\r
+ Size = new Size(moreButtonWidth, moreButtonHeight),\r
+ BackgroundColor = new Color(0.37f, 0.38f, 0.4f, 1.0f),\r
+ Icon = new ImageViewStyle\r
+ {\r
+ Size = new Size(moreButtonWidth / 2, moreButtonHeight / 2),\r
+ ResourceUrl = new Selector<string>\r
+ {\r
+ Normal = ImageURL + "B09_predictive_icon_arrow_down.png",\r
+ Selected = ImageURL + "B09_predictive_icon_arrow_up.png",\r
+ },\r
+ },\r
+ };\r
+\r
+ moreButton = new Button(Style)\r
+ {\r
+ Margin = new Extents((ushort)(margin * 3), 0, (ushort)((viewHeight - moreButtonHeight) / 4), (ushort)((viewHeight - moreButtonHeight) / 4)),\r
+ Position = new Position(imeSize.Width - moreButtonWidth - ((viewHeight - moreButtonHeight) / 4), 0),\r
+ CellHorizontalAlignment = HorizontalAlignmentType.Right,\r
+ CellVerticalAlignment = VerticalAlignmentType.Center,\r
+ };\r
+\r
+ moreButton.Clicked += moreButtonClicked;\r
+ candidateView.Add(moreButton);\r
+ }\r
+\r
+ private void ResetCandidateView()\r
+ {\r
+ if (labelList.Count > 0)\r
+ {\r
+ labelList.ForEach(label =>\r
+ {\r
+ label.Unparent();\r
+ label.Dispose();\r
+ });\r
+ }\r
+\r
+ if (popupLineList.Count > 0)\r
+ {\r
+ popupLineList.ForEach(line =>\r
+ {\r
+ line.Unparent();\r
+ line.Dispose();\r
+ });\r
+ }\r
+\r
+ labelList.Clear();\r
+ popupLineList.Clear();\r
+\r
+ if (candidateExpanded)\r
+ {\r
+ candidateView.Size = new Size(imeSize.Width, viewHeight);\r
+ candidateExpanded = false;\r
+ }\r
+\r
+ if (moreButton != null)\r
+ {\r
+ moreButton.Unparent();\r
+ moreButton.Dispose();\r
+ }\r
+ }\r
+\r
+ public void UpdateCandidateList()\r
+ {\r
+ if (imeSize == null)\r
+ return;\r
+\r
+ ResetCandidateView();\r
+ index = 0;\r
+ int columnCount = (int)(imeSize.Width / (itemWidth + margin));\r
+ GridLayout gridLayout = new GridLayout()\r
+ {\r
+ Columns = columnCount,\r
+ };\r
+ candidateView.Layout = gridLayout;\r
+\r
+ for (int i = 0; i < candidateStrings.Count; i++)\r
+ {\r
+ CreateCandidateText(candidateStrings[i]);\r
+\r
+ if (i == columnCount - 2)\r
+ {\r
+ index = i;\r
+ CreateMoreButton();\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ public void Show(View parent)\r
+ {\r
+ if (!visible)\r
+ {\r
+ Log.Info("NUIIME", "Show candidate view");\r
+ parentView = parent;\r
+ parent.Add(candidateView);\r
+ visible = true;\r
+ }\r
+ }\r
+\r
+ public void Hide()\r
+ {\r
+ if (timer.IsRunning())\r
+ {\r
+ timer.Stop();\r
+ }\r
+\r
+ timer.Start();\r
+ }\r
+\r
+ public void SetPosition(Size imeSize)\r
+ {\r
+ this.imeSize = imeSize;\r
+ candidateView.Size = new Size(imeSize.Width, viewHeight);\r
+ candidateView.Position = new Position(0, 0);\r
+ }\r
+ }\r
+}\r
using System;
using System.Collections.Generic;
+using System.Linq;\r
using System.Runtime.InteropServices;
using Tizen;
using Tizen.Internals;
Done /* We're done with this event, do not call any other default SCL event handlers */
}
+ internal enum SclNuiCandidateEvent\r
+ {\r
+ Start = 0,\r
+ End\r
+ }
+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
//internal delegate void DrawTextCallback(IntPtr str, int x, int y, int w, int h, int fontsize, IntPtr userData);
//internal delegate void DrawTextCallback(SclFontInfo fontinfo, SclColor color, IntPtr str, int x, int y, int w, int h, int label_alignment, int padding_x, int padding_y, int inner_width, int inner_height, IntPtr userData);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void ProcessKeyEventWithImengineCallback(UInt32 code, UInt32 mask, UInt32 layout, UInt32 devClass, UInt32 devSubclass, string devName, UInt32 serial, IntPtr user_data);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CandidateShowCallback(IntPtr user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CandidateHideCallback(IntPtr user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void LookupTableChangedCallback(SclNuiCandidateEvent eventType, IntPtr user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void CandidateForeachCallback(IntPtr candidate, IntPtr user_data);
+
[DllImport(Libraries.SclNui, EntryPoint = "scl_nui_init")]
internal static extern int SclNuiInit(string entry_filepath);
[DllImport(Libraries.SclNui, EntryPoint = "scl_set_process_key_event_with_imengine_cb")]
internal static extern int SclSetProcessKeyEventWithImengineCb(ProcessKeyEventWithImengineCallback callbackFunction, IntPtr userData);
+
+ [DllImport(Libraries.SclNui, EntryPoint = "scl_set_candidate_show_cb")]
+ internal static extern int SclSetCandidateShowCb(CandidateShowCallback callbackFunction, IntPtr userData);
+
+ [DllImport(Libraries.SclNui, EntryPoint = "scl_set_candidate_hide_cb")]
+ internal static extern int SclSetCandidateHideCb(CandidateHideCallback callbackFunction, IntPtr userData);
+
+ [DllImport(Libraries.SclNui, EntryPoint = "scl_set_lookup_table_changed_cb")]
+ internal static extern int SclSetLookupTableChangedCb(LookupTableChangedCallback callbackFunction, IntPtr userData);
+
+ [DllImport(Libraries.SclNui, EntryPoint = "scl_set_candidate_string_foreach_cb")]
+ internal static extern int SclSetCandidateStringForeachCb(CandidateForeachCallback callbackFunction, IntPtr userData);
+
+ [DllImport(Libraries.SclNui, EntryPoint = "scl_nui_set_custom_starting_coordinates")]
+ internal static extern int SclNuiSetCustomStartingCoordinates(int x, int y);
+
+ [DllImport(Libraries.SclNui, EntryPoint = "scl_select_candidate")]
+ internal static extern int SclSelectCandidate(UInt32 index);
}
}
private EventNotificationCallback _onEventNotification = null;
private UpdateWindowPositionCallback _updateWindowPositionChangedEvent = null;
private ProcessKeyEventWithImengineCallback _onProcessKeyEventWithImengineEvent = null;
+ private CandidateShowCallback _onCandidateShowEvent = null;
+ private CandidateHideCallback _onCandidateHideEvent = null;
+ private LookupTableChangedCallback _onLookupTableChangedEvent = null;
+ private CandidateForeachCallback _onCandidateStringForeach = null;
private List<ImageView> image_list;
private List<TextLabel> label_list;
private Size2D imePortraitSize;
private Size2D imeLandscapeSize;
+ private CandidateView candidateView = CandidateView.Instance;
enum LabelAlignment
{
Max,
}
+ enum CandidateRequest
+ {
+ None = 0,
+ Show,
+ Hide,
+ }
+
public SCLNUI(Navigator Navigator) : base()
{
Layout = new AbsoluteLayout();
}
};
SclNuiUpdateWindowPositionCb(_updateWindowPositionChangedEvent, (IntPtr)null);
+
+ _onCandidateShowEvent = (IntPtr userData) =>
+ {
+ if (imePortraitSize == null || imeLandscapeSize == null)
+ GetDefaultSize();
+
+ if (candidateView.IsVisible == false)
+ {
+ if (deviceAngle == 0 || deviceAngle == 180)
+ candidateView.SetPosition(imePortraitSize);
+ else
+ candidateView.SetPosition(imeLandscapeSize);
+ candidateView.Show(this);
+ SetImeSize(CandidateRequest.Show);
+ }
+ };
+ SclSetCandidateShowCb(_onCandidateShowEvent, (IntPtr)null);
+
+ _onCandidateHideEvent = (IntPtr userData) =>
+ {
+ if (candidateView.IsVisible)
+ {
+ candidateView.Hide();
+ }
+ SetImeSize(CandidateRequest.Hide);
+ };
+ SclSetCandidateHideCb(_onCandidateHideEvent, (IntPtr)null);
+
+ _onLookupTableChangedEvent = (SclNuiCandidateEvent eventType, IntPtr userData) =>
+ {
+ switch (eventType)
+ {
+ case SclNuiCandidateEvent.Start:
+ candidateView.CandidateStrings.Clear();
+ break;
+ case SclNuiCandidateEvent.End:
+ candidateView.UpdateCandidateList();
+ break;
+ default:
+ break;
+ }
+ };
+ SclSetLookupTableChangedCb(_onLookupTableChangedEvent, (IntPtr)null);
+
+ _onCandidateStringForeach = (IntPtr candidate, IntPtr userData) =>
+ {
+ string candidateString = Marshal.PtrToStringAnsi(candidate);
+ candidateView.CandidateStrings.Add(candidateString);
+ };
+ SclSetCandidateStringForeachCb(_onCandidateStringForeach, (IntPtr)null);
}
private bool CommitTimerTick(object source, Timer.TickEventArgs e)
Log.Info("NUIIME", "### start draw text");
Log.Info("NUIIME", "font name(" + FontName + "), italic(" + is_italic + "), bold(" + is_bold + ")");
-
Log.Info("NUIIME", "key string(" + keystr + "), x: " + pos_x + ", y: " + pos_y);
Log.Info("NUIIME", "padding_x:" + padding_x + ", padding_y: " + padding_y + ", inner_width: " + inner_width + ", inner_height: " + inner_height);
emoticonView = null;
}
+ private void SetImeSize(CandidateRequest request)
+ {
+ if (imePortraitSize == null || imeLandscapeSize == null)\r
+ GetDefaultSize();
+
+ switch (request)
+ {
+ case CandidateRequest.None:
+ if (candidateView.IsVisible)
+ SclNuiSetCustomStartingCoordinates(0, candidateView.ViewHeight);
+ else
+ SclNuiSetCustomStartingCoordinates(0, 0);
+ break;
+ case CandidateRequest.Show:
+ SclNuiSetCustomStartingCoordinates(0, candidateView.ViewHeight);
+ imePortraitSize = new Size2D(imePortraitSize.Width, imePortraitSize.Height + candidateView.ViewHeight);
+ imeLandscapeSize = new Size2D(imeLandscapeSize.Width, imeLandscapeSize.Height + candidateView.ViewHeight);
+ break;
+ case CandidateRequest.Hide:
+ SclNuiSetCustomStartingCoordinates(0, 0);
+ break;
+ default:
+ break;
+ }
+
+ IntPtr nativeHandle = new Window.SafeNativeWindowHandle().DangerousGetHandle();
+ InputMethodEditor.SetSize(nativeHandle, imePortraitSize.Width, imePortraitSize.Height, imeLandscapeSize.Width, imeLandscapeSize.Height);
+ }\r
+\r
+ private void GetDefaultSize()\r
+ {\r
+ IntPtr inputModePtr;\r
+ GetInputMode(out inputModePtr);\r
+ string inputMode = Marshal.PtrToStringAnsi(inputModePtr);\r
+\r
+ int portraitWidth, portraitHeight, landscapeWidth, landscapeHeight;\r
+ GetInputModeSize(inputMode, (int)WindowAttribute.DisplayMode.Portrait, out portraitWidth, out portraitHeight);\r
+ GetInputModeSize(inputMode, (int)WindowAttribute.DisplayMode.Landscape, out landscapeWidth, out landscapeHeight);\r
+\r
+ imePortraitSize = new Size2D(portraitWidth, portraitHeight);\r
+ imeLandscapeSize = new Size2D(landscapeWidth, landscapeHeight);\r
+ }\r
+\r
public int Init(string entry_filepath)
{
return SclNuiInit(entry_filepath);