OSDN Git Service

TextField, updates to use displayed text for glyph positions rather than actual text...
authornathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Fri, 2 Mar 2012 23:39:55 +0000 (23:39 +0000)
committernathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Fri, 2 Mar 2012 23:39:55 +0000 (23:39 +0000)
gdx/src/com/badlogic/gdx/scenes/scene2d/ui/TextField.java

index 1143eed..0eda845 100644 (file)
@@ -58,6 +58,7 @@ public class TextField extends Widget {
 \r
        private TextFieldStyle style;\r
        private String text, messageText;\r
+       private CharSequence displayText;\r
        private int cursor;\r
        private Clipboard clipboard;\r
        private TextFieldListener listener;\r
@@ -65,11 +66,6 @@ public class TextField extends Widget {
        private OnscreenKeyboard keyboard = new DefaultOnscreenKeyboard();\r
 \r
        private boolean passwordMode;\r
-       \r
-       /**\r
-        * Used to calculate the cursor position.\r
-        */\r
-       private StringBuilder hiddenText = new StringBuilder();\r
        private StringBuilder passwordBuffer;\r
 \r
        private final Rectangle fieldBounds = new Rectangle();\r
@@ -135,7 +131,6 @@ public class TextField extends Widget {
 \r
        public void setPasswordCharacter (char passwordCharacter) {\r
                this.passwordCharacter = passwordCharacter;\r
-               computeGlyphAdvancesAndPositions(style.font, text);\r
        }\r
 \r
        /** Returns the text field's style. Modifying the returned style may not have an effect until {@link #setStyle(TextFieldStyle)}\r
@@ -183,8 +178,8 @@ public class TextField extends Widget {
                }\r
 \r
                // calculate last visible char based on visible width and render offset\r
-               visibleTextEnd = Math.min(text.length(), cursor + 1);\r
-               for (; visibleTextEnd <= text.length(); visibleTextEnd++) {\r
+               visibleTextEnd = Math.min(displayText.length(), cursor + 1);\r
+               for (; visibleTextEnd <= displayText.length(); visibleTextEnd++) {\r
                        if (glyphPositions.items[visibleTextEnd] - startPos > visibleWidth) break;\r
                }\r
                visibleTextEnd = Math.max(0, visibleTextEnd - 1);\r
@@ -223,7 +218,7 @@ public class TextField extends Widget {
                                y + textY - textBounds.height - font.getDescent() / 2, selectionWidth, textBounds.height);\r
                }\r
 \r
-               if (text.length() == 0) {\r
+               if (displayText.length() == 0) {\r
                        if (!focused && messageText != null) {\r
                                if (style.messageFontColor != null) {\r
                                        font.setColor(style.messageFontColor.r, style.messageFontColor.g, style.messageFontColor.b,\r
@@ -235,17 +230,7 @@ public class TextField extends Widget {
                        }\r
                } else {\r
                        font.setColor(fontColor.r, fontColor.g, fontColor.b, fontColor.a * parentAlpha);\r
-                       if (passwordMode && font.containsCharacter(passwordCharacter)) {\r
-                               if (passwordBuffer == null) passwordBuffer = new StringBuilder(text.length());\r
-                               if (passwordBuffer.length() > text.length()) //\r
-                                       passwordBuffer.setLength(text.length());\r
-                               else {\r
-                                       for (int i = passwordBuffer.length(), n = text.length(); i < n; i++)\r
-                                               passwordBuffer.append(passwordCharacter);\r
-                               }\r
-                               font.draw(batch, passwordBuffer, x + bgLeftWidth + textOffset, y + textY, visibleTextStart, visibleTextEnd);\r
-                       } else\r
-                               font.draw(batch, text, x + bgLeftWidth + textOffset, y + textY, visibleTextStart, visibleTextEnd);\r
+                       font.draw(batch, displayText, x + bgLeftWidth + textOffset, y + textY, visibleTextStart, visibleTextEnd);\r
                }\r
                if (focused) {\r
                        blink();\r
@@ -256,6 +241,21 @@ public class TextField extends Widget {
                }\r
        }\r
 \r
+       private void updateDisplayText () {\r
+               if (passwordMode && style.font.containsCharacter(passwordCharacter)) {\r
+                       if (passwordBuffer == null) passwordBuffer = new StringBuilder(text.length());\r
+                       if (passwordBuffer.length() > text.length()) //\r
+                               passwordBuffer.setLength(text.length());\r
+                       else {\r
+                               for (int i = passwordBuffer.length(), n = text.length(); i < n; i++)\r
+                                       passwordBuffer.append(passwordCharacter);\r
+                       }\r
+                       displayText = passwordBuffer;\r
+               } else\r
+                       displayText = text;\r
+               style.font.computeGlyphAdvancesAndPositions(displayText, glyphAdvances, glyphPositions);\r
+       }\r
+\r
        private void blink () {\r
                long time = System.nanoTime();\r
                if ((time - lastBlink) / 1000000000.0f > blinkTime) {\r
@@ -285,6 +285,8 @@ public class TextField extends Widget {
        }\r
 \r
        public boolean keyDown (int keycode) {\r
+               final BitmapFont font = style.font;\r
+\r
                if (stage != null && stage.getKeyboardFocus() == this) {\r
                        if (Gdx.input.isKeyPressed(Keys.CONTROL_LEFT) || Gdx.input.isKeyPressed(Keys.CONTROL_RIGHT)) {\r
                                // paste\r
@@ -379,8 +381,8 @@ public class TextField extends Widget {
                        }\r
                        content = builder.toString();\r
                        text = text.substring(0, cursor) + content + text.substring(cursor, text.length());\r
+                       updateDisplayText();\r
                        cursor += content.length();\r
-                       computeGlyphAdvancesAndPositions(style.font, text);\r
                }\r
        }\r
 \r
@@ -389,8 +391,8 @@ public class TextField extends Widget {
                int maxIndex = Math.max(cursor, selectionStart);\r
                text = (minIndex > 0 ? text.substring(0, minIndex) : "")\r
                        + (maxIndex < text.length() ? text.substring(maxIndex, text.length()) : "");\r
+               updateDisplayText();\r
                cursor = minIndex;\r
-               style.font.computeGlyphAdvancesAndPositions(text, glyphAdvances, glyphPositions);\r
                clearSelection();\r
        }\r
 \r
@@ -401,8 +403,8 @@ public class TextField extends Widget {
                        if (character == BACKSPACE && (cursor > 0 || hasSelection)) {\r
                                if (!hasSelection) {\r
                                        text = text.substring(0, cursor - 1) + text.substring(cursor);\r
+                                       updateDisplayText();\r
                                        cursor--;\r
-                                       computeGlyphAdvancesAndPositions(font, text);\r
                                } else {\r
                                        delete();\r
                                }\r
@@ -411,7 +413,7 @@ public class TextField extends Widget {
                                if (cursor < text.length() || hasSelection) {\r
                                        if (!hasSelection) {\r
                                                text = text.substring(0, cursor) + text.substring(cursor + 1);\r
-                                               computeGlyphAdvancesAndPositions(font, text);\r
+                                               updateDisplayText();\r
                                        } else {\r
                                                delete();\r
                                        }\r
@@ -426,8 +428,8 @@ public class TextField extends Widget {
                        if (font.containsCharacter(character)) {\r
                                if (!hasSelection) {\r
                                        text = text.substring(0, cursor) + character + text.substring(cursor, text.length());\r
+                                       updateDisplayText();\r
                                        cursor++;\r
-                                       computeGlyphAdvancesAndPositions(font, text);\r
                                } else {\r
                                        int minIndex = Math.min(cursor, selectionStart);\r
                                        int maxIndex = Math.max(cursor, selectionStart);\r
@@ -436,8 +438,8 @@ public class TextField extends Widget {
                                                + (maxIndex < text.length() ? text.substring(maxIndex, text.length()) : "");\r
                                        cursor = minIndex;\r
                                        text = text.substring(0, cursor) + character + text.substring(cursor, text.length());\r
+                                       updateDisplayText();\r
                                        cursor++;\r
-                                       computeGlyphAdvancesAndPositions(font, text);\r
                                        clearSelection();\r
                                }\r
                        }\r
@@ -447,17 +449,6 @@ public class TextField extends Widget {
                        return false;\r
        }\r
 \r
-       public void computeGlyphAdvancesAndPositions (final BitmapFont font, String text) {\r
-               if (!passwordMode) {\r
-                       font.computeGlyphAdvancesAndPositions(text, glyphAdvances, glyphPositions);\r
-               } else {\r
-                       hiddenText.delete(0, hiddenText.length());\r
-                       for (int i = 0; i < text.length(); i++) \r
-                               hiddenText.append(passwordCharacter);\r
-                       font.computeGlyphAdvancesAndPositions(hiddenText, glyphAdvances, glyphPositions);\r
-               }\r
-       }\r
-\r
        /** Focuses the next TextField. If none is found, the keyboard is hidden. Does nothing if the text field is not in a stage.\r
         * @param up If true, the TextField with the same or next smallest y coordinate is found, else the next highest. */\r
        public void next (boolean up) {\r
@@ -518,13 +509,13 @@ public class TextField extends Widget {
                }\r
 \r
                this.text = buffer.toString();\r
+               updateDisplayText();\r
                cursor = 0;\r
                clearSelection();\r
-               computeGlyphAdvancesAndPositions(font, text);\r
 \r
-               textBounds.set(font.getBounds(text));\r
+               textBounds.set(font.getBounds(displayText));\r
                textBounds.height -= font.getDescent() * 2;\r
-               computeGlyphAdvancesAndPositions(font, text);\r
+               font.computeGlyphAdvancesAndPositions(displayText, glyphAdvances, glyphPositions);\r
        }\r
 \r
        /** @return Never null, might be an empty string. */\r
@@ -595,7 +586,6 @@ public class TextField extends Widget {
         * no affect. */\r
        public void setPasswordMode (boolean passwordMode) {\r
                this.passwordMode = passwordMode;\r
-               computeGlyphAdvancesAndPositions(style.font, text);\r
        }\r
 \r
        /** Interface for listening to typed characters.\r