public override void Update() { bool altPressed = KeyboardInput.AltIsPressed; bool released = prevAltPressed && !altPressed; if (released && specialChar != null) { // If specialChar is anything but valid numbers this will throw. // Ignore and move on. try { char c = (char)int.Parse(specialChar); if (TextHelper.CharIsValid(c)) { TextInput(c); } } catch { } specialChar = null; } prevAltPressed = altPressed; // Our children may have input focus but we can still steal away the buttons we care about. GamePadInput pad = GamePadInput.GetGamePad0(); // Mouse input Vector2 hit = MouseInput.PositionVec; hit = (hit - BokuGame.ScreenPosition); // Touch input TouchContact touch = TouchInput.GetOldestTouch(); Vector2 touchHit = Vector2.Zero; if (touch != null) { touchHit = touch.position; touchHit = (touchHit - BokuGame.ScreenPosition); } // If the virtual keybaord is active, don't let touch input leak through. if (touch != null && VirtualKeyboard.Active && VirtualKeyboard.HitBox.Contains(touch.position)) { touch = null; } bool bSave = false; bool bCanceled = false; if (null != touch) { parent.touchedThisFrame = true; if (shared.bHitBox.Touched(touch, touchHit)) { bCanceled = true; } if (shared.aHitBox.Touched(touch, touchHit)) { bSave = true; } } bCanceled = bCanceled || pad.ButtonB.WasPressed || shared.bHitBox.LeftPressed(hit); bSave = bSave || pad.ButtonA.WasPressed || KeyboardInput.WasPressed(Keys.Escape) || shared.aHitBox.LeftPressed(hit); if (bCanceled) { // Cancel. // Ignore the edited text. Just exit. // Don't Ignore the EditDone Callback. if (null != shared.onEditDone) { shared.onEditDone(true, ""); shared.onEditDone = null; } parent.Deactivate(); pad.ButtonB.ClearAllWasPressedState(); } else if (bSave) { shared.onEditDone(false, shared.blob.ScrubbedText); shared.onEditDone = null; parent.Deactivate(); pad.ButtonA.ClearAllWasPressedState(); KeyboardInput.ClearAllWasPressedState(Keys.Escape); } Vector2 testhit = hit; if (touch != null) { testhit = touchHit; } bool bMouseHit = shared.textAreaHitBox.LeftPressed(hit); bool bTouched = touch != null && shared.textAreaHitBox.Touched(touch, touchHit); // Check for hits in the text area. The scroll arrows intrude a bit so ignore anything in that area. if (bMouseHit || bTouched) { if (bTouched) { KeyboardInput.ShowOnScreenKeyboard(); } // Move the cursor to where the user pressed. // Calc line we're on. int line = (int)((testhit.Y - shared.textAreaHitBox.Min.Y) / shared.blob.TotalSpacing) + shared.topLine; int curLine = 0; int x = 0; shared.blob.FindCursorLineAndPosition(out curLine, out x); if (curLine > line) { for (int i = 0; i < curLine - line; i++) { shared.blob.CursorUp(); } } else if (curLine < line) { for (int i = 0; i < line - curLine; i++) { shared.blob.CursorDown(); } } shared.blob.FindCursorLineAndPosition(out curLine, out x); int mouseX = (int)(testhit.X - shared.textAreaHitBox.Min.X); // Ensure mouseX is within the current line. Be sure to account for justification. int curLineWidth = shared.blob.GetLineWidth(curLine); int totalWidth = shared.blob.Width; //Calculate margin based on justification. int margin = 0; switch (shared.blob.Justification) { case UIGridElement.Justification.Center: margin = (totalWidth - curLineWidth) / 2; break; case UIGridElement.Justification.Right: margin = totalWidth - curLineWidth; break; } mouseX = Math.Max(mouseX, margin); mouseX = Math.Min(mouseX, margin + curLineWidth); shared.blob.SetCursorPosition(curLine, mouseX); shared.blob.FindCursorLineAndPosition(out curLine, out x); } // If we're not shutting down... if (parent.Active) { } // end if not shutting down. } // end of Update()