00001
00002
00003
00004
00005
00006
00007
00009
00010 #include <sstream>
00011
00012 #include "utils.h"
00013
00014 #include "option.h"
00015 #include "video.h"
00016
00017 using namespace std;
00018
00019 using namespace hoa_utils;
00020 using namespace hoa_video::private_video;
00021
00022 namespace hoa_video {
00023
00024 OptionBox::OptionBox() {
00025 _option_xalign = VIDEO_X_LEFT;
00026 _option_yalign = VIDEO_Y_TOP;
00027 _selection_mode = VIDEO_SELECT_SINGLE;
00028 _switching = false;
00029 _horizontal_wrap_mode = VIDEO_WRAP_MODE_NONE;
00030 _vertical_wrap_mode = VIDEO_WRAP_MODE_NONE;
00031 _cursor_state = VIDEO_CURSOR_STATE_VISIBLE;
00032 _event = 0;
00033 _selection = -1;
00034 _first_selection = -1;
00035 _number_options = 0;
00036 _scrolling = 0;
00037 _scroll_offset = 0;
00038 _blink_time = 0;
00039 _scroll_time = 0;
00040 _blink = false;
00041 _cursor_xoffset = 0.0f;
00042 _cursor_yoffset = 0.0f;
00043 _horizontal_spacing = _vertical_spacing = 0.0f;
00044 _number_rows = _number_columns = 0;
00045 _initialized = IsInitialized(_initialization_errors);
00046 _TEMP_overide_scissorring = false;
00047 }
00048
00049
00050
00051 OptionBox::~OptionBox() {
00052 ClearOptions();
00053 }
00054
00055
00056
00057 void OptionBox::Update(uint32 frame_time) {
00058 _event = 0;
00059
00060 _blink = ((_blink_time / VIDEO_CURSOR_BLINK_RATE) % 2) == 1;
00061 _blink_time += frame_time;
00062
00063 if (_scrolling) {
00064 _scroll_time += frame_time;
00065
00066 if (_scroll_time > VIDEO_OPTION_SCROLL_TIME) {
00067 _scroll_time = 0;
00068 _scrolling = false;
00069 }
00070 }
00071 }
00072
00073
00074
00075 void OptionBox::Draw() {
00076
00077 if (_initialized == false) {
00078 return;
00079 }
00080
00081 VideoManager->_PushContext();
00082 VideoManager->SetDrawFlags(_xalign, _yalign, VIDEO_BLEND, 0);
00083
00084
00085 float left, right, bottom, top;
00086 left = 0.0f;
00087 right = _number_columns * _horizontal_spacing;
00088 bottom = 0.0f;
00089 top = _number_rows * _vertical_spacing;
00090
00091 CalculateAlignedRect(left, right, bottom, top);
00092
00093 int32 x, y, w, h;
00094
00095 x = static_cast<int32>(left < right ? left : right);
00096 y = static_cast<int32>(top < bottom ? top : bottom);
00097 w = static_cast<int32>(right - left);
00098 if (w < 0)
00099 w = -w;
00100 h = static_cast<int32>(top - bottom);
00101 if (h < 0)
00102 h = -h;
00103
00104 ScreenRect rect(x, y, w, h);
00105
00106 int32 cursor_margin = static_cast<int32>(VideoManager->GetDefaultCursor()->GetWidth() + 1 - _cursor_xoffset);
00107 rect.left -= cursor_margin;
00108 rect.width += cursor_margin;
00109
00110
00111
00112
00113 bool scissoring_rollback = VideoManager->IsScissoringEnabled();
00114 if (_TEMP_overide_scissorring) {
00115 rect.top += 71;
00116 rect.height += 10;
00117 rect.Intersect(VideoManager->GetScissorRect());
00118 VideoManager->EnableScissoring(true);
00119 VideoManager->SetScissorRect(rect);
00120 }
00121 else {
00122 if (_owner && VideoManager->IsScissoringEnabled() ) {
00123 rect.Intersect(_owner->GetScissorRect());
00124 rect.Intersect(VideoManager->GetScissorRect());
00125 VideoManager->EnableScissoring(true);
00126 VideoManager->SetScissorRect(rect);
00127 }
00128 }
00129
00130 CoordSys &cs = VideoManager->_coord_sys;
00131 VideoManager->SetFont(_font);
00132 VideoManager->SetDrawFlags(_option_xalign, _option_yalign, VIDEO_X_NOFLIP, VIDEO_Y_NOFLIP, VIDEO_BLEND, 0);
00133
00134 int32 row_min, row_max;
00135 float cell_offset = 0.0f;
00136
00137 if (!_scrolling) {
00138 row_min = _scroll_offset;
00139 row_max = _scroll_offset + _number_rows;
00140 }
00141 else if (_scroll_direction == -1) {
00142 row_min = _scroll_offset;
00143 row_max = _scroll_offset + _number_rows + 1;
00144
00145 cell_offset = cs.GetVerticalDirection() * (1.0f - (_scroll_time / (VIDEO_OPTION_SCROLL_TIME))) * _vertical_spacing;
00146 }
00147 else {
00148 row_min = _scroll_offset - 1;
00149 row_max = _scroll_offset + _number_rows;
00150 cell_offset = cs.GetVerticalDirection() * ((_scroll_time / (VIDEO_OPTION_SCROLL_TIME))) * _vertical_spacing;
00151 }
00152
00153 OptionCellBounds bounds;
00154 bounds.y_top = top + cell_offset;
00155 bounds.y_center = bounds.y_top - 0.5f * _vertical_spacing * cs.GetVerticalDirection();
00156 bounds.y_bottom = (bounds.y_center * 2.0f) - bounds.y_top;
00157
00158 float yoff = -_vertical_spacing * cs.GetVerticalDirection();
00159 float xoff = _horizontal_spacing * cs.GetHorizontalDirection();
00160 bool finished = false;
00161
00162
00163 for (int32 row = row_min; row < row_max; row++) {
00164 bounds.x_left = left;
00165 bounds.x_center = bounds.x_left + (0.5f * _horizontal_spacing * cs.GetHorizontalDirection());
00166 bounds.x_right = (bounds.x_center * 2.0f) - bounds.x_left;
00167
00168
00169 for (int32 col = 0; col < _number_columns; ++col) {
00170 int32 index = row * _number_columns + col;
00171
00172 if (index >= _number_options || index < 0) {
00173 finished = true;
00174 break;
00175 }
00176
00177 float left_edge = 999999.0f;
00178 float x, y;
00179
00180 int32 xalign = _option_xalign;
00181 int32 yalign = _option_yalign;
00182 _SetupAlignment(xalign, yalign, bounds, x, y);
00183
00184 Option &op = _options.at(index);
00185 if (op.disabled)
00186 VideoManager->SetTextColor(Color::gray);
00187 else
00188 VideoManager->SetTextColor(Color::white);
00189
00190
00191 for (int32 element = 0; element < static_cast<int32>(op.elements.size()); element++) {
00192 switch (op.elements[element].type) {
00193 case VIDEO_OPTION_ELEMENT_LEFT_ALIGN:
00194 {
00195 xalign = VIDEO_X_LEFT;
00196 _SetupAlignment(xalign, _option_yalign, bounds, x, y);
00197 break;
00198 }
00199 case VIDEO_OPTION_ELEMENT_CENTER_ALIGN:
00200 {
00201 xalign = VIDEO_X_CENTER;
00202 _SetupAlignment(xalign, _option_yalign, bounds, x, y);
00203 break;
00204 }
00205 case VIDEO_OPTION_ELEMENT_RIGHT_ALIGN:
00206 {
00207 xalign = VIDEO_X_RIGHT;
00208 _SetupAlignment(xalign, _option_yalign, bounds, x, y);
00209 break;
00210 }
00211 case VIDEO_OPTION_ELEMENT_IMAGE:
00212 {
00213 int32 image_index = op.elements[element].value;
00214
00215 if (image_index >= 0 && image_index < static_cast<int32>(op.images.size())) {
00216 if (op.disabled)
00217 VideoManager->DrawImage(op.images[image_index], Color::gray);
00218 else
00219 VideoManager->DrawImage(op.images[image_index], Color::white);
00220
00221 float width = op.images[image_index].GetWidth();
00222 float edge = x - bounds.x_left;
00223 if (xalign == VIDEO_X_CENTER)
00224 edge -= width * 0.5f * cs.GetHorizontalDirection();
00225 else if (xalign == VIDEO_X_RIGHT)
00226 edge -= width * cs.GetHorizontalDirection();
00227
00228 if (edge < left_edge)
00229 left_edge = edge;
00230
00231 }
00232 break;
00233 }
00234 case VIDEO_OPTION_ELEMENT_POSITION:
00235 {
00236 x = bounds.x_left + op.elements[element].value * cs.GetHorizontalDirection();
00237 VideoManager->Move(x, y);
00238 break;
00239 }
00240 case VIDEO_OPTION_ELEMENT_TEXT:
00241 {
00242 int32 text_index = op.elements[element].value;
00243
00244 if (text_index >= 0 && text_index < static_cast<int32>(op.text.size())) {
00245 const ustring& text = op.text[text_index];
00246 float width = static_cast<float>(VideoManager->CalculateTextWidth(_font, text));
00247 float edge = x - bounds.x_left;
00248
00249 if (xalign == VIDEO_X_CENTER)
00250 edge -= width * 0.5f * cs.GetHorizontalDirection();
00251 else if (xalign == VIDEO_X_RIGHT)
00252 edge -= width * cs.GetHorizontalDirection();
00253
00254 if (edge < left_edge)
00255 left_edge = edge;
00256
00257 VideoManager->DrawText(text);
00258 }
00259
00260 break;
00261 }
00262 case VIDEO_OPTION_ELEMENT_INVALID:
00263 case VIDEO_OPTION_ELEMENT_TOTAL:
00264 default:
00265 {
00266 cerr << "VIDEO WARNING: In OptionBox::Draw(), invalid option element type was present" << endl;
00267 break;
00268 }
00269 }
00270 }
00271
00272 float cursor_offset = 0;
00273 if (_scrolling) {
00274 if (_scroll_direction == -1)
00275 cursor_offset = -cell_offset;
00276 else
00277 cursor_offset = -cell_offset + cs.GetVerticalDirection() * _vertical_spacing;
00278 }
00279
00280
00281 if (index == _first_selection && _blink == false && _cursor_state != VIDEO_CURSOR_STATE_HIDDEN) {
00282 _SetupAlignment(VIDEO_X_LEFT, _option_yalign, bounds, x, y);
00283 VideoManager->SetDrawFlags(VIDEO_BLEND, 0);
00284 VideoManager->MoveRelative(_cursor_xoffset + left_edge + _cursor_xoffset, cursor_offset + _cursor_yoffset + _cursor_yoffset);
00285 StillImage *default_cursor = VideoManager->GetDefaultCursor();
00286
00287 if (default_cursor)
00288 VideoManager->DrawImage(*default_cursor, Color::white);
00289 }
00290
00291
00292 if (index == _selection && (_blink && _cursor_state == VIDEO_CURSOR_STATE_BLINKING) == false && _cursor_state != VIDEO_CURSOR_STATE_HIDDEN) {
00293 _SetupAlignment(VIDEO_X_LEFT, _option_yalign, bounds, x, y);
00294 VideoManager->SetDrawFlags(VIDEO_BLEND, 0);
00295 VideoManager->MoveRelative(_cursor_xoffset + left_edge, cursor_offset + _cursor_yoffset);
00296 StillImage *default_cursor = VideoManager->GetDefaultCursor();
00297
00298 if (default_cursor)
00299 VideoManager->DrawImage(*default_cursor, Color::white);
00300 }
00301
00302 bounds.x_left += xoff;
00303 bounds.x_center += xoff;
00304 bounds.x_right += xoff;
00305 }
00306
00307 if (finished)
00308 break;
00309
00310 bounds.y_top += yoff;
00311 bounds.y_center += yoff;
00312 bounds.y_bottom += yoff;
00313 }
00314
00315 VideoManager->EnableScissoring(scissoring_rollback);
00316 VideoManager->_PopContext();
00317 }
00318
00319
00320
00321 void OptionBox::ClearOptions() {
00322
00323 for(int32 j = 0; j < static_cast<int32>(_options.size()); ++j) {
00324 for(int32 i = 0; i < static_cast<int32>(_options[j].images.size()); ++i) {
00325 VideoManager->DeleteImage(_options[j].images[i]);
00326 }
00327 }
00328
00329 _options.clear();
00330 }
00331
00332
00333
00334 bool OptionBox::SetOptions(const vector<ustring>& format_text) {
00335 _options.clear();
00336 _number_options = 0;
00337
00338 vector<ustring>::const_iterator i = format_text.begin();
00339 while (i != format_text.end()) {
00340 const ustring &str = *i;
00341
00342 Option option;
00343
00344 if (_ConstructOption(str, option) == false) {
00345 _options.clear();
00346 _number_options = 0;
00347 if (VIDEO_DEBUG)
00348 cerr << "VIDEO ERROR: OptionBox::SetOptions() failed due to an invalid format string: "
00349 << MakeStandardString(*i) << endl;
00350 return false;
00351 }
00352
00353 _options.push_back(option);
00354
00355 _number_options++;
00356 i++;
00357 }
00358
00359 return true;
00360 }
00361
00362
00363
00364 bool OptionBox::AddOption(const hoa_utils::ustring &text) {
00365 Option option;
00366
00367
00368 if (_ConstructOption(text, option) == false) {
00369 return false;
00370 }
00371
00372 _options.push_back(option);
00373 _number_options++;
00374 return true;
00375 }
00376
00377
00378
00379 bool OptionBox::SetOptionText(int32 index, const hoa_utils::ustring &text) {
00380 if (index < 0 || index >= _number_options) {
00381 if (VIDEO_DEBUG)
00382 cerr << "VIDEO WARNING: OptionBox::SetOptionText() failed because it was given an invalid index: " << index << endl;
00383 return false;
00384 }
00385
00386 _ConstructOption(text, _options[index]);
00387 return true;
00388 }
00389
00390
00391
00392 void OptionBox::SetSelection(int32 index) {
00393 if (index < 0 || index >= _number_options) {
00394 if (VIDEO_DEBUG)
00395 cerr << "VIDEO WARNING: OptionBox::SetSelection() failed because it was passed an invalid index: "
00396 << index << endl;
00397 return;
00398 }
00399 _selection = index;
00400
00401 int32 select_row = _selection / _number_columns;
00402
00403
00404 if (select_row < _scroll_offset || select_row > _scroll_offset + _number_rows - 1) {
00405 _scroll_offset = select_row - _number_rows + 1;
00406
00407 int32 total_num_rows = (_number_options + _number_columns - 1) / _number_columns;
00408
00409 if (_scroll_offset + _number_rows >= total_num_rows) {
00410 _scroll_offset = total_num_rows - _number_rows;
00411 }
00412 }
00413 }
00414
00415
00416
00417 void OptionBox::EnableOption(int32 index, bool enable) {
00418 if (index < 0 || index >= _number_options) {
00419 if (VIDEO_DEBUG)
00420 cerr << "VIDEO WARNING: OptionBox::EnableOption() failed because an invalid "
00421 << "option index was specified: " << index << endl;
00422 return;
00423 }
00424
00425 _options[index].disabled = !enable;
00426 }
00427
00428
00429
00430 bool OptionBox::IsInitialized(string& error_messages) {
00431 ostringstream s;
00432 error_messages.clear();
00433
00434 if (_number_rows <= 0)
00435 s << "* Invalid number of rows (" << _number_rows << ")" << endl;
00436
00437 if (_number_columns <= 0)
00438 s << "* Invalid number of columns (" << _number_columns << ")" << endl;
00439
00440 if (_horizontal_spacing <= 0.0f && _number_columns > 1)
00441 s << "* Invalid horizontal spacing (" << _horizontal_spacing << ")" << endl;
00442
00443 if (_vertical_spacing <= 0.0f && _number_rows > 1)
00444 s << "* Invalid vertical spacing (" << _vertical_spacing << ")" << endl;
00445
00446 if (_option_xalign < VIDEO_X_LEFT || _option_xalign > VIDEO_X_RIGHT)
00447 s << "* Invalid x align (" << _option_xalign << ")" << endl;
00448
00449 if (_option_yalign < VIDEO_Y_TOP || _option_yalign > VIDEO_Y_BOTTOM)
00450 s << "* Invalid y align (" << _option_yalign << ")" << endl;
00451
00452 if (_font.empty())
00453 s << "* Invalid font (none has been set)" << endl;
00454
00455 if (_selection_mode <= VIDEO_SELECT_INVALID || _selection_mode >= VIDEO_SELECT_TOTAL)
00456 s << "* Invalid selection mode (" << _selection_mode << ")" << endl;
00457
00458 error_messages = s.str();
00459
00460 if (error_messages.empty())
00461 _initialized = true;
00462 else
00463 _initialized = false;
00464
00465 return _initialized;
00466 }
00467
00468
00469
00470
00471
00472 void OptionBox::HandleUpKey() {
00473
00474 if (_scrolling || _event)
00475 return;
00476
00477 if (_ChangeSelection(-1, false) == false)
00478 _event = VIDEO_OPTION_BOUNDS_UP;
00479 }
00480
00481
00482
00483 void OptionBox::HandleDownKey() {
00484
00485 if (_scrolling || _event)
00486 return;
00487
00488 if(_ChangeSelection(1, false) == false)
00489 _event = VIDEO_OPTION_BOUNDS_DOWN;
00490 }
00491
00492
00493
00494 void OptionBox::HandleLeftKey() {
00495
00496 if (_scrolling || _event)
00497 return;
00498
00499 if (_ChangeSelection(-1, true) == false)
00500 _event = VIDEO_OPTION_BOUNDS_LEFT;
00501 }
00502
00503
00504
00505 void OptionBox::HandleRightKey() {
00506
00507 if (_scrolling || _event)
00508 return;
00509
00510
00511 if (_ChangeSelection(1, true) == false)
00512 _event = VIDEO_OPTION_BOUNDS_RIGHT;
00513 }
00514
00515
00516
00517 void OptionBox::HandleConfirmKey() {
00518
00519 if (_scrolling || _event)
00520 return;
00521
00522
00523 if (_selection < 0 || _selection >= _number_options) {
00524 if (VIDEO_DEBUG)
00525 cerr << "VIDEO WARNING: In OptionBox::HandleConfirmKey(), an invalid (out of bounds) option "
00526 << "was selected: " << _selection << endl;
00527 return;
00528 }
00529
00530
00531 if (_switching && _first_selection >= 0 && _selection != _first_selection) {
00532
00533 Option temp = _options[_selection];
00534 _options[_selection] = _options[_first_selection];
00535 _options[_first_selection] = temp;
00536
00537 _first_selection = -1;
00538
00539 _event = VIDEO_OPTION_SWITCH;
00540 }
00541
00542
00543 else if (_selection_mode == VIDEO_SELECT_DOUBLE && _first_selection == -1) {
00544
00545 _first_selection = _selection;
00546 }
00547
00548
00549 else {
00550 if (_options[_selection].disabled) {
00551
00552 return;
00553 }
00554
00555 _event = VIDEO_OPTION_CONFIRM;
00556
00557
00558 _first_selection = -1;
00559 }
00560 }
00561
00562
00563
00564 void OptionBox::HandleCancelKey() {
00565
00566 if (_scrolling || _event)
00567 return;
00568
00569
00570 if (_first_selection >= 0)
00571 _first_selection = -1;
00572 else
00573 _event = VIDEO_OPTION_CANCEL;
00574 }
00575
00576
00577
00578
00579
00580 void OptionBox::SetFont(const std::string& font_name) {
00581 if (VideoManager->GetFontProperties(font_name) == NULL) {
00582 if(VIDEO_DEBUG)
00583 cerr << "VIDEO WARNING: OptionBox::SetFont() failed because GameVideo::GetFontProperties() returned false for font: " << font_name << endl;
00584 return;
00585 }
00586
00587 _font = font_name;
00588 _initialized = IsInitialized(_initialization_errors);
00589 }
00590
00591
00592
00593 void OptionBox::SetCursorState(CursorState state) {
00594 if (state <= VIDEO_CURSOR_STATE_INVALID || state >= VIDEO_CURSOR_STATE_TOTAL) {
00595 if (VIDEO_DEBUG)
00596 cerr << "VIDEO WARNING: OptionBox::SetCursorState() failed because the argument passed was invalid: "
00597 << state << endl;
00598 return;
00599 }
00600
00601 _cursor_state = state;
00602 }
00603
00604
00605
00606
00607
00608 bool OptionBox::_ConstructOption(const ustring& format_string, Option& op) {
00609
00610 op.disabled = false;
00611
00612
00613 op.elements.clear();
00614 op.text.clear();
00615 op.images.clear();
00616
00617
00618 if (format_string.empty()) {
00619 return true;
00620 }
00621
00622
00623 ustring tmp = format_string;
00624
00625 while (tmp.empty() == false) {
00626 OptionElement new_element;
00627
00628 if (tmp[0] == OPEN_TAG) {
00629 size_t length = tmp.length();
00630
00631 if (length < 3) {
00632
00633
00634
00635 if (VIDEO_DEBUG)
00636 cerr << "VIDEO ERROR: OptionBox::_ConstructOption() failed because a tag opening was detected "
00637 << "with an inadequate number of remaining characters to construct a full tag: "
00638 << MakeStandardString(format_string) << endl;
00639 return false;
00640 }
00641
00642 size_t end_position = tmp.find(END_TAG);
00643
00644 if (end_position == ustring::npos) {
00645 if (VIDEO_DEBUG)
00646 cerr << "VIDEO ERROR: OptionBox::_ConstructOption() failed because a matching end tag could not "
00647 << "be found for an open tag: " << MakeStandardString(format_string) << endl;
00648 return false;
00649 }
00650
00651 if (tmp[2] == END_TAG) {
00652 if (tmp[1] == CENTER_TAG1 || tmp[1] == CENTER_TAG2) {
00653 new_element.type = VIDEO_OPTION_ELEMENT_CENTER_ALIGN;
00654 }
00655 else if (tmp[1] == RIGHT_TAG1 || tmp[1] == RIGHT_TAG2) {
00656 new_element.type = VIDEO_OPTION_ELEMENT_RIGHT_ALIGN;
00657 }
00658 else if (tmp[1] == LEFT_TAG1 || tmp[1] == LEFT_TAG2) {
00659 new_element.type = VIDEO_OPTION_ELEMENT_LEFT_ALIGN;
00660 }
00661 }
00662 else {
00663
00664 string tag_text = MakeStandardString(tmp.substr(1, end_position - 1));
00665
00666 if (IsStringNumeric(tag_text)) {
00667 new_element.type = VIDEO_OPTION_ELEMENT_POSITION;
00668 new_element.value = atoi(tag_text.c_str());
00669 }
00670 else {
00671 StillImage imd;
00672 imd.SetFilename(tag_text);
00673
00674 if (VideoManager->LoadImage(imd) == false) {
00675 if (VIDEO_DEBUG)
00676 cerr << "VIDEO ERROR: OptionBox::_ConstructOption failed because of an invalid image tag: "
00677 << MakeStandardString(format_string) << endl;
00678 return false;
00679 }
00680 new_element.type = VIDEO_OPTION_ELEMENT_IMAGE;
00681 new_element.value = static_cast<int32> (op.images.size());
00682 op.images.push_back(imd);
00683 }
00684 }
00685
00686
00687 if (end_position == length - 1) {
00688 tmp.clear();
00689 }
00690 else {
00691 tmp = tmp.substr(end_position + 1, length - end_position - 1);
00692 }
00693 }
00694
00695 else {
00696 new_element.type = VIDEO_OPTION_ELEMENT_TEXT;
00697 new_element.value = static_cast<int32>(op.text.size());
00698
00699
00700 size_t tag_begin = tmp.find(OPEN_TAG);
00701
00702 if (tag_begin == ustring::npos) {
00703 op.text.push_back(tmp);
00704 tmp.clear();
00705 }
00706 else {
00707 op.text.push_back(tmp.substr(0, tag_begin));
00708 tmp = tmp.substr(tag_begin, tmp.length() - tag_begin);
00709 }
00710 }
00711
00712 op.elements.push_back(new_element);
00713 }
00714
00715 return true;
00716 }
00717
00718
00719
00720 bool OptionBox::_ChangeSelection(int32 offset, bool horizontal) {
00721
00722 if (horizontal == true && _number_columns == 1 && _horizontal_wrap_mode != VIDEO_WRAP_MODE_SHIFTED)
00723 return false;
00724
00725 if (horizontal == false && _number_rows == 1 && _vertical_wrap_mode != VIDEO_WRAP_MODE_SHIFTED)
00726 return false;
00727
00728
00729 int32 row = _selection / _number_columns;
00730 int32 col = _selection % _number_columns;
00731 bool bounds_exceeded = false;
00732
00733
00734 if ((horizontal == true && ((col + offset < 0) || (col + offset >= _number_columns))) ||
00735 (horizontal == false && ((row + offset < 0) || (row + offset >= _number_rows))))
00736 {
00737 bounds_exceeded = true;
00738 }
00739
00740
00741 if (bounds_exceeded == false) {
00742 if (horizontal)
00743 _selection += offset;
00744 else
00745 _selection += (offset * _number_columns);
00746 }
00747
00748
00749 else if ((horizontal == true && _horizontal_wrap_mode == VIDEO_WRAP_MODE_NONE) ||
00750 (horizontal == false && _vertical_wrap_mode == VIDEO_WRAP_MODE_NONE))
00751 {
00752 return false;
00753 }
00754
00755
00756 else if (horizontal == true) {
00757 if (col + offset < 0) {
00758 if (_horizontal_wrap_mode == VIDEO_WRAP_MODE_STRAIGHT)
00759 offset += _number_columns;
00760 else if (_horizontal_wrap_mode == VIDEO_WRAP_MODE_SHIFTED) {
00761 if (_vertical_wrap_mode != VIDEO_WRAP_MODE_NONE)
00762 offset += _number_options;
00763 else
00764 return false;
00765 }
00766 }
00767 else {
00768 if (_horizontal_wrap_mode == VIDEO_WRAP_MODE_STRAIGHT)
00769 offset -= _number_columns;
00770 else if (_horizontal_wrap_mode == VIDEO_WRAP_MODE_SHIFTED) {
00771 if (_vertical_wrap_mode != VIDEO_WRAP_MODE_NONE)
00772 offset -= _number_options;
00773 else
00774 return false;
00775 }
00776 }
00777 _selection = (_selection + offset) % _number_options;
00778 }
00779
00780
00781 else {
00782 if (row + offset < 0) {
00783 if (_vertical_wrap_mode == VIDEO_WRAP_MODE_STRAIGHT)
00784 offset += _number_options;
00785 else if (_vertical_wrap_mode == VIDEO_WRAP_MODE_SHIFTED) {
00786 if (_horizontal_wrap_mode != VIDEO_WRAP_MODE_NONE)
00787 offset += (_number_columns - 1);
00788 else
00789 return false;
00790 }
00791 }
00792 else {
00793 if (_vertical_wrap_mode == VIDEO_WRAP_MODE_STRAIGHT)
00794 offset -= _number_options;
00795 else if (_vertical_wrap_mode == VIDEO_WRAP_MODE_SHIFTED) {
00796 if (_horizontal_wrap_mode != VIDEO_WRAP_MODE_NONE)
00797 offset -= (_number_columns - 1);
00798 else
00799 return false;
00800 }
00801 }
00802 _selection = (_selection + (offset * _number_columns)) % _number_options;
00803 }
00804
00805
00806 row = _selection / _number_columns;
00807 if (row < _scroll_offset || row > _scroll_offset + _number_rows - 1) {
00808 _scrolling = true;
00809 _scroll_time = 0;
00810
00811 if (row < _scroll_offset)
00812 _scroll_direction = -1;
00813 else
00814 _scroll_direction = 1;
00815
00816 _scroll_offset += _scroll_direction;
00817 }
00818
00819 _event = VIDEO_OPTION_SELECTION_CHANGE;
00820
00821 return true;
00822 }
00823
00824
00825
00826 void OptionBox::_SetupAlignment(int32 xalign, int32 yalign, const OptionCellBounds& bounds, float& x, float& y) {
00827 VideoManager->SetDrawFlags(xalign, yalign, 0);
00828
00829 switch (xalign) {
00830 case VIDEO_X_LEFT:
00831 x = bounds.x_left;
00832 break;
00833 case VIDEO_X_CENTER:
00834 x = bounds.x_center;
00835 break;
00836 default:
00837 x = bounds.x_right;
00838 break;
00839 }
00840
00841 switch(yalign) {
00842 case VIDEO_Y_TOP:
00843 y = bounds.y_top;
00844 break;
00845 case VIDEO_Y_CENTER:
00846 y = bounds.y_center;
00847 break;
00848 default:
00849 y = bounds.y_bottom;
00850 break;
00851 }
00852
00853 VideoManager->Move(x, y);
00854 }
00855
00856 }