1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 #include <sstream>
11 
12 #include "video.h"
13 #include "menu_window.h"
14 
15 using namespace std;
16 using namespace hoa_utils;
17 using namespace hoa_video;
18 using namespace hoa_video::private_video;
19 using namespace hoa_gui::private_gui;
20 
21 namespace hoa_gui {
22 
MenuWindow()23 MenuWindow::MenuWindow() :
24 	_skin(NULL),
25 	_window_state(VIDEO_MENU_STATE_HIDDEN),
26 	_display_timer(0),
27 	_display_mode(VIDEO_MENU_INSTANT),
28 	_is_scissored(false)
29 {
30 	_id = GUIManager->_GetNextMenuWindowID();
31 	_initialized = IsInitialized(_initialization_errors);
32 }
33 
34 
35 
Create(string skin_name,float w,float h,int32 visible_flags,int32 shared_flags)36 bool MenuWindow::Create(string skin_name, float w, float h, int32 visible_flags, int32 shared_flags) {
37 	_skin = GUIManager->_GetMenuSkin(skin_name);
38 	if (_skin == NULL) {
39 		IF_PRINT_WARNING(VIDEO_DEBUG) << "the requested menu skin was not found: " << skin_name << endl;
40 		return false;
41 	}
42 
43 	return Create(w, h, visible_flags, shared_flags);
44 }
45 
46 
47 
Create(float w,float h,int32 visible_flags,int32 shared_flags)48 bool MenuWindow::Create(float w, float h, int32 visible_flags, int32 shared_flags) {
49 	if (w <= 0 || h <= 0) {
50 		IF_PRINT_WARNING(VIDEO_DEBUG) << "width and/or height argument was invalid: "
51 			<< "(width = " << w << ", height = " << h << ")" << endl;
52 		return false;
53 	}
54 
55 	_width = w;
56 	_height = h;
57 	_edge_visible_flags = visible_flags;
58 	_edge_shared_flags = shared_flags;
59 
60 	if (_skin == NULL) {
61 		_skin = GUIManager->_GetDefaultMenuSkin();
62 	}
63 	if (_skin == NULL) {
64 		IF_PRINT_WARNING(VIDEO_DEBUG) << "a default menu skin was unavailable (no skins were loaded)" << endl;
65 		return false;
66 	}
67 
68 	if (_RecreateImage() == false) {
69 		return false;
70 	}
71 
72 	// Add the new menu window to the menu map
73 	GUIManager->_AddMenuWindow(this);
74 	_initialized = IsInitialized(_initialization_errors);
75 	return true;
76 }
77 
78 
79 
Destroy()80 void MenuWindow::Destroy() {
81 	_skin = NULL;
82 	GUIManager->_RemoveMenuWindow(this);
83 }
84 
85 
86 
Update(uint32 frame_time)87 void MenuWindow::Update(uint32 frame_time) {
88 	_display_timer += frame_time;
89 
90 	if (_display_timer >= VIDEO_MENU_SCROLL_TIME) {
91 		if (_window_state == VIDEO_MENU_STATE_SHOWING)
92 			_window_state = VIDEO_MENU_STATE_SHOWN;
93 		else if (_window_state == VIDEO_MENU_STATE_HIDING)
94 			_window_state = VIDEO_MENU_STATE_HIDDEN;
95 	}
96 
97 	// TODO: This does not need to be done every update call (it always retuns the same thing so long
98 	// as the window does not move. This is a performance problem and should be fixed so that this is
99 	// only done with the window size or alignment changes.
100 	if (_window_state == VIDEO_MENU_STATE_HIDDEN || _window_state == VIDEO_MENU_STATE_SHOWN) {
101 //		if (_is_scissored == true) {
102 			float x_buffer = (_width - _inner_width) / 2;
103 			float y_buffer = (_height - _inner_height) / 2;
104 
105 			float left, right, bottom, top;
106 			left = 0.0f;
107 			right = _width;
108 			bottom = 0.0f;
109 			top = _height;
110 
111 			VideoManager->PushState();
112 			VideoManager->SetDrawFlags(_xalign, _yalign, 0);
113 			CalculateAlignedRect(left, right, bottom, top);
114 			VideoManager->PopState();
115 
116 			_scissor_rect = VideoManager->CalculateScreenRect(left, right, bottom, top);
117 
118 			_scissor_rect.left   += static_cast<int32>(x_buffer);
119 			_scissor_rect.width  -= static_cast<int32>(x_buffer * 2);
120 			_scissor_rect.top    += static_cast<int32>(y_buffer);
121 			_scissor_rect.height -= static_cast<int32>(y_buffer * 2);
122 // 		}
123 
124 		_is_scissored = false;
125 		return;
126 	}
127 
128 	_is_scissored = true;
129 
130 	// Holds the amount of the window that should be drawn (1.0 == 100%)
131 	float draw_percent = 1.0f;
132 
133 	if (_display_mode != VIDEO_MENU_INSTANT && _window_state != VIDEO_MENU_STATE_SHOWN) {
134 		float time = static_cast<float>(_display_timer) / static_cast<float>(VIDEO_MENU_SCROLL_TIME);
135 		if (time > 1.0f)
136 			time = 1.0f;
137 
138 		if (_window_state == VIDEO_MENU_STATE_HIDING)
139 			time = 1.0f - time;
140 
141 		draw_percent = time;
142 	}
143 
144 	if (IsFloatEqual(draw_percent, 1.0f) == false) {
145 		if (_display_mode == VIDEO_MENU_EXPAND_FROM_CENTER) {
146 			float left, right, bottom, top;
147 			left = 0.0f;
148 			right = _width;
149 			bottom = 0.0f;
150 			top = _height;
151 
152 			VideoManager->PushState();
153 			VideoManager->SetDrawFlags(_xalign, _yalign, 0);
154 			CalculateAlignedRect(left, right, bottom, top);
155 			VideoManager->PopState();
156 
157 			float center = (top + bottom) * 0.5f;
158 
159 			bottom = center * (1.0f - draw_percent) + bottom * draw_percent;
160 			top    = center * (1.0f - draw_percent) + top * draw_percent;
161 
162 			_scissor_rect = VideoManager->CalculateScreenRect(left, right, bottom, top);
163 		}
164 	}
165 } // void MenuWindow::Update(uint32 frame_time)
166 
167 
168 
Draw()169 void MenuWindow::Draw() {
170 	if (_initialized == false) {
171 		IF_PRINT_WARNING(VIDEO_DEBUG) << "the menu window was not initialized:\n" << _initialization_errors << endl;
172 		return;
173 	}
174 
175 	if (_window_state == VIDEO_MENU_STATE_HIDDEN)
176 		return;
177 
178 	VideoManager->PushState();
179 	VideoManager->SetDrawFlags(_xalign, _yalign, VIDEO_BLEND, 0);
180 
181 	if (_is_scissored) {
182 		ScreenRect rect = _scissor_rect;
183 		if (VideoManager->IsScissoringEnabled()) {
184 			rect.Intersect(VideoManager->GetScissorRect());
185 		}
186 		else {
187 			VideoManager->EnableScissoring();
188 		}
189 		VideoManager->SetScissorRect(rect);
190 	}
191 
192 	VideoManager->Move(_x_position, _y_position);
193 	_menu_image.Draw(Color::white);
194 
195 	if (GUIManager->DEBUG_DrawOutlines() == true) {
196 		_DEBUG_DrawOutline();
197 	}
198 
199 	VideoManager->PopState();
200 	return;
201 } // void MenuWindow::Draw()
202 
203 
204 
Show()205 void MenuWindow::Show() {
206 	if (_initialized == false) {
207 		IF_PRINT_WARNING(VIDEO_DEBUG) << "the menu window was not initialized:\n" << _initialization_errors << endl;
208 		return;
209 	}
210 
211 	if (_window_state == VIDEO_MENU_STATE_SHOWING || _window_state == VIDEO_MENU_STATE_SHOWN) {
212 		return;
213 	}
214 
215 	_display_timer = 0;
216 
217 	if (_display_mode == VIDEO_MENU_INSTANT)
218 		_window_state = VIDEO_MENU_STATE_SHOWN;
219 	else
220 		_window_state = VIDEO_MENU_STATE_SHOWING;
221 } // void MenuWindow::Show()
222 
223 
224 
Hide()225 void MenuWindow::Hide() {
226 	if (_initialized == false) {
227 		IF_PRINT_WARNING(VIDEO_DEBUG) << "the menu window was not initialized:\n" << _initialization_errors << endl;
228 		return;
229 	}
230 
231 	if (_window_state == VIDEO_MENU_STATE_HIDING || _window_state == VIDEO_MENU_STATE_HIDDEN) {
232 		return;
233 	}
234 
235 	_display_timer = 0;
236 
237 	if (_display_mode == VIDEO_MENU_INSTANT)
238 		_window_state = VIDEO_MENU_STATE_HIDDEN;
239 	else
240 		_window_state = VIDEO_MENU_STATE_HIDING;
241 } // void MenuWindow::Hide()
242 
243 
244 
IsInitialized(string & errors)245 bool MenuWindow::IsInitialized(string& errors) {
246 	errors.clear();
247 	ostringstream stream;
248 
249 	// Check width
250 	if (_width <= 0.0f || _width > 1024.0f)
251 		stream << "* Invalid width (" << _width << ")" << endl;
252 
253 	// Check height
254 	if (_height <= 0.0f || _height > 768.0f)
255 		stream << "* Invalid height (" << _height << ")" << endl;
256 
257 	// Check display mode
258 	if (_display_mode <= VIDEO_MENU_INVALID || _display_mode >= VIDEO_MENU_TOTAL)
259 		stream << "* Invalid display mode (" << _display_mode << ")" << endl;
260 
261 	// Check state
262 	if (_window_state <= VIDEO_MENU_STATE_INVALID || _window_state >= VIDEO_MENU_STATE_TOTAL)
263 		stream << "* Invalid state (" << _window_state << ")" << endl;
264 
265 	// Check to see that a valid menu skin is being used
266 	if (_skin == NULL)
267 		stream << "* No menu skin is assigned" << endl;
268 
269 	// Check to see if the composite image composing the window is valid
270 	if (_menu_image.GetWidth() == 0)
271 		stream << "* Menu image is not valid" << endl;
272 
273 	errors = stream.str();
274 	if (errors.empty()) {
275 		_initialized = true;
276 	}
277 	else {
278 		_initialized = false;
279 	}
280 
281 	return _initialized;
282 } // bool MenuWindow::IsInitialized(string& errors)
283 
284 
285 
SetDimensions(float w,float h)286 void MenuWindow::SetDimensions(float w, float h) {
287 	if (w <= 0.0f) {
288 		IF_PRINT_WARNING(VIDEO_DEBUG) << "invalid width argument: " << w << endl;
289 		return;
290 	}
291 
292 	if (h <= 0.0f) {
293 		IF_PRINT_WARNING(VIDEO_DEBUG) << "invalid height argument: " << h << endl;
294 		return;
295 	}
296 
297 	_width = w;
298 	_height = h;
299 	_RecreateImage();
300 }
301 
302 
303 
SetMenuSkin(string & skin_name)304 void MenuWindow::SetMenuSkin(string& skin_name) {
305 	MenuSkin* new_skin = GUIManager->_GetMenuSkin(skin_name);
306 	if (new_skin == NULL) {
307 		IF_PRINT_WARNING(VIDEO_DEBUG) << "the skin_name \"" << skin_name << "\" was invalid" << endl;
308 		return;
309 	}
310 
311 	_skin = new_skin;
312 	_RecreateImage();
313 }
314 
315 
316 
SetDisplayMode(VIDEO_MENU_DISPLAY_MODE mode)317 void MenuWindow::SetDisplayMode(VIDEO_MENU_DISPLAY_MODE mode) {
318 	if (mode <= VIDEO_MENU_INVALID || mode >= VIDEO_MENU_TOTAL) {
319 		IF_PRINT_WARNING(VIDEO_DEBUG) << "invalid mode argument passed to function: " << mode << endl;
320 		return;
321 	}
322 
323 	_display_mode = mode;
324 	_initialized = IsInitialized(_initialization_errors);
325 }
326 
327 
328 
_RecreateImage()329 bool MenuWindow::_RecreateImage() {
330 	if (_skin == NULL) {
331 		IF_PRINT_WARNING(VIDEO_DEBUG) << "no menu skin set when function was invoked" << endl;
332 		return false;
333 	}
334 
335 	_menu_image.Clear();
336 
337 	// Get information about the border sizes
338 	float left_border_size   = _skin->borders[1][0].GetWidth();
339 	float right_border_size  = _skin->borders[1][2].GetWidth();
340 	float top_border_size    = _skin->borders[2][1].GetHeight();
341 	float bottom_border_size = _skin->borders[0][1].GetHeight();
342 
343 	float horizontal_border_size = left_border_size + right_border_size;
344 	float vertical_border_size   = top_border_size  + bottom_border_size;
345 
346 	float top_width   = _skin->borders[2][1].GetWidth();
347 	float left_height = _skin->borders[1][0].GetHeight();
348 
349 	// Calculate how many times the top/bottom images have to be tiled in order to make up the width of the window
350 	_inner_width = _width - horizontal_border_size;
351 	_inner_height = _height - vertical_border_size;
352 
353 	if (_inner_width < 0.0f) {
354 		IF_PRINT_WARNING(VIDEO_DEBUG) << "_inner_width was computed as negative" << endl;
355 		return false;
356 	}
357 
358 	if (_inner_height < 0.0f) {
359 		IF_PRINT_WARNING(VIDEO_DEBUG) << "_inner_height was computed as negative" << endl;
360 		return false;
361 	}
362 
363 	// Will be true if there is a background image for the menu skin being used
364 	bool background_loaded = _skin->background.GetWidth();
365 
366 	// Find how many times we have to tile the border images to fit the dimensions given
367 	float num_x_tiles = _inner_width  / top_width;
368 	float num_y_tiles = _inner_height / left_height;
369 
370 	int32 inum_x_tiles = static_cast<int32>(num_x_tiles);
371 	int32 inum_y_tiles = static_cast<int32>(num_y_tiles);
372 
373 	// Ideally, the border sizes should evenly divide into the window sizes but the person who
374 	// created the window might have passed in a width and height that is not a multiple of
375 	// the border sizes. If this is the case, we have to extend the dimensions a little bit.
376 	float dnum_x_tiles = num_x_tiles - inum_x_tiles;
377 	float dnum_y_tiles = num_y_tiles - inum_y_tiles;
378 
379 	if (dnum_x_tiles > 0.001f) {
380 		float width_adjust = (1.0f - dnum_x_tiles) * top_width;
381 		_width += width_adjust;
382 		_inner_width += width_adjust;
383 		++inum_x_tiles;
384 	}
385 
386 	if (dnum_y_tiles > 0.001f) {
387 		float height_adjust = (1.0f - dnum_y_tiles) * top_width;
388 		_height += height_adjust;
389 		_inner_height += height_adjust;
390 		++inum_y_tiles;
391 	}
392 
393 	// Now we have all the information we need to create the window.
394 	// Begin by re-creating the overlay at the correct width and height
395 	Color c[4];
396 	_skin->borders[1][1].GetVertexColor(c[0], 0);
397 	_skin->borders[1][1].GetVertexColor(c[1], 1);
398 	_skin->borders[1][1].GetVertexColor(c[2], 2);
399 	_skin->borders[1][1].GetVertexColor(c[3], 3);
400 
401 	_skin->borders[1][1].SetDimensions(left_border_size, top_border_size);
402 	_skin->borders[1][1].SetVertexColors(c[0], c[1], c[2], c[3]);
403 // 	VideoManager->LoadImage(_skin->borders[1][1]);
404 
405 	// If a valid background image is loaded, then tile the interior of the window with it
406 	if (background_loaded) {
407 		_skin->background.SetVertexColors(c[0], c[1], c[2], c[3]);
408 
409 		float width = _skin->background.GetWidth();
410 		float height = _skin->background.GetHeight();
411 
412 		float min_x = 0;
413 		float min_y = 0;
414 
415 		float max_x = _inner_width + horizontal_border_size;
416 		float max_y = _inner_height + vertical_border_size;
417 
418 		if (_edge_visible_flags & VIDEO_MENU_EDGE_TOP)
419 			max_y -= (top_border_size / 2);
420 		if (_edge_visible_flags & VIDEO_MENU_EDGE_BOTTOM)
421 			min_y += (bottom_border_size / 2);
422 		if (_edge_visible_flags & VIDEO_MENU_EDGE_LEFT)
423 			min_x += (left_border_size / 2);
424 		if (_edge_visible_flags & VIDEO_MENU_EDGE_RIGHT)
425 			max_x -= (right_border_size / 2);
426 
427 		for (float y = min_y ; y < max_y; y += height) {
428 			for (float x = min_x; x < max_x; x += width) {
429 				float u = 1.0, v = 1.0;
430 
431 				if (x + width > max_x)
432 					u = (max_x - x) / width;
433 				if (y + height > max_y)
434 					v = (max_y - y) / height;
435 
436 				_menu_image.AddImage(_skin->background, x, y, 0.0f, 0.0f, u, v);
437 			}
438 		}
439 	}
440 	else {
441 		// Otherwise re-create the overlay at the correct width and height
442 		_skin->borders[1][1].SetDimensions(_inner_width, _inner_height);
443 		_skin->borders[1][1].SetVertexColors(c[0], c[1], c[2], c[3]);
444 		_menu_image.AddImage(_skin->borders[1][1], left_border_size, bottom_border_size);
445 	}
446 
447 	// First create the corners of the image
448 	float max_x = left_border_size + inum_x_tiles * top_width;
449 	float max_y = bottom_border_size + inum_y_tiles * left_height;
450 	float min_x = 0.0f;
451 	float min_y = 0.0f;
452 
453 	// Bottom left
454 	if (_edge_visible_flags & VIDEO_MENU_EDGE_LEFT && _edge_visible_flags & VIDEO_MENU_EDGE_BOTTOM) {
455 		if (_edge_shared_flags & VIDEO_MENU_EDGE_LEFT && _edge_shared_flags & VIDEO_MENU_EDGE_BOTTOM)
456 			_menu_image.AddImage(_skin->connectors[4], min_x, min_y);
457 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_LEFT)
458 			_menu_image.AddImage(_skin->connectors[1], min_x, min_y);
459 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_BOTTOM)
460 			_menu_image.AddImage(_skin->connectors[2], min_x, min_y);
461 		else
462 			_menu_image.AddImage(_skin->borders[2][0], min_x, min_y);
463 	}
464 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_LEFT)
465 		_menu_image.AddImage(_skin->borders[1][0], min_x, min_y);
466 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_BOTTOM)
467 		_menu_image.AddImage(_skin->borders[0][1], min_x, min_y);
468 	else if (!background_loaded)
469 		_menu_image.AddImage(_skin->borders[1][1], min_x, min_y);
470 
471 	// Bottom right
472 	if (_edge_visible_flags & VIDEO_MENU_EDGE_RIGHT && _edge_visible_flags & VIDEO_MENU_EDGE_BOTTOM) {
473 		if (_edge_shared_flags & VIDEO_MENU_EDGE_RIGHT && _edge_shared_flags & VIDEO_MENU_EDGE_BOTTOM)
474 			_menu_image.AddImage(_skin->connectors[4], max_x, min_y);
475 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_RIGHT)
476 			_menu_image.AddImage(_skin->connectors[1], max_x, min_y);
477 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_BOTTOM)
478 			_menu_image.AddImage(_skin->connectors[3], max_x, min_y);
479 		else
480 			_menu_image.AddImage(_skin->borders[2][2], max_x, min_y);
481 	}
482 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_RIGHT)
483 		_menu_image.AddImage(_skin->borders[1][2], max_x, min_y);
484 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_BOTTOM)
485 		_menu_image.AddImage(_skin->borders[2][1], max_x, min_y);
486 	else if (!background_loaded)
487 		_menu_image.AddImage(_skin->borders[1][1], max_x, min_y);
488 
489 	// Top left
490 	if (_edge_visible_flags & VIDEO_MENU_EDGE_LEFT && _edge_visible_flags & VIDEO_MENU_EDGE_TOP) {
491 		if (_edge_shared_flags & VIDEO_MENU_EDGE_LEFT && _edge_shared_flags & VIDEO_MENU_EDGE_TOP)
492 			_menu_image.AddImage(_skin->connectors[4], min_x, max_y);
493 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_LEFT)
494 			_menu_image.AddImage(_skin->connectors[0], min_x, max_y);
495 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_TOP)
496 			_menu_image.AddImage(_skin->connectors[2], min_x, max_y);
497 		else
498 			_menu_image.AddImage(_skin->borders[0][0], min_x, max_y);
499 	}
500 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_LEFT)
501 		_menu_image.AddImage(_skin->borders[1][0], min_x, max_y);
502 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_TOP)
503 		_menu_image.AddImage(_skin->borders[0][1], min_x, max_y);
504 	else if (!background_loaded)
505 		_menu_image.AddImage(_skin->borders[1][1], min_x, max_y);
506 
507 	// Top right
508 	if (_edge_visible_flags & VIDEO_MENU_EDGE_TOP && _edge_visible_flags & VIDEO_MENU_EDGE_RIGHT) {
509 		if (_edge_shared_flags & VIDEO_MENU_EDGE_RIGHT && _edge_shared_flags & VIDEO_MENU_EDGE_TOP)
510 			_menu_image.AddImage(_skin->connectors[4], max_x, max_y);
511 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_RIGHT)
512 			_menu_image.AddImage(_skin->connectors[0], max_x, max_y);
513 		else if (_edge_shared_flags & VIDEO_MENU_EDGE_TOP)
514 			_menu_image.AddImage(_skin->connectors[3], max_x, max_y);
515 		else
516 			_menu_image.AddImage(_skin->borders[0][2], max_x, max_y);
517 	}
518 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_TOP)
519 		_menu_image.AddImage(_skin->borders[0][1], max_x, max_y);
520 	else if (_edge_visible_flags & VIDEO_MENU_EDGE_RIGHT)
521 		_menu_image.AddImage(_skin->borders[1][2], max_x, max_y);
522 	else if (!background_loaded)
523 		_menu_image.AddImage(_skin->borders[1][1], max_x, max_y);
524 
525 	// Iterate from left to right and fill in the horizontal borders
526 	for (int32 tile_x = 0; tile_x < inum_x_tiles; ++tile_x) {
527 		if (_edge_visible_flags & VIDEO_MENU_EDGE_TOP)
528 			_menu_image.AddImage(_skin->borders[0][1], left_border_size + top_width * tile_x, max_y);
529 		else if (!background_loaded)
530 			_menu_image.AddImage(_skin->borders[1][1], left_border_size + top_width * tile_x, max_y);
531 
532 		if (_edge_visible_flags & VIDEO_MENU_EDGE_BOTTOM)
533 			_menu_image.AddImage(_skin->borders[2][1], left_border_size + top_width * tile_x, 0.0f);
534 		else if (!background_loaded)
535 			_menu_image.AddImage(_skin->borders[1][1], left_border_size + top_width * tile_x, 0.0f);
536 	}
537 
538 	// Iterate from bottom to top and fill in the vertical borders
539 	for (int32 tile_y = 0; tile_y < inum_y_tiles; ++tile_y) {
540 		if (_edge_visible_flags & VIDEO_MENU_EDGE_LEFT)
541 			_menu_image.AddImage(_skin->borders[1][0], 0.0f, bottom_border_size + left_height * tile_y);
542 		else if (!background_loaded)
543 			_menu_image.AddImage(_skin->borders[1][1], 0.0f, bottom_border_size + left_height * tile_y);
544 
545 		if (_edge_visible_flags & VIDEO_MENU_EDGE_RIGHT)
546 			_menu_image.AddImage(_skin->borders[1][2], max_x, bottom_border_size + left_height * tile_y);
547 		else if (!background_loaded)
548 			_menu_image.AddImage(_skin->borders[1][1], max_x, bottom_border_size + left_height * tile_y);
549 	}
550 
551 	return true;
552 }
553 
554 }  // namespace hoa_gui
555