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 /** ****************************************************************************
11 *** \file    option.h
12 *** \author  Raj Sharma, roos@allacrost.org
13 *** \brief   Header file for OptionBox GUI control and supporting classes
14 ***
15 *** OptionBox is a type of GUI control that allows you to create several
16 *** option choices, which the player can select from by using the arrow keys.
17 *** ***************************************************************************/
18 
19 #ifndef __OPTION_HEADER__
20 #define __OPTION_HEADER__
21 
22 #include "defs.h"
23 #include "utils.h"
24 
25 #include "gui.h"
26 #include "system.h"
27 
28 namespace hoa_gui {
29 
30   //! [phuedx] Should these constants not be in a core settings file?
31 
32 //! \brief The number of milliseconds that the menu cursor blinks when in the blinking state
33 const int32 VIDEO_CURSOR_BLINK_RATE = 40;
34 
35 //! \brief The number of milliseconds it takes to scroll when the cursor goes past the end of an option box
36 const int32 VIDEO_OPTION_SCROLL_TIME = 100;
37 
38 //! \brief These are the types of events that an option box can generate
39 enum OptionBoxEvent {
40 	VIDEO_OPTION_INVALID          = -1,
41 	//! The selected option changed
42 	VIDEO_OPTION_SELECTION_CHANGE =  0,
43 	//! The player confirmed a selection
44 	VIDEO_OPTION_CONFIRM          =  1,
45 	//! The player pressed the cancel key
46 	VIDEO_OPTION_CANCEL           =  2,
47 	//! Two options were switched by the player
48 	VIDEO_OPTION_SWITCH           =  3,
49 	//! The player tried to exceed the top most option
50 	VIDEO_OPTION_BOUNDS_UP        =  4,
51 	//! The player tried to exceed the bottom most option
52 	VIDEO_OPTION_BOUNDS_DOWN      =  5,
53 	//! The player tried to exceed the left most option
54 	VIDEO_OPTION_BOUNDS_LEFT      =  6,
55 	//! The player tried to exceed the right most option
56 	VIDEO_OPTION_BOUNDS_RIGHT     =  7,
57 	VIDEO_OPTION_TOTAL            =  8
58 };
59 
60 
61 //! \brief Type identifiers for options, whether the option is text, an image, or an align flag
62 enum OptionElementType {
63 	VIDEO_OPTION_ELEMENT_INVALID      = -1,
64 	//! Identifies mark-up for left alignment
65 	VIDEO_OPTION_ELEMENT_LEFT_ALIGN   =  0,
66 	//! Identifies mark-up for center alignment
67 	VIDEO_OPTION_ELEMENT_CENTER_ALIGN =  1,
68 	//! Identifies mark-up for right alignment
69 	VIDEO_OPTION_ELEMENT_RIGHT_ALIGN  =  2,
70 	//! Identifies the position tag
71 	VIDEO_OPTION_ELEMENT_POSITION     =  3,
72 	//! Represents option images
73 	VIDEO_OPTION_ELEMENT_IMAGE        =  4,
74 	//! Represents option text
75 	VIDEO_OPTION_ELEMENT_TEXT         =  5,
76 	VIDEO_OPTION_ELEMENT_TOTAL        =  6
77 };
78 
79 
80 //! \brief For representing the visual state of the menu cursor
81 enum CursorState {
82 	VIDEO_CURSOR_STATE_INVALID  = -1,
83 	//! Hides the cursor so it is not drawn on the screen
84 	VIDEO_CURSOR_STATE_HIDDEN   =  0,
85 	//! Shows the cursor next to the selected option
86 	VIDEO_CURSOR_STATE_VISIBLE  =  1,
87 	//! Causes the cursor to continuously blink
88 	VIDEO_CURSOR_STATE_BLINKING =  2,
89 	VIDEO_CURSOR_STATE_TOTAL    =  3
90 };
91 
92 
93 //! \brief Modes to control how the cursor wraps around when the cursor exceeds the list boundary
94 enum WrapMode {
95 	VIDEO_WRAP_MODE_INVALID  = -1,
96 	//! Cursor retains its position on the list boundary
97 	VIDEO_WRAP_MODE_NONE     =  0,
98 	//! Cursor wraps around left to right, top to bottom, when exceeding the boundary
99 	VIDEO_WRAP_MODE_STRAIGHT =  1,
100 	//! Similar to straight, but the cursor will move one row or column when it exceeds a column or row boundary
101 	VIDEO_WRAP_MODE_SHIFTED  =  2,
102 	VIDEO_WRAP_MODE_TOTAL    =  3
103 };
104 
105 
106 //! \brief These select modes control how confirming works when you choose options
107 enum SelectMode {
108 	VIDEO_SELECT_INVALID = -1,
109 	//! Options only require a single confirmation
110 	VIDEO_SELECT_SINGLE  =  0,
111 	//! The first confirmation highlights the item, and the second confirms it.
112 	//! \note If you press confirm on one item and confirm again on a different item, the two items get switched.
113 	VIDEO_SELECT_DOUBLE  =  1,
114 	VIDEO_SELECT_TOTAL   =  2
115 };
116 
117 enum HORIZONTAL_ARROWS_POSITION {
118   H_POSITION_INVALID = -1,
119   H_POSITION_BOTTOM = 0,
120   H_POSITION_MIDDLE = 1,
121   H_POSITION_TOP = 2,
122   H_POSITION_TOTAL = 3
123 };
124 
125 enum VERTICAL_ARROWS_POSITION {
126   V_POSITION_INVALID = -1,
127   V_POSITION_LEFT = 0,
128   V_POSITION_CENTER = 1,
129   V_POSITION_RIGHT = 2,
130   V_POSITION_TOTAL = 3
131 };
132 
133 
134 namespace private_gui {
135 
136 /** \name Option Tag Constants
137 *** These constants are used in option format strings to parse the text
138 *** and construct the options from that text.
139 **/
140 //@{
141 const uint16 OPEN_TAG     = static_cast<uint16>('<');
142 const uint16 END_TAG      = static_cast<uint16>('>');
143 const uint16 LEFT_TAG1    = static_cast<uint16>('l');
144 const uint16 CENTER_TAG1  = static_cast<uint16>('c');
145 const uint16 RIGHT_TAG1   = static_cast<uint16>('r');
146 const uint16 LEFT_TAG2    = static_cast<uint16>('L');
147 const uint16 CENTER_TAG2  = static_cast<uint16>('C');
148 const uint16 RIGHT_TAG2   = static_cast<uint16>('R');
149 //@}
150 
151 
152 /** ****************************************************************************
153 *** \brief A class which encapsulates the various contents of an option.
154 ***
155 *** Contents can include text, images, mark-up tags, etc.
156 ***
157 *** \todo Store the element content in here as well instead of in the Option
158 *** class. Will require multiple derived classes for images, text, alignment
159 *** flags, etc. Text should also be stored as rendered text images
160 *** ***************************************************************************/
161 class OptionElement {
162 public:
163 	//! \brief A type indentifier for determining what this option represents
164 	OptionElementType type;
165 
166 	//! \brief A simple integer value used for various purposes such as offsets
167 	int32 value;
168 };
169 
170 
171 /** ****************************************************************************
172 *** \brief Holds the bound coordinates for a particular "cell" in an option box.
173 ***
174 *** This is used for calculations when drawing an option box
175 *** ***************************************************************************/
176 class OptionCellBounds {
177 public:
178 
179 	//! \brief The y coordinate for the top, bottom, and center of the cell
180 	float y_top, y_center, y_bottom;
181 
182 	//! \brief The x coordinate for the left, right, and center of the cell
183 	float x_left, x_center, x_right;
184 };
185 
186 
187 /** ****************************************************************************
188 *** \brief Represents one particular option in a list and all its elements
189 ***
190 *** For example in a shop menu, one option might be "Mythril Knife" and contain
191 *** an icon of a knife, the text "Mythril Knife", a right alignment flag, and
192 *** finally the text "500 drunes".
193 ***
194 *** \todo Text should contain rendered text images instead of text that needs
195 *** to be rendered and drawn every frame
196 ***
197 *** \todo Add support for animated images? (Low priority task)
198 *** ***************************************************************************/
199 class Option {
200 public:
201 	Option();
202 
203 	~Option();
204 
205 	Option(const Option& copy);
206 
207 	Option& operator=(const Option& copy);
208 
209 	//! \brief Deletes all data maintained by the object
210 	void Clear();
211 
212 	//! \brief A flag to specify whether this option is disabled or not
213 	bool disabled;
214 
215 	//! \brief The elements that this option is composed of
216 	std::vector<OptionElement> elements;
217 
218 	//! \brief Contains all pieces of text for this option
219 	std::vector<hoa_utils::ustring> text;
220 
221 	//! \brief Contains all images used for this option
222 	hoa_video::StillImage* image;
223 }; // class Option
224 
225 } // namespace private_video
226 
227 
228 /** ****************************************************************************
229 *** \brief Represents rows and columns of options that the player may select
230 ***
231 *** The OptionBox control is used for presenting the player with several choices,
232 *** of actions to take, wares to buy, etc.
233 ***
234 *** Scrolling feature now supported.
235 ***
236 *** Contains support for drawing scroll arrows on the option box to indicate
237 *** additional options that are not currently in view
238 ***
239 *** \todo Allow the user to set an arbitrary cursor blink rate and scroll rate
240 ***
241 *** \todo Support multiple forms of scroll animations.
242 *** (This should be considered a low priority task, if dealt with at all.)
243 *** ***************************************************************************/
244 class OptionBox : public private_gui::GUIControl {
245 public:
246 	OptionBox();
247 
~OptionBox()248 	~OptionBox()
249 		{}
250 
251 	/** \brief Updates any blinking or scrolling effects for the option box
252 	*** \param frame_time The number of milliseconds elapsed this frame
253 	*** This method also resets any registered events, allowing new events
254 	*** to be processed by the option box. Therefore it is recommended that
255 	*** this method be called on every frame while it is active.
256 	**/
257 	void Update(uint32 frame_time = hoa_system::SystemManager->GetUpdateTime());
258 
259 	//! \brief Draws each enabled option to the screen
260 	void Draw();
261 
262 	/** \brief Sets the visible dimensions, 2D data structure, and visible data layout
263 	*** \param width The width to set for the entire option box
264 	*** \param height The height to set for the entire option box
265 	*** \param num_cols The number of columns of options (should be non-zero)
266 	*** \param num_rows The number of rows of options (should be non-zero)
267 	*** \param cell_cols The number of columns of cells that should be visible in the display area (should be non-zero)
268 	*** \param cell_rows The number of rows of cells that should be visible in the display area (should be non-zero)
269 	***
270 	*** These settings will determine the size of each cell. Cell size is computed as (width/cell_cols), (height/cell_rows).
271 	*** The num_cols and num_rows must be greater than or equal to visible_rows and visible_cols. This requirement is necessary
272 	*** because it is silly to try to represent a structure of 2 columns and 2 rows in a layout of 4 columns and 4 rows. Failure
273 	*** to observe this requirement will result in no changes being made by this function.
274 	**/
275 	void SetDimensions(float width, float height, uint8 num_cols, uint8 num_rows, uint8 cell_cols, uint8 cell_rows);
276 
277 	/** \brief Sets the options to display in this option box
278 	*** \param option_text A vector of unicode strings which contain the text for each item, along with any formatting tags
279 	*** \note Calling this function will clear any current options
280 	***
281 	*** If any single option contains formatting errors, then the entire set of options will not be added.
282 	*** Example of an option with formatting: "<img/weapons/mythril.png>Mythril knife<r>500 drunes"
283 	**/
284 	void SetOptions(const std::vector<hoa_utils::ustring>& option_text);
285 
286 	//! \brief Removes all options and their allocated data from the OptionBox
287 	void ClearOptions();
288 
289 	/** \brief Adds a blank new option to the OptionBox
290 	*** The option added is an empty string. Invoke the various AddOptionElement*() methods to construct the option after this call.
291 	**/
292 	void AddOption();
293 
294 	/** \brief Adds a new option to the OptionBox
295 	*** \param text The formatting text for the new option
296 	*** The option will not be added if it contained formatting errors.
297 	**/
298 	void AddOption(const hoa_utils::ustring &text);
299 
300 	/** \brief Appends a text string element to an existing option
301 	*** \param option_index The index of the option to append the text element to
302 	*** \param text The unicode string to add to the text
303 	*** \note This string is treated as pure text and formatting options embedded in the string will
304 	*** <b>not</b> be processed by this function.
305 	**/
306 	void AddOptionElementText(uint32 option_index, const hoa_utils::ustring& text);
307 
308 	/** \brief Appends an image element to an existing option
309 	*** \param option_index The index of the option to append the image element to
310 	*** \param filename The name of the image file to load for use in this option
311 	**/
312 	void AddOptionElementImage(uint32 option_index, std::string& image_filename);
313 
314 	/** \brief Appends an image element to an existing option
315 	*** \param option_index The index of the option to append the image element to
316 	*** \param image A pointer to the image to create a copy of for the option (must be non-NULL)
317 	**/
318 	void AddOptionElementImage(uint32 option_index, const hoa_video::StillImage* image);
319 
320 	/** \brief Appends an alignment element to an existing option
321 	*** \param option_index The index of the option to append the alignment element to
322 	*** \param postion_type The only valid values for this argument are: VIDEO_OPTION_ELEMENT_LEFT_ALIGN,
323 	*** VIDEO_OPTION_ELEMENT_CENTER_ALIGN, and VIDEO_OPTION_ELEMENT_RIGHT_ALIGN. All other values will be
324 	*** ignored.
325 	**/
326 	void AddOptionElementAlignment(uint32 option_index, OptionElementType position_type);
327 
328 	/** \brief Changes the stored information of a particular option
329 	*** \param index The index of the option to change
330 	*** \param text The text to change the option to
331 	*** \return False if the option text could not be changed
332 	**/
333 	bool SetOptionText(uint32 index, const hoa_utils::ustring &text);
334 
335 	/** \brief Sets the currently selected option (0 to # of options - 1)
336 	*** \param index The desired selection index in the list of options
337 	*** You should not call this method until after options have been added.
338 	*** If no options are currently stored when this method is called, the
339 	*** method will print a warning message and return.
340 	**/
341 	void SetSelection(uint32 index);
342 
343 	/** \brief Enables or disables the option located at a specified index
344 	*** \param index The index of the option to enable or disable
345 	*** \param enable Set to true to enable, false to disable
346 	**/
347 	void EnableOption(uint32 index, bool enable);
348 
349 	/** \brief Determines if an option is enabled or not
350 	*** \param index The index of the option in the list to check
351 	*** \return True if the option is enabled, false if it is not
352 	**/
353 	bool IsOptionEnabled(uint32 index);
354 
355 	/** \brief Returns true if the given option is enabled
356 	*** \param index The index of the option to check
357 	*** \return True if option is enabled, false if it's not
358 	**/
359 	bool IsEnabled(uint32 index) const;
360 
361 	/** \brief Retrieves a pointer to the image embedded within the option
362 	*** \param index The index of the option to retrieve the image
363 	*** \return NULL if the index is invalid or the option does not embed an image, otherwise a valid pointer to a StillImage
364 	**/
365 	hoa_video::StillImage* GetEmbeddedImage(uint32 index) const;
366 
367 	/** \brief Used to determine whether the option box is initialized and ready for use
368 	*** \param error_messages Used to report the list of reasons why the option box is not initialized
369 	*** \return True if the option box is initialized, false if it is not
370 	**/
371 	bool IsInitialized(std::string& error_messages);
372 
373 	/** \name Input Processing Methods
374 	*** \brief Processes the input commands for moving the cursor, selecting options, etcetra
375 	**/
376 	//@{
377 	void InputConfirm();
378 	void InputCancel();
379 	void InputUp();
380 	void InputDown();
381 	void InputLeft();
382 	void InputRight();
383 	//@}
384 
385 	//! \name Member Access Functions
386 	//@{
387 	/** \brief Sets the alignment of the option text and cursor
388 	*** \param xalign Left/center/right alignment of text in the cell
389 	*** \param yalign Top/center/bottom alignment of text in the cell
390 	**/
SetOptionAlignment(int32 xalign,int32 yalign)391 	void SetOptionAlignment(int32 xalign, int32 yalign)
392 		{ _option_xalign = xalign; _option_yalign = yalign; _initialized = IsInitialized(_initialization_errors); }
393 
394 	/** \brief Sets the option selection mode (single or double confirm)
395 	*** \param mode The selection mode to be set
396 	**/
SetSelectMode(SelectMode mode)397 	void SetSelectMode(SelectMode mode)
398 		{ _selection_mode = mode; _initialized = IsInitialized(_initialization_errors); }
399 
400 	/** \brief Sets the behavior for vertical wrapping of the cursor
401 	*** \param mode The vertical wrap behavior to set
402 	**/
SetVerticalWrapMode(WrapMode mode)403 	void SetVerticalWrapMode(WrapMode mode)
404 		{ _vertical_wrap_mode = mode; }
405 
406 	/** \brief Sets the behavior for horizontal wrapping of the cursor
407 	*** \param mode The horizontal wrap behavior to set
408 	**/
SetHorizontalWrapMode(WrapMode mode)409 	void SetHorizontalWrapMode(WrapMode mode)
410 		{ _horizontal_wrap_mode = mode; }
411 
412 	/** \brief Enables or disables the ability to switch the location of two options
413 	*** \param enable True enables switching, false disables it
414 	*** \note Switching is disabled by default
415 	**/
SetEnableSwitching(bool enable)416 	void SetEnableSwitching(bool enable)
417 		{ _enable_switching = enable; }
418 
419 	/** \brief Sets the cursor offset relative to the text position
420 	*** \param x Horizontal offset (the sign determines whether its left or right)
421 	*** \param y Vertical offset (the sign determines whether its up or down)
422 	**/
SetCursorOffset(float x,float y)423 	void SetCursorOffset(float x, float y)
424 		{ _cursor_xoffset = x; _cursor_yoffset = y; }
425 
426 	/** \brief Sets the text style to use for this textbox.
427 	*** \param style The style intended \see #TextStyle
428 	**/
429 	void SetTextStyle(const hoa_video::TextStyle& style);
430 
431 	/** \brief Sets the state of the cursor icon
432 	*** \param state The cursor state to set
433 	**/
434 	void SetCursorState(CursorState state);
435 
436 	/** \brief Sets the horizontal arrows position
437 	*** \param position The position to set
438 	**/
439 	void SetHorizontalArrowsPosition(HORIZONTAL_ARROWS_POSITION position);
440 
441 	/** \brief Sets the vertical arrows position
442 	*** \param position The position to set
443 	**/
444 	void SetVerticalArrowsPosition(VERTICAL_ARROWS_POSITION position);
445 
446 	/** \brief Checks if the option box is in the process of scrolling
447 	*** \return True if the option box is scrolling, false if it is not
448 	**/
IsScrolling()449 	bool IsScrolling() const
450 		{ return _scrolling; }
451 
452 	/** \brief Retreives an event that has occurred, or zero if no event occurred.
453 	*** \return An integer int representing an option box event (i.e. cancel, confirm, left, right, etc.)
454 	*** \note Calling the Update() method will clear any registered events
455 	**/
GetEvent()456 	int32 GetEvent()
457 		{ return _event; }
458 
459 	/** \brief Returns the index of the currently selected option
460 	*** \return The current selection index, or -1 if nothing is selected
461 	**/
GetSelection()462 	int32 GetSelection() const
463 		{ return _selection; }
464 
465 	//! \brief Returns the number of rows of options
GetNumberRows()466 	int32 GetNumberRows() const
467 		{ return _number_rows; }
468 
469 	//! \brief Returns the number of columns of options
GetNumberColumns()470 	int32 GetNumberColumns() const
471 		{ return _number_columns; }
472 
473 	//! \brief Retreives the number of options in the option box
GetNumberOptions()474 	uint32 GetNumberOptions() const
475 		{ return _options.size(); }
476 	//@}
477 
478 	/** \brief Used to enable scissoring of the option box
479 	*** \param enable Set to true to enable, or false to disable
480 	*** \param owner Set to true to scissor to the _owner's size, or false to scissor to the box's size
481 	**/
Scissoring(bool enable,bool owner)482 	void Scissoring( bool enable, bool owner )
483 		{ _scissoring = enable; _scissoring_owner = owner; }
484 
485 private:
486 	//! \brief When set to true, indicates that the option box is initialized and ready to be used
487 	bool _initialized;
488 
489 	//! \name Option Property Members
490 	//@{
491 	/** \brief The vector containing all of the options
492 	*** This 1D structure represents a 2D array of options. For an option box with 2 rows and 3 columns,
493 	*** the first 3 elements would contain the contents of the 1st row (left to right) and the last 3
494 	*** elements would contain the second row.
495 	**/
496 	std::vector<private_gui::Option> _options;
497 
498 	//! \brief The total number of rows and columns of data represented by the box
499 	int32 _number_rows, _number_columns;
500 
501 	//! \brief How many rows and columns of cells can fit in the option box dimensions
502 	int32 _number_cell_rows, _number_cell_columns;
503 
504 	//! \brief The dimenions of each cell within the option box
505 	float _cell_width, _cell_height;
506 
507 	//! \brief The selection mode for the option box (ie single or double confirm selection)
508 	SelectMode _selection_mode;
509 
510 	//! \brief The wrapping modes used for horizontal and vertical cursor movement
511 	WrapMode _horizontal_wrap_mode, _vertical_wrap_mode;
512 
513 	//! \brief When set to true, the user may switch the locations of two different options
514 	bool _enable_switching;
515 	//@}
516 
517 	//! \name Drawing Related Members
518 	//@{
519 	//! \brief The text style that the options should be rendered in
520 	hoa_video::TextStyle _text_style;
521 
522 	//! \brief The column of row of data that is drawn in the top-left cell
523 	uint32 _draw_left_column, _draw_top_row;
524 
525 	//! \brief Retains the x and y offsets for where the cursor should be drawn relative to the selected option
526 	float _cursor_xoffset, _cursor_yoffset;
527 
528 	//! \brief A draw offset used for the option box when it is scrolling
529 	int32 _scroll_offset;
530 
531 	//! \brief The horizontal alignment type for option cell contents
532 	int32 _option_xalign;
533 
534 	//! \brief The vertical alignment type for option cell contents
535 	int32 _option_yalign;
536 
537 	//! \brief True if scissoring is enabled
538 	bool _scissoring;
539 
540 	//! \brief True if scissoring should be applied according to the owner window, false for the box's size
541 	bool _scissoring_owner;
542 
543 	//! \brief When true the scroll arrows for the horizontal and vertical directions will be drawn
544 	bool _draw_horizontal_arrows, _draw_vertical_arrows;
545 
546 	//! \brief When true the scroll arrows in these directions will be drawn with the grey arrow
547 	bool _grey_up_arrow, _grey_down_arrow, _grey_left_arrow, _grey_right_arrow;
548 	//@}
549 
550 	//! \name Active State Members
551 	//@{
552 	//! \brief Holds the most recent OptionBox event that occurred
553 	int32 _event;
554 
555 	//! \brief The index of the currently selected option
556 	int32 _selection;
557 
558 	/** \brief The first selection that the player made when in double-confirm selection mode
559 	*** \note This is set to -1 when no first selection has been made
560 	**/
561 	int32 _first_selection;
562 
563 	//! \brief The current cursor state (blinking, visible, hidden, etc)
564 	CursorState _cursor_state;
565 
566 	//! \brief Used for the blinking cursor feature. When false, the cursor will not be drawn.
567 	bool _blink;
568 
569 	//! \brief The timer used for controlling the cursor blinking rate
570 	int32 _blink_time;
571 
572 	//! \brief Set to true if the box is currently in the middle of scrolling
573 	bool _scrolling;
574 
575 	//! \brief The timer used for controlling option scrolling
576 	int32 _scroll_time;
577 
578 	//! \brief Indicates the scrolling direction; 1 for down or -1 for up
579 	int32 _scroll_direction;
580 
581 	//! \brief The position of the horizontal scroll arrows
582 	HORIZONTAL_ARROWS_POSITION _horizontal_arrows_position;
583 
584 	//! \brief The position of the vertical scroll arrows
585 	VERTICAL_ARROWS_POSITION _vertical_arrows_position;
586 
587 	//@}
588 
589 	// ---------- Private methods
590 
591 	/** \brief helper function to parse text for an option box, and fill an Option structure
592 	*** \param format_string the formatted string, using the XML structure described by SetOptions()
593 	*** \param option which option the string corresponds to
594 	*** \return True if the option was successfully constructed from the string, or false if there was an error.
595 	**/
596 	bool _ConstructOption(const hoa_utils::ustring &format_string, private_gui::Option &option);
597 
598 	/** \brief Changes the selected option by making a movement relative to the current selection
599 	*** \param offset The amount to move in specified direction (ie 1 row up, 1 column right, etc.)
600 	*** \param horizontal true if moving horizontally, false if moving vertically
601 	*** \return False if the selection does not change
602 	**/
603 	bool _ChangeSelection(int32 offset, bool horizontal);
604 
605 	/** \brief Sets draw flags and determines the x and y coordinates for rendering an option inside a cell
606 	*** \param xalign The x alignement for the cell contents
607 	*** \param yalign The y alignement for the cell contents
608 	*** \param bounds The boundary coordinates for the option cell
609 	*** \param x A reference to return the x position for the cursor
610 	*** \param y A reference to return the y position for the cursor
611 	***
612 	*** This function also moves the draw cursor to the position specified by the alignment and the cell boundaries.
613 	**/
614 	void _SetupAlignment(int32 xalign, int32 yalign, const private_gui::OptionCellBounds& bounds, float& x, float& y);
615 
616 	/** \brief Calling this method will re-examine which scroll arrow boolean members need to be set
617 	*** This should be called whenever the data or cell columns/rows changed, whenever the selection in changed,
618 	*** and in general whenever the viewable contents of the option box are changed.
619 	**/
620 	void _DetermineScrollArrows();
621 
622 	/** \brief Draws a single option cell
623 	*** \param op The option contents to draw within the cell
624 	*** \param bounds The boundary coordinates for the information cell
625 	*** \param scroll_offset A draw offset for when the option box is in the process of scrolling from one option to another
626 	*** \param left_edge Returns a coordinate that represents the left edge of the cell content (as opposed to strictly the cell boundary)
627 	**/
628 	void _DrawOption(const private_gui::Option& op, const private_gui::OptionCellBounds &bounds, float cell_offset, float &left_edge);
629 
630 	/** \brief Draws the cursor
631 	*** \param op The option contents to draw within the cell
632 	*** \param bounds The boundary coordinates for the information cell
633 	*** \param scroll_offset A draw offset for when the option box is in the process of scrolling from one option to another
634 	*** \param left_edge A draw coordiante that represents the left edge of the cell content (as opposed to strictly the cell boundary)
635 	*** \param darken If true, the cursor image will be drawn with a 50% alpha black color applied
636 	***
637 	*** This method should be called immediately proceeding the _DrawOption method so that it can retrieve the correct value for left_edge
638 	*** from the cell which should have a cursor drawn.
639 	**/
640 	void _DrawCursor(const private_gui::OptionCellBounds &bounds, float cell_offset, float left_edge, bool darken);
641 
642 	//! \brief Draws an outline of the option box and the inner cell boundaries
643 	void _DEBUG_DrawOutline();
644 }; // class OptionBox : public private_video::GUIControl
645 
646 } // namespace hoa_gui
647 
648 #endif  // __OPTION_HEADER__
649