make the GUI frame drawing routines more object-oriented

This commit is contained in:
Patrick Parker 2007-05-28 11:16:55 +00:00
parent dabf4d7873
commit 7e9fb4c90c
10 changed files with 257 additions and 173 deletions

View file

@ -228,7 +228,10 @@ void show_about(display &disp, std::string campaign)
map_rect.w * 13 / 16,
map_rect.h - top_margin - bottom_margin
};
gui::draw_dialog_background(frame.x, frame.y, frame.w, frame.h,disp.video(),style);
gui::frame f(disp.video(), "", &style);
f.layout(frame.x, frame.y, frame.w, frame.h);
f.draw_background();
// draw one screen full of text
const int line_spacing = 5;
int y = map_rect.y + top_margin - offset;

View file

@ -110,7 +110,7 @@ dialog::dimension_measurements::dimension_measurements() :
dialog::dialog(display &disp, const std::string& title, const std::string& message,
const DIALOG_TYPE type, const std::string& dialog_style,
const std::string& help_topic) : disp_(disp), image_(NULL),
title_(title), style_(dialog_style), message_(NULL),
title_(title), style_(dialog_style), title_widget_(NULL), message_(NULL),
type_(type), menu_(NULL),
help_button_(disp, help_topic), text_widget_(NULL),
action_(NULL), bg_restore_(NULL), result_(CONTINUE_DIALOG)
@ -158,6 +158,8 @@ dialog::~dialog()
{
delete menu_;
}
delete title_widget_;
delete message_;
delete text_widget_;
delete image_;
// delete action_;
@ -171,7 +173,6 @@ dialog::~dialog()
// delete (*p);
// }
delete bg_restore_;
delete message_;
}
const bool dialog::option_checked(unsigned int option_index)
@ -321,9 +322,10 @@ void dialog::draw_frame()
frame_buttons.push_back(*b);
}
bg_restore_ = new surface_restorer;
draw_dialog(dim_.interior.x, dim_.interior.y, dim_.interior.w, dim_.interior.h,
screen, title_, &style_, &frame_buttons, bg_restore_,
frame f(screen, title_, &style_, &frame_buttons, bg_restore_,
help_button_.topic().empty() ? NULL : &help_button_);
dim_.frame = f.layout(dim_.interior.x, dim_.interior.y, dim_.interior.w, dim_.interior.h);
f.draw();
}
void dialog::update_widget_positions()
@ -693,9 +695,9 @@ int dialog::process(dialog_process_info &info)
//note: this will also close any context-menu or drop-down when it is right-clicked
// but that may be changed to allow right-click selection instead.
if (new_right_button && !info.right_button) {
if( standard_buttons_.empty() ||
(!point_in_rect(mousex,mousey,dim_.interior) && !(type_ == OK_ONLY && use_menu)) )
//FIXME: should check outer frame instead of dim_.interior
if( standard_buttons_.empty()
|| (!point_in_rect(mousex,mousey,dim_.frame.exterior)
&& !(type_ == OK_ONLY && use_menu)))
return CLOSE_DIALOG;
}

View file

@ -133,6 +133,7 @@ public:
int menu_x, menu_y;
int image_x, image_y, caption_x, caption_y;
std::map<dialog_button *const, std::pair<int,int> > buttons;
frame::dimension_measurements frame;
};
private:
typedef std::vector<preview_pane *>::iterator pp_iterator;
@ -241,7 +242,7 @@ private:
display &disp_;
dialog_image *image_;
const std::string title_, style_;
label* message_;
label *title_widget_, *message_;
const DIALOG_TYPE type_;
mutable gui::menu *menu_;
std::vector<preview_pane*> preview_panes_;

View file

@ -856,7 +856,10 @@ void campaign_preview_pane::draw_contents()
/* background frame */
static const std::string default_style("mainmenu");
const std::string* style = &default_style;
gui::draw_dialog_frame(area.x,area.y,area.w,area.h,video(),style);
gui::frame f(video(), "", style);
f.layout(area.x,area.y,area.w,area.h);
f.draw_background();
f.draw_border();
/* description text */
const std::string& desc_text = font::word_wrap_text((*descriptions_)[index_].first,font::SIZE_SMALL,area.w-2*campaign_preview_border);

View file

@ -2597,9 +2597,12 @@ void show_help(display &disp, const section &toplevel_sec, const std::string sho
gui::button close_button_(disp.video(), _("Close"));
buttons_ptr.push_back(&close_button_);
surface_restorer restorer;
gui::draw_dialog(xloc, yloc, width, height, disp.video(), _("The Battle for Wesnoth Help"),
NULL, &buttons_ptr, &restorer);
gui::frame f(disp.video(), _("The Battle for Wesnoth Help"),
NULL, &buttons_ptr, &restorer);
f.layout(xloc, yloc, width, height);
f.draw();
if (preferences::encountered_units().size() != size_t(last_num_encountered_units) ||
preferences::encountered_terrains().size() != size_t(last_num_encountered_terrains) ||
last_num_encountered_units < 0) {

View file

@ -101,7 +101,9 @@ void default_map_generator::user_config(display& disp)
gui::button close_button(screen,_("Close Window"));
std::vector<gui::button*> buttons(1,&close_button);
gui::draw_dialog(xpos,ypos,width,height,screen,_("Map Generator"),NULL,&buttons,&restorer);
gui::frame f(screen,_("Map Generator"),NULL,&buttons,&restorer);
f.layout(xpos,ypos,width,height);
f.draw();
SDL_Rect dialog_rect = {xpos,ypos,width,height};
surface_restorer dialog_restorer(&screen,dialog_rect);

View file

@ -1274,7 +1274,9 @@ void show_hotkeys_dialog (display & disp, config *save_config)
buttons.push_back(&close_button);
surface_restorer restorer;
gui::draw_dialog(xpos,ypos,width,height,disp.video(),_("Hotkey Settings"),NULL,&buttons,&restorer);
gui::frame f(disp.video(),_("Hotkey Settings"),NULL,&buttons,&restorer);
f.layout(xpos,ypos,width,height);
f.draw();
SDL_Rect clip_rect = { 0, 0, disp.w (), disp.h () };
SDL_Rect text_size = font::draw_text(NULL, clip_rect, font::SIZE_PLUS,
@ -1326,10 +1328,13 @@ void show_hotkeys_dialog (display & disp, config *save_config)
text_size.w+60,
text_size.h+32};
surface_restorer restorer(&disp.video(),dlgr);
gui::draw_dialog_frame (centerx-text_size.w/2 - 20,
gui::frame mini_frame(disp.video());
mini_frame.layout(centerx-text_size.w/2 - 20,
centery-text_size.h/2 - 6,
text_size.w+40,
text_size.h+12,disp.video());
text_size.h+12);
mini_frame.draw_background();
mini_frame.draw_border();
font::draw_text (&disp.video(), clip_rect, font::SIZE_LARGE,font::NORMAL_COLOUR,
_("Press desired Hotkey"),centerx-text_size.w/2-10,
centery-text_size.h/2-3);

View file

@ -54,9 +54,16 @@ bool is_in_dialog = false;
namespace gui {
//static initialization
const int ButtonHPadding = 10;
const int ButtonVPadding = 10;
const std::string frame::default_style("menu");
const int frame::title_border_w = 10;
const int frame::title_border_h = 5;
bool in_dialog() { return is_in_dialog; }
dialog_manager::dialog_manager() : cursor::setter(cursor::NORMAL), reset_to(is_in_dialog)
@ -79,192 +86,203 @@ dialog_manager::~dialog_manager()
SDL_PushEvent(&pb_event);
}
void draw_dialog_frame(int x, int y, int w, int h, CVideo &video, const std::string* dialog_style, surface_restorer* restorer)
frame::frame(CVideo &video, const std::string& title,
const std::string* style, std::vector<button*>* buttons,
surface_restorer* restorer, button* help_button) : video_(video),
title_(title), dialog_style_(style ? style : &default_style),
buttons_(buttons), help_button_(help_button), restorer_(restorer),
top_(image::get_image("misc/" + *dialog_style_ + "-border-top.png",image::UNSCALED)),
bot_(image::get_image("misc/" + *dialog_style_ + "-border-bottom.png",image::UNSCALED)),
left_(image::get_image("misc/" + *dialog_style_ + "-border-left.png",image::UNSCALED)),
right_(image::get_image("misc/" + *dialog_style_ + "-border-right.png",image::UNSCALED)),
top_left_(image::get_image("misc/" + *dialog_style_ + "-border-topleft.png",image::UNSCALED)),
bot_left_(image::get_image("misc/" + *dialog_style_ + "-border-botleft.png",image::UNSCALED)),
top_right_(image::get_image("misc/" + *dialog_style_ + "-border-topright.png",image::UNSCALED)),
bot_right_(image::get_image("misc/" + *dialog_style_ + "-border-botright.png",image::UNSCALED)),
bg_(image::get_image("misc/" + *dialog_style_ + "-background.png",image::UNSCALED))
{
if(dialog_style == NULL) {
static const std::string default_style("menu");
dialog_style = &default_style;
}
const surface top(image::get_image("misc/" + *dialog_style + "-border-top.png",image::UNSCALED));
const surface bot(image::get_image("misc/" + *dialog_style + "-border-bottom.png",image::UNSCALED));
const surface left(image::get_image("misc/" + *dialog_style + "-border-left.png",image::UNSCALED));
const surface right(image::get_image("misc/" + *dialog_style + "-border-right.png",image::UNSCALED));
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(&video,rect);
} else if(restorer != NULL) {
const SDL_Rect rect = {x,y,w,h};
*restorer = surface_restorer(&video,rect);
}
draw_dialog_background(x,y,w,h,video,*dialog_style);
if(have_border == false) {
return;
}
surface top_image(scale_surface(top,w,top->h));
if(top_image != NULL) {
video.blit_surface(x,y-top->h,top_image);
}
surface bot_image(scale_surface(bot,w,bot->h));
if(bot_image != NULL) {
video.blit_surface(x,y+h,bot_image);
}
surface left_image(scale_surface(left,left->w,h));
if(left_image != NULL) {
video.blit_surface(x-left->w,y,left_image);
}
surface right_image(scale_surface(right,right->w,h));
if(right_image != NULL) {
video.blit_surface(x+w,y,right_image);
}
update_rect(x-left->w,y-top->h,w+left->w+right->w,h+top->h+bot->h);
const surface top_left(image::get_image("misc/" + *dialog_style + "-border-topleft.png",image::UNSCALED));
const surface bot_left(image::get_image("misc/" + *dialog_style + "-border-botleft.png",image::UNSCALED));
const surface top_right(image::get_image("misc/" + *dialog_style + "-border-topright.png",image::UNSCALED));
const 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) {
return;
}
video.blit_surface(x-top_left->w,y-top_left->h,top_left);
video.blit_surface(x-bot_left->w,y+h,bot_left);
video.blit_surface(x+w,y-top_right->h,top_right);
video.blit_surface(x+w,y+h,bot_right);
}
void draw_dialog_background(int x, int y, int w, int h, CVideo &video, const std::string& style)
{
const std::string menu_background = "misc/" + style + "-background.png";
frame::~frame()
{}
const surface bg(image::get_image(menu_background,image::UNSCALED));
if(bg == NULL) {
ERR_DP << "could not find dialog background '" << style << "'\n";
return;
frame::dimension_measurements::dimension_measurements() :
interior(empty_rect), exterior(empty_rect), title(empty_rect), button_row(empty_rect)
{}
frame::dimension_measurements frame::layout(int x, int y, int w, int h) {
dim_ = dimension_measurements();
if(!title_.empty()) {
dim_.title = draw_title(NULL);
dim_.title.w += title_border_w;
}
if(buttons_ != NULL) {
for(std::vector<button*>::const_iterator b = buttons_->begin(); b != buttons_->end(); ++b) {
dim_.button_row.w += (**b).width() + ButtonHPadding;
dim_.button_row.h = maximum<int>((**b).height() + ButtonVPadding,dim_.button_row.h);
}
dim_.button_row.x = -dim_.button_row.w;
dim_.button_row.y = y + h;
dim_.button_row.w += ButtonHPadding;
}
const SDL_Rect& screen_bounds = screen_area();
if(x < 0) {
size_t buttons_width = dim_.button_row.w;
if(help_button_ != NULL) {
buttons_width += help_button_->width() + ButtonHPadding*2;
dim_.button_row.y = y + h;
}
y -= dim_.title.h;
w = maximum<int>(w,maximum<int>(int(dim_.title.w),int(buttons_width)));
h += dim_.title.h + dim_.button_row.h;
dim_.button_row.x += x + w;
have_border_ = top_ != NULL && bot_ != NULL && left_ != NULL && right_ != NULL;
SDL_Rect bounds = screen_area();
if(have_border_) {
bounds.x += left_->w;
bounds.y += top_->h;
bounds.w -= left_->w + right_->w;
bounds.h -= top_->h + bot_->h;
}
if(x < bounds.x) {
w += x;
x = 0;
x = bounds.x;
}
if(y < 0) {
if(y < bounds.y) {
h += y;
y = 0;
y = bounds.y;
}
if(x > bounds.w) {
w = 0;
} else if(x + w > bounds.w) {
w = bounds.w - x;
}
if(y > bounds.h) {
h = 0;
} else if(y + h > bounds.h) {
h = bounds.h - y;
}
dim_.interior.x = x;
dim_.interior.y = y;
dim_.interior.w = w;
dim_.interior.h = h;
if(have_border_) {
dim_.exterior.x = dim_.interior.x - left_->w;
dim_.exterior.y = dim_.interior.y - top_->h;
dim_.exterior.w = dim_.interior.w + left_->w + right_->w;
dim_.exterior.h = dim_.interior.h + top_->h + bot_->h;
} else {
dim_.exterior = dim_.interior;
}
dim_.title.x = dim_.interior.x + title_border_w;
dim_.title.y = dim_.interior.y + title_border_h;
return dim_;
}
if(x > screen_bounds.w) {
void frame::draw_border()
{
if(have_border_ == false) {
return;
}
if(y > screen_bounds.h) {
surface top_image(scale_surface(top_, dim_.interior.w, top_->h));
if(top_image != NULL) {
video_.blit_surface(dim_.interior.x, dim_.exterior.y, top_image);
}
surface bot_image(scale_surface(bot_, dim_.interior.w, bot_->h));
if(bot_image != NULL) {
video_.blit_surface(dim_.interior.x, dim_.interior.y + dim_.interior.h, bot_image);
}
surface left_image(scale_surface(left_, left_->w, dim_.interior.h));
if(left_image != NULL) {
video_.blit_surface(dim_.exterior.x, dim_.interior.y, left_image);
}
surface right_image(scale_surface(right_, right_->w, dim_.interior.h));
if(right_image != NULL) {
video_.blit_surface(dim_.interior.x + dim_.interior.w, dim_.interior.y, right_image);
}
update_rect(dim_.exterior);
if(top_left_ == NULL || bot_left_ == NULL || top_right_ == NULL || bot_right_ == NULL) {
return;
}
if(x + w > screen_bounds.w) {
w = screen_bounds.w - x;
}
video_.blit_surface(dim_.interior.x - top_left_->w, dim_.interior.y - top_left_->h, top_left_);
video_.blit_surface(dim_.interior.x - bot_left_->w, dim_.interior.y + dim_.interior.h, bot_left_);
video_.blit_surface(dim_.interior.x + dim_.interior.w, dim_.interior.y - top_right_->h, top_right_);
video_.blit_surface(dim_.interior.x + dim_.interior.w, dim_.interior.y + dim_.interior.h, bot_right_);
}
if(y + h > screen_bounds.h) {
h = screen_bounds.h - y;
void frame::draw_background()
{
if(restorer_ != NULL) {
*restorer_ = surface_restorer(&video_, dim_.exterior);
}
for(int i = 0; i < w; i += bg->w) {
for(int j = 0; j < h; j += bg->h) {
if(bg_ == NULL) {
ERR_DP << "could not find dialog background '" << *dialog_style_ << "'\n";
return;
}
for(int i = 0; i < dim_.interior.w; i += bg_->w) {
for(int j = 0; j < dim_.interior.h; j += bg_->h) {
SDL_Rect src = {0,0,0,0};
src.w = minimum(w - i,bg->w);
src.h = minimum(h - j,bg->h);
src.w = minimum(dim_.interior.w - i, bg_->w);
src.h = minimum(dim_.interior.h - j, bg_->h);
SDL_Rect dst = src;
dst.x = x + i;
dst.y = y + j;
SDL_BlitSurface(bg,&src,video.getSurface(),&dst);
dst.x = dim_.interior.x + i;
dst.y = dim_.interior.y + j;
SDL_BlitSurface(bg_, &src, video_.getSurface(), &dst);
}
}
}
SDL_Rect draw_dialog_title(int x, int y, CVideo* video, const std::string& text)
SDL_Rect frame::draw_title(CVideo* video)
{
SDL_Rect rect = {0, 0, 10000, 10000};
rect = screen_area();
return font::draw_text(video, rect, font::SIZE_LARGE, font::TITLE_COLOUR,
text, x, y + 5, false, TTF_STYLE_BOLD);
title_, dim_.title.x, dim_.title.y, false, TTF_STYLE_BOLD);
}
void draw_dialog(int x, int y, int w, int h, CVideo &video, const std::string& title,
const std::string* style, std::vector<button*>* buttons,
surface_restorer* restorer, button* help_button)
void frame::draw()
{
int border_size = 10;
SDL_Rect title_area = {0,0,0,0};
//draw background
draw_background();
if (!title.empty()) {
title_area = draw_dialog_title(0,0,NULL,title);
title_area.w += border_size;
//draw frame border
draw_border();
//draw title
if (!title_.empty()) {
draw_title(&video_);
}
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;
}
size_t buttons_width = buttons_area.w;
if(help_button != NULL) {
buttons_width += help_button->width() + ButtonHPadding*2;
buttons_area.y = y + h;
}
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_width)));
const int height = title_area.h + buttons_area.h + h;
buttons_area.x += xpos + width;
draw_dialog_frame(xpos,ypos,width,height,video,style,restorer);
if (!title.empty()) {
draw_dialog_title(x + border_size, y - title_area.h, &video, title);
}
if(buttons != NULL) {
//draw buttons
SDL_Rect buttons_area = dim_.button_row;
if(buttons_ != NULL) {
#ifdef OK_BUTTON_ON_RIGHT
std::reverse(buttons->begin(),buttons->end());
std::reverse(buttons_->begin(),buttons_->end());
#endif
for(std::vector<button*>::const_iterator b = buttons->begin(); b != buttons->end(); ++b) {
(**b).set_location(buttons_area.x,buttons_area.y);
for(std::vector<button*>::const_iterator b = buttons_->begin(); b != buttons_->end(); ++b) {
(**b).set_location(buttons_area.x, buttons_area.y);
buttons_area.x += (**b).width() + ButtonHPadding;
}
}
if(help_button != NULL) {
help_button->set_location(x+ButtonHPadding,buttons_area.y);
if(help_button_ != NULL) {
help_button_->set_location(dim_.interior.x+ButtonHPadding, buttons_area.y);
}
}
@ -392,7 +410,9 @@ network::connection network_data_dialog(display& disp, const std::string& msg, c
std::vector<gui::button*> buttons_ptr(1,&cancel_button);
surface_restorer restorer;
gui::draw_dialog(left,top,width,height,disp.video(),msg,NULL,&buttons_ptr,&restorer);
gui::frame f(disp.video(),msg,NULL,&buttons_ptr,&restorer);
f.layout(left,top,width,height);
f.draw();
const SDL_Rect progress_rect = {left+border,top+border,width-border*2,height-border*2};
gui::progress_bar progress(disp.video());
@ -487,7 +507,9 @@ network::connection network_connect_dialog(display& disp, const std::string& msg
std::vector<gui::button*> buttons_ptr(1,&cancel_button);
surface_restorer restorer;
gui::draw_dialog(left,top,width,height,disp.video(),msg,NULL,&buttons_ptr,&restorer);
gui::frame f(disp.video(),msg,NULL,&buttons_ptr,&restorer);
f.layout(left,top,width,height);
f.draw();
events::raise_draw_event();
disp.flip();

View file

@ -54,13 +54,50 @@ private:
bool reset_to;
};
void draw_dialog_frame(int x, int y, int w, int h, CVideo &video, const std::string* dialog_style=NULL, surface_restorer* restorer=NULL);
class frame {
public:
//Static members
static const std::string default_style;
static const int title_border_w, title_border_h;
void draw_dialog_background(int x, int y, int w, int h, CVideo &video, const std::string& dialog_style);
struct dimension_measurements {
dimension_measurements();
SDL_Rect interior, exterior, title, button_row;
};
frame(CVideo &video, const std::string& title="",
const std::string* dialog_style=NULL, std::vector<button*>* buttons=NULL,
surface_restorer* restorer=NULL, button* help_button=NULL);
~frame();
dimension_measurements layout(int x, int y, int w, int h);
void draw();
//called by draw
void draw_border();
void draw_background();
//also called by layout with null param
SDL_Rect draw_title(CVideo *video);
private:
std::string title_;
CVideo &video_;
const std::string *dialog_style_;
std::vector<button*>* buttons_;
button* help_button_;
surface_restorer* restorer_;
dimension_measurements dim_;
surface top_, bot_, left_, right_, top_left_, bot_left_, top_right_, bot_right_, bg_;
bool have_border_;
};
//frame_measurements draw_dialog_frame(int x, int y, int w, int h, CVideo &video, const std::string* dialog_style=NULL, surface_restorer* restorer=NULL);
//SDL_Rect draw_dialog_background(int x, int y, int w, int h, CVideo &video, const std::string& dialog_style);
//given the location of a dialog, will draw its title.
//Returns the area the title takes up
SDL_Rect draw_dialog_title(int x, int y, CVideo* disp, const std::string& text);
//SDL_Rect draw_dialog_title(int x, int y, CVideo* disp, const std::string& text, label** label_widget);
//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
@ -71,9 +108,12 @@ SDL_Rect draw_dialog_title(int x, int y, CVideo* disp, const std::string& text);
//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, CVideo &video, const std::string& title,
const std::string* dialog_style=NULL, std::vector<button*>* buttons=NULL,
surface_restorer* restorer=NULL, button* help_button=NULL);
//void draw_dialog(int x, int y, int w, int h, CVideo &video, const std::string& title,
// const std::string* dialog_style=NULL, std::vector<button*>* buttons=NULL,
// surface_restorer* restorer=NULL, button* help_button=NULL, label** label_widget);
//void draw_dialog(frame_measurements &fm, CVideo &video, const std::string& title,
// const std::string* dialog_style=NULL, std::vector<button*>* buttons=NULL,
// surface_restorer* restorer=NULL, button* help_button=NULL, label** label_widget);
class dialog_action
{

View file

@ -187,10 +187,10 @@ static void draw_tip_of_day(display& screen, config& tips_of_day, int* ntip, con
help_tip_button->set_location(area.x + pad,
area.y + area.h - pad - next_tip_button->location().h);
help_tip_button->set_dirty(); //force redraw even if location did not change.
gui::draw_dialog_frame(area.x,area.y,area.w,area.h,screen.video(),&style, &tip_of_day_restorer);
gui::frame f(screen.video(), "", &style, NULL, &tip_of_day_restorer);
f.layout(area.x,area.y,area.w,area.h);
f.draw_background();
f.draw_border();
font::draw_text(&screen.video(), area, font::SIZE_NORMAL, font::NORMAL_COLOUR,
tip_of_day, area.x + pad, area.y + pad);
@ -297,7 +297,10 @@ TITLE_RESULT show_title(display& screen, config& tips_of_day, int* ntip)
SDL_Rect main_dialog_area = {menu_xbase-padding,menu_ybase-padding,max_width+padding*2,menu_yincr*(nbuttons-1)+buttons.back().height()+padding*2};
const std::string style = "mainmenu";
draw_dialog_frame(main_dialog_area.x,main_dialog_area.y,main_dialog_area.w,main_dialog_area.h,screen.video(),&style);
gui::frame main_frame(screen.video(), "", &style);
main_frame.layout(main_dialog_area.x,main_dialog_area.y,main_dialog_area.w,main_dialog_area.h);
main_frame.draw_background();
main_frame.draw_border();
for(b = 0; b != nbuttons; ++b) {
buttons[b].set_width(max_width);