Guest User

Untitled

a guest
Sep 18th, 2014
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.19 KB | None | 0 0
  1. package org.newdawn.slick.gui;
  2.  
  3. import org.lwjgl.Sys;
  4. import org.newdawn.slick.Color;
  5. import org.newdawn.slick.Font;
  6. import org.newdawn.slick.Graphics;
  7. import org.newdawn.slick.Input;
  8. import org.newdawn.slick.geom.Rectangle;
  9.  
  10. /**
  11.  * A single text field supporting text entry
  12.  *
  13.  * @author kevin
  14.  */
  15. public class TextField extends AbstractComponent {
  16.     /** The key repeat interval */
  17.     private static final int INITIAL_KEY_REPEAT_INTERVAL = 400;
  18.     /** The key repeat interval */
  19.     private static final int KEY_REPEAT_INTERVAL = 50;
  20.    
  21.     /** The width of the field */
  22.     private int width;
  23.  
  24.     /** The height of the field */
  25.     private int height;
  26.    
  27.     /** The location in the X coordinate */
  28.     protected int x;
  29.  
  30.     /** The location in the Y coordinate */
  31.     protected int y;
  32.  
  33.     /** The maximum number of characters allowed to be input */
  34.     private int maxCharacter = 10000;
  35.  
  36.     /** The value stored in the text field */
  37.     private String value = "";
  38.  
  39.     /** The font used to render text in the field */
  40.     private Font font;
  41.  
  42.     /** The border color - null if no border */
  43.     private Color border = Color.white;
  44.  
  45.     /** The text color */
  46.     private Color text = Color.white;
  47.  
  48.     /** The background color - null if no background */
  49.     private Color background = new Color(0, 0, 0, 0.5f);
  50.  
  51.     /** The current cursor position */
  52.     private int cursorPos;
  53.  
  54.     /** True if the cursor should be visible */
  55.     private boolean visibleCursor = true;
  56.  
  57.     /** The last key pressed */
  58.     private int lastKey = -1;
  59.    
  60.     /** The last character pressed */
  61.     private char lastChar = 0;
  62.    
  63.     /** The time since last key repeat */
  64.     private long repeatTimer;
  65.    
  66.     /** The text before the paste in */
  67.     private String oldText;
  68.    
  69.     /** The cursor position before the paste */
  70.     private int oldCursorPos;
  71.    
  72.     /** True if events should be consumed by the field */
  73.     private boolean consume = true;
  74.    
  75.     /**
  76.      * Create a new text field
  77.      *
  78.      * @param container
  79.      *            The container rendering this field
  80.      * @param font
  81.      *            The font to use in the text field
  82.      * @param x
  83.      *            The x coordinate of the top left corner of the text field
  84.      * @param y
  85.      *            The y coordinate of the top left corner of the text field
  86.      * @param width
  87.      *            The width of the text field
  88.      * @param height
  89.      *            The height of the text field
  90.      * @param listener
  91.      *            The listener to add to the text field
  92.      */
  93.     public TextField(GUIContext container, Font font, int x, int y, int width,
  94.                      int height, ComponentListener listener) {
  95.         this(container,font,x,y,width,height);
  96.         addListener(listener);
  97.     }
  98.    
  99.     /**
  100.      * Create a new text field
  101.      *
  102.      * @param container
  103.      *            The container rendering this field
  104.      * @param font
  105.      *            The font to use in the text field
  106.      * @param x
  107.      *            The x coordinate of the top left corner of the text field
  108.      * @param y
  109.      *            The y coordinate of the top left corner of the text field
  110.      * @param width
  111.      *            The width of the text field
  112.      * @param height
  113.      *            The height of the text field
  114.      */
  115.     public TextField(GUIContext container, Font font, int x, int y, int width,
  116.             int height) {
  117.         super(container);
  118.  
  119.         this.font = font;
  120.  
  121.         setLocation(x, y);
  122.         this.width = width;
  123.         this.height = height;
  124.     }
  125.  
  126.     /**
  127.      * Indicate if the input events should be consumed by this field
  128.      *
  129.      * @param consume True if events should be consumed by this field
  130.      */
  131.     public void setConsumeEvents(boolean consume) {
  132.         this.consume = consume;
  133.     }
  134.    
  135.     /**
  136.      * Deactivate the key input handling for this field
  137.      */
  138.     public void deactivate() {
  139.         setFocus(false);
  140.     }
  141.    
  142.     /**
  143.      * Moves the component.
  144.      *
  145.      * @param x
  146.      *            X coordinate
  147.      * @param y
  148.      *            Y coordinate
  149.      */
  150.     public void setLocation(int x, int y) {
  151.         this.x = x;
  152.         this.y = y;
  153.     }
  154.  
  155.     /**
  156.      * Returns the position in the X coordinate
  157.      *
  158.      * @return x
  159.      */
  160.     public int getX() {
  161.         return x;
  162.     }
  163.  
  164.     /**
  165.      * Returns the position in the Y coordinate
  166.      *
  167.      * @return y
  168.      */
  169.     public int getY() {
  170.         return y;
  171.     }
  172.    
  173.     /**
  174.      * Get the width of the component
  175.      *
  176.      * @return The width of the component
  177.      */
  178.     public int getWidth() {
  179.         return width;
  180.     }
  181.  
  182.     /**
  183.      * Get the height of the component
  184.      *
  185.      * @return The height of the component
  186.      */
  187.     public int getHeight() {
  188.         return height;
  189.     }
  190.  
  191.     /**
  192.      * Set the background color. Set to null to disable the background
  193.      *
  194.      * @param color
  195.      *            The color to use for the background
  196.      */
  197.     public void setBackgroundColor(Color color) {
  198.         background = color;
  199.     }
  200.  
  201.     /**
  202.      * Set the border color. Set to null to disable the border
  203.      *
  204.      * @param color
  205.      *            The color to use for the border
  206.      */
  207.     public void setBorderColor(Color color) {
  208.         border = color;
  209.     }
  210.  
  211.     /**
  212.      * Set the text color.
  213.      *
  214.      * @param color
  215.      *            The color to use for the text
  216.      */
  217.     public void setTextColor(Color color) {
  218.         text = color;
  219.     }
  220.  
  221.     /**
  222.      * @see org.newdawn.slick.gui.AbstractComponent#render(org.newdawn.slick.gui.GUIContext,
  223.      *      org.newdawn.slick.Graphics)
  224.      */
  225.     public void render(GUIContext container, Graphics g) {
  226.         if (lastKey != -1) {
  227.             if (input.isKeyDown(lastKey)) {
  228.                 if (repeatTimer < System.currentTimeMillis()) {
  229.                     repeatTimer = System.currentTimeMillis() + KEY_REPEAT_INTERVAL;
  230.                     keyPressed(lastKey, lastChar);
  231.                 }
  232.             } else {
  233.                 lastKey = -1;
  234.             }
  235.         }
  236.         Rectangle oldClip = g.getClip();
  237.         g.setWorldClip(x,y,width, height);
  238.        
  239.         // Someone could have set a color for me to blend...
  240.         Color clr = g.getColor();
  241.  
  242.         if (background != null) {
  243.             g.setColor(background.multiply(clr));
  244.             g.fillRect(x, y, width, height);
  245.         }
  246.         g.setColor(text.multiply(clr));
  247.         Font temp = g.getFont();
  248.  
  249.         int cpos = font.getWidth(value.substring(0, cursorPos));
  250.         int tx = 0;
  251.         if (cpos > width) {
  252.             tx = width - cpos - font.getWidth("_");
  253.         }
  254.  
  255.         g.translate(tx + 2, 0);
  256.         g.setFont(font);
  257.         g.drawString(value, x + 1, y + 1);
  258.  
  259.         if (hasFocus() && visibleCursor) {
  260.             g.drawString("_", x + 1 + cpos + 2, y + 1);
  261.         }
  262.  
  263.         g.translate(-tx - 2, 0);
  264.  
  265.         if (border != null) {
  266.             g.setColor(border.multiply(clr));
  267.             g.drawRect(x, y, width, height);
  268.         }
  269.         g.setColor(clr);
  270.         g.setFont(temp);
  271.         g.clearWorldClip();
  272.         g.setClip(oldClip);
  273.     }
  274.  
  275.     /**
  276.      * Get the value in the text field
  277.      *
  278.      * @return The value in the text field
  279.      */
  280.     public String getText() {
  281.         return value;
  282.     }
  283.  
  284.     /**
  285.      * Set the value to be displayed in the text field
  286.      *
  287.      * @param value
  288.      *            The value to be displayed in the text field
  289.      */
  290.     public void setText(String value) {
  291.         this.value = value;
  292.         if (cursorPos > value.length()) {
  293.             cursorPos = value.length();
  294.         }
  295.     }
  296.  
  297.     /**
  298.      * Set the position of the cursor
  299.      *
  300.      * @param pos
  301.      *            The new position of the cursor
  302.      */
  303.     public void setCursorPos(int pos) {
  304.         cursorPos = pos;
  305.         if (cursorPos > value.length()) {
  306.             cursorPos = value.length();
  307.         }
  308.     }
  309.  
  310.     /**
  311.      * Indicate whether the mouse cursor should be visible or not
  312.      *
  313.      * @param visibleCursor
  314.      *            True if the mouse cursor should be visible
  315.      */
  316.     public void setCursorVisible(boolean visibleCursor) {
  317.         this.visibleCursor = visibleCursor;
  318.     }
  319.  
  320.     /**
  321.      * Set the length of the allowed input
  322.      *
  323.      * @param length
  324.      *            The length of the allowed input
  325.      */
  326.     public void setMaxLength(int length) {
  327.         maxCharacter = length;
  328.         if (value.length() > maxCharacter) {
  329.             value = value.substring(0, maxCharacter);
  330.         }
  331.     }
  332.  
  333.     /**
  334.      * Do the paste into the field, overrideable for custom behaviour
  335.      *
  336.      * @param text The text to be pasted in
  337.      */
  338.     protected void doPaste(String text) {
  339.         recordOldPosition();
  340.        
  341.         for (int i=0;i<text.length();i++) {
  342.             keyPressed(-1, text.charAt(i));
  343.         }
  344.     }
  345.    
  346.     /**
  347.      * Record the old position and content
  348.      */
  349.     protected void recordOldPosition() {
  350.         oldText = getText();
  351.         oldCursorPos = cursorPos;
  352.     }
  353.    
  354.     /**
  355.      * Do the undo of the paste, overrideable for custom behaviour
  356.      *
  357.      * @param oldCursorPos before the paste
  358.      * @param oldText The text before the last paste
  359.      */
  360.     protected void doUndo(int oldCursorPos, String oldText) {
  361.         if (oldText != null) {
  362.             setText(oldText);
  363.             setCursorPos(oldCursorPos);
  364.         }
  365.     }
  366.    
  367.     /**
  368.      * @see org.newdawn.slick.gui.AbstractComponent#keyPressed(int, char)
  369.      */
  370.     public void keyPressed(int key, char c) {
  371.         if (hasFocus()) {
  372.             if (key != -1)
  373.             {
  374.                 if ((key == Input.KEY_V) &&
  375.                    ((input.isKeyDown(Input.KEY_LCONTROL)) || (input.isKeyDown(Input.KEY_RCONTROL)))) {
  376.                     String text = Sys.getClipboard();
  377.                     if (text != null) {
  378.                         doPaste(text);
  379.                     }
  380.                     return;
  381.                 }
  382.                 if ((key == Input.KEY_Z) &&
  383.                    ((input.isKeyDown(Input.KEY_LCONTROL)) || (input.isKeyDown(Input.KEY_RCONTROL)))) {
  384.                     if (oldText != null) {
  385.                         doUndo(oldCursorPos, oldText);
  386.                     }
  387.                     return;
  388.                 }
  389.                
  390.                 // alt and control keys don't come through here
  391.                 if (input.isKeyDown(Input.KEY_LCONTROL) || input.isKeyDown(Input.KEY_RCONTROL)) {
  392.                     return;
  393.                 }
  394.                 if (input.isKeyDown(Input.KEY_LALT) || input.isKeyDown(Input.KEY_RALT)) {
  395.                     return;
  396.                 }
  397.             }
  398.            
  399.             if (lastKey != key) {
  400.                 lastKey = key;
  401.                 repeatTimer = System.currentTimeMillis() + INITIAL_KEY_REPEAT_INTERVAL;
  402.             } else {
  403.                 repeatTimer = System.currentTimeMillis() + KEY_REPEAT_INTERVAL;
  404.             }
  405.             lastChar = c;
  406.            
  407.             if (key == Input.KEY_LEFT) {
  408.                 if (cursorPos > 0) {
  409.                     cursorPos--;
  410.                 }
  411.                 // Nobody more will be notified
  412.                 if (consume) {
  413.                     container.getInput().consumeEvent();
  414.                 }
  415.             } else if (key == Input.KEY_RIGHT) {
  416.                 if (cursorPos < value.length()) {
  417.                     cursorPos++;
  418.                 }
  419.                 // Nobody more will be notified
  420.                 if (consume) {
  421.                     container.getInput().consumeEvent();
  422.                 }
  423.             } else if (key == Input.KEY_BACK) {
  424.                 if ((cursorPos > 0) && (value.length() > 0)) {
  425.                     if (cursorPos < value.length()) {
  426.                         value = value.substring(0, cursorPos - 1)
  427.                                 + value.substring(cursorPos);
  428.                     } else {
  429.                         value = value.substring(0, cursorPos - 1);
  430.                     }
  431.                     cursorPos--;
  432.                 }
  433.                 // Nobody more will be notified
  434.                 if (consume) {
  435.                     container.getInput().consumeEvent();
  436.                 }
  437.             } else if (key == Input.KEY_DELETE) {
  438.                 if (value.length() > cursorPos) {
  439.                     value = value.substring(0,cursorPos) + value.substring(cursorPos+1);
  440.                 }
  441.                 // Nobody more will be notified
  442.                 if (consume) {
  443.                     container.getInput().consumeEvent();
  444.                 }
  445.             } else if ((c < 127) && (c > 31) && (value.length() < maxCharacter)) {
  446.                 if (cursorPos < value.length()) {
  447.                     value = value.substring(0, cursorPos) + c
  448.                             + value.substring(cursorPos);
  449.                 } else {
  450.                     value = value.substring(0, cursorPos) + c;
  451.                 }
  452.                 cursorPos++;
  453.                 // Nobody more will be notified
  454.                 if (consume) {
  455.                     container.getInput().consumeEvent();
  456.                 }
  457.             } else if (key == Input.KEY_RETURN) {
  458.                 notifyListeners();
  459.                 // Nobody more will be notified
  460.                 if (consume) {
  461.                     container.getInput().consumeEvent();
  462.                 }
  463.             }
  464.  
  465.         }
  466.     }
  467.  
  468.     /**
  469.      * @see org.newdawn.slick.gui.AbstractComponent#setFocus(boolean)
  470.      */
  471.     public void setFocus(boolean focus) {
  472.         lastKey = -1;
  473.        
  474.         super.setFocus(focus);
  475.     }
  476. }
Advertisement
Add Comment
Please, Sign In to add comment