Jypeli  5
The simple game programming library
InputBox.cs
Siirry tämän tiedoston dokumentaatioon.
1 #region MIT License
2 /*
3  * Copyright (c) 2009-2011 University of Jyväskylä, Department of Mathematical
4  * Information Technology.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #endregion
25 
26 /*
27  * Authors: Tomi Karppinen, Tero Jäntti
28  */
29 
30 
31 using System;
32 using System.Collections.Generic;
33 using System.Linq;
34 using System.Text;
35 using Microsoft.Xna.Framework.Graphics;
36 using Microsoft.Xna.Framework;
37 using Microsoft.Xna.Framework.GamerServices;
38 using Jypeli.Controls;
39 using Jypeli.GameObjects;
40 using Jypeli.WP7;
41 
42 namespace Jypeli.Widgets
43 {
47  public class InputBox : Label
48  {
49 #if WINDOWS
50  private static int InputBoxes = 0;
51  const long eraseDelay = 1000000;
52 
53  long remainingDelay = 0;
54 #endif
55 
56  Timer cursorBlinkTimer;
57  Color cursorColor = new Color( 255, 0, 0, 100 );
58 
62  public int WidthInCharacters { get; set; }
63 
67  public int MaxCharacters { get; set; }
68 
72  public Widget Cursor { get; set; }
73 
74  public override Vector PreferredSize
75  {
76  get
77  {
78  return new Vector( Font.CharacterWidth * WidthInCharacters + 2 * XMargin, Font.CharacterHeight + 2 * YMargin );
79  }
80  }
81 
82  public override Vector Size
83  {
84  get { return base.Size; }
85  set
86  {
87  base.Size = value;
88  if ( Cursor != null )
89  UpdateCursorPosition();
90  }
91  }
92 
93  public override string Text
94  {
95  get { return base.Text; }
96  set
97  {
98  if ( value.Length <= MaxCharacters )
99  {
100  base.Text = value;
101 
102  }
103  else
104  {
105  base.Text = value.Substring( 0, MaxCharacters );
106  }
107  UpdateCursorPosition();
108  }
109  }
110 
114  public event Action<string> TextChanged;
115 
116  protected void OnTextChanged()
117  {
118  if ( TextChanged != null )
119  TextChanged( Text );
120  }
121 
129  public InputBox( int characters )
130  : base()
131  {
132  MaxCharacters = int.MaxValue;
133  WidthInCharacters = characters;
135  HorizontalSizing = Sizing.Expanding;
136  XMargin = 7;
137  YMargin = 2;
138  TextColor = Color.Black;
139  Color = new Color( 0, 255, 255, 150 );
140  BorderColor = new Color( 200, 200, 200 );
141  SizeMode = TextSizeMode.None;
142  Size = PreferredSize;
143 
144  Cursor = new Widget( Font.CharacterWidth, Font.CharacterHeight );
145  Cursor.Color = cursorColor;
146  Add( Cursor );
147  AddedToGame += UpdateCursorPosition;
148 
149  cursorBlinkTimer = new Timer();
150  cursorBlinkTimer.Interval = 0.5;
151  cursorBlinkTimer.Timeout += blinkCursor;
152 
153  AddedToGame += onAdded;
154  Removed += onRemoved;
155 
156 #if WINDOWS_PHONE
157  AddedToGame += AddTouchListener;
158 #endif
159  }
160 
161  private void onAdded()
162  {
163  cursorBlinkTimer.Start();
164 #if WINDOWS
165  InputBoxes++;
166  Keyboard.Buffer.Enabled = true;
167  Keyboard.Buffer.BackspaceEnabled = true;
168  Keyboard.Buffer.Clear();
169  Keyboard.Buffer.TextChanged += updateText;
170 #endif
171  }
172 
173  private void onRemoved()
174  {
175  cursorBlinkTimer.Stop();
176 #if WINDOWS
177  InputBoxes--;
178  Keyboard.Buffer.Enabled = InputBoxes > 0;
179  Keyboard.Buffer.TextChanged -= updateText;
180 #endif
181  }
182 
183  private void blinkCursor()
184  {
185  Cursor.Color = ( Cursor.Color != cursorColor ) ? cursorColor : Color.Transparent;
186  }
187 
188  void UpdateCursorPosition()
189  {
190  Cursor.Left = Math.Min( -Width / 2 + XMargin + TextSize.X, Width / 2 - Font.CharacterWidth );
191  }
192 
193 #if WINDOWS
194  private void updateText()
195  {
196  if ( !ControlContext.Active ) return;
197  if ( Keyboard.Buffer.TextLength == 0 || Keyboard.Buffer.Text.Length == 0 ) return;
198 
199  bool changed = false;
200 
201  if ( Keyboard.Buffer.Text[0] == '\b' )
202  {
203  // Erase
204  if ( remainingDelay <= 0 )
205  {
206  if ( Text.Length > 0 )
207  {
208  Text = Text.Remove( Text.Length - 1 );
209  changed = true;
210  }
211  remainingDelay = InputBox.eraseDelay;
212  }
213  }
214  else if ( Text.Length < MaxCharacters )
215  {
216  // Type
217  Text += Keyboard.Buffer.Text;
218  changed = true;
219  }
220 
221  Keyboard.Buffer.Clear();
222 
223  UpdateCursorPosition();
224 
225  if ( changed )
226  OnTextChanged();
227  }
228 #endif
229 
230 #if WINDOWS_PHONE
231  void AddTouchListener()
232  {
233  Game.Instance.TouchPanel.ListenOn(this, ButtonState.Pressed, ShowTouchKeyboard, null).InContext( this );
234  }
235 
236  void ShowTouchKeyboard( Touch touch )
237  {
238  if ( !Guide.IsVisible )
239  Guide.BeginShowKeyboardInput( PlayerIndex.One, "", "", "", TouchTextEntered, this );
240  }
241 
242  void TouchTextEntered( IAsyncResult result )
243  {
244  string typedText = Guide.EndShowKeyboardInput( result );
245  if ( typedText != null )
246  {
247  Text = ( typedText.Length <= MaxCharacters ) ? typedText : typedText.Substring( 0, MaxCharacters );
248  UpdateCursorPosition();
249  OnTextChanged();
250  }
251  }
252 #endif
253 
257  public InputBox()
258  : this( 15 )
259  {
260  }
261 
262  public override void Update( Time time )
263  {
264 #if WINDOWS
265  if ( remainingDelay > 0 )
266  {
267  remainingDelay -= time.SinceLastUpdate.Ticks;
268  }
269 #endif
270 
271  base.Update( time );
272  }
273 
274  protected override void Draw( Matrix parentTransformation, Matrix transformation )
275  {
276  if ( ! IsTruncated )
277  base.Draw( parentTransformation, transformation, Text );
278  else
279  {
280  String shownText = "";
281 
282  for ( int i = Text.Length - 1; i >= 0; i-- )
283  {
284  String newText = Text[i] + shownText.ToString();
285 
286  if ( Font.XnaFont.MeasureString( newText ).X >= Width )
287  break;
288 
289  shownText = newText;
290  }
291 
292  base.Draw( parentTransformation, transformation, shownText );
293  }
294  }
295  }
296 }
double Interval
Aika sekunneissa, jonka välein TimeOut tapahtuu.
Definition: Timer.cs:99
HorizontalAlignment
Asemointi vaakasuunnassa.
Definition: View.cs:177
InputBox(int characters)
Alustaa uuden syöttökentän.
Definition: InputBox.cs:129
static readonly Color Black
Musta.
Definition: Color.cs:494
void Stop()
Pysäyttää ajastimen ja nollaa sen tilan.
Definition: Timer.cs:255
Action Timeout
Tapahtuu väliajoin.
Definition: Timer.cs:46
double CharacterHeight
Merkin korkeus.
Definition: Font.cs:76
Listener ListenOn(IGameObject o, ButtonState state, TouchHandler handler, String helpText)
Definition: TouchPanel.cs:334
Fontti.
Definition: Font.cs:22
Action< string > TextChanged
Tapahtuma tekstin muuttumiselle.
Definition: InputBox.cs:114
double CharacterWidth
Merkin leveys.
Definition: Font.cs:68
Kosketuspaneelin kosketus.
Definition: Touch.cs:16
Sizing
Olion koon asettaminen asettelijan sisällä.
Definition: ILayout.cs:38
Laatikko, johon käyttäjä voi syöttää tekstiä.
Definition: InputBox.cs:47
Tekstikenttä.
Definition: Label.cs:65
ButtonState
Napin (minkä tahansa) asento.
Definition: ButtonState.cs:37
static Game Instance
Definition: Game.cs:149
TimeSpan SinceLastUpdate
Aika joka on kulunut viime päivityksestä.
Definition: Time.cs:24
Käyttöliittymän komponentti.
Definition: Appearance.cs:9
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:13
Näppäimistö peliohjaimena.
Definition: Keyboard.cs:41
static readonly Color Transparent
Läpinäkyvä väri.
Definition: Color.cs:869
Peliluokka reaaliaikaisille peleille.
Definition: DebugScreen.cs:10
Listener InContext(ListenContext context)
Kuuntelee tapahtumaa vain tietyssä kontekstissa.
Definition: Listeners.cs:239
TouchPanel TouchPanel
Kosketusnäyttö. Vain kännykässä.
Definition: Game.cs:258
Ajastin, joka voidaan asettaa laukaisemaan tapahtumia tietyin väliajoin.
Definition: Timer.cs:39
Väri.
Definition: Color.cs:13
override void Draw(Matrix parentTransformation, Matrix transformation)
Definition: InputBox.cs:274
void Start()
Käynnistää ajastimen.
Definition: Timer.cs:220
InputBox()
Alustaa uuden syöttökentän.
Definition: InputBox.cs:257
override void Update(Time time)
Peliolion päivitys. Tätä kutsutaan, kun IsUpdated-ominaisuuden arvoksi on asetettu true ja olio on li...
Definition: InputBox.cs:262
2D-vektori.
Definition: Vector.cs:56