Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
EditText.iOS.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if SILICONSTUDIO_PLATFORM_IOS
4 
5 using System;
6 using System.Drawing;
7 using MonoTouch.Foundation;
8 using MonoTouch.UIKit;
9 using SiliconStudio.Paradox.Games;
10 using SiliconStudio.Paradox.UI.Events;
11 
12 namespace SiliconStudio.Paradox.UI.Controls
13 {
14  public partial class EditText
15  {
16  private UITextField attachedTextField;
17 
18  private static UIButton doneButton;
19  private static UITextField textField;
20  private static EditText currentActiveEditText;
21  private static UIView barView;
22  private static UIView overlayView;
23  private static GameContext gameContext;
24 
25  private static void InitializeStaticImpl()
26  {
27  doneButton = UIButton.FromType(UIButtonType.RoundedRect);
28  doneButton.SetTitle(NSBundle.MainBundle.LocalizedString("UIDoneButton", null), UIControlState.Normal);
29  doneButton.SetTitleColor(UIColor.Black, UIControlState.Normal);
30  doneButton.TouchDown += DoneButtonOnTouchDown;
31 
32  textField = new UITextField
33  {
34  KeyboardType = UIKeyboardType.Default,
35  BorderStyle = UITextBorderStyle.RoundedRect,
36  };
37  textField.EditingDidEnd += TextFieldOnEditingDidEnd;
38  textField.EditingDidBegin += TextFieldOnEditingDidBegin;
39 
40  barView = new UIView { Hidden = true };
41  barView.AddSubview(textField);
42  barView.AddSubview(doneButton);
43  barView.BackgroundColor = UIColor.Gray;
44 
45  overlayView = new UIView { Hidden = true };
46  overlayView.AddSubview(barView);
47  overlayView.BackgroundColor = new UIColor(0,0,0,0.4f);
48  }
49 
50  private static void TextFieldOnEditingDidBegin(object sender, EventArgs eventArgs)
51  {
52  overlayView.Hidden = false;
53  barView.Hidden = false;
54 
55  if (currentActiveEditText != null)
56  {
57  // we need to skip some draw calls here to let the time to iOS to draw its own keyboard animations... (Thank you iOS)
58  // If we don't do this when changing the type of keyboard (split / docked / undocked), the keyboard freeze for about 5/10 seconds before updating.
59  // Note: Setting UIView.EnableAnimation to false does not solve the problem. Only animation when the keyboard appear/disappear are skipped.
60  currentActiveEditText.game.SlowDownDrawCalls = true;
61  }
62  }
63 
64  private void InitializeImpl()
65  {
66  if (gameContext == null)
67  {
68  gameContext = game.Context;
69  gameContext.GameView.AddSubview(overlayView);
70 
71  NSNotificationCenter.DefaultCenter.AddObserver(UIDevice.OrientationDidChangeNotification, OnScreenRotated);
72 
73  UpdateOverlayAndEditBarLayout();
74  }
75  }
76 
77  private void OnScreenRotated(NSNotification nsNotification)
78  {
79  if (gameContext == null)
80  return;
81 
82  UpdateOverlayAndEditBarLayout();
83  }
84 
85  private static void UpdateOverlayAndEditBarLayout()
86  {
87  const int spaceX = 10;
88  const int spaceY = 5;
89  const int buttonWidth = 60;
90  const int buttonHeight = 35;
91  const int barHeight = buttonHeight + 2*spaceY;
92 
93  var viewFrame = gameContext.GameView.Frame;
94 
95  barView.Frame = new RectangleF(0, 0, viewFrame.Width, barHeight);
96  overlayView.Frame = new RectangleF(viewFrame.X, viewFrame.Y, 2 * viewFrame.Width, viewFrame.Height); // if we don't over-set width background can be seen during rotation...
97  textField.Frame = new RectangleF(spaceX, spaceY, viewFrame.Width - buttonWidth - 3*spaceX, buttonHeight);
98  doneButton.Frame = new RectangleF(viewFrame.Width - buttonWidth - spaceX, spaceY, buttonWidth, buttonHeight);
99  }
100 
101  private static void TextFieldOnEditingDidEnd(object sender, EventArgs eventArgs)
102  {
103  currentActiveEditText.IsSelectionActive = false;
104  barView.Hidden = true;
105  overlayView.Hidden = true;
106  FocusedElement = null;
107 
108  if (currentActiveEditText != null)
109  {
110  // Editing finished, we can now draw back to normal frame rate.
111  currentActiveEditText.game.SlowDownDrawCalls = false;
112  }
113  }
114 
115  private static void DoneButtonOnTouchDown(object sender, EventArgs eventArgs)
116  {
117  currentActiveEditText.IsSelectionActive = false;
118  }
119 
120  private void TextFieldOnValueChanged(object sender, EventArgs eventArgs)
121  {
122  if (attachedTextField == null)
123  return;
124 
125  // early exit if text did not changed
126  if (text == attachedTextField.Text)
127  return;
128 
129  text = attachedTextField.Text;
130  UpdateTextToDisplay();
131 
132  RaiseEvent(new RoutedEventArgs(TextChangedEvent));
133  InvalidateMeasure();
134  }
135 
136  private int GetLineCountImpl()
137  {
138  return 1;
139  }
140 
141  private void OnMaxLinesChangedImpl()
142  {
143  }
144 
145  private void OnMinLinesChangedImpl()
146  {
147  }
148 
149  private void ActivateEditTextImpl()
150  {
151  currentActiveEditText = this;
152  attachedTextField = textField;
153 
154  UpdateInputTypeImpl();
155  attachedTextField.Text = text;
156  attachedTextField.EditingChanged += TextFieldOnValueChanged;
157  attachedTextField.ShouldChangeCharacters += ShouldChangeCharacters;
158  attachedTextField.BecomeFirstResponder();
159  }
160 
161  private bool ShouldChangeCharacters(UITextField theTextField, NSRange range, string replacementString)
162  {
163  // check that new characters are correct.
164  var predicate = CharacterFilterPredicate;
165  foreach (var character in replacementString)
166  {
167  if (predicate != null && !predicate(character))
168  return false;
169  }
170 
171  var replacementSize = replacementString.Length - range.Length;
172  return replacementSize < 0 || theTextField.Text.Length + replacementSize <= MaxLength;
173  }
174 
175  private void DeactivateEditTextImpl()
176  {
177  attachedTextField.EditingChanged -= TextFieldOnValueChanged;
178  attachedTextField.ShouldChangeCharacters -= ShouldChangeCharacters;
179  attachedTextField.SecureTextEntry = false;
180  attachedTextField.ResignFirstResponder();
181  attachedTextField = null;
182  currentActiveEditText = null;
183  }
184 
185  private void OnTouchMoveImpl(TouchEventArgs args)
186  {
187  }
188 
189  private void OnTouchDownImpl(TouchEventArgs args)
190  {
191  }
192 
193  private void UpdateInputTypeImpl()
194  {
195  if (attachedTextField == null)
196  return;
197 
198  attachedTextField.SecureTextEntry = ShouldHideText;
199  }
200 
201  private void UpdateSelectionToEditImpl()
202  {
203  if (attachedTextField == null)
204  return;
205 
206  attachedTextField.SelectedTextRange = attachedTextField.GetTextRange(
207  attachedTextField.GetPosition(attachedTextField.BeginningOfDocument, selectionStart),
208  attachedTextField.GetPosition(attachedTextField.BeginningOfDocument, selectionStop));
209  }
210 
211  private void UpdateSelectionFromEditImpl()
212  {
213  if (attachedTextField == null)
214  return;
215 
216  selectionStart = attachedTextField.GetOffsetFromPosition(attachedTextField.BeginningOfDocument, attachedTextField.SelectedTextRange.Start);
217  selectionStop = attachedTextField.GetOffsetFromPosition(attachedTextField.BeginningOfDocument, attachedTextField.SelectedTextRange.End);
218  }
219 
220  private void UpdateTextToEditImpl()
221  {
222  if (attachedTextField == null)
223  return;
224 
225  // update the iOS text edit only the text changed to avoid re-triggering events.
226  if (Text != attachedTextField.Text)
227  attachedTextField.Text = text;
228  }
229  }
230 }
231 
232 #endif
SiliconStudio.Core.Mathematics.RectangleF RectangleF
Definition: SpriteFont.cs:17