textInputComponent.cpp

00001 /*
00002   キー入力用のコンポーネント
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "textInputComponent.h"
00008 #include "drawSurface.h"
00009 #include <SDL.h>
00010 
00011 
00012 TextInputComponent::TextInputComponent(TTF_Draw& ttfObj, int pxSize,
00013                                        const VXV::Rect& size,
00014                                        unsigned long color, unsigned long back)
00015   : ttf(ttfObj), px_size(pxSize), draw_rect(size),
00016     fore_color(color), back_color(back), buffer_max(BufferSize),
00017     decided(false), ctrl_disable(false), cursor_it(inputed.end()),
00018     back_surface(NULL) {
00019   w = draw_rect.w;
00020   h = draw_rect.h;
00021   position = VXV::Grid(0, 0);
00022   back_surface = new FillSurface(draw_rect, back_color);
00023 }
00024 
00025 
00026 TextInputComponent::~TextInputComponent(void) {
00027   delete back_surface;
00028   back_surface = NULL;
00029 }
00030 
00031 
00032 void TextInputComponent::setBufferMax(int maxSize) {
00033   buffer_max = maxSize;
00034 }
00035 
00036 
00037 void TextInputComponent::addInputToBuffer(const UserInput& ui) {
00038 
00039   int n = ui.keys_sys.size();
00040   for (int i = 0; i < n; ++i) {
00041     char ch = ui.keys_sys[i];
00042     if (isprint(ch)) {
00043       inputed.insert(cursor_it, ch);
00044       continue;
00045     }
00046     bool ctrl_pressed = (ui.sdl_mods_sys[i] & KMOD_CTRL) ? true : false;
00047     switch (ui.sdl_keys_sys[i]) {
00048     case SDLK_RETURN:
00049       decided = true;
00050       return;
00051       break;
00052 
00053     case SDLK_h:
00054       if (!ctrl_pressed) {
00055         break;
00056       }
00057     case SDLK_BACKSPACE:
00058     if (cursor_it != inputed.begin()) {
00059         cursor_it = inputed.erase(--cursor_it);
00060       }
00061       break;
00062 
00063     case SDLK_b:
00064       if (!ctrl_pressed) {
00065         break;
00066       }
00067     case SDLK_LEFT:
00068       if (cursor_it != inputed.begin()) {
00069         --cursor_it;
00070       }
00071       break;
00072 
00073     case SDLK_f:
00074       if (!ctrl_pressed) {
00075         break;
00076       }
00077     case SDLK_RIGHT:
00078       if (cursor_it != inputed.end()) {
00079         ++cursor_it;
00080       } else {
00081         inputed.insert(cursor_it, ' ');
00082       }
00083       break;
00084 
00085     case SDLK_d:
00086       if (!ctrl_pressed) {
00087         break;
00088       }
00089     case SDLK_DELETE:
00090       if (cursor_it != inputed.end()) {
00091         cursor_it = inputed.erase(cursor_it);
00092       }
00093       break;
00094     }
00095   }
00096 }
00097 
00098 
00099 bool TextInputComponent::drawChar(Uint16 uch, unsigned long fore,
00100                                   unsigned long back, VXV::Grid& next) {
00101   bool ch_draw = false;
00102 
00103   Uint16 ch[] = { uch, 0x0000 };
00104   DrawSurface* surface =
00105     new DrawSurface(ttf.createText(ch, px_size, fore, back), false);
00106   int width = surface->w;
00107   if (next.x + width <= draw_rect.w) {
00108     ch_draw = true;
00109     LabelComponent* label = new LabelComponent(surface);
00110     label->draw(position, VXV::Rect(0, 0, w, h), 1.0, next, false);
00111     delete label;
00112   }
00113   delete surface;
00114   next.x += width;
00115 
00116   return ch_draw;
00117 }
00118 
00119 
00120 bool TextInputComponent::draw(unsigned long ticks, const UserInput& ui) {
00121 
00122   // 内部バッファの処理
00123   // !!! 変換オブジェクトを使えるように変更する
00124 
00125   if (!ctrl_disable && !decided) {
00126     addInputToBuffer(ui);
00127   }
00128 
00129   // 背景色で塗りつぶし
00130   back_surface->draw(draw_rect, position, ticks);
00131 
00132   // 表示文字列の描画
00133   inputed.push_back(0x0000);
00134 
00135   // 文字列の描画
00136   bool cursor_found = false;
00137   bool cursor_on = (ticks & 0x200) ? (!ctrl_disable && !decided) : false;
00138   VXV::Grid next = VXV::Grid(0, 0);
00139   int index = 0;
00140   for (std::list<unsigned short>::iterator it = inputed.begin();
00141        it != inputed.end(); ++it, ++index) {
00142 
00143     // 文字数制限
00144     cursor_found |= (it != cursor_it);
00145     if (index > buffer_max) {
00146       inputed.erase(it, inputed.end());
00147       if (!cursor_found) {
00148         cursor_it = inputed.end();
00149       }
00150       break;
00151     }
00152     if ((it == cursor_it) && cursor_on) {
00153       drawChar(*it, back_color, fore_color, next);
00154     } else {
00155       drawChar(*it, fore_color, back_color, next);
00156     }
00157   }
00158   if ((cursor_it == inputed.end()) && cursor_on) {
00159     drawChar(' ', back_color, fore_color, next);
00160   }
00161 
00162   inputed.pop_back();
00163   return true;
00164 }
00165 
00166 
00167 void TextInputComponent::clear(void) {
00168   inputed.clear();
00169 }
00170 
00171 
00172 void TextInputComponent::setText(const char* text) {
00173   clear();
00174   int n = strlen(text);
00175   n = (n > buffer_max) ? buffer_max : n;
00176   for (int i = 0; i < n; ++i) {
00177     inputed.push_back(text[i]);
00178   }
00179 }
00180 
00181 
00182 void TextInputComponent::activate(bool on) {
00183 }
00184 
00185 
00186 bool TextInputComponent::isDecided(void) {
00187   return decided;
00188 }
00189 
00190 
00191 void TextInputComponent::disable(bool on) {
00192   ctrl_disable = on;
00193   if (!on) {
00194     decided = false;
00195   }
00196 }
00197 
00198 
00199 void TextInputComponent::beginFocus(void) {
00200   SDL_EnableKeyRepeat(500, 25);
00201   ctrl_disable = false;
00202   disable(false);
00203 }
00204 
00205 
00206 void TextInputComponent::endFocus(void) {
00207   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00208   ctrl_disable = true;
00209   disable(true);
00210 }
00211 

Generated on Mon Apr 13 22:52:02 2009 by  doxygen 1.5.7.1