refactored menu class into its own source file

This commit is contained in:
Dave White 2003-10-11 00:30:46 +00:00
parent edb9436fa7
commit 839eac713c
21 changed files with 420 additions and 347 deletions

View File

@ -8,7 +8,7 @@ SDL_CFLAGS=`sdl-config --cflags` `freetype-config --cflags`
SDL_LIBS=`sdl-config --libs` `freetype-config --libs` -lSDL_mixer -lSDL_ttf -lSDL_image -lSDL_net
LIBS=${SDL_LIBS} -lstdc++
INCLUDES=-I. -Isrc -Isrc/tools -Isrc/widgets
OBJS=src/actions.o src/ai.o src/ai_attack.o src/ai_move.o src/config.o src/dialogs.o src/display.o src/filesystem.o src/font.o src/game.o src/game_config.o src/game_events.o src/gamestatus.o src/hotkeys.o src/intro.o src/key.o src/language.o src/log.o src/map.o src/menu.o src/multiplayer.o src/network.o src/pathfind.o src/playlevel.o src/playturn.o src/preferences.o src/replay.o src/sdl_utils.o src/sound.o src/team.o src/terrain.o src/tooltips.o src/unit.o src/unit_types.o src/video.o src/widgets/button.o src/widgets/slider.o src/widgets/textbox.o
OBJS=src/actions.o src/ai.o src/ai_attack.o src/ai_move.o src/config.o src/dialogs.o src/display.o src/filesystem.o src/font.o src/game.o src/game_config.o src/game_events.o src/gamestatus.o src/hotkeys.o src/intro.o src/key.o src/language.o src/log.o src/map.o src/multiplayer.o src/network.o src/pathfind.o src/playlevel.o src/playturn.o src/preferences.o src/replay.o src/sdl_utils.o src/show_dialog.o src/sound.o src/team.o src/terrain.o src/tooltips.o src/unit.o src/unit_types.o src/video.o src/widgets/button.o src/widgets/menu.o src/widgets/slider.o src/widgets/textbox.o
MAKE_TRANS_OBJS=src/tools/make_translation.o src/config.o src/filesystem.o src/log.o
MERGE_TRANS_OBJS=src/tools/merge_translations.o src/config.o src/filesystem.o src/log.o

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -17,11 +17,11 @@
#include "dialogs.hpp"
#include "game_config.hpp"
#include "log.hpp"
#include "menu.hpp"
#include "pathfind.hpp"
#include "playlevel.hpp"
#include "playturn.hpp"
#include "replay.hpp"
#include "show_dialog.hpp"
#include <iostream>

View File

@ -15,7 +15,7 @@
#include "actions.hpp"
#include "display.hpp"
#include "menu.hpp"
#include "show_dialog.hpp"
namespace dialogs
{

View File

@ -19,9 +19,9 @@
#include "hotkeys.hpp"
#include "language.hpp"
#include "log.hpp"
#include "menu.hpp"
#include "preferences.hpp"
#include "sdl_utils.hpp"
#include "show_dialog.hpp"
#include "sound.hpp"
#include "tooltips.hpp"
#include "util.hpp"

View File

@ -25,13 +25,13 @@
#include "gamestatus.hpp"
#include "key.hpp"
#include "language.hpp"
#include "menu.hpp"
#include "multiplayer.hpp"
#include "network.hpp"
#include "pathfind.hpp"
#include "playlevel.hpp"
#include "preferences.hpp"
#include "replay.hpp"
#include "show_dialog.hpp"
#include "sound.hpp"
#include "team.hpp"
#include "unit_types.hpp"
@ -153,8 +153,14 @@ int play_game(int argc, char** argv)
for(int arg = 1; arg != argc; ++arg) {
const std::string val(argv[arg]);
if(val.empty()) {
continue;
}
if(val == "--windowed" || val == "-w") {
preferences::set_fullscreen(false);
} else if(val == "--fullscreen" || val == "-f") {
preferences::set_fullscreen(true);
} else if(val == "--test" || val == "-t") {
test_mode = true;
} else if(val == "--debug" || val == "-d") {
@ -162,9 +168,14 @@ int play_game(int argc, char** argv)
} else if(val == "--help" || val == "-h") {
std::cout << "usage: " << argv[0]
<< " [options] [data-directory]\n";
return 0;
} else if(val == "--version" || val == "-v") {
std::cout << "Battle for Wesnoth " << game_config::version
<< "\n";
return 0;
} else if(val[0] == '-') {
std::cerr << "unknown option: " << val << "\n";
return 0;
} else {
if(!is_directory(val)) {
std::cerr << "Could not find directory '" << val << "'\n";

View File

@ -11,10 +11,10 @@
See the COPYING file for more details.
*/
#include "game_events.hpp"
#include "menu.hpp"
#include "language.hpp"
#include "playlevel.hpp"
#include "replay.hpp"
#include "show_dialog.hpp"
#include "sound.hpp"
#include "util.hpp"

View File

@ -13,9 +13,9 @@
#include "config.hpp"
#include "hotkeys.hpp"
#include "language.hpp"
#include "menu.hpp"
#include "playlevel.hpp"
#include "preferences.hpp"
#include "show_dialog.hpp"
#include "video.hpp"
#include <algorithm>

View File

@ -14,7 +14,7 @@
#include "intro.hpp"
#include "key.hpp"
#include "language.hpp"
#include "menu.hpp"
#include "show_dialog.hpp"
#include "widgets/button.hpp"
#include <cstdlib>

View File

@ -13,11 +13,11 @@
#include "language.hpp"
#include "log.hpp"
#include "menu.hpp"
#include "multiplayer.hpp"
#include "network.hpp"
#include "playlevel.hpp"
#include "replay.hpp"
#include "show_dialog.hpp"
#include <iostream>
#include <sstream>

View File

@ -21,8 +21,8 @@
#include "game_config.hpp"
#include "gamestatus.hpp"
#include "key.hpp"
#include "menu.hpp"
#include "pathfind.hpp"
#include "show_dialog.hpp"
#include "team.hpp"
#include "unit_types.hpp"
#include "unit.hpp"

View File

@ -22,8 +22,8 @@
#include "game_events.hpp"
#include "gamestatus.hpp"
#include "key.hpp"
#include "menu.hpp"
#include "pathfind.hpp"
#include "show_dialog.hpp"
#include "team.hpp"
#include "unit_types.hpp"
#include "unit.hpp"

View File

@ -14,8 +14,8 @@
#include "font.hpp"
#include "hotkeys.hpp"
#include "language.hpp"
#include "menu.hpp"
#include "preferences.hpp"
#include "show_dialog.hpp"
#include "sound.hpp"
#include "util.hpp"
#include "widgets/button.hpp"

View File

@ -17,11 +17,11 @@
#include "dialogs.hpp"
#include "game_config.hpp"
#include "log.hpp"
#include "menu.hpp"
#include "pathfind.hpp"
#include "playlevel.hpp"
#include "playturn.hpp"
#include "replay.hpp"
#include "show_dialog.hpp"
#include <cstdio>
#include <cstdlib>

View File

@ -10,16 +10,18 @@
See the COPYING file for more details.
*/
#include "config.hpp"
#include "font.hpp"
#include "language.hpp"
#include "menu.hpp"
#include "playlevel.hpp"
#include "show_dialog.hpp"
#include "language.hpp"
#include "sdl_utils.hpp"
#include "tooltips.hpp"
#include "util.hpp"
#include "widgets/button.hpp"
#include "widgets/menu.hpp"
#include "widgets/textbox.hpp"
#include <iostream>
@ -171,336 +173,6 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h,
} //end namespace gui
namespace {
const size_t max_menu_items = 18;
const size_t menu_font_size = 16;
const size_t menu_cell_padding = 10;
class menu
{
display* display_;
int x_, y_;
std::vector<std::vector<std::string> > items_;
mutable std::vector<int> column_widths_;
scoped_sdl_surface buffer_;
int selected_;
bool click_selects_;
bool previous_button_;
bool drawn_;
mutable int height_;
mutable int width_;
mutable int first_item_on_screen_;
gui::button uparrow_, downarrow_;
const std::vector<int>& column_widths() const
{
if(column_widths_.empty()) {
for(size_t row = 0; row != items_.size(); ++row) {
for(size_t col = 0; col != items_[row].size(); ++col) {
static const SDL_Rect area =
{0,0,display_->x(),display_->y()};
const SDL_Rect res =
font::draw_text(NULL,area,menu_font_size,
font::NORMAL_COLOUR,items_[row][col],x_,y_);
if(col == column_widths_.size()) {
column_widths_.push_back(res.w + menu_cell_padding);
} else if(res.w > column_widths_[col] - menu_cell_padding) {
column_widths_[col] = res.w + menu_cell_padding;
}
}
}
}
return column_widths_;
}
void draw_item(int item) {
SDL_Rect rect = get_item_rect(item);
if(rect.w == 0)
return;
if(buffer_.get() != NULL) {
const int ypos = items_start()+(item-first_item_on_screen_)*rect.h;
SDL_Rect srcrect = {0,ypos,rect.w,rect.h};
SDL_BlitSurface(buffer_,&srcrect,
display_->video().getSurface(),&rect);
}
gui::draw_solid_tinted_rectangle(x_,rect.y,width(),rect.h,
item == selected_ ? 150:0,0,0,
item == selected_ ? 0.6 : 0.2,
display_->video().getSurface());
SDL_Rect area = {0,0,display_->x(),display_->y()};
const std::vector<int>& widths = column_widths();
int xpos = rect.x;
for(size_t i = 0; i != items_[item].size(); ++i) {
font::draw_text(display_,area,menu_font_size,font::NORMAL_COLOUR,
items_[item][i],xpos,rect.y);
xpos += widths[i];
}
}
void draw() {
drawn_ = true;
for(size_t i = 0; i != items_.size(); ++i)
draw_item(i);
display_->video().flip();
}
int hit(int x, int y) const {
if(x > x_ && x < x_ + width() && y > y_ && y < y_ + height()){
for(size_t i = 0; i != items_.size(); ++i) {
const SDL_Rect& rect = get_item_rect(i);
if(y > rect.y && y < rect.y + rect.h)
return i;
}
}
return -1;
}
mutable std::map<int,SDL_Rect> itemRects_;
SDL_Rect get_item_rect(int item) const
{
const SDL_Rect empty_rect = {0,0,0,0};
if(item < first_item_on_screen_ ||
size_t(item) >= first_item_on_screen_ + max_menu_items) {
return empty_rect;
}
const std::map<int,SDL_Rect>::const_iterator i = itemRects_.find(item);
if(i != itemRects_.end())
return i->second;
int y = y_ + items_start();
if(item != first_item_on_screen_) {
const SDL_Rect& prev = get_item_rect(item-1);
y = prev.y + prev.h;
}
static const SDL_Rect area = {0,0,display_->x(),display_->y()};
SDL_Rect res = font::draw_text(NULL,area,menu_font_size,
font::NORMAL_COLOUR,items_[item][0],x_,y);
res.w = width();
//only insert into the cache if the menu's co-ordinates have
//been initialized
if(x_ > 0 && y_ > 0)
itemRects_.insert(std::pair<int,SDL_Rect>(item,res));
return res;
}
int items_start() const
{
if(items_.size() > max_menu_items)
return uparrow_.height();
else
return 0;
}
int items_end() const
{
if(items_.size() > max_menu_items)
return height() - downarrow_.height();
else
return height();
}
int items_height() const
{
return items_end() - items_start();
}
public:
menu(display& disp, const std::vector<std::string>& items,
bool click_selects=false)
: display_(&disp), x_(0), y_(0), buffer_(NULL),
selected_(-1), click_selects_(click_selects),
previous_button_(true), drawn_(false), height_(-1), width_(-1),
first_item_on_screen_(0),
uparrow_(disp,"",gui::button::TYPE_PRESS,"uparrow"),
downarrow_(disp,"",gui::button::TYPE_PRESS,"downarrow")
{
for(std::vector<std::string>::const_iterator item = items.begin();
item != items.end(); ++item) {
items_.push_back(config::split(*item));
//make sure there is always at least one item
if(items_.back().empty())
items_.back().push_back(" ");
}
}
int height() const {
if(height_ == -1) {
height_ = 0;
for(size_t i = 0; i != items_.size() && i != max_menu_items; ++i) {
height_ += get_item_rect(i).h;
}
if(items_.size() > max_menu_items) {
height_ += uparrow_.height() + downarrow_.height();
}
}
return height_;
}
int width() const {
if(width_ == -1) {
const std::vector<int>& widths = column_widths();
width_ = std::accumulate(widths.begin(),widths.end(),0);
}
return width_;
}
int selection() const { return selected_; }
void set_loc(int x, int y) {
x_ = x;
y_ = y;
const int w = width();
SDL_Rect portion = {x_,y_,w,height()};
SDL_Surface* const screen = display_->video().getSurface();
buffer_.assign(get_surface_portion(screen, portion));
if(items_.size() > max_menu_items) {
uparrow_.set_x(x_);
uparrow_.set_y(y_);
downarrow_.set_x(x_);
downarrow_.set_y(y_+items_end());
}
}
int process(int x, int y, bool button,bool up_arrow,bool down_arrow,
bool page_up, bool page_down, int select_item) {
if(items_.size() > size_t(max_menu_items)) {
const bool up = uparrow_.process(x,y,button);
if(up && first_item_on_screen_ > 0) {
itemRects_.clear();
--first_item_on_screen_;
draw();
}
const bool down = downarrow_.process(x,y,button);
if(down &&
size_t(first_item_on_screen_+max_menu_items) < items_.size()) {
itemRects_.clear();
++first_item_on_screen_;
draw();
}
}
if(select_item >= 0 && size_t(select_item) < items_.size()) {
selected_ = select_item;
if(selected_ < first_item_on_screen_) {
itemRects_.clear();
first_item_on_screen_ = selected_;
}
if(size_t(selected_ - first_item_on_screen_) >= max_menu_items) {
itemRects_.clear();
first_item_on_screen_ = selected_ - max_menu_items - 1;
}
draw();
}
if(up_arrow && !click_selects_ && selected_ > 0) {
--selected_;
if(selected_ < first_item_on_screen_) {
itemRects_.clear();
first_item_on_screen_ = selected_;
}
draw();
}
if(down_arrow && !click_selects_ && selected_ < int(items_.size()-1)) {
++selected_;
if(size_t(selected_ - first_item_on_screen_) == max_menu_items) {
itemRects_.clear();
++first_item_on_screen_;
}
draw();
}
if(page_up && !click_selects_) {
selected_ -= max_menu_items;
if(selected_ < 0)
selected_ = 0;
itemRects_.clear();
first_item_on_screen_ = selected_;
draw();
}
if(page_down && !click_selects_) {
selected_ += max_menu_items;
if(size_t(selected_) >= items_.size())
selected_ = items_.size()-1;
first_item_on_screen_ = selected_ - (max_menu_items-1);
if(first_item_on_screen_ < 0)
first_item_on_screen_ = 0;
itemRects_.clear();
draw();
}
const int starting_selected = selected_;
const int hit_item = hit(x,y);
if(click_selects_) {
selected_ = hit_item;
if(button && !previous_button_)
return selected_;
else {
if(!drawn_ || selected_ != starting_selected)
draw();
previous_button_ = button;
return -1;
}
}
if(button && hit_item != -1){
selected_ = hit_item;
}
if(selected_ == -1)
selected_ = 0;
if(selected_ != starting_selected)
draw();
return -1;
}
};
}
namespace gui
{

View File

@ -10,8 +10,9 @@
See the COPYING file for more details.
*/
#ifndef MENU_HPP_INCLUDED
#define MENU_HPP_INCLUDED
#ifndef SHOW_DIALOG_HPP_INCLUDED
#define SHOW_DIALOG_HPP_INCLUDED
#include "display.hpp"
#include "SDL.h"

View File

@ -1,5 +1,5 @@
#include "font.hpp"
#include "menu.hpp"
#include "show_dialog.hpp"
#include "tooltips.hpp"
#include "sdl_utils.hpp"

323
src/widgets/menu.cpp Normal file
View File

@ -0,0 +1,323 @@
#include "menu.hpp"
#include "../font.hpp"
#include "../show_dialog.hpp"
#include <numeric>
namespace {
const size_t max_menu_items = 18;
const size_t menu_font_size = 16;
const size_t menu_cell_padding = 10;
}
namespace gui {
menu::menu(display& disp, const std::vector<std::string>& items,
bool click_selects)
: display_(&disp), x_(0), y_(0), buffer_(NULL),
selected_(-1), click_selects_(click_selects),
previous_button_(true), drawn_(false), height_(-1), width_(-1),
first_item_on_screen_(0),
uparrow_(disp,"",gui::button::TYPE_PRESS,"uparrow"),
downarrow_(disp,"",gui::button::TYPE_PRESS,"downarrow")
{
for(std::vector<std::string>::const_iterator item = items.begin();
item != items.end(); ++item) {
items_.push_back(config::split(*item));
//make sure there is always at least one item
if(items_.back().empty())
items_.back().push_back(" ");
}
}
int menu::height() const
{
if(height_ == -1) {
height_ = 0;
for(size_t i = 0; i != items_.size() && i != max_menu_items; ++i) {
height_ += get_item_rect(i).h;
}
if(items_.size() > max_menu_items) {
height_ += uparrow_.height() + downarrow_.height();
}
}
return height_;
}
int menu::width() const
{
if(width_ == -1) {
const std::vector<int>& widths = column_widths();
width_ = std::accumulate(widths.begin(),widths.end(),0);
}
return width_;
}
int menu::selection() const { return selected_; }
void menu::set_loc(int x, int y)
{
x_ = x;
y_ = y;
const int w = width();
SDL_Rect portion = {x_,y_,w,height()};
SDL_Surface* const screen = display_->video().getSurface();
buffer_.assign(get_surface_portion(screen, portion));
if(items_.size() > max_menu_items) {
uparrow_.set_x(x_);
uparrow_.set_y(y_);
downarrow_.set_x(x_);
downarrow_.set_y(y_+items_end());
}
}
int menu::process(int x, int y, bool button,bool up_arrow,bool down_arrow,
bool page_up, bool page_down, int select_item)
{
if(items_.size() > size_t(max_menu_items)) {
const bool up = uparrow_.process(x,y,button);
if(up && first_item_on_screen_ > 0) {
itemRects_.clear();
--first_item_on_screen_;
draw();
}
const bool down = downarrow_.process(x,y,button);
if(down &&
size_t(first_item_on_screen_+max_menu_items) < items_.size()) {
itemRects_.clear();
++first_item_on_screen_;
draw();
}
}
if(select_item >= 0 && size_t(select_item) < items_.size()) {
selected_ = select_item;
if(selected_ < first_item_on_screen_) {
itemRects_.clear();
first_item_on_screen_ = selected_;
}
if(size_t(selected_ - first_item_on_screen_) >= max_menu_items) {
itemRects_.clear();
first_item_on_screen_ = selected_ - max_menu_items - 1;
}
draw();
}
if(up_arrow && !click_selects_ && selected_ > 0) {
--selected_;
if(selected_ < first_item_on_screen_) {
itemRects_.clear();
first_item_on_screen_ = selected_;
}
draw();
}
if(down_arrow && !click_selects_ && selected_ < int(items_.size()-1)) {
++selected_;
if(size_t(selected_ - first_item_on_screen_) == max_menu_items) {
itemRects_.clear();
++first_item_on_screen_;
}
draw();
}
if(page_up && !click_selects_) {
selected_ -= max_menu_items;
if(selected_ < 0)
selected_ = 0;
itemRects_.clear();
first_item_on_screen_ = selected_;
draw();
}
if(page_down && !click_selects_) {
selected_ += max_menu_items;
if(size_t(selected_) >= items_.size())
selected_ = items_.size()-1;
first_item_on_screen_ = selected_ - (max_menu_items-1);
if(first_item_on_screen_ < 0)
first_item_on_screen_ = 0;
itemRects_.clear();
draw();
}
const int starting_selected = selected_;
const int hit_item = hit(x,y);
if(click_selects_) {
selected_ = hit_item;
if(button && !previous_button_)
return selected_;
else {
if(!drawn_ || selected_ != starting_selected)
draw();
previous_button_ = button;
return -1;
}
}
if(button && hit_item != -1){
selected_ = hit_item;
}
if(selected_ == -1)
selected_ = 0;
if(selected_ != starting_selected)
draw();
return -1;
}
const std::vector<int>& menu::column_widths() const
{
if(column_widths_.empty()) {
for(size_t row = 0; row != items_.size(); ++row) {
for(size_t col = 0; col != items_[row].size(); ++col) {
static const SDL_Rect area =
{0,0,display_->x(),display_->y()};
const SDL_Rect res =
font::draw_text(NULL,area,menu_font_size,
font::NORMAL_COLOUR,items_[row][col],x_,y_);
if(col == column_widths_.size()) {
column_widths_.push_back(res.w + menu_cell_padding);
} else if(res.w > column_widths_[col] - menu_cell_padding) {
column_widths_[col] = res.w + menu_cell_padding;
}
}
}
}
return column_widths_;
}
void menu::draw_item(int item)
{
SDL_Rect rect = get_item_rect(item);
if(rect.w == 0)
return;
if(buffer_.get() != NULL) {
const int ypos = items_start()+(item-first_item_on_screen_)*rect.h;
SDL_Rect srcrect = {0,ypos,rect.w,rect.h};
SDL_BlitSurface(buffer_,&srcrect,
display_->video().getSurface(),&rect);
}
gui::draw_solid_tinted_rectangle(x_,rect.y,width(),rect.h,
item == selected_ ? 150:0,0,0,
item == selected_ ? 0.6 : 0.2,
display_->video().getSurface());
SDL_Rect area = {0,0,display_->x(),display_->y()};
const std::vector<int>& widths = column_widths();
int xpos = rect.x;
for(size_t i = 0; i != items_[item].size(); ++i) {
font::draw_text(display_,area,menu_font_size,font::NORMAL_COLOUR,
items_[item][i],xpos,rect.y);
xpos += widths[i];
}
}
void menu::draw()
{
drawn_ = true;
for(size_t i = 0; i != items_.size(); ++i)
draw_item(i);
display_->video().flip();
}
int menu::hit(int x, int y) const
{
if(x > x_ && x < x_ + width() && y > y_ && y < y_ + height()){
for(size_t i = 0; i != items_.size(); ++i) {
const SDL_Rect& rect = get_item_rect(i);
if(y > rect.y && y < rect.y + rect.h)
return i;
}
}
return -1;
}
SDL_Rect menu::get_item_rect(int item) const
{
const SDL_Rect empty_rect = {0,0,0,0};
if(item < first_item_on_screen_ ||
size_t(item) >= first_item_on_screen_ + max_menu_items) {
return empty_rect;
}
const std::map<int,SDL_Rect>::const_iterator i = itemRects_.find(item);
if(i != itemRects_.end())
return i->second;
int y = y_ + items_start();
if(item != first_item_on_screen_) {
const SDL_Rect& prev = get_item_rect(item-1);
y = prev.y + prev.h;
}
static const SDL_Rect area = {0,0,display_->x(),display_->y()};
SDL_Rect res = font::draw_text(NULL,area,menu_font_size,
font::NORMAL_COLOUR,items_[item][0],x_,y);
res.w = width();
//only insert into the cache if the menu's co-ordinates have
//been initialized
if(x_ > 0 && y_ > 0)
itemRects_.insert(std::pair<int,SDL_Rect>(item,res));
return res;
}
int menu::items_start() const
{
if(items_.size() > max_menu_items)
return uparrow_.height();
else
return 0;
}
int menu::items_end() const
{
if(items_.size() > max_menu_items)
return height() - downarrow_.height();
else
return height();
}
int menu::items_height() const
{
return items_end() - items_start();
}
}

66
src/widgets/menu.hpp Normal file
View File

@ -0,0 +1,66 @@
#ifndef WIDGET_MENU_HPP_INCLUDED
#define WIDGET_MENU_HPP_INCLUDED
#include <string>
#include <vector>
#include "../display.hpp"
#include "../sdl_utils.hpp"
#include "button.hpp"
#include "SDL.h"
namespace gui {
class menu
{
public:
menu(display& disp, const std::vector<std::string>& items,
bool click_selects=false);
int height() const;
int width() const;
int selection() const;
void set_loc(int x, int y);
int process(int x, int y, bool button,bool up_arrow,bool down_arrow,
bool page_up, bool page_down, int select_item);
private:
display* display_;
int x_, y_;
std::vector<std::vector<std::string> > items_;
mutable std::vector<int> column_widths_;
scoped_sdl_surface buffer_;
int selected_;
bool click_selects_;
bool previous_button_;
bool drawn_;
mutable int height_;
mutable int width_;
mutable int first_item_on_screen_;
gui::button uparrow_, downarrow_;
const std::vector<int>& column_widths() const;
void draw_item(int item);
void draw();
int hit(int x, int y) const;
mutable std::map<int,SDL_Rect> itemRects_;
SDL_Rect get_item_rect(int item) const;
int items_start() const;
int items_end() const;
int items_height() const;
};
}
#endif