comboBoxComponent.cpp

00001 /*
00002   コンボボックスのコンポーネント
00003   Satofumi KAMIMURAJ
00004   $Id$
00005 */
00006 
00007 #include "comboBoxComponent.h"
00008 #include "deleteObjects.h"
00009 
00010 
00011 ComboBoxComponent::ComboBoxComponent(TTF_Draw& ttf_resource)
00012   : ttf(ttf_resource),
00013     fore_color(Black), back_color(White),
00014     focused_fore_color(White), focused_back_color(Blue),
00015     menu(NULL), selected_item(NULL), selected_surface(NULL),
00016     button_label(NULL), button_surface(NULL), button_offset(VXV::Grid(0,0)),
00017     fill_normal(NULL), fill_focused(NULL), now_index(0), view_list(false),
00018     font_size(DefaultFontSize), focused(false), decided(false) {
00019   w = 0;
00020   h = 0;
00021   position = VXV::Grid(0, 0);
00022 }
00023 
00024 
00025 ComboBoxComponent::~ComboBoxComponent(void) {
00026   deleteObject();
00027 }
00028 
00029 
00030 void ComboBoxComponent::deleteObject(void) {
00031   for_each(items_normal.begin(), items_normal.end(), DeleteObjects());
00032   items_normal.clear();
00033 
00034   for_each(items_focused.begin(), items_focused.end(), DeleteObjects());
00035   items_focused.clear();
00036 
00037   for_each(surface_normal.begin(), surface_normal.end(), DeleteObjects());
00038   surface_normal.clear();
00039 
00040   for_each(surface_focused.begin(), surface_focused.end(), DeleteObjects());
00041   surface_focused.clear();
00042 
00043   delete selected_item;
00044   selected_item = NULL;
00045 
00046   delete button_label;
00047   button_label = NULL;
00048 
00049   delete button_surface;
00050   button_surface = NULL;
00051 
00052   delete selected_surface;
00053   selected_surface = NULL;
00054 
00055   delete fill_normal;
00056   fill_normal = NULL;
00057 
00058   delete fill_focused;
00059   fill_focused = NULL;
00060 
00061   delete menu;
00062   menu = NULL;
00063 }
00064 
00065 
00066 bool ComboBoxComponent::draw(unsigned long ticks, const UserInput& ui) {
00067   // 項目がなければ、戻る
00068   if (items.empty()) {
00069     return true;
00070   }
00071 
00072   // 項目の描画
00073   selected_item->setPosition(position);
00074   selected_item->draw(ticks, ui);
00075 
00076   // ボタンの描画
00077   button_label->setPosition(position + button_offset, VXV::Middle);
00078   button_label->draw(ticks, ui);
00079 
00080   // 選択項目の描画
00081   menu->setPosition(position + VXV::Grid(0, selected_item->h));
00082   menu->draw(ticks, ui);
00083 
00084   // リストの描画時の処理
00085   if (selected_item->isPressed() ||
00086       (!view_list && focused &&
00087        ((ui.state.isPressedCode(SDLK_DOWN) ||
00088          (ui.state.ctrl_pressed && ui.state.isPressedCode(SDLK_n)))))) {
00089     view_list = !view_list;
00090     menu->hide(!view_list);
00091 
00092   } else if (menu->isDecided()) {
00093     // 選択時の処理
00094     decided = true;
00095     view_list = !view_list;
00096     int index = menu->getNowIndex();
00097     if (index >= 0) {
00098       setNowIndex(index);
00099     }
00100     menu->hide(!view_list);
00101     menu->activate(true);
00102 
00103   } else if (ui.state.left_released) {
00104     view_list = false;
00105     menu->hide(true);
00106   }
00107   return true;
00108 }
00109 
00110 
00111 void ComboBoxComponent::add(const Uint16* text) {
00112   add_text.push_back(text);
00113 }
00114 
00115 
00116 void ComboBoxComponent::add(const char* text) {
00117   int n = static_cast<int>(strlen(text)) +1;
00118   Uint16* p = new Uint16[n];
00119   for (int i = 0; i < n; ++i) {
00120     p[i] = text[i];
00121   }
00122   add_text.push_back(p);
00123   char_text.push_back(p);
00124 }
00125 
00126 
00127 void ComboBoxComponent::setColor(unsigned long fore, unsigned long back,
00128                                  unsigned long focused_fore,
00129                                  unsigned long focused_back) {
00130   fore_color = fore;
00131   back_color = back;
00132   focused_fore_color = focused_fore;
00133   focused_back_color = focused_back;
00134 }
00135 
00136 
00137 void ComboBoxComponent::setFontSize(int size) {
00138   font_size = size;
00139 }
00140 
00141 
00142 void ComboBoxComponent::updateSelected(void) {
00143   if (items.empty()) {
00144     return;
00145   }
00146 
00147   delete selected_surface;
00148   selected_surface = new MultiSurface(VXV::Rect(fill_normal->w,
00149                                                 fill_normal->h));
00150   selected_surface->addSurface(fill_normal);
00151   selected_surface->addSurface(surface_normal[now_index]);
00152 
00153   delete selected_item;
00154   selected_item = new ButtonComponent(selected_surface);
00155 }
00156 
00157 
00158 void ComboBoxComponent::activate(bool on) {
00159 
00160   // サーフェスの作成
00161   deleteObject();
00162   for (std::vector<const Uint16*>::iterator it = add_text.begin();
00163        it != add_text.end(); ++it) {
00164     DrawSurface* normal =
00165       new DrawSurface(ttf.createText(*it, font_size, fore_color, back_color));
00166     DrawSurface* focused =
00167       new DrawSurface(ttf.createText(*it, font_size,
00168                                      focused_fore_color, focused_back_color));
00169     surface_normal.push_back(normal);
00170     surface_focused.push_back(focused);
00171 
00172     w = (normal->w > w) ? normal->w : w;
00173     h = (normal->h > h) ? normal->h : h;
00174   }
00175   for (std::vector<Uint16*>::iterator it = char_text.begin();
00176        it != char_text.end(); ++it) {
00177     delete [] *it;
00178   }
00179   add_text.clear();
00180   char_text.clear();
00181 
00182   // ▼ボタンの作成
00183   int btn_size = font_size >> 1;
00184   btn_size = (btn_size < 12) ? 12 : btn_size;
00185   if (!button_surface) {
00186     Uint16 button_text[] = { 0x25bc, 0x0000 }; // ▼ の文字
00187     button_surface = new DrawSurface(ttf.createText(button_text, btn_size,
00188                                                     fore_color, back_color));
00189     button_label = new LabelComponent(button_surface);
00190     button_offset = VXV::Grid(w + btn_size/3, h/2);
00191   }
00192   w += button_surface->w + btn_size/2;
00193 
00194   // 背景の作成
00195   delete fill_normal;
00196   VXV::Rect fill_rect = VXV::Rect(w, h);
00197   fill_normal = new FillSurface(fill_rect, back_color);
00198   delete fill_focused;
00199   fill_focused = new FillSurface(fill_rect, focused_back_color);
00200 
00201 
00202   // 項目ボタンの作成
00203   menu = new MenuComponent();
00204   menu->defaultSelection(false);
00205   std::vector<DrawSurface*>::iterator focused = surface_focused.begin();
00206   for (std::vector<DrawSurface*>::iterator normal = surface_normal.begin();
00207        normal != surface_normal.end(); ++normal, ++focused) {
00208 
00209     MultiSurface* multi = new MultiSurface(VXV::Rect(w, h));
00210     multi->addSurface(fill_normal);
00211     multi->addSurface(*normal);
00212     items_normal.push_back(multi);
00213     ButtonComponent* button = new ButtonComponent(multi);
00214 
00215     multi = new MultiSurface(VXV::Rect(w, h));
00216     multi->addSurface(fill_focused);
00217     multi->addSurface(*focused);
00218     items_focused.push_back(multi);
00219     button->setFocusedSurface(multi);
00220     items.push_back(button);
00221 
00222     menu->add(button);
00223   }
00224 
00225   // menu の生成
00226   menu->hide(true);
00227   menu->activate(true);
00228 
00229   updateSelected();
00230 }
00231 
00232 
00233 void ComboBoxComponent::setNowIndex(int index) {
00234   now_index = index;
00235   if (menu) {
00236     menu->setNowIndex(index);
00237   }
00238   updateSelected();
00239 }
00240 
00241 
00242 bool ComboBoxComponent::isDecided(void) {
00243   return decided;
00244 }
00245 
00246 
00247 unsigned int ComboBoxComponent::getNowIndex(void) {
00248   decided = false;
00249   return now_index;
00250 }
00251 
00252 
00253 void ComboBoxComponent::beginFocus(void) {
00254   focused = true;
00255   view_list = true;
00256   menu->hide(false);
00257 }
00258 
00259 
00260 void ComboBoxComponent::endFocus(void) {
00261   focused = false;
00262   view_list = false;
00263   menu->hide(true);
00264 }
00265 

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