2 * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.ComponentModel;
21 using Xamarin.Forms.Platform.Tizen;
22 using Xamarin.Forms.Platform.Tizen.Native;
23 using EColor = ElmSharp.Color;
24 using ELayout = ElmSharp.Layout;
25 using XForms = Xamarin.Forms.Forms;
26 using XEntry = Xamarin.Forms.Entry;
28 [assembly: ExportRenderer(typeof(Tizen.Wearable.CircularUI.Forms.PopupEntry), typeof(Tizen.Wearable.CircularUI.Forms.Renderer.PopupEntryRenderer))]
30 namespace Tizen.Wearable.CircularUI.Forms.Renderer
32 public class PopupEntryRenderer : EntryRenderer
34 Background _editorPopup;
35 EColor _popupBackgroundColor;
37 Xamarin.Forms.Platform.Tizen.Native.Entry _editor;
39 Interop.EFL.InputPanelEventCallback _editorStateChanged;
41 Interop.EFL.InputPanelState _IMEState;
43 EColor DefaultColor { get; set; }
45 bool _IsPopupOpened = false;
47 public PopupEntryRenderer()
49 DefaultColor = new EColor(40, 40, 40, 255); //editfield bg default color
50 RegisterPropertyHandler(PopupEntry.PopupBackgroundColorProperty, UpdatePopupBackgroundColor);
51 RegisterPropertyHandler(PopupEntry.IsPopupOpenedProperty, UpdateIsPopupOpened);
54 protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Entry> e)
56 base.OnElementChanged(e);
57 if (e.NewElement != null)
59 Control.IsEditable = false;
60 Control.SetInputPanelEnabled(false);
61 Control.Clicked += OnClicked;
63 // Set Text again for apply text style because IsEditable reset the style of text
64 Control.Text = string.Empty;
65 Control.Text = Element.Text;
69 protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
71 base.OnElementPropertyChanged(sender, e);
72 if (_IsPopupOpened && _editor != null)
74 if (e.PropertyName == XEntry.TextColorProperty.PropertyName ||
75 e.PropertyName == XEntry.FontSizeProperty.PropertyName ||
76 e.PropertyName == XEntry.FontFamilyProperty.PropertyName ||
77 e.PropertyName == XEntry.FontAttributesProperty.PropertyName)
79 _editor.TextStyle = Control.TextStyle;
84 protected override void Dispose(bool disposing)
90 IntPtr entryHandle = Interop.EFL.elm_entry_imf_context_get(_editor.RealHandle);
91 Interop.EFL.ecore_imf_context_input_panel_event_callback_del(entryHandle, Interop.EFL.InputPanelEventType.State, _editorStateChanged);
94 base.Dispose(disposing);
97 void OnClicked(object sender, EventArgs e) => ShowPopup();
99 Window FindWindow(EvasObject obj)
101 EvasObject parent = obj.Parent;
102 while (!(parent is Window) && parent != null)
104 parent = parent.Parent;
106 return parent as Window;
111 var rect = XForms.NativeParent.Geometry;
113 var root = FindWindow(XForms.NativeParent);
115 _editorPopup = new Background(root)
120 var layout = new ELayout(_editorPopup);
121 layout.SetTheme("layout", "entry", "default");
124 _editorPopup.SetPartContent("overlay", layout);
126 _editor = new Xamarin.Forms.Platform.Tizen.Native.Entry(layout);
127 _editor.IsSingleLine = true;
128 _editor.Scrollable = true;
129 _editor.SetInputPanelEnabled(false);
130 _editor.AllowFocus(true);
133 _editor.SetInputPanelReturnKeyType(Element.ReturnType.ToInputPanelReturnKeyType());
135 _editor.UpdateKeyboard(Element.Keyboard, Element.IsSpellCheckEnabled, Element.IsTextPredictionEnabled);
137 _editorPopup.BackButtonPressed += (s, e) => HidePopup();
139 _editor.Activated += (s, e) => HidePopup();
141 IntPtr entryHandle = Interop.EFL.elm_entry_imf_context_get(_editor.RealHandle);
143 _editorStateChanged = EditorStateChanged;
144 Interop.EFL.ecore_imf_context_input_panel_event_callback_add(entryHandle, Interop.EFL.InputPanelEventType.State, _editorStateChanged, IntPtr.Zero);
146 layout.SetPartContent("elm.swallow.content", _editor);
149 void PopupEntryTextChanged(object sender, TextChangedEventArgs e)
151 Control.Text = e.NewTextValue;
154 void PopupEntryActivated(object sender, EventArgs e)
156 ((IEntryController)Element).SendCompleted();
161 if (Control is IEntry ie)
163 ie.TextChanged -= OnTextChanged;
166 if (_IMEState != Interop.EFL.InputPanelState.Hide)
168 _editor.HideInputPanel();
170 else if (_IMEState == Interop.EFL.InputPanelState.Hide)
173 _editor.TextChanged -= PopupEntryTextChanged;
174 _editor.Activated -= PopupEntryActivated;
176 _IsPopupOpened = false;
177 ((PopupEntry)Element).IsPopupOpened = false;
182 if (_editorPopup == null)
186 _editor.IsPassword = Control.IsPassword;
187 if (Control is IEntry ie)
189 _editor.HorizontalTextAlignment = ie.HorizontalTextAlignment;
190 ie.TextChanged += OnTextChanged;
193 _editor.Text = Control.Text;
194 _editor.TextChanged += PopupEntryTextChanged;
195 _editor.Activated += PopupEntryActivated;
197 _editor.TextStyle = Control.TextStyle;
198 _editorPopup.Color = _popupBackgroundColor;
200 _editor.MoveCursorEnd();
201 _editor.ShowInputPanel();
203 _IsPopupOpened = true;
204 ((PopupEntry)Element).IsPopupOpened = true;
207 void EditorStateChanged(IntPtr data, IntPtr ctx, int value)
209 _IMEState = (Interop.EFL.InputPanelState)value;
210 if (_IMEState == Interop.EFL.InputPanelState.Hide)
214 else if (_IMEState == Interop.EFL.InputPanelState.Show)
216 _editor.SetFocus(true);
217 _editorPopup.RaiseTop();
222 void UpdatePopupBackgroundColor()
224 Xamarin.Forms.Color bgColor = ((PopupEntry)Element).PopupBackgroundColor;
225 if (bgColor == Xamarin.Forms.Color.Default)
227 _popupBackgroundColor = DefaultColor;
231 _popupBackgroundColor = bgColor.ToNative();
234 if (_IsPopupOpened == true && _editorPopup != null)
236 _editorPopup.Color = _popupBackgroundColor;
240 void OnTextChanged(object sender, EventArgs e)
244 if (_editor.Text != Control.Text)
246 _editor.Text = Control.Text;
247 if (!_editor.IsFocused)
249 _editor.MoveCursorEnd();
255 void UpdateIsPopupOpened()
257 bool isOpended = ((PopupEntry)Element).IsPopupOpened;
258 if (isOpended == _IsPopupOpened)
263 _IsPopupOpened = isOpended;
275 internal static class EntryExtensions
277 internal static InputPanelReturnKeyType ToInputPanelReturnKeyType(this ReturnType returnType)
282 return InputPanelReturnKeyType.Go;
283 case ReturnType.Next:
284 return InputPanelReturnKeyType.Next;
285 case ReturnType.Send:
286 return InputPanelReturnKeyType.Send;
287 case ReturnType.Search:
288 return InputPanelReturnKeyType.Search;
289 case ReturnType.Done:
290 return InputPanelReturnKeyType.Done;
291 case ReturnType.Default:
292 return InputPanelReturnKeyType.Default;
294 throw new NotImplementedException($"ReturnType {returnType} not supported");