made a standard title display for dialog boxes, ...

...and ok/close/cancel buttons appear in the bottom-right corner
This commit is contained in:
Dave White 2004-04-28 19:30:50 +00:00
parent 2c78051d25
commit f9496ed360
8 changed files with 188 additions and 111 deletions

View file

@ -25,6 +25,7 @@
#include "game_events.hpp"
#include "log.hpp"
#include "scoped_resource.hpp"
#include "util.hpp"
bool operator<(const line_source& a, const line_source& b)
{
@ -618,8 +619,44 @@ void config::read(const std::string& data,
in_quotes = !in_quotes;
has_quotes = true;
} else if(c == '\n' && !in_quotes) {
//see if this is a CVS list=CVS list style assignment (e.g. x,y=5,8)
std::vector<std::string> vars, values;
if(std::count(var.begin(),var.end(),',') > 1) {
vars = config::split(var);
values = config::split(value);
} else {
vars.push_back(var);
values.push_back(value);
}
//iterate over the names and values, assigning each to its corresponding
//element. If there are more names than values, than remaining names get
//assigned to the last value. If there are more values than names, then
//all the last values get concatenated onto the last name
if(vars.empty() == false) {
for(size_t n = 0; n != maximum<size_t>(vars.size(),values.size()); ++n) {
const std::string& varname = n < vars.size() ? vars[n] : vars.back();
std::string value = "";
if(n < values.size()) {
value = values[n];
} else if(values.empty() == false) {
value = values.back();
}
if(has_quotes == false) {
strip(value);
}
if(n < vars.size()) {
elements.top()->values[vars[n]] = value;
} else {
elements.top()->values[vars.back()] += "," + value;
}
}
}
state = IN_ELEMENT;
elements.top()->values[var] = has_quotes ? value : strip(value);
var = "";
value = "";
has_quotes = false;

View file

@ -158,7 +158,7 @@ void multiplayer_game_setup_dialog::set_area(const SDL_Rect& area)
//gui::draw_dialog_background(left,top,width,height,disp_,"menu");
int xpos = left + border_size;
int ypos = gui::draw_dialog_title(left,top,disp_,string_table["create_new_game"]) + border_size;
int ypos = top + gui::draw_dialog_title(left,top,&disp_,string_table["create_new_game"]).h + border_size;
std::cerr << "b\n";
@ -247,8 +247,11 @@ void multiplayer_game_setup_dialog::set_area(const SDL_Rect& area)
std::cerr << "h\n";
//Buttons
launch_game_->set_xy(left + (width/2)-launch_game_->width()*2-19,bottom-29);
cancel_game_->set_xy(left + (width/2)+cancel_game_->width()+19,bottom-29);
cancel_game_->set_xy(right - cancel_game_->width() - gui::ButtonHPadding,
bottom - cancel_game_->height() - gui::ButtonVPadding);
launch_game_->set_xy(right - cancel_game_->width() - launch_game_->width() - gui::ButtonHPadding*2,
bottom - launch_game_->height() - gui::ButtonVPadding);
regenerate_map_->set_xy(rect.x,rect.y);
regenerate_map_->backup_background();

View file

@ -126,8 +126,8 @@ public:
font::draw_text(&disp_,rect,14,font::NORMAL_COLOUR,text,rect.x,rect.y);
cancel_button_.assign(new gui::button(disp_,string_table["cancel"]));
cancel_button_->set_xy(area.x+area.w/2 - cancel_button_->width()/2,
area.y+area.h - cancel_button_->height() - 10);
cancel_button_->set_xy(area.x+area.w - cancel_button_->width() - gui::ButtonHPadding,
area.y+area.h - cancel_button_->height() - gui::ButtonVPadding);
cancel_button_->draw();
}

View file

@ -331,12 +331,13 @@ void mp_connect::set_area(const SDL_Rect& rect)
//gui::draw_dialog_background(left, right, width, height, *disp_, "menu");
//Buttons
launch_.set_xy(center_x-launch_.width()/2-100,bottom-30);
cancel_.set_xy(center_x-launch_.width()/2+100,bottom-30);
cancel_.set_xy(right - cancel_.width() - gui::ButtonHPadding,bottom-cancel_.height()-gui::ButtonVPadding);
launch_.set_xy(right - cancel_.width() - launch_.width() - gui::ButtonHPadding*2,bottom-launch_.height()-gui::ButtonVPadding);
ai_.set_xy(left+30,bottom-60);
//Title and labels
gui::draw_dialog_title(left,top,*disp_,string_table["game_lobby"]);
gui::draw_dialog_title(left,top,disp_,string_table["game_lobby"]);
SDL_Rect labelr = font::draw_text(NULL,rect,14,font::GOOD_COLOUR,
string_table["player_type"],0,0);

View file

@ -457,25 +457,19 @@ void show_preferences_dialog(display& disp)
log_scope("show_preferences_dialog");
const int width = 600;
const int height = 440;
const int height = 400;
const int xpos = disp.x()/2 - width/2;
const int ypos = disp.y()/2 - height/2;
//make sure that the frame buffer is restored to its original state
//when the dialog closes. Not const, because we might want to cancel
//it in the case of video mode changes
SDL_Rect dialog_rect = {xpos-10,ypos-10,width+20,height+20};
surface_restorer restorer(&disp.video(),dialog_rect);
gui::draw_dialog_frame(xpos,ypos,width,height,disp);
SDL_Rect clip_rect = {0,0,disp.x(),disp.y()};
SDL_Rect title_rect = font::draw_text(NULL,clip_rect,16,font::NORMAL_COLOUR,
string_table["preferences"],0,0);
gui::button close_button(disp,string_table["close_window"]);
close_button.set_x(xpos + width/2 - close_button.width()/2);
close_button.set_y(ypos + height - close_button.height()-14);
std::vector<gui::button*> buttons;
buttons.push_back(&close_button);
surface_restorer restorer;
gui::draw_dialog(xpos,ypos,width,height,disp,string_table["preferences"],NULL,&buttons,&restorer);
const std::string& music_label = string_table["music_volume"];
const std::string& sound_label = string_table["sound_volume"];
@ -496,7 +490,7 @@ void show_preferences_dialog(display& disp)
const int text_right = xpos + maximum(scroll_rect.w,maximum(music_rect.w,sound_rect.w)) + 5;
const int music_pos = ypos + title_rect.h + 20;
const int music_pos = ypos + 20;
const int sound_pos = music_pos + 50;
const int scroll_pos = sound_pos + 50;
@ -613,7 +607,8 @@ void show_preferences_dialog(display& disp)
}
if(redraw_all) {
gui::draw_dialog_frame(xpos,ypos,width,height,disp);
restorer.cancel();
gui::draw_dialog(xpos,ypos,width,height,disp,string_table["preferences"],NULL,&buttons,&restorer);
fullscreen_button.draw();
turbo_button.draw();
grid_button.draw();
@ -635,10 +630,6 @@ void show_preferences_dialog(display& disp)
font::draw_text(&disp,clip_rect,14,font::NORMAL_COLOUR,scroll_label,
scroll_rect.x,scroll_rect.y);
font::draw_text(&disp,clip_rect,18,font::NORMAL_COLOUR,
string_table["preferences"],
xpos+(width-title_rect.w)/2,ypos+10);
update_rect(disp.screen_area());
redraw_all = false;
@ -770,23 +761,23 @@ void show_hotkeys_dialog (display & disp)
const int ypos = centery - 250;
const int width = 600;
const int height = 500;
gui::draw_dialog_frame(xpos, ypos, width, height, disp);
gui::button close_button (disp, string_table["close_window"]);
std::vector<gui::button*> buttons;
buttons.push_back(&close_button);
surface_restorer restorer;
gui::draw_dialog(xpos,ypos,width,height,disp,string_table["hotkeys_dialog"],NULL,&buttons,&restorer);
SDL_Rect clip_rect = { 0, 0, disp.x (), disp.y () };
SDL_Rect title_rect = font::draw_text (NULL, clip_rect, 16,
font::NORMAL_COLOUR,
string_table["hotkeys_dialog"], 0, 0);
SDL_Rect text_size = font::draw_text(NULL, clip_rect, 16,
font::NORMAL_COLOUR,string_table["set_hotkey"],
0, 0);
std::vector < std::string > menu_items;
std::vector<std::string> menu_items;
std::vector < hotkey::hotkey_item > hotkeys =
hotkey::get_hotkeys ();
for (std::vector<hotkey::hotkey_item>::iterator i = hotkeys.begin(); i != hotkeys.end(); ++i)
{
std::vector<hotkey::hotkey_item> hotkeys = hotkey::get_hotkeys();
for(std::vector<hotkey::hotkey_item>::iterator i = hotkeys.begin(); i != hotkeys.end(); ++i) {
std::stringstream str,name;
name << "action_"<< hotkey::command_to_string(i->action);
str << string_table[name.str()];
@ -795,14 +786,10 @@ void show_hotkeys_dialog (display & disp)
menu_items.push_back (str.str ());
}
gui::menu menu_ (disp, menu_items);
gui::menu menu_ (disp, menu_items, false, height);
menu_.set_width(400);
menu_.set_loc (xpos + 20, ypos + 30);
menu_.set_loc (xpos + 20, ypos);
gui::button close_button (disp, string_table["close_window"]);
close_button.set_x (xpos + width - close_button.width () - 30);
close_button.set_y (ypos + height - close_button.height () - 70);
gui::button change_button (disp, string_table["change_hotkey_button"]);
change_button.set_x (xpos + width -
change_button.width () -30);
@ -815,37 +802,27 @@ void show_hotkeys_dialog (display & disp)
bool redraw_all = true;
for (;;)
{
for(;;) {
int mousex, mousey;
const int mouse_flags =
SDL_GetMouseState (&mousex, &mousey);
const bool left_button =
mouse_flags & SDL_BUTTON_LMASK;
const int mouse_flags = SDL_GetMouseState (&mousex, &mousey);
const bool left_button = mouse_flags & SDL_BUTTON_LMASK;
if (redraw_all)
{
gui::draw_dialog_frame (xpos, ypos, width,
height, disp);
if(redraw_all) {
menu_.redraw();
close_button.draw ();
change_button.draw();
save_button.draw();
font::draw_text (&disp, clip_rect, 18,font::NORMAL_COLOUR,
string_table["hotkeys_dialog"],
xpos + (width - title_rect.w) / 2,ypos + 10);
redraw_all = false;
};
if (close_button.process (mousex, mousey, left_button))
{
if(close_button.process (mousex, mousey, left_button)) {
break;
}
if (change_button.process (mousex, mousey, left_button))
{ // Lets change this hotkey......
if(change_button.process (mousex, mousey, left_button)) {
// Lets change this hotkey......
SDL_Rect dlgr = {centerx-text_size.w/2-30,
centery-text_size.h/2 - 16,
text_size.w+60,

View file

@ -36,6 +36,9 @@ bool is_in_dialog = false;
namespace gui {
const int ButtonHPadding = 10;
const int ButtonVPadding = 10;
bool in_dialog() { return is_in_dialog; }
dialog_manager::dialog_manager() : cursor::setter(cursor::NORMAL), reset_to(is_in_dialog)
@ -48,23 +51,33 @@ dialog_manager::~dialog_manager()
is_in_dialog = reset_to;
}
void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::string* dialog_style)
void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::string* dialog_style, surface_restorer* restorer)
{
if(dialog_style == NULL) {
static const std::string default_style("menu");
dialog_style = &default_style;
}
draw_dialog_background(x,y,w,h,disp,*dialog_style);
const scoped_sdl_surface top(image::get_image("misc/" + *dialog_style + "-border-top.png",image::UNSCALED));
const scoped_sdl_surface bot(image::get_image("misc/" + *dialog_style + "-border-bottom.png",image::UNSCALED));
const scoped_sdl_surface left(image::get_image("misc/" + *dialog_style + "-border-left.png",image::UNSCALED));
const scoped_sdl_surface right(image::get_image("misc/" + *dialog_style + "-border-right.png",image::UNSCALED));
if(top == NULL || bot == NULL || left == NULL || right == NULL)
const bool have_border = top != NULL && bot != NULL && left != NULL && right != NULL;
if(have_border && restorer != NULL) {
const SDL_Rect rect = {x-top->h,y-left->w,w+left->w+right->w,h+top->h+bot->h};
*restorer = surface_restorer(&disp.video(),rect);
} else if(restorer != NULL) {
const SDL_Rect rect = {x,y,w,h};
*restorer = surface_restorer(&disp.video(),rect);
}
draw_dialog_background(x,y,w,h,disp,*dialog_style);
if(have_border == false) {
return;
}
scoped_sdl_surface top_image(scale_surface(top,w,top->h));
@ -96,8 +109,9 @@ void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::str
const scoped_sdl_surface bot_left(image::get_image("misc/" + *dialog_style + "-border-botleft.png",image::UNSCALED));
const scoped_sdl_surface top_right(image::get_image("misc/" + *dialog_style + "-border-topright.png",image::UNSCALED));
const scoped_sdl_surface bot_right(image::get_image("misc/" + *dialog_style + "-border-botright.png",image::UNSCALED));
if(top_left == NULL || bot_left == NULL || top_right == NULL || bot_right == NULL)
if(top_left == NULL || bot_left == NULL || top_right == NULL || bot_right == NULL) {
return;
}
disp.blit_surface(x-top_left->w,y-top_left->h,top_left);
disp.blit_surface(x-bot_left->w,y+h,bot_left);
@ -155,11 +169,61 @@ void draw_dialog_background(int x, int y, int w, int h, display& disp, const std
}
}
int draw_dialog_title(int x, int y, display& disp, const std::string& text)
SDL_Rect draw_dialog_title(int x, int y, display* disp, const std::string& text)
{
const SDL_Rect rect = font::draw_text(&disp,disp.screen_area(),24,font::NORMAL_COLOUR,
text,x+5,y+5);
return rect.y + rect.h;
SDL_Rect rect = {0,0,10000,10000};
if(disp != NULL) {
rect = disp->screen_area();
}
return font::draw_text(disp,rect,24,font::NORMAL_COLOUR,text,x+5,y+5);
}
void draw_dialog(int x, int y, int w, int h, display& disp, const std::string& title,
const std::string* style, std::vector<button*>* buttons,
surface_restorer* restorer)
{
int border_size = 10;
SDL_Rect title_area = {0,0,0,0};
if(title != "") {
title_area = draw_dialog_title(0,0,NULL,title);
title_area.w += border_size;
title_area.h += border_size;
}
SDL_Rect buttons_area = {0,0,0,0};
if(buttons != NULL) {
for(std::vector<button*>::const_iterator b = buttons->begin(); b != buttons->end(); ++b) {
buttons_area.w += (**b).width() + ButtonHPadding;
buttons_area.h = maximum<int>((**b).height() + ButtonVPadding,buttons_area.h);
}
buttons_area.x = -buttons_area.w;
buttons_area.y = y + h;
buttons_area.w += ButtonHPadding;
}
const int xpos = x;
const int ypos = y - int(title_area.h);
const int width = maximum<int>(w,maximum<int>(int(title_area.w),int(buttons_area.w)));
const int height = title_area.h + buttons_area.h + h;
buttons_area.x += xpos + width;
draw_dialog_frame(xpos,ypos,width,height,disp,style,restorer);
if(title != "") {
draw_dialog_title(x + border_size, y - title_area.h, &disp, title);
}
if(buttons != NULL) {
for(std::vector<button*>::const_iterator b = buttons->begin(); b != buttons->end(); ++b) {
(**b).set_xy(buttons_area.x,buttons_area.y);
buttons_area.x += (**b).width() + ButtonHPadding;
}
}
}
void draw_rectangle(int x, int y, int w, int h, Uint16 colour,SDL_Surface* target)
@ -286,7 +350,7 @@ int show_dialog(display& disp, SDL_Surface* image,
}
SDL_Rect caption_size = { 0, 0, 0, 0 };
if(!caption.empty()) {
if(caption != "" && image != NULL) {
caption_size = font::draw_text(NULL, clipRect, caption_font_size,
font::NORMAL_COLOUR,caption,0,0,NULL);
}
@ -323,21 +387,11 @@ int show_dialog(display& disp, SDL_Surface* image,
}
}
const int button_height_padding = 10;
int button_width_padding = 0;
int button_heights = 0;
int button_widths = 0;
if(button_list != NULL) {
try {
while(button_list->empty() == false) {
buttons.push_back(button(disp,string_table[*button_list]));
if(buttons.back().height() > button_heights)
button_heights = buttons.back().height();
button_widths += buttons.back().width();
button_width_padding += 5;
++button_list;
}
@ -346,12 +400,9 @@ int show_dialog(display& disp, SDL_Surface* image,
}
}
if(button_heights > 0) {
button_heights += button_height_padding;
}
int check_button_height = 0;
int check_button_width = 0;
const int button_height_padding = 5;
std::vector<button> check_buttons;
if(options != NULL) {
@ -393,17 +444,14 @@ int show_dialog(display& disp, SDL_Surface* image,
if(menu_.width() > text_width)
text_width = menu_.width();
int total_width = total_image_width + text_width +
padding_width;
if(button_widths + button_width_padding > total_width)
total_width = button_widths + button_width_padding;
int total_width = total_image_width + text_width + padding_width;
if(text_widget_width+left_padding+right_padding > total_width)
total_width = text_widget_width+left_padding+right_padding;
const int total_height = (total_image_height > text_size.h ?
total_image_height : text_size.h) +
padding_height + button_heights + menu_.height() +
padding_height + menu_.height() +
text_widget_height + check_button_height;
if(xloc <= -1 || yloc <= -1) {
@ -436,22 +484,15 @@ int show_dialog(display& disp, SDL_Surface* image,
yloc = scr->h - frame_height;
}
const int button_wpadding = total_width - button_widths;
int button_offset = 0;
for(size_t button_num = 0; button_num != buttons.size(); ++button_num) {
const int padding_amount = button_wpadding/(buttons.size()+1);
buttons[button_num].set_x(xloc + padding_amount*(button_num+1) +
button_offset);
buttons[button_num].set_y(yloc + total_height - button_heights);
button_offset += buttons[button_num].width();
std::vector<button*> buttons_ptr;
for(std::vector<button>::iterator bt = buttons.begin(); bt != buttons.end(); ++bt) {
buttons_ptr.push_back(&*bt);
}
SDL_Rect dlgr = {xloc-border_padding,yloc-border_padding,
total_width+border_padding*2,total_height+border_padding*2};
surface_restorer restorer;
const surface_restorer restorer(&disp.video(),dlgr);
draw_dialog_frame(xloc,yloc,total_width,total_height,disp,dialog_style);
const std::string& title = image == NULL ? caption : "";
draw_dialog(xloc,yloc,total_width,total_height,disp,title,dialog_style,&buttons_ptr,&restorer);
if(menu_.height() > 0)
menu_.set_loc(xloc+total_image_width+left_padding+image_h_padding,

View file

@ -22,6 +22,8 @@
#include "unit.hpp"
#include "video.hpp"
#include "widgets/button.hpp"
#include "SDL.h"
#include <string>
@ -30,6 +32,9 @@
namespace gui
{
extern const int ButtonHPadding;
extern const int ButtonVPadding;
bool in_dialog();
struct dialog_manager : private cursor::setter, private font::floating_label_hider {
@ -40,7 +45,7 @@ private:
bool reset_to;
};
void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::string* dialog_style=NULL);
void draw_dialog_frame(int x, int y, int w, int h, display& disp, const std::string* dialog_style=NULL, surface_restorer* restorer=NULL);
void draw_dialog_background(int x, int y, int w, int h, display& disp, const std::string& dialog_style);
@ -51,8 +56,21 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h,
double alpha, SDL_Surface* target);
//given the location of a dialog, will draw its title.
//Returns the y co-ordinate of the top of the dialog box after the title
int draw_dialog_title(int x, int y, display& disp, const std::string& text);
//Returns the area the title takes up
SDL_Rect draw_dialog_title(int x, int y, display* disp, const std::string& text);
//function to draw a dialog on the screen. x,y,w,h give the dimensions of the client area
//of the dialog. 'title' is the title of the dialog. The title will be displayed at the
//top of the dialog above the client area. 'dialog_style' if present gives the style of
//the dialog to use.
//'buttons' contains pointers to standard dialog buttons such as 'ok' and 'cancel' that
//will appear on the dialog. If present, they will be located at the bottom of the dialog,
//below the client area.
//if 'restorer' is present, it will be set to a restorer that will reset the screen area
//to its original state after the dialog is drawn.
void draw_dialog(int x, int y, int w, int h, display& disp, const std::string& title,
const std::string* dialog_style=NULL, std::vector<button*>* buttons=NULL,
surface_restorer* restorer=NULL);
class dialog_action
{

View file

@ -82,7 +82,7 @@ int menu::width() const
if(width_ == -1) {
const std::vector<int>& widths = column_widths();
width_ = std::accumulate(widths.begin(),widths.end(),0);
if (show_scrollbar()) {
if(show_scrollbar()) {
width_ += scrollbar_.get_max_width();
}
}
@ -103,9 +103,9 @@ void menu::set_loc(int x, int y)
SDL_Surface* const screen = display_->video().getSurface();
buffer_.assign(get_surface_portion(screen, portion));
const std::vector<int>& widths = column_widths();
int menu_width = std::accumulate(widths.begin(), widths.end(), 0);
if(show_scrollbar()) {
const int menu_width = width() - scrollbar_.get_max_width();
scrollbar_.enable(true);
int scr_width = scrollbar_.get_width();