void TextBox::_DEBUG_DrawOutline() { // Stores the positions of the four sides of the rectangle float left = 0.0f; float right = _width; float bottom = 0.0f; float top = _height; // Draw the outline of the textbox VideoManager->Move(0.0f, 0.0f); CalculateAlignedRect(left, right, bottom, top); VideoManager->DrawRectangleOutline(left, right, bottom, top, 3, alpha_black); VideoManager->DrawRectangleOutline(left, right, bottom, top, 1, alpha_white); // Draw the inner boundaries for each line of text uint32 possible_lines = _height / _font_properties->line_skip; float line_height = _font_properties->line_skip * -VideoManager->_current_context.coordinate_system.GetVerticalDirection(); float line_offset = top; for(uint32 i = 1; i <= possible_lines; ++i) { line_offset += line_height; VideoManager->DrawLine(left, line_offset, right, line_offset, 3, alpha_black); VideoManager->DrawLine(left, line_offset, right, line_offset, 1, alpha_white); } }
void GUIControl::_DEBUG_DrawOutline() { float left = 0.0f; float right = _width; float bottom = 0.0f; float top = _height; VideoManager->Move(0.0f, 0.0f); CalculateAlignedRect(left, right, bottom, top); VideoManager->DrawRectangleOutline(left, right, bottom, top, 3, alpha_black); VideoManager->DrawRectangleOutline(left, right, bottom, top, 1, alpha_white); }
void TextBox::Draw() { if (_text.empty()) return; if (_initialized == false) { IF_PRINT_WARNING(VIDEO_DEBUG) << "function failed because the textbox was not initialized:\n" << _initialization_errors << endl; return; } // Don't draw text window if parent window is hidden if (_owner && _owner->GetState() == VIDEO_MENU_STATE_HIDDEN) return; // Take the following steps to draw the text: // (1): Save the video engine's context and enable appropriate draw settings // (2): Determine the coordinates of the textbox rectangle to draw // (3): Create a ScreenRect for the textbox area and apply scissoring if its enabled // (4): Determine the text draw position from the alignment flags // (5): Draw each line of text to the screen // (6): Restore the original video engine context VideoManager->PushState(); VideoManager->SetDrawFlags(_xalign, _yalign, VIDEO_BLEND, 0); // Stores the positions of the four sides of the rectangle float left = 0.0f; float right = _width; float bottom = 0.0f; float top = _height; CalculateAlignedRect(left, right, bottom, top); // Create a screen rectangle for the position and apply any scissoring int32 x, y, w, h; x = static_cast<int32>(left < right ? left : right); y = static_cast<int32>(top < bottom ? top : bottom); w = static_cast<int32>(right - left); h = static_cast<int32>(top - bottom); if (w < 0) w = -w; if (h < 0) h = -h; ScreenRect rect(x, y, w, h); // TODO: this block of code (scissoring for textboxes) does not work properly /* if (_owner) { rect.Intersect(_owner->GetScissorRect()); } rect.Intersect(VideoManager->GetScissorRect()); VideoManager->EnableScissoring(_owner || VideoManager->IsScissoringEnabled()); if (VideoManager->IsScissoringEnabled()) { VideoManager->SetScissorRect(rect); } */ // Holds the height of the text to be drawn float text_height = static_cast<float>(CalculateTextHeight()); // Holds the x and y position where the text should be drawn float text_xpos, text_ypos; // Determine the vertical position of the text based on the alignment if (_text_yalign == VIDEO_Y_TOP) { text_ypos = top; } else if (_text_yalign == VIDEO_Y_CENTER) { text_ypos = top - (VideoManager->_current_context.coordinate_system.GetVerticalDirection() * (_height - text_height) * 0.5f); } else { // (_yalign == VIDEO_Y_BOTTOM) text_ypos = top - (VideoManager->_current_context.coordinate_system.GetVerticalDirection() * (_height - text_height)); } // Determine the horizontal position of the text based on the alignment if (_text_xalign == VIDEO_X_LEFT) { text_xpos = left; } else if (_text_xalign == VIDEO_X_CENTER) { text_xpos = (left + right) * 0.5f; // TODO: Is this logic right? It doesn't seem so... } else { // (_text_xalign == VIDEO_X_RIGHT) text_xpos = right; } // Set the draw cursor, draw flags, and draw the text VideoManager->Move(0.0f, text_ypos); VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_TOP, VIDEO_BLEND, 0); _DrawTextLines(text_xpos, text_ypos, rect); if (GUIManager->DEBUG_DrawOutlines() == true) _DEBUG_DrawOutline(text_ypos); VideoManager->PopState(); } // void TextBox::Draw()
void TextBox::_ReformatText() { // (1): Go through the text ustring and determine where the newline characters can be found, examining one line at a time and adding it to the _text vector. size_t newline_pos; size_t startline_pos = 0; const size_t temp_length = _text_save.length(); _text.clear(); _num_chars = 0; // If font not set, return (leave _text vector empty) if(!_font_properties) { IF_PRINT_WARNING(VIDEO_DEBUG) << "textbox font is invalid" << std::endl; return; } while(startline_pos < temp_length) { newline_pos = _text_save.find(NEWLINE_CHARACTER,startline_pos); // If the end of the string has been reached, add the new line and exit if(newline_pos == ustring::npos) { _AddLine(_text_save.substr(startline_pos, temp_length - startline_pos)); break; } // Otherwise, add the new line segment and proceed to find the next else { ustring tmp = _text_save.substr(startline_pos, newline_pos - startline_pos); _AddLine(_text_save.substr(startline_pos, newline_pos - startline_pos)); startline_pos = newline_pos + 1; } } // Update the scissor cache // Stores the positions of the four sides of the rectangle float left = 0.0f; float right = _width; float bottom = 0.0f; float top = _height; VideoManager->PushState(); VideoManager->SetDrawFlags(_xalign, _yalign, VIDEO_BLEND, 0); CalculateAlignedRect(left, right, bottom, top); VideoManager->PopState(); // Create a screen rectangle for the position and apply any scissoring int32 x, y, w, h; x = static_cast<int32>(left < right ? left : right); y = static_cast<int32>(top < bottom ? top : bottom); w = static_cast<int32>(right - left); h = static_cast<int32>(top - bottom); if(w < 0) w = -w; if(h < 0) h = -h; _scissor_rect.Set(x, y, w, h); // Update the text height _text_height = static_cast<float>(CalculateTextHeight()); // Calculate the height of the text and check it against the height of the textbox. if(_text_height > _height) { IF_PRINT_WARNING(VIDEO_DEBUG) << "tried to display text of height (" << _text_height << ") in a window of lower height (" << _height << ")" << std::endl; } // Determine the vertical position of the text based on the alignment if(_text_yalign == VIDEO_Y_TOP) { _text_ypos = top; } else if(_text_yalign == VIDEO_Y_CENTER) { _text_ypos = top - (VideoManager->_current_context.coordinate_system.GetVerticalDirection() * (_height - _text_height) * 0.5f); } else { // (_yalign == VIDEO_Y_BOTTOM) _text_ypos = top - (VideoManager->_current_context.coordinate_system.GetVerticalDirection() * (_height - _text_height)); } // Determine the horizontal position of the text based on the alignment if(_text_xalign == VIDEO_X_LEFT) { _text_xpos = left; } else if(_text_xalign == VIDEO_X_CENTER) { _text_xpos = (left + right) * 0.5f; // * 0.5 equals /2. } else { // (_text_xalign == VIDEO_X_RIGHT) _text_xpos = right; } } // void TextBox::_ReformatText()
void MenuWindow::Update(uint32 frame_time) { _display_timer += frame_time; if (_display_timer >= VIDEO_MENU_SCROLL_TIME) { if (_window_state == VIDEO_MENU_STATE_SHOWING) _window_state = VIDEO_MENU_STATE_SHOWN; else if (_window_state == VIDEO_MENU_STATE_HIDING) _window_state = VIDEO_MENU_STATE_HIDDEN; } // TODO: This does not need to be done every update call (it always retuns the same thing so long // as the window does not move. This is a performance problem and should be fixed so that this is // only done with the window size or alignment changes. if (_window_state == VIDEO_MENU_STATE_HIDDEN || _window_state == VIDEO_MENU_STATE_SHOWN) { // if (_is_scissored == true) { float x_buffer = (_width - _inner_width) / 2; float y_buffer = (_height - _inner_height) / 2; float left, right, bottom, top; left = 0.0f; right = _width; bottom = 0.0f; top = _height; VideoManager->PushState(); VideoManager->SetDrawFlags(_xalign, _yalign, 0); CalculateAlignedRect(left, right, bottom, top); VideoManager->PopState(); _scissor_rect = VideoManager->CalculateScreenRect(left, right, bottom, top); _scissor_rect.left += static_cast<int32>(x_buffer); _scissor_rect.width -= static_cast<int32>(x_buffer * 2); _scissor_rect.top += static_cast<int32>(y_buffer); _scissor_rect.height -= static_cast<int32>(y_buffer * 2); // } _is_scissored = false; return; } _is_scissored = true; // Holds the amount of the window that should be drawn (1.0 == 100%) float draw_percent = 1.0f; if (_display_mode != VIDEO_MENU_INSTANT && _window_state != VIDEO_MENU_STATE_SHOWN) { float time = static_cast<float>(_display_timer) / static_cast<float>(VIDEO_MENU_SCROLL_TIME); if (time > 1.0f) time = 1.0f; if (_window_state == VIDEO_MENU_STATE_HIDING) time = 1.0f - time; draw_percent = time; } if (IsFloatEqual(draw_percent, 1.0f) == false) { if (_display_mode == VIDEO_MENU_EXPAND_FROM_CENTER) { float left, right, bottom, top; left = 0.0f; right = _width; bottom = 0.0f; top = _height; VideoManager->PushState(); VideoManager->SetDrawFlags(_xalign, _yalign, 0); CalculateAlignedRect(left, right, bottom, top); VideoManager->PopState(); float center = (top + bottom) * 0.5f; bottom = center * (1.0f - draw_percent) + bottom * draw_percent; top = center * (1.0f - draw_percent) + top * draw_percent; _scissor_rect = VideoManager->CalculateScreenRect(left, right, bottom, top); } } } // void MenuWindow::Update(uint32 frame_time)