refactored menu code

This commit is contained in:
Dave White 2003-10-29 01:25:28 +00:00
parent fdd523eefa
commit 1347eaf79b
2 changed files with 132 additions and 103 deletions

View file

@ -16,9 +16,9 @@ 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),
selected_(click_selects ? -1:0), click_selects_(click_selects),
previous_button_(true), drawn_(false), show_result_(false),
height_(-1), width_(-1), first_item_on_screen_(0),
uparrow_(disp,"",gui::button::TYPE_PRESS,"uparrow"),
downarrow_(disp,"",gui::button::TYPE_PRESS,"downarrow")
{
@ -79,114 +79,135 @@ void menu::set_loc(int x, int y)
}
}
void menu::calculate_position()
{
if(click_selects_)
return;
if(selected_ < first_item_on_screen_) {
first_item_on_screen_ = selected_;
itemRects_.clear();
} else if(selected_ >= first_item_on_screen_ + int(max_menu_items)) {
first_item_on_screen_ = selected_ - (max_menu_items - 1);
itemRects_.clear();
}
}
void menu::key_press(SDLKey key)
{
switch(key) {
case SDLK_UP: {
if(!click_selects_ && selected_ > 0) {
--selected_;
calculate_position();
drawn_ = false;
}
break;
}
case SDLK_DOWN: {
if(!click_selects_ && selected_ < int(items_.size())-1) {
++selected_;
calculate_position();
drawn_ = false;
}
break;
}
case SDLK_PAGEUP: {
if(!click_selects_) {
selected_ -= max_menu_items;
if(selected_ < 0)
selected_ = 0;
calculate_position();
drawn_ = false;
}
break;
}
case SDLK_PAGEDOWN: {
if(!click_selects_) {
selected_ += max_menu_items;
if(selected_ >= int(items_.size()))
selected_ = int(items_.size())-1;
calculate_position();
drawn_ = false;
}
break;
}
default:
break;
}
if(key >= SDLK_1 && key <= SDLK_9) {
const int pos = key - SDLK_1;
if(size_t(pos) < items_.size()) {
selected_ = pos;
calculate_position();
drawn_ = false;
}
}
}
void menu::handle_event(const SDL_Event& event)
{
if(event.type == SDL_KEYDOWN) {
key_press(event.key.keysym.sym);
} else if(event.type == SDL_MOUSEBUTTONDOWN &&
event.button.button == SDL_BUTTON_LEFT) {
const int item = hit(event.button.x,event.button.y);
if(item != -1) {
selected_ = item;
drawn_ = false;
if(click_selects_) {
show_result_ = true;
}
}
} else if(event.type == SDL_MOUSEMOTION && click_selects_) {
const int item = hit(event.motion.x,event.motion.y);
if(item != selected_) {
selected_ = item;
drawn_ = false;
}
}
}
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;
const bool up = uparrow_.process(x,y,button);
if(up && first_item_on_screen_ > 0) {
--first_item_on_screen_;
itemRects_.clear();
first_item_on_screen_ = selected_;
draw();
drawn_ = false;
}
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;
const bool down = downarrow_.process(x,y,button);
if(down && first_item_on_screen_ + max_menu_items < items_.size()) {
++first_item_on_screen_;
itemRects_.clear();
drawn_ = false;
}
if(!drawn_) {
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(show_result_) {
return selected_;
} else {
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
@ -194,8 +215,7 @@ 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()};
static const SDL_Rect area = {0,0,display_->x(),display_->y()};
const SDL_Rect res =
font::draw_text(NULL,area,menu_font_size,
@ -216,8 +236,9 @@ const std::vector<int>& menu::column_widths() const
void menu::draw_item(int item)
{
SDL_Rect rect = get_item_rect(item);
if(rect.w == 0)
if(rect.w == 0) {
return;
}
if(buffer_.get() != NULL) {
const int ypos = items_start()+(item-first_item_on_screen_)*rect.h;

View file

@ -5,6 +5,7 @@
#include <vector>
#include "../display.hpp"
#include "../events.hpp"
#include "../sdl_utils.hpp"
#include "button.hpp"
@ -13,7 +14,7 @@
namespace gui {
class menu
class menu : public events::handler
{
public:
menu(display& disp, const std::vector<std::string>& items,
@ -30,6 +31,11 @@ public:
bool page_up, bool page_down, int select_item=-1);
private:
void calculate_position();
void key_press(SDLKey key);
void handle_event(const SDL_Event& event);
display* display_;
int x_, y_;
std::vector<std::vector<std::string> > items_;
@ -41,6 +47,8 @@ private:
bool previous_button_;
bool drawn_;
bool show_result_;
mutable int height_;
mutable int width_;