00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gui/widgets/textfield.h"
00023
00024 #include "gui/palette.h"
00025 #include "gui/sdlinput.h"
00026
00027 #include "configuration.h"
00028 #include "graphics.h"
00029
00030 #include "resources/image.h"
00031 #include "resources/resourcemanager.h"
00032
00033 #include "utils/dtor.h"
00034
00035 #include <guichan/font.hpp>
00036
00037 #undef DELETE //Win32 compatibility hack
00038
00039 int TextField::instances = 0;
00040 float TextField::mAlpha = 1.0;
00041 ImageRect TextField::skin;
00042
00043 TextField::TextField(const std::string &text):
00044 gcn::TextField(text),
00045 mNumeric(false),
00046 mListener(0)
00047 {
00048 setFrameSize(2);
00049
00050 if (instances == 0)
00051 {
00052
00053 ResourceManager *resman = ResourceManager::getInstance();
00054 Image *textbox = resman->getImage("graphics/gui/deepbox.png");
00055 int gridx[4] = {0, 3, 28, 31};
00056 int gridy[4] = {0, 3, 28, 31};
00057 int a = 0, x, y;
00058
00059 for (y = 0; y < 3; y++)
00060 {
00061 for (x = 0; x < 3; x++)
00062 {
00063 skin.grid[a] = textbox->getSubImage(
00064 gridx[x], gridy[y],
00065 gridx[x + 1] - gridx[x] + 1,
00066 gridy[y + 1] - gridy[y] + 1);
00067 skin.grid[a]->setAlpha(config.getValue("guialpha", 0.8));
00068 a++;
00069 }
00070 }
00071
00072 textbox->decRef();
00073 }
00074
00075 instances++;
00076 }
00077
00078 TextField::~TextField()
00079 {
00080 instances--;
00081
00082 if (instances == 0)
00083 for_each(skin.grid, skin.grid + 9, dtor<Image*>());
00084 }
00085
00086 void TextField::draw(gcn::Graphics *graphics)
00087 {
00088 if (isFocused())
00089 {
00090 drawCaret(graphics,
00091 getFont()->getWidth(mText.substr(0, mCaretPosition)) -
00092 mXScroll);
00093 }
00094
00095 graphics->setColor(guiPalette->getColor(Palette::TEXT));
00096 graphics->setFont(getFont());
00097 graphics->drawText(mText, 1 - mXScroll, 1);
00098
00099 if (config.getValue("guialpha", 0.8) != mAlpha)
00100 {
00101 mAlpha = config.getValue("guialpha", 0.8);
00102 for (int a = 0; a < 9; a++)
00103 skin.grid[a]->setAlpha(mAlpha);
00104 }
00105 }
00106
00107 void TextField::drawFrame(gcn::Graphics *graphics)
00108 {
00109 int w, h, bs;
00110 bs = getFrameSize();
00111 w = getWidth() + bs * 2;
00112 h = getHeight() + bs * 2;
00113
00114 static_cast<Graphics*>(graphics)->drawImageRect(0, 0, w, h, skin);
00115 }
00116
00117 void TextField::setNumeric(bool numeric)
00118 {
00119 mNumeric = numeric;
00120 if (!numeric)
00121 return;
00122
00123 const char *text = mText.c_str();
00124 for (const char *textPtr = text; *textPtr; ++textPtr)
00125 {
00126 if (*textPtr < '0' || *textPtr > '9')
00127 {
00128 setText(mText.substr(0, textPtr - text));
00129 return;
00130 }
00131 }
00132 }
00133
00134 int TextField::getValue() const
00135 {
00136 if (!mNumeric)
00137 return 0;
00138
00139 int value = atoi(mText.c_str());
00140 if (value < mMinimum)
00141 return mMinimum;
00142
00143 if (value > mMaximum)
00144 return mMaximum;
00145
00146 return value;
00147 }
00148
00149 void TextField::keyPressed(gcn::KeyEvent &keyEvent)
00150 {
00151 int val = keyEvent.getKey().getValue();
00152
00153 if (val >= 32)
00154 {
00155 int l;
00156 if (val < 128) l = 1;
00157 else if (val < 0x800) l = 2;
00158 else if (val < 0x10000) l = 3;
00159 else l = 4;
00160
00161 char buf[4];
00162 for (int i = 0; i < l; ++i)
00163 {
00164 buf[i] = val >> (6 * (l - i - 1));
00165 if (i > 0) buf[i] = (buf[i] & 63) | 128;
00166 }
00167
00168 if (l > 1) buf[0] |= 255 << (8 - l);
00169
00170 mText.insert(mCaretPosition, std::string(buf, buf + l));
00171 mCaretPosition += l;
00172 }
00173
00174
00175
00176
00177 switch (val)
00178 {
00179 case Key::LEFT:
00180 {
00181 while (mCaretPosition > 0)
00182 {
00183 --mCaretPosition;
00184 if ((mText[mCaretPosition] & 192) != 128)
00185 break;
00186 }
00187 } break;
00188
00189 case Key::RIGHT:
00190 {
00191 unsigned sz = mText.size();
00192 while (mCaretPosition < sz)
00193 {
00194 ++mCaretPosition;
00195 if (mCaretPosition == sz ||
00196 (mText[mCaretPosition] & 192) != 128)
00197 break;
00198 }
00199 } break;
00200
00201 case Key::DELETE:
00202 {
00203 unsigned sz = mText.size();
00204 while (mCaretPosition < sz)
00205 {
00206 --sz;
00207 mText.erase(mCaretPosition, 1);
00208 if (mCaretPosition == sz ||
00209 (mText[mCaretPosition] & 192) != 128)
00210 break;
00211 }
00212 } break;
00213
00214 case Key::BACKSPACE:
00215 {
00216 while (mCaretPosition > 0)
00217 {
00218 --mCaretPosition;
00219 int v = mText[mCaretPosition];
00220 mText.erase(mCaretPosition, 1);
00221 if ((v & 192) != 128) break;
00222 }
00223 } break;
00224
00225 case Key::ENTER:
00226 distributeActionEvent();
00227 break;
00228
00229 case Key::HOME:
00230 mCaretPosition = 0;
00231 break;
00232
00233 case Key::END:
00234 mCaretPosition = mText.size();
00235 break;
00236
00237 case Key::TAB:
00238 return;
00239 }
00240
00241 keyEvent.consume();
00242 fixScroll();
00243 }