menuComponent.cpp

00001 /*
00002   メニュー表示のコンポーネント
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "menuComponent.h"
00008 #include "deleteObjects.h"
00009 
00010 
00011 MenuComponent::MenuComponent(void)
00012   : button_offset(VXV::Rect(0, 0)), icon_offset(VXV::Rect(0, 0)), icon(NULL),
00013     activated(false), draw_hide(false), ctrl_disable(false),
00014     initialized(false), decided(false), no_default(true), now_index(0) {
00015   w = 0;
00016   h = 0;
00017   position = VXV::Grid(0, 0);
00018   changeKeySettings(true);
00019 }
00020 
00021 
00022 MenuComponent::~MenuComponent(void) {
00023   delete icon;
00024   for_each(items.begin(), items.end(), DeleteObjects());
00025 }
00026 
00027 
00028 MenuComponent::item_t::item_t(void) : button(NULL), select_enable(true) {
00029 }
00030 
00031 
00032 MenuComponent::item_t::~item_t(void) {
00033   delete button;
00034 }
00035 
00036 
00037 void MenuComponent::changeKeySettings(bool set_default) {
00038   if (set_default) {
00039     code_down = SDLK_DOWN;
00040     code_n = SDLK_n;
00041     code_up = SDLK_UP;
00042     code_p = SDLK_p;
00043     code_first = SDLK_LEFT;
00044     code_last = SDLK_RIGHT;
00045   } else {
00046     code_down = SDLK_RIGHT;
00047     code_n = SDLK_f;
00048     code_up = SDLK_LEFT;
00049     code_p = SDLK_b;
00050     code_first = SDLK_UP;
00051     code_last = SDLK_DOWN;
00052   }
00053 }
00054 
00055 
00056 bool MenuComponent::draw(unsigned long ticks, const UserInput& ui) {
00057   if (!activated) {
00058     return false;
00059   }
00060   if (draw_hide) {
00061     return true;
00062   }
00063 
00064   // 選択項目の決定
00065   if (ctrl_disable) {
00066     decided = false;
00067   }
00068 
00069   int index = 0;
00070   if (!decided && !ctrl_disable) {
00071     int items_size = items.size();
00072     for (UserInput::sdl_keys_t::const_iterator it = ui.sdl_keys_sys.begin();
00073          it != ui.sdl_keys_sys.end(); ++it, ++index) {
00074       int key_moved = 0;
00075 
00076       if ((*it == SDLK_RETURN) ||
00077           ((ui.sdl_mods_sys[index] & KMOD_CTRL) &&
00078            ((*it == SDLK_j) || (*it == SDLK_m)))) {
00079         decided = true;
00080       }
00081 
00082       // 選択項目の変更、描画
00083       if ((*it == code_down) ||
00084           ((ui.sdl_mods_sys[index] & KMOD_CTRL) && (*it == code_n))) {
00085         ++key_moved;
00086       }
00087       if ((*it == code_up) ||
00088           ((ui.sdl_mods_sys[index] & KMOD_CTRL) && (*it == code_p))) {
00089         --key_moved;
00090       }
00091       if (*it == code_last) {
00092         key_moved = static_cast<int>(items.size()-1 - now_index);
00093       } else if (*it == code_first) {
00094         key_moved = -now_index;
00095       }
00096 
00097       // 選択できない項目にアイコンをセットしない
00098       while ((key_moved != 0) &&
00099              (now_index + key_moved < items_size) &&
00100              (now_index + key_moved >= 0) &&
00101              (!items[now_index + key_moved]->select_enable)) {
00102         if (key_moved > 0) {
00103           ++key_moved;
00104         } else {
00105           --key_moved;
00106         }
00107       }
00108 
00109       // 項目にアイコンが移動できるかの判定
00110       int next_index = now_index + key_moved;
00111       if ((next_index >= 0) && (next_index < items_size)) {
00112         now_index += key_moved;
00113       }
00114     }
00115   }
00116 
00117   VXV::Grid button_pos;
00118   index = 0;
00119   int next_index = now_index;
00120   if (!no_default && ui.state.mouse_moved) {
00121     next_index = -1;
00122   }
00123   for (std::vector<item_t*>::iterator it = items.begin();
00124        it != items.end(); ++it, ++index) {
00125     (*it)->button->setPosition(position + button_pos);
00126 
00127     (*it)->button->setDrawSurface((index == now_index) ?
00128                                   ButtonComponent::Focused :
00129                                   ButtonComponent::Normal);
00130     (*it)->button->draw(ticks, ui);
00131     if ((*it)->button->isPressed() && (*it)->select_enable) {
00132       decided = true;
00133     }
00134     if ((*it)->button->isFocused() &&
00135         ui.state.mouse_moved && !decided && !ctrl_disable &&
00136         (*it)->select_enable) {
00137       next_index = index;
00138     }
00139     button_pos.x += button_offset.w;
00140     button_pos.y += button_offset.h;
00141   }
00142   now_index = next_index;
00143   if (icon && (now_index >= 0)) {
00144     VXV::Grid icon_pos = position
00145       + VXV::Grid(icon_offset.w, icon_offset.h)
00146       + VXV::Grid(button_offset.w * now_index, button_offset.h * now_index);
00147     icon->setPosition(icon_pos);
00148     icon->draw(ticks, ui);
00149   }
00150   return initialized;
00151 }
00152 
00153 
00154 void MenuComponent::add(ButtonComponent* button) {
00155   item_t* add = new item_t;
00156   add->button = button;
00157   items.push_back(add);
00158   if (button->h > button_offset.h) {
00159     button_offset.h = button->h;
00160   }
00161 }
00162 
00163 
00164 void MenuComponent::addIcon(LabelComponent* label) {
00165   icon = label;
00166 }
00167 
00168 
00169 void MenuComponent::setOffset(const VXV::Rect& offset) {
00170   button_offset = offset;
00171 }
00172 
00173 
00174 void MenuComponent::setIconOffset(const VXV::Rect& offset) {
00175   icon_offset = offset;
00176 }
00177 
00178 
00179 void MenuComponent::setSelectedIndex(int index) {
00180   // !!! 未実装
00181 }
00182 
00183 
00184 // 幅は、登録ボタンを囲むサイズとなり、アイコンは考慮されない
00185 // 位置は、最初に登録したボタンの左上座標を基準に描画を始める
00186 void MenuComponent::activate(bool on) {
00187   w = 0; h = 0;
00188   int w_max = 0, h_max = 0;
00189   for (std::vector<item_t*>::iterator it = items.begin();
00190        it != items.end(); ++it) {
00191     if (w + (*it)->button->w > w_max) {
00192       w_max = w + (*it)->button->w;
00193     }
00194     if (h + (*it)->button->h > h_max) {
00195       h_max = h + (*it)->button->h;
00196     }
00197     w += button_offset.w;
00198     h += button_offset.h;
00199   }
00200   w = w_max;
00201   h = h_max;
00202 
00203   activated = on;
00204   initialized = true;
00205   decided = false;
00206   ctrl_disable = false;
00207 }
00208 
00209 
00210 void MenuComponent::hide(bool on) {
00211   draw_hide = on;
00212 }
00213 
00214 void MenuComponent::disable(bool on) {
00215   ctrl_disable = on;
00216 }
00217 
00218 
00219 void MenuComponent::defaultSelection(bool on) {
00220   no_default = on;
00221   if (!on) {
00222     now_index = -1;
00223   }
00224 }
00225 
00226 
00227 bool MenuComponent::isDecided(void) {
00228   return decided;
00229 }
00230 
00231 
00232 void MenuComponent::setNowIndex(int index) {
00233   now_index = index;
00234 }
00235 
00236 int MenuComponent::getNowIndex(void) {
00237   return now_index;
00238 }
00239 
00240 
00241 void MenuComponent::beginFocus(void) {
00242   if (now_index < 0) {
00243     now_index = 0;
00244   }
00245   disable(false);
00246 }
00247 
00248 
00249 void MenuComponent::endFocus(void) {
00250   if (!no_default) {
00251     now_index = -1;
00252   }
00253   disable(true);
00254 }
00255 
00256 
00257 void MenuComponent::setIndexActive(int index, bool on) {
00258   if ((index < 0) || (index >= static_cast<int>(items.size()))) {
00259     return;
00260   }
00261   items[index]->select_enable = on;
00262 }
00263 

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