00001
00002
00003
00004
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