    001    package net.minecraft.client.gui;
    002
    003    import cpw.mods.fml.relauncher.Side;
    004    import cpw.mods.fml.relauncher.SideOnly;
    005    import net.minecraft.client.renderer.Tessellator;
    006    import net.minecraft.util.ChatAllowedCharacters;
    007    import org.lwjgl.opengl.GL11;
    008
    009    @SideOnly(Side.CLIENT)
    010    public class GuiTextField extends Gui
    011    {
    012        /**
    013         * Have the font renderer from GuiScreen to render the textbox text into the screen.
    014         */
    015        private final FontRenderer fontRenderer;
    016        private final int xPos;
    017        private final int yPos;
    018
    019        /** The width of this text field. */
    020        private final int width;
    021        private final int height;
    022
    023        /** Have the current text beign edited on the textbox. */
    024        private String text = "";
    025        private int maxStringLength = 32;
    026        private int cursorCounter;
    027        private boolean enableBackgroundDrawing = true;
    028
    029        /**
    030         * if true the textbox can lose focus by clicking elsewhere on the screen
    031         */
    032        private boolean canLoseFocus = true;
    033
    034        /**
    035         * If this value is true along isEnabled, keyTyped will process the keys.
    036         */
    037        private boolean isFocused = false;
    038
    039        /**
    040         * If this value is true along isFocused, keyTyped will process the keys.
    041         */
    042        private boolean isEnabled = true;
    043        private int field_73816_n = 0;
    044        private int cursorPosition = 0;
    045
    046        /** other selection position, maybe the same as the cursor */
    047        private int selectionEnd = 0;
    048        private int enabledColor = 14737632;
    049        private int disabledColor = 7368816;
    050
    051        /** True if this textbox is visible */
    052        private boolean visible = true;
    053
    054        public GuiTextField(FontRenderer par1FontRenderer, int par2, int par3, int par4, int par5)
    055        {
    056            this.fontRenderer = par1FontRenderer;
    057            this.xPos = par2;
    058            this.yPos = par3;
    059            this.width = par4;
    060            this.height = par5;
    061        }
    062
    063        /**
    064         * Increments the cursor counter
    065         */
    066        public void updateCursorCounter()
    067        {
    068            ++this.cursorCounter;
    069        }
    070
    071        /**
    072         * Sets the text of the textbox.
    073         */
    074        public void setText(String par1Str)
    075        {
    076            if (par1Str.length() > this.maxStringLength)
    077            {
    078                this.text = par1Str.substring(0, this.maxStringLength);
    079            }
    080            else
    081            {
    082                this.text = par1Str;
    083            }
    084
    085            this.setCursorPositionEnd();
    086        }
    087
    088        /**
    089         * Returns the text beign edited on the textbox.
    090         */
    091        public String getText()
    092        {
    093            return this.text;
    094        }
    095
    096        /**
    097         * @return returns the text between the cursor and selectionEnd
    098         */
    099        public String getSelectedtext()
    100        {
    101            int var1 = this.cursorPosition < this.selectionEnd ? this.cursorPosition : this.selectionEnd;
    102            int var2 = this.cursorPosition < this.selectionEnd ? this.selectionEnd : this.cursorPosition;
    103            return this.text.substring(var1, var2);
    104        }
    105
    106        /**
    107         * replaces selected text, or inserts text at the position on the cursor
    108         */
    109        public void writeText(String par1Str)
    110        {
    111            String var2 = "";
    112            String var3 = ChatAllowedCharacters.filerAllowedCharacters(par1Str);
    113            int var4 = this.cursorPosition < this.selectionEnd ? this.cursorPosition : this.selectionEnd;
    114            int var5 = this.cursorPosition < this.selectionEnd ? this.selectionEnd : this.cursorPosition;
    115            int var6 = this.maxStringLength - this.text.length() - (var4 - this.selectionEnd);
    116            boolean var7 = false;
    117
    118            if (this.text.length() > 0)
    119            {
    120                var2 = var2 + this.text.substring(0, var4);
    121            }
    122
    123            int var8;
    124
    125            if (var6 < var3.length())
    126            {
    127                var2 = var2 + var3.substring(0, var6);
    128                var8 = var6;
    129            }
    130            else
    131            {
    132                var2 = var2 + var3;
    133                var8 = var3.length();
    134            }
    135
    136            if (this.text.length() > 0 && var5 < this.text.length())
    137            {
    138                var2 = var2 + this.text.substring(var5);
    139            }
    140
    141            this.text = var2;
    142            this.moveCursorBy(var4 - this.selectionEnd + var8);
    143        }
    144
    145        /**
    146         * Deletes the specified number of words starting at the cursor position. Negative numbers will delete words left of
    147         * the cursor.
    148         */
    149        public void deleteWords(int par1)
    150        {
    151            if (this.text.length() != 0)
    152            {
    153                if (this.selectionEnd != this.cursorPosition)
    154                {
    155                    this.writeText("");
    156                }
    157                else
    158                {
    159                    this.deleteFromCursor(this.getNthWordFromCursor(par1) - this.cursorPosition);
    160                }
    161            }
    162        }
    163
    164        /**
    165         * delete the selected text, otherwsie deletes characters from either side of the cursor. params: delete num
    166         */
    167        public void deleteFromCursor(int par1)
    168        {
    169            if (this.text.length() != 0)
    170            {
    171                if (this.selectionEnd != this.cursorPosition)
    172                {
    173                    this.writeText("");
    174                }
    175                else
    176                {
    177                    boolean var2 = par1 < 0;
    178                    int var3 = var2 ? this.cursorPosition + par1 : this.cursorPosition;
    179                    int var4 = var2 ? this.cursorPosition : this.cursorPosition + par1;
    180                    String var5 = "";
    181
    182                    if (var3 >= 0)
    183                    {
    184                        var5 = this.text.substring(0, var3);
    185                    }
    186
    187                    if (var4 < this.text.length())
    188                    {
    189                        var5 = var5 + this.text.substring(var4);
    190                    }
    191
    192                    this.text = var5;
    193
    194                    if (var2)
    195                    {
    196                        this.moveCursorBy(par1);
    197                    }
    198                }
    199            }
    200        }
    201
    202        /**
    203         * see @getNthNextWordFromPos() params: N, position
    204         */
    205        public int getNthWordFromCursor(int par1)
    206        {
    207            return this.getNthWordFromPos(par1, this.getCursorPosition());
    208        }
    209
    210        /**
    211         * gets the position of the nth word. N may be negative, then it looks backwards. params: N, position
    212         */
    213        public int getNthWordFromPos(int par1, int par2)
    214        {
    215            return this.func_73798_a(par1, this.getCursorPosition(), true);
    216        }
    217
    218        public int func_73798_a(int par1, int par2, boolean par3)
    219        {
    220            int var4 = par2;
    221            boolean var5 = par1 < 0;
    222            int var6 = Math.abs(par1);
    223
    224            for (int var7 = 0; var7 < var6; ++var7)
    225            {
    226                if (var5)
    227                {
    228                    while (par3 && var4 > 0 && this.text.charAt(var4 - 1) == 32)
    229                    {
    230                        --var4;
    231                    }
    232
    233                    while (var4 > 0 && this.text.charAt(var4 - 1) != 32)
    234                    {
    235                        --var4;
    236                    }
    237                }
    238                else
    239                {
    240                    int var8 = this.text.length();
    241                    var4 = this.text.indexOf(32, var4);
    242
    243                    if (var4 == -1)
    244                    {
    245                        var4 = var8;
    246                    }
    247                    else
    248                    {
    249                        while (par3 && var4 < var8 && this.text.charAt(var4) == 32)
    250                        {
    251                            ++var4;
    252                        }
    253                    }
    254                }
    255            }
    256
    257            return var4;
    258        }
    259
    260        /**
    261         * Moves the text cursor by a specified number of characters and clears the selection
    262         */
    263        public void moveCursorBy(int par1)
    264        {
    265            this.setCursorPosition(this.selectionEnd + par1);
    266        }
    267
    268        /**
    269         * sets the position of the cursor to the provided index
    270         */
    271        public void setCursorPosition(int par1)
    272        {
    273            this.cursorPosition = par1;
    274            int var2 = this.text.length();
    275
    276            if (this.cursorPosition < 0)
    277            {
    278                this.cursorPosition = 0;
    279            }
    280
    281            if (this.cursorPosition > var2)
    282            {
    283                this.cursorPosition = var2;
    284            }
    285
    286            this.setSelectionPos(this.cursorPosition);
    287        }
    288
    289        /**
    290         * sets the cursors position to the beginning
    291         */
    292        public void setCursorPositionZero()
    293        {
    294            this.setCursorPosition(0);
    295        }
    296
    297        /**
    298         * sets the cursors position to after the text
    299         */
    300        public void setCursorPositionEnd()
    301        {
    302            this.setCursorPosition(this.text.length());
    303        }
    304
    305        /**
    306         * Call this method from you GuiScreen to process the keys into textbox.
    307         */
    308        public boolean textboxKeyTyped(char par1, int par2)
    309        {
    310            if (this.isEnabled && this.isFocused)
    311            {
    312                switch (par1)
    313                {
    314                    case 1:
    315                        this.setCursorPositionEnd();
    316                        this.setSelectionPos(0);
    317                        return true;
    318                    case 3:
    319                        GuiScreen.setClipboardString(this.getSelectedtext());
    320                        return true;
    321                    case 22:
    322                        this.writeText(GuiScreen.getClipboardString());
    323                        return true;
    324                    case 24:
    325                        GuiScreen.setClipboardString(this.getSelectedtext());
    326                        this.writeText("");
    327                        return true;
    328                    default:
    329                        switch (par2)
    330                        {
    331                            case 14:
    332                                if (GuiScreen.isCtrlKeyDown())
    333                                {
    334                                    this.deleteWords(-1);
    335                                }
    336                                else
    337                                {
    338                                    this.deleteFromCursor(-1);
    339                                }
    340
    341                                return true;
    342                            case 199:
    343                                if (GuiScreen.isShiftKeyDown())
    344                                {
    345                                    this.setSelectionPos(0);
    346                                }
    347                                else
    348                                {
    349                                    this.setCursorPositionZero();
    350                                }
    351
    352                                return true;
    353                            case 203:
    354                                if (GuiScreen.isShiftKeyDown())
    355                                {
    356                                    if (GuiScreen.isCtrlKeyDown())
    357                                    {
    358                                        this.setSelectionPos(this.getNthWordFromPos(-1, this.getSelectionEnd()));
    359                                    }
    360                                    else
    361                                    {
    362                                        this.setSelectionPos(this.getSelectionEnd() - 1);
    363                                    }
    364                                }
    365                                else if (GuiScreen.isCtrlKeyDown())
    366                                {
    367                                    this.setCursorPosition(this.getNthWordFromCursor(-1));
    368                                }
    369                                else
    370                                {
    371                                    this.moveCursorBy(-1);
    372                                }
    373
    374                                return true;
    375                            case 205:
    376                                if (GuiScreen.isShiftKeyDown())
    377                                {
    378                                    if (GuiScreen.isCtrlKeyDown())
    379                                    {
    380                                        this.setSelectionPos(this.getNthWordFromPos(1, this.getSelectionEnd()));
    381                                    }
    382                                    else
    383                                    {
    384                                        this.setSelectionPos(this.getSelectionEnd() + 1);
    385                                    }
    386                                }
    387                                else if (GuiScreen.isCtrlKeyDown())
    388                                {
    389                                    this.setCursorPosition(this.getNthWordFromCursor(1));
    390                                }
    391                                else
    392                                {
    393                                    this.moveCursorBy(1);
    394                                }
    395
    396                                return true;
    397                            case 207:
    398                                if (GuiScreen.isShiftKeyDown())
    399                                {
    400                                    this.setSelectionPos(this.text.length());
    401                                }
    402                                else
    403                                {
    404                                    this.setCursorPositionEnd();
    405                                }
    406
    407                                return true;
    408                            case 211:
    409                                if (GuiScreen.isCtrlKeyDown())
    410                                {
    411                                    this.deleteWords(1);
    412                                }
    413                                else
    414                                {
    415                                    this.deleteFromCursor(1);
    416                                }
    417
    418                                return true;
    419                            default:
    420                                if (ChatAllowedCharacters.isAllowedCharacter(par1))
    421                                {
    422                                    this.writeText(Character.toString(par1));
    423                                    return true;
    424                                }
    425                                else
    426                                {
    427                                    return false;
    428                                }
    429                        }
    430                }
    431            }
    432            else
    433            {
    434                return false;
    435            }
    436        }
    437
    438        /**
    439         * Args: x, y, buttonClicked
    440         */
    441        public void mouseClicked(int par1, int par2, int par3)
    442        {
    443            boolean var4 = par1 >= this.xPos && par1 < this.xPos + this.width && par2 >= this.yPos && par2 < this.yPos + this.height;
    444
    445            if (this.canLoseFocus)
    446            {
    447                this.setFocused(this.isEnabled && var4);
    448            }
    449
    450            if (this.isFocused && par3 == 0)
    451            {
    452                int var5 = par1 - this.xPos;
    453
    454                if (this.enableBackgroundDrawing)
    455                {
    456                    var5 -= 4;
    457                }
    458
    459                String var6 = this.fontRenderer.trimStringToWidth(this.text.substring(this.field_73816_n), this.getWidth());
    460                this.setCursorPosition(this.fontRenderer.trimStringToWidth(var6, var5).length() + this.field_73816_n);
    461            }
    462        }
    463
    464        /**
    465         * Draws the textbox
    466         */
    467        public void drawTextBox()
    468        {
    469            if (this.getVisible())
    470            {
    471                if (this.getEnableBackgroundDrawing())
    472                {
    473                    drawRect(this.xPos - 1, this.yPos - 1, this.xPos + this.width + 1, this.yPos + this.height + 1, -6250336);
    474                    drawRect(this.xPos, this.yPos, this.xPos + this.width, this.yPos + this.height, -16777216);
    475                }
    476
    477                int var1 = this.isEnabled ? this.enabledColor : this.disabledColor;
    478                int var2 = this.cursorPosition - this.field_73816_n;
    479                int var3 = this.selectionEnd - this.field_73816_n;
    480                String var4 = this.fontRenderer.trimStringToWidth(this.text.substring(this.field_73816_n), this.getWidth());
    481                boolean var5 = var2 >= 0 && var2 <= var4.length();
    482                boolean var6 = this.isFocused && this.cursorCounter / 6 % 2 == 0 && var5;
    483                int var7 = this.enableBackgroundDrawing ? this.xPos + 4 : this.xPos;
    484                int var8 = this.enableBackgroundDrawing ? this.yPos + (this.height - 8) / 2 : this.yPos;
    485                int var9 = var7;
    486
    487                if (var3 > var4.length())
    488                {
    489                    var3 = var4.length();
    490                }
    491
    492                if (var4.length() > 0)
    493                {
    494                    String var10 = var5 ? var4.substring(0, var2) : var4;
    495                    var9 = this.fontRenderer.drawStringWithShadow(var10, var7, var8, var1);
    496                }
    497
    498                boolean var13 = this.cursorPosition < this.text.length() || this.text.length() >= this.getMaxStringLength();
    499                int var11 = var9;
    500
    501                if (!var5)
    502                {
    503                    var11 = var2 > 0 ? var7 + this.width : var7;
    504                }
    505                else if (var13)
    506                {
    507                    var11 = var9 - 1;
    508                    --var9;
    509                }
    510
    511                if (var4.length() > 0 && var5 && var2 < var4.length())
    512                {
    513                    this.fontRenderer.drawStringWithShadow(var4.substring(var2), var9, var8, var1);
    514                }
    515
    516                if (var6)
    517                {
    518                    if (var13)
    519                    {
    520                        Gui.drawRect(var11, var8 - 1, var11 + 1, var8 + 1 + this.fontRenderer.FONT_HEIGHT, -3092272);
    521                    }
    522                    else
    523                    {
    524                        this.fontRenderer.drawStringWithShadow("_", var11, var8, var1);
    525                    }
    526                }
    527
    528                if (var3 != var2)
    529                {
    530                    int var12 = var7 + this.fontRenderer.getStringWidth(var4.substring(0, var3));
    531                    this.drawCursorVertical(var11, var8 - 1, var12 - 1, var8 + 1 + this.fontRenderer.FONT_HEIGHT);
    532                }
    533            }
    534        }
    535
    536        /**
    537         * draws the vertical line cursor in the textbox
    538         */
    539        private void drawCursorVertical(int par1, int par2, int par3, int par4)
    540        {
    541            int var5;
    542
    543            if (par1 < par3)
    544            {
    545                var5 = par1;
    546                par1 = par3;
    547                par3 = var5;
    548            }
    549
    550            if (par2 < par4)
    551            {
    552                var5 = par2;
    553                par2 = par4;
    554                par4 = var5;
    555            }
    556
    557            Tessellator var6 = Tessellator.instance;
    558            GL11.glColor4f(0.0F, 0.0F, 255.0F, 255.0F);
    559            GL11.glDisable(GL11.GL_TEXTURE_2D);
    560            GL11.glEnable(GL11.GL_COLOR_LOGIC_OP);
    561            GL11.glLogicOp(GL11.GL_OR_REVERSE);
    562            var6.startDrawingQuads();
    563            var6.addVertex((double)par1, (double)par4, 0.0D);
    564            var6.addVertex((double)par3, (double)par4, 0.0D);
    565            var6.addVertex((double)par3, (double)par2, 0.0D);
    566            var6.addVertex((double)par1, (double)par2, 0.0D);
    567            var6.draw();
    568            GL11.glDisable(GL11.GL_COLOR_LOGIC_OP);
    569            GL11.glEnable(GL11.GL_TEXTURE_2D);
    570        }
    571
    572        public void setMaxStringLength(int par1)
    573        {
    574            this.maxStringLength = par1;
    575
    576            if (this.text.length() > par1)
    577            {
    578                this.text = this.text.substring(0, par1);
    579            }
    580        }
    581
    582        /**
    583         * returns the maximum number of character that can be contained in this textbox
    584         */
    585        public int getMaxStringLength()
    586        {
    587            return this.maxStringLength;
    588        }
    589
    590        /**
    591         * returns the current position of the cursor
    592         */
    593        public int getCursorPosition()
    594        {
    595            return this.cursorPosition;
    596        }
    597
    598        /**
    599         * get enable drawing background and outline
    600         */
    601        public boolean getEnableBackgroundDrawing()
    602        {
    603            return this.enableBackgroundDrawing;
    604        }
    605
    606        /**
    607         * enable drawing background and outline
    608         */
    609        public void setEnableBackgroundDrawing(boolean par1)
    610        {
    611            this.enableBackgroundDrawing = par1;
    612        }
    613
    614        /**
    615         * Sets the text colour for this textbox (disabled text will not use this colour)
    616         */
    617        public void setTextColor(int par1)
    618        {
    619            this.enabledColor = par1;
    620        }
    621
    622        public void func_82266_h(int par1)
    623        {
    624            this.disabledColor = par1;
    625        }
    626
    627        /**
    628         * setter for the focused field
    629         */
    630        public void setFocused(boolean par1)
    631        {
    632            if (par1 && !this.isFocused)
    633            {
    634                this.cursorCounter = 0;
    635            }
    636
    637            this.isFocused = par1;
    638        }
    639
    640        /**
    641         * getter for the focused field
    642         */
    643        public boolean isFocused()
    644        {
    645            return this.isFocused;
    646        }
    647
    648        public void func_82265_c(boolean par1)
    649        {
    650            this.isEnabled = par1;
    651        }
    652
    653        /**
    654         * the side of the selection that is not the cursor, maye be the same as the cursor
    655         */
    656        public int getSelectionEnd()
    657        {
    658            return this.selectionEnd;
    659        }
    660
    661        /**
    662         * returns the width of the textbox depending on if the the box is enabled
    663         */
    664        public int getWidth()
    665        {
    666            return this.getEnableBackgroundDrawing() ? this.width - 8 : this.width;
    667        }
    668
    669        /**
    670         * Sets the position of the selection anchor (i.e. position the selection was started at)
    671         */
    672        public void setSelectionPos(int par1)
    673        {
    674            int var2 = this.text.length();
    675
    676            if (par1 > var2)
    677            {
    678                par1 = var2;
    679            }
    680
    681            if (par1 < 0)
    682            {
    683                par1 = 0;
    684            }
    685
    686            this.selectionEnd = par1;
    687
    688            if (this.fontRenderer != null)
    689            {
    690                if (this.field_73816_n > var2)
    691                {
    692                    this.field_73816_n = var2;
    693                }
    694
    695                int var3 = this.getWidth();
    696                String var4 = this.fontRenderer.trimStringToWidth(this.text.substring(this.field_73816_n), var3);
    697                int var5 = var4.length() + this.field_73816_n;
    698
    699                if (par1 == this.field_73816_n)
    700                {
    701                    this.field_73816_n -= this.fontRenderer.trimStringToWidth(this.text, var3, true).length();
    702                }
    703
    704                if (par1 > var5)
    705                {
    706                    this.field_73816_n += par1 - var5;
    707                }
    708                else if (par1 <= this.field_73816_n)
    709                {
    710                    this.field_73816_n -= this.field_73816_n - par1;
    711                }
    712
    713                if (this.field_73816_n < 0)
    714                {
    715                    this.field_73816_n = 0;
    716                }
    717
    718                if (this.field_73816_n > var2)
    719                {
    720                    this.field_73816_n = var2;
    721                }
    722            }
    723        }
    724
    725        /**
    726         * if true the textbox can lose focus by clicking elsewhere on the screen
    727         */
    728        public void setCanLoseFocus(boolean par1)
    729        {
    730            this.canLoseFocus = par1;
    731        }
    732
    733        /**
    734         * @return {@code true} if this textbox is visible
    735         */
    736        public boolean getVisible()
    737        {
    738            return this.visible;
    739        }
    740
    741        /**
    742         * Sets whether or not this textbox is visible
    743         */
    744        public void setVisible(boolean par1)
    745        {
    746            this.visible = par1;
    747        }
    748    }