optionComponent.cpp

00001 /*
00002   オプション設定用の専用メニュー
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "optionComponent.h"
00008 #include "deleteObjects.h"
00009 
00010 
00011 OptionComponent::OptionComponent(TTF_Draw& ttf_resource, int fontSize,
00012                                  LabelComponent* selectedIcon)
00013   : ttf(ttf_resource),
00014     fore_color(White), back_color(Black),
00015     font_size(fontSize), activated(false), titleMaxWidth(0),
00016     base_offset(VXV::Grid(0, 0)), selected_row(0), decided_row(-1),
00017     selected_icon(selectedIcon) {
00018   w = 0;
00019   h = 0;
00020   position = VXV::Grid(0, 0);
00021 }
00022 
00023 
00024 OptionComponent::~OptionComponent(void) {
00025   for_each(lines.begin(), lines.end(), DeleteObjects());
00026   delete selected_icon;
00027 }
00028 
00029 
00030 void OptionComponent::setFontSize(int size) {
00031   font_size = size;
00032 }
00033 
00034 
00035 void OptionComponent::setBaseOffset(const VXV::Grid& offset) {
00036   base_offset = offset;
00037 }
00038 
00039 
00040 void OptionComponent::setColor(unsigned long fore, unsigned long back,
00041                                unsigned long focused) {
00042   fore_color = fore;
00043   back_color = back;
00044   focused_color = focused;
00045 }
00046 
00047 
00048 OptionComponent::optionLine::optionLine(const VXV::Grid& base_offset)
00049   : selected_col(0), under_bar(NULL), title(NULL), offset(base_offset) {
00050 }
00051 
00052 
00053 OptionComponent::optionLine::text_t::~text_t(void) {
00054   if (text) {
00055     delete [] text;
00056   }
00057   delete label;
00058   delete surface;
00059   delete focused;
00060 }
00061 
00062 
00063 OptionComponent::optionLine::~optionLine(void) {
00064   delete title;
00065   for_each(items.begin(), items.end(), DeleteObjects());
00066 
00067   delete under_bar;
00068 }
00069 
00070 
00071 Uint16* OptionComponent::optionLine::copyString(const char* str) {
00072   int n = strlen(str) +1;
00073   Uint16* p = new Uint16[n];
00074   for (int i = 0; i < n; ++i) {
00075     p[i] = str[i];
00076   }
00077   return p;
00078 }
00079 
00080 
00081 Uint16* OptionComponent::optionLine::copyString(const unsigned short* str) {
00082   int n = 0;
00083   while (str[n++] != 0x0000)
00084     ;
00085   Uint16* p = new Uint16[n];
00086   for (int i = 0; i < n; ++i) {
00087     p[i] = str[i];
00088   }
00089   return p;
00090 }
00091 
00092 
00093 void OptionComponent::optionLine::setTitle(const char* name) {
00094   title = new text_t;
00095   title->text = copyString(name);
00096 }
00097 
00098 
00099 void OptionComponent::optionLine::setTitle(const unsigned short* name) {
00100   title = new text_t;
00101   title->text = copyString(name);
00102 }
00103 
00104 
00105 void OptionComponent::optionLine::addItem(const char* item) {
00106   text_t* p = new text_t;
00107   p->text = copyString(item);
00108   items.push_back(p);
00109 }
00110 
00111 
00112 void OptionComponent::optionLine::addItem(const unsigned short* item) {
00113   text_t* p = new text_t;
00114   p->text = copyString(item);
00115   items.push_back(p);
00116 }
00117 
00118 
00119 void OptionComponent::optionLine::setSelected(int index) {
00120   selected_col = index;
00121 }
00122 
00123 
00124 DrawSurface* OptionComponent::createSurface(Uint16* text,
00125                                             unsigned long fore,
00126                                             unsigned long back) {
00127   return new DrawSurface(ttf.createText(text, font_size, fore, back), true);
00128 }
00129 
00130 
00131 void OptionComponent::createLabel(optionLine::text_t& text) {
00132   if (!text.text) {
00133     return;
00134   }
00135   text.surface = createSurface(text.text, fore_color, back_color);
00136   text.label = new LabelComponent(text.surface);
00137 }
00138 
00139 
00140 void OptionComponent::createButton(optionLine::text_t& text) {
00141   if (!text.text) {
00142     return;
00143   }
00144   text.surface = createSurface(text.text, fore_color, back_color);
00145   text.focused = createSurface(text.text, focused_color, back_color);
00146   text.button = new ButtonComponent(text.surface);
00147   text.button->setFocusedSurface(text.focused);
00148 }
00149 
00150 
00151 void OptionComponent::activate(void) {
00152   // 行毎にサーフェスの作成
00153   int w_max = 0;
00154   for (std::vector<optionLine*>::iterator it = lines.begin();
00155        it != lines.end(); ++it) {
00156     int now_w = 0;
00157     // タイトルの作成
00158     optionLine::text_t* title_p = (*it)->title;
00159     if (title_p) {
00160       createLabel(*title_p);
00161     }
00162 
00163     // 項目ボタンの作成
00164     for (std::vector<optionLine::text_t*>::iterator item_it =
00165            (*it)->items.begin(); item_it != (*it)->items.end(); ++item_it) {
00166       createButton(*(*item_it));
00167       now_w += (*it)->offset.x + (*item_it)->button->w;
00168     }
00169 
00170     // 最大のサブタイトル幅を保持
00171     if (title_p && title_p->label && (title_p->label->w > titleMaxWidth)) {
00172       titleMaxWidth = title_p->label->w;
00173     }
00174     if (now_w > w_max) {
00175       w_max = now_w;
00176     }
00177   }
00178   w = w_max + titleMaxWidth;
00179   h = lines.size() * font_size;
00180 }
00181 
00182 
00183 bool OptionComponent::draw(unsigned long ticks, const UserInput& ui) {
00184 
00185   // マウスクリックによる選択変更
00186   unsigned int row_index = 0, col_index = 0;
00187   for (std::vector<optionLine*>::iterator it = lines.begin();
00188        it != lines.end(); ++it, ++row_index) {
00189     col_index = 0;
00190     for (std::vector<optionLine::text_t*>::iterator item_it =
00191            (*it)->items.begin(); item_it != (*it)->items.end();
00192          ++item_it, ++col_index) {
00193       if ((*item_it)->button->isPressed()) {
00194         selected_row = row_index;
00195         decided_row = row_index;
00196         (*it)->selected_col = col_index;
00197       }
00198     }
00199   }
00200 
00201   // キーボードによる選択変更
00202   int i = 0;
00203   for (UserInput::sdl_keys_t::const_iterator it =
00204          ui.sdl_keys_sys.begin(); it != ui.sdl_keys_sys.end(); ++it, ++i) {
00205     if (decided_row > 0) {
00206       break;
00207     }
00208 
00209     if ((*it == SDLK_DOWN) ||
00210         ((ui.sdl_mods_sys[i] & KMOD_CTRL) && (*it == SDLK_n))) {
00211       ++selected_row;
00212     } else if ((*it == SDLK_UP) ||
00213                ((ui.sdl_mods_sys[i] & KMOD_CTRL) && (*it == SDLK_p))) {
00214       --selected_row;
00215 
00216     } else if (((*it == SDLK_RIGHT) ||
00217                 ((ui.sdl_mods_sys[i] & KMOD_CTRL) && (*it == SDLK_f))) &&
00218                (lines[selected_row]->selected_col <
00219                 (lines[selected_row]->items.size()-1))) {
00220       ++lines[selected_row]->selected_col;
00221 
00222     } else if (((*it == SDLK_LEFT) ||
00223                 ((ui.sdl_mods_sys[i] & KMOD_CTRL) && (*it == SDLK_b))) &&
00224                (lines[selected_row]->selected_col > 0)) {
00225       --lines[selected_row]->selected_col;
00226     } else if (*it == SDLK_RETURN) {
00227       decided_row = selected_row;
00228       break;
00229     }
00230   }
00231   int row_max = lines.size();
00232   selected_row = (selected_row + row_max) % row_max;
00233 
00234   // 行毎に描画
00235   row_index = 0;
00236   VXV::Grid draw_offset = VXV::Grid(0, 0);
00237   for (std::vector<optionLine*>::iterator it = lines.begin();
00238        it != lines.end(); ++it, ++row_index) {
00239     // タイトルの描画
00240     if ((*it)->title && (*it)->title->label) {
00241       LabelComponent* label = (*it)->title->label;
00242       label->setPosition(position + draw_offset);
00243       label->draw(ticks, ui);
00244     }
00245 
00246     // 項目の描画
00247     col_index = 0;
00248     VXV::Grid next_offset =
00249       position + draw_offset + VXV::Grid(titleMaxWidth, 0) + (*it)->offset;
00250     for (std::vector<optionLine::text_t*>::iterator item_it =
00251            (*it)->items.begin(); item_it != (*it)->items.end();
00252          ++item_it, ++col_index) {
00253       // 選択を示すアンダーバーを描画
00254       if ((*it)->selected_col == col_index) {
00255         if (selected_row == row_index) {
00256           // アイコンの描画
00257           VXV::Grid diff =
00258             VXV::Grid(selected_icon->w +6, (selected_icon->h - font_size)/2);
00259           selected_icon->setPosition(next_offset - diff);
00260           selected_icon->draw(ticks, ui);
00261         }
00262 
00263         // アンダーバーの描画
00264         if ((*it)->items.size() > 1) {
00265           delete (*it)->under_bar;
00266           (*it)->under_bar =
00267             new FillSurface(VXV::Rect((*item_it)->button->w, 4), Gray8);
00268           LabelComponent* label = new LabelComponent((*it)->under_bar);
00269           label->setPosition(next_offset + VXV::Grid(0, font_size - 2));
00270           label->draw(ticks, ui);
00271           delete label;
00272         }
00273       }
00274 
00275       ButtonComponent* button = (*item_it)->button;
00276       button->setPosition(next_offset);
00277       button->draw(ticks, ui);
00278 
00279       next_offset += (*it)->offset + VXV::Grid(button->w, 0);
00280     }
00281     draw_offset += VXV::Grid(0, font_size) + base_offset;
00282   }
00283   return true;
00284 }
00285 
00286 
00287 void OptionComponent::beginFocus(void) {
00288 }
00289 
00290 
00291 void OptionComponent::endFocus(void) {
00292 }
00293 
00294 
00295 void OptionComponent::setIconRow(int row) {
00296   selected_row = row;
00297 }
00298 
00299 void OptionComponent::setSelectedIndex(unsigned int row, unsigned int nth) {
00300   lines[row]->selected_col = nth;
00301 }
00302 
00303 
00304 int OptionComponent::getSelected(unsigned int row) {
00305   if ((row < 0) || (row > (lines.size()-1))) {
00306     return -1;
00307   }
00308   return lines[row]->selected_col;
00309 }
00310 
00311 
00312 bool OptionComponent::isDecided(void) {
00313   return (decided_row > 0) ? true : false;
00314 }
00315 
00316 int OptionComponent::getDecidedRow(void) {
00317   int ret = decided_row;
00318   decided_row = -1;
00319 
00320   return ret;
00321 }
00322 

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