Jypeli 10
The simple game programming library
VirtualKeyboard.cs
Siirry tämän tiedoston dokumentaatioon.
1using Microsoft.Xna.Framework;
2using Microsoft.Xna.Framework.Graphics;
3using Microsoft.Xna.Framework.Input;
4using System;
5using System.Collections.Generic;
6using System.Linq;
7using System.Text;
8using System.Threading.Tasks;
9using XnaGame = Microsoft.Xna.Framework.Game;
10using XnaRectangle = Microsoft.Xna.Framework.Rectangle;
11using XnaColor = Microsoft.Xna.Framework.Color;
12using XnaMouse = Microsoft.Xna.Framework.Input.Mouse;
13using XnaTouchPanel = Microsoft.Xna.Framework.Input.Touch.TouchPanel;
14using XnaButtonState = Microsoft.Xna.Framework.Input.ButtonState;
15using Microsoft.Xna.Framework.Input.Touch;
16using FontStashSharp;
17
19{
26 class VirtualKeyboard : DrawableGameComponent
27 {
28 internal const int KEY_PADDING = 5;
29
30 private static readonly VirtualKeyInfo[][] keyLines = new VirtualKeyInfo[][]
31 {
32 new VirtualKeyInfo[] {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", new VirtualKeyInfo("<=", "", 1.0, VirtualKeyType.Backspace)},
33 new VirtualKeyInfo[] {"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "Å"},
34 new VirtualKeyInfo[] {"A", "S", "D", "F", "G", "H", "J", "K", "L", "Ö", "Ä"},
35 new VirtualKeyInfo[] {"Z", "X", "C", "V", "B", "N", "M", ".", ",", "-", "*"},
36 new VirtualKeyInfo[] {new VirtualKeyInfo("Space", " ", 7), new VirtualKeyInfo("= >", "", 4, VirtualKeyType.Enter)},
37 };
38
39 public VirtualKeyboard(Game jypeliGame) : base(jypeliGame)
40 {
41 this.game = jypeliGame;
42 }
43
44 public event EventHandler<VirtualKeyboardInputEventArgs> InputEntered;
45 public event EventHandler EnterPressed;
46 public event EventHandler BackspacePressed;
47
48 private Game game;
49 private SpriteBatch spriteBatch;
50
51 private List<VirtualKey> keys;
52
53 private int Y;
54 private int X = 0;
55 private int Width;
56 private int Height;
57
58 private Texture2D whitePixelTexture;
59
61
62 public override void Initialize()
63 {
64 base.Initialize();
65
66 keys = new List<VirtualKey>();
67 Width = Game.GraphicsDevice.Viewport.Width;
68 Height = Game.GraphicsDevice.Viewport.Height / 2;
69
70 Y = Game.GraphicsDevice.Viewport.Height - Height;
71
72 int highestKeyCount = GetKeyCountOnSingleLine();
73
74 int baseKeyWidth = (Width - KEY_PADDING * (1 + highestKeyCount)) / highestKeyCount;
75 int keyHeight = ((Height - KEY_PADDING) / keyLines.Length) - KEY_PADDING;
76
77 // Create keys
78 for (int y = 0; y < keyLines.Length; y++)
79 {
80 int yCoord = KEY_PADDING + y * (keyHeight + KEY_PADDING);
81 int xCoord = KEY_PADDING;
82
83 for (int x = 0; x < keyLines[y].Length; x++)
84 {
85 VirtualKeyInfo keyInfo = keyLines[y][x];
86
87 var virtualKey = new VirtualKey(game, keyInfo.DisplayString, keyInfo.Value,
88 xCoord, yCoord, (int)(baseKeyWidth * keyInfo.WidthMultiplier), keyHeight,
89 new Font(60), keyInfo.KeyType);
90 xCoord += virtualKey.Width;
91 xCoord += KEY_PADDING;
92
93 keys.Add(virtualKey);
94 }
95 }
96
97 spriteBatch = new SpriteBatch(GraphicsDevice);
98 whitePixelTexture = XnaRenderer.CreateTexture(GraphicsDevice, Color.White, 1, 1);
99 }
100
102 {
103 int highestKeyCount = int.MinValue;
104
105 foreach (VirtualKeyInfo[] line in keyLines)
106 {
107 if (highestKeyCount < line.Length)
108 highestKeyCount = line.Length;
109 }
110
111 return highestKeyCount;
112 }
113
117 public void Hide()
118 {
119 Visible = false;
120 Enabled = false;
121 }
122
126 public void Show()
127 {
128 Visible = true;
129 Enabled = true;
130 }
131
136 private void HandleKeyPress(VirtualKey key)
137 {
138 switch (key.Type)
139 {
140 case VirtualKeyType.Enter:
141 EnterPressed?.Invoke(this, EventArgs.Empty);
142 break;
143 case VirtualKeyType.Backspace:
144 BackspacePressed?.Invoke(this, EventArgs.Empty);
145 break;
146 case VirtualKeyType.Normal:
147 default:
148 InputEntered?.Invoke(this, new VirtualKeyboardInputEventArgs(key.Value));
149 break;
150 }
151
152 key.Pressed();
153 }
154
155 public override void Update(GameTime gameTime)
156 {
157 bool checkForKeyPress;
158
159#if NETCOREAPP
160 MouseState mouseState = XnaMouse.GetState();
161
162 checkForKeyPress = prevMouseState.LeftButton == XnaButtonState.Pressed &&
163 mouseState.LeftButton == XnaButtonState.Released;
164#endif
165
166#if ANDROID
167 TouchCollection touchCollection = XnaTouchPanel.GetState();
168 checkForKeyPress = touchCollection.Count > 0 && touchCollection[0].State == TouchLocationState.Released;
169 // TODO multi-touch support?
170 Vector2 touchPos = touchCollection.Count > 0 ? touchCollection[0].Position : Vector2.Zero;
171#endif
172
173 foreach (VirtualKey key in keys)
174 {
175 if (checkForKeyPress)
176 {
177#if WINDOWS
178 if (mouseState.Y > Y + key.Y && mouseState.Y < Y + key.Y + key.Height &&
179 mouseState.X > X + key.X && mouseState.X < X + key.X + key.Width)
180 {
181 HandleKeyPress(key);
182 checkForKeyPress = false;
183 }
184#endif
185
186#if ANDROID
187 if (touchPos.Y > Y + key.Y && touchPos.Y < Y + key.Y + key.Height &&
188 touchPos.X > X + key.X && touchPos.X < X + key.X + key.Width)
189 {
190 HandleKeyPress(key);
191 checkForKeyPress = false;
192 }
193#endif
194 }
195
196 key.Update(gameTime);
197 }
198
199#if WINDOWS
200 prevMouseState = mouseState;
201#endif
202
203 base.Update(gameTime);
204 }
205
206 public override void Draw(GameTime gameTime)
207 {
208 spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied,
209 null, null, null, null, null);
211 new XnaRectangle(X, Y, Width, Height), XnaColor.White);
212 foreach (VirtualKey key in keys)
213 {
215 }
216 spriteBatch.End();
217
218 base.Draw(gameTime);
219 }
220 }
221
225 internal class VirtualKey
226 {
227 private static XnaColor backgroundColorIdle = XnaColor.Gray;
228 private static XnaColor textColorIdle = XnaColor.White;
230 private static XnaColor textColorPressed = XnaColor.Red;
231
232 private const float HIGHLIGHT_TIME_ON_PRESS = 0.125f;
233
234 public VirtualKey(XnaGame game, string text)
235 {
236 UIText = text;
237 }
238
239 public VirtualKey(XnaGame game, string text, string value,
240 int x, int y, int width, int height, Font font, VirtualKeyType type) : this(game, text)
241 {
242 X = x;
243 Y = y;
244 Width = width;
245 Height = height;
246 Font = font;
247 Value = value;
248 Type = type;
249 }
250
254 public VirtualKeyType Type { get; private set; }
255
259 public string Value { get; private set; }
260
264 public string UIText { get; private set; }
265
266 public int X { get; set; }
267 public int Y { get; set; }
268 public int Width { get; set; }
269 public int Height { get; set; }
270 public Font Font { get; set; }
271
272 private double highlightTime;
273
276
280 public void Pressed()
281 {
285 }
286
291 public void Update(GameTime gameTime)
292 {
293 if (highlightTime > 0.0)
294 {
295 highlightTime -= gameTime.ElapsedGameTime.TotalSeconds;
296 if (highlightTime < 0.0)
297 {
300 }
301 }
302 }
303
307 public void Draw(Texture2D whitePixelTexture, SpriteBatch sb, int xOffset, int yOffset)
308 {
309 var drawRectangle = new XnaRectangle(xOffset + X, yOffset + Y, Width, Height);
310 XnaRenderer.FillRectangle(whitePixelTexture, sb, drawRectangle, backgroundColor);
311 XnaRenderer.DrawRectangle(whitePixelTexture, sb, drawRectangle, 2, new XnaColor(196, 196, 196, 255));
314 }
315 }
316
320 internal static class XnaRenderer
321 {
322 public static void FillRectangle(Texture2D whitePixelTexture, SpriteBatch sb, XnaRectangle rect, XnaColor color)
323 {
324 sb.Draw(whitePixelTexture, rect, color);
325 }
326
327 public static Texture2D CreateTexture(GraphicsDevice gd, Color color, int width, int height)
328 {
329 Texture2D texture = new Texture2D(gd, width, height, false, SurfaceFormat.Color);
330
331 Color[] colorArray = new Color[width * height];
332
333 for (int i = 0; i < colorArray.Length; i++)
334 colorArray[i] = color;
335
336 texture.SetData(colorArray);
337
338 return texture;
339 }
340
341 public static void DrawStringWithShadow(SpriteBatch sb, string text, DynamicSpriteFont font, Vector2 location, XnaColor color)
342 {
343 font.DrawText(Graphics.FontRenderer, text, (new Vector2(location.X + 1f, location.Y + 1f)).ToSystemNumerics(), XnaColor.Black.ToSystemDrawing());
344 font.DrawText(Graphics.FontRenderer, text, location.ToSystemNumerics(), color.ToSystemDrawing());
345 }
346
347 public static void DrawRectangle(Texture2D whitePixelTexture, SpriteBatch sb, XnaRectangle rect, int thickness, XnaColor color)
348 {
349 sb.Draw(whitePixelTexture, new XnaRectangle(rect.X, rect.Y, rect.Width, thickness), color);
350 sb.Draw(whitePixelTexture, new XnaRectangle(rect.X, rect.Y + thickness, thickness, rect.Height - thickness), color);
351 sb.Draw(whitePixelTexture, new XnaRectangle(rect.X + rect.Width - thickness, rect.Y, thickness, rect.Height), color);
352 sb.Draw(whitePixelTexture, new XnaRectangle(rect.X, rect.Y + rect.Height - thickness, rect.Width, thickness), color);
353 }
354 }
355
356
360 internal enum VirtualKeyType
361 {
365 Normal,
366
370 Enter,
371
376 }
377
378
382 internal struct VirtualKeyInfo
383 {
384 public VirtualKeyInfo(string displayString, string value, double widthMultiplier = 1.0, VirtualKeyType keyType = VirtualKeyType.Normal) : this()
385 {
386 DisplayString = displayString;
387 WidthMultiplier = widthMultiplier;
388 KeyType = keyType;
389 Value = value;
390 }
391
392 public static implicit operator VirtualKeyInfo(char c)
393 {
394 return new VirtualKeyInfo(c.ToString(), c.ToString());
395 }
396
397 public static implicit operator VirtualKeyInfo(string s)
398 {
399 return new VirtualKeyInfo(s, s);
400 }
401
402 public string DisplayString { get; private set; }
403 public double WidthMultiplier { get; private set; }
404 public VirtualKeyType KeyType { get; private set; }
405 public string Value { get; private set; }
406 }
407
408
412 internal class VirtualKeyboardInputEventArgs : EventArgs
413 {
415 {
416 Text = text;
417 }
418
422 public string Text { get; private set; }
423 }
424}
System.Numerics.Vector2 Vector2
Microsoft.Xna.Framework.Game XnaGame
Microsoft.Xna.Framework.Rectangle XnaRectangle
Microsoft.Xna.Framework.Color XnaColor
Microsoft.Xna.Framework.Input.Mouse XnaMouse
Microsoft.Xna.Framework.Input.ButtonState XnaButtonState
Microsoft.Xna.Framework.Input.Touch.TouchPanel XnaTouchPanel
Yksittäinen näppäin virtuaalisessa näppäimistössä.
string Value
Teksti, joka syötetään näppäintä painettaessa.
VirtualKeyType Type
Näppäimen tyyppi.
void Update(GameTime gameTime)
Päivittää näppäimen tilaa.
VirtualKey(XnaGame game, string text)
string UIText
Käyttöliittymässä näppäimen kohdalla näytetty teksti.
VirtualKey(XnaGame game, string text, string value, int x, int y, int width, int height, Font font, VirtualKeyType type)
void Draw(Texture2D whitePixelTexture, SpriteBatch sb, int xOffset, int yOffset)
Piirtää näppäimen.
void Pressed()
Kutsutaan, kun näppäintä on painettu.
Virtuaalinen näppäimistö. Tarkoitettu ensisijaisesti mobiilialustoille, joiden oman virtuaalinäppäimi...
static readonly VirtualKeyInfo[][] keyLines
EventHandler< VirtualKeyboardInputEventArgs > InputEntered
override void Draw(GameTime gameTime)
override void Update(GameTime gameTime)
void Show()
Avaa virtuaalisen näppäimistön.
void Hide()
Piilottaa virtuaalisen näppäimistön.
void HandleKeyPress(VirtualKey key)
Käsittelee näppäimen painalluksen.
Tavallisen näppäimen (ei Enter tai Backspace) painalluksesta syntyvän tapahtuman tiedot.
Sisältää näppäimistön piitämiseen käytettyjä metodeja.
static Texture2D CreateTexture(GraphicsDevice gd, Color color, int width, int height)
static void FillRectangle(Texture2D whitePixelTexture, SpriteBatch sb, XnaRectangle rect, XnaColor color)
static void DrawRectangle(Texture2D whitePixelTexture, SpriteBatch sb, XnaRectangle rect, int thickness, XnaColor color)
static void DrawStringWithShadow(SpriteBatch sb, string text, DynamicSpriteFont font, Vector2 location, XnaColor color)
Fontti.
Definition: Font.cs:24
DynamicSpriteFont XnaFont
Definition: Font.cs:50
static new GraphicsDevice GraphicsDevice
XNA:n grafiikkakortti.
Definition: Graphics.cs:49
Contains graphics resources.
Definition: Graphics.cs:36
static FontStashSharp.Renderer FontRenderer
Definition: Graphics.cs:42
VirtualKeyType
Näppäimen tyyppi.
@ Normal
Näppäin syöttää tekstiä kuin "tavallinen" näppäin.
@ Backspace
Näppäin toimii Backspace-painikkeena.
Microsoft.Xna.Framework.Input.Touch.TouchPanel XnaTouchPanel
Definition: TouchPanel.cs:8
Microsoft.Xna.Framework.Input.MouseState MouseState
Definition: Mouse.cs:39
@ Enter
Siirtymässä olion päälle.
Microsoft.Xna.Framework.Input.ButtonState XnaButtonState
Definition: Mouse.cs:40
Microsoft.Xna.Framework.Input.Mouse XnaMouse
Definition: Mouse.cs:38
Väri.
Definition: Color.cs:13
static readonly Color White
Valkoinen.
Definition: Color.cs:956
Tietue, joka sisältää olennaiset tiedot näppäimestä sen luontia varten.
VirtualKeyInfo(string displayString, string value, double widthMultiplier=1.0, VirtualKeyType keyType=VirtualKeyType.Normal)