void the_end(CVideo &video, std::string text, unsigned int duration) { // // Some sane defaults. // if(text.empty()) text = _("The End"); if(!duration) duration = 3500; SDL_Rect area = screen_area(); sdl::fill_rect(video.getSurface(),&area,0); update_whole_screen(); video.flip(); const size_t font_size = font::SIZE_XLARGE; area = font::text_area(text,font_size); area.x = screen_area().w/2 - area.w/2; area.y = screen_area().h/2 - area.h/2; for(size_t n = 0; n < 255; n += 5) { if(n) sdl::fill_rect(video.getSurface(),&area,0); const SDL_Color col = create_color(n, n, n, n); font::draw_text(&video,area,font_size,col,text,area.x,area.y); update_rect(area); events::pump(); events::raise_process_event(); events::raise_draw_event(); video.flip(); CVideo::delay(10); } // // Delay after the end of fading. // Rounded to multiples of 10. // unsigned int count = duration/10; while(count) { events::pump(); events::raise_process_event(); events::raise_draw_event(); video.flip(); CVideo::delay(10); --count; } }
void default_map_generator::user_config(CVideo& v) { const events::event_context dialog_events_context; CVideo& screen = v; const int width = 600; const int height = 400; const int xpos = screen.getx()/2 - width/2; int ypos = screen.gety()/2 - height/2; gui::button close_button(screen,_("Close")); std::vector<gui::button*> buttons(1,&close_button); gui::dialog_frame f(screen,_("Map Generator"),gui::dialog_frame::default_style,true,&buttons); f.layout(xpos,ypos,width,height); f.draw(); SDL_Rect dialog_rect = sdl::create_rect(xpos, ypos, width, height); surface_restorer dialog_restorer(&screen,dialog_rect); const std::string& players_label = _("Players:"); const std::string& width_label = _("Width:"); const std::string& height_label = _("Height:"); const std::string& iterations_label = _("Number of hills:"); const std::string& hillsize_label = _("Max hill size:"); const std::string& villages_label = _("Villages:"); const std::string& castlesize_label = _("Castle size:"); const std::string& landform_label = _("Landform:"); SDL_Rect players_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,players_label,0,0); SDL_Rect width_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,width_label,0,0); SDL_Rect height_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,height_label,0,0); SDL_Rect iterations_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,0,0); SDL_Rect hillsize_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,hillsize_label,0,0); SDL_Rect villages_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_label,0,0); SDL_Rect castlesize_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,castlesize_label,0,0); SDL_Rect landform_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_label,0,0); const int horz_margin = 15; const int text_right = xpos + horz_margin + std::max<int>(std::max<int>(std::max<int>(std::max<int>(std::max<int>(std::max<int>( players_rect.w,width_rect.w),height_rect.w),iterations_rect.w),hillsize_rect.w),villages_rect.w),castlesize_rect.w); players_rect.x = text_right - players_rect.w; width_rect.x = text_right - width_rect.w; height_rect.x = text_right - height_rect.w; iterations_rect.x = text_right - iterations_rect.w; hillsize_rect.x = text_right - hillsize_rect.w; villages_rect.x = text_right - villages_rect.w; castlesize_rect.x = text_right - castlesize_rect.w; landform_rect.x = text_right - landform_rect.w; const int vertical_margin = 20; players_rect.y = ypos + vertical_margin*2; width_rect.y = players_rect.y + players_rect.h + vertical_margin; height_rect.y = width_rect.y + width_rect.h + vertical_margin; iterations_rect.y = height_rect.y + height_rect.h + vertical_margin; hillsize_rect.y = iterations_rect.y + iterations_rect.h + vertical_margin; villages_rect.y = hillsize_rect.y + hillsize_rect.h + vertical_margin; castlesize_rect.y = villages_rect.y + iterations_rect.h + vertical_margin; landform_rect.y = castlesize_rect.y + villages_rect.h + vertical_margin; const int right_space = 150; const int slider_left = text_right + 10; const int slider_right = xpos + width - horz_margin - right_space; SDL_Rect slider_rect = sdl::create_rect(slider_left , players_rect.y , slider_right - slider_left , players_rect.h); gui::slider players_slider(screen); players_slider.set_location(slider_rect); players_slider.set_min(2); players_slider.set_max(gamemap::MAX_PLAYERS); players_slider.set_value(nplayers_); const int min_width = 20; const int max_width = 100; const int max_height = 100; const int extra_size_per_player = 2; slider_rect.y = width_rect.y; gui::slider width_slider(screen); width_slider.set_location(slider_rect); width_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player); width_slider.set_max(max_width); width_slider.set_value(width_); slider_rect.y = height_rect.y; gui::slider height_slider(screen); height_slider.set_location(slider_rect); height_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player); height_slider.set_max(max_height); height_slider.set_value(height_); const int min_iterations = 10; const int max_iterations = 3000; slider_rect.y = iterations_rect.y; gui::slider iterations_slider(screen); iterations_slider.set_location(slider_rect); iterations_slider.set_min(min_iterations); iterations_slider.set_max(max_iterations); iterations_slider.set_value(iterations_); const int min_hillsize = 1; const int max_hillsize = 50; slider_rect.y = hillsize_rect.y; gui::slider hillsize_slider(screen); hillsize_slider.set_location(slider_rect); hillsize_slider.set_min(min_hillsize); hillsize_slider.set_max(max_hillsize); hillsize_slider.set_value(hill_size_); const int min_villages = 0; const int max_villages = 50; slider_rect.y = villages_rect.y; gui::slider villages_slider(screen); villages_slider.set_location(slider_rect); villages_slider.set_min(min_villages); villages_slider.set_max(max_villages); villages_slider.set_value(nvillages_); const int min_castlesize = 2; const int max_castlesize = 14; slider_rect.y = castlesize_rect.y; gui::slider castlesize_slider(screen); castlesize_slider.set_location(slider_rect); castlesize_slider.set_min(min_castlesize); castlesize_slider.set_max(max_castlesize); castlesize_slider.set_value(castle_size_); const int min_landform = 0; const int max_landform = int(max_island); slider_rect.y = landform_rect.y; gui::slider landform_slider(screen); landform_slider.set_location(slider_rect); landform_slider.set_min(min_landform); landform_slider.set_max(max_landform); landform_slider.set_value(island_size_); SDL_Rect link_rect = slider_rect; link_rect.y = link_rect.y + link_rect.h + vertical_margin; gui::button link_castles(screen,_("Roads between castles"),gui::button::TYPE_CHECK); link_castles.set_check(link_castles_); link_castles.set_location(link_rect); SDL_Rect labels_rect = link_rect; labels_rect.y = labels_rect.y + labels_rect.h + vertical_margin; gui::button show_labels(screen,_("Show labels"),gui::button::TYPE_CHECK); show_labels.set_check(show_labels_); show_labels.set_location(labels_rect); while(true) { nplayers_ = players_slider.value(); width_ = width_slider.value(); height_ = height_slider.value(); iterations_ = iterations_slider.value(); hill_size_ = hillsize_slider.value(); nvillages_ = villages_slider.value(); castle_size_ = castlesize_slider.value(); island_size_ = landform_slider.value(); dialog_restorer.restore(); close_button.set_dirty(true); if (close_button.pressed()) break; players_slider.set_dirty(); width_slider.set_dirty(); height_slider.set_dirty(); iterations_slider.set_dirty(); hillsize_slider.set_dirty(); villages_slider.set_dirty(); castlesize_slider.set_dirty(); landform_slider.set_dirty(); link_castles.set_dirty(); show_labels.set_dirty(); width_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player); height_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player); f.draw(); events::raise_process_event(); events::raise_draw_event(); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,players_label,players_rect.x,players_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,width_label,width_rect.x,width_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,height_label,height_rect.x,height_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,iterations_rect.x,iterations_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,hillsize_label,hillsize_rect.x,hillsize_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_label,villages_rect.x,villages_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,castlesize_label,castlesize_rect.x,castlesize_rect.y); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_label,landform_rect.x,landform_rect.y); font::draw_text(&screen, screen_area(), font::SIZE_NORMAL, font::NORMAL_COLOR, std::to_string(nplayers_), slider_right + horz_margin, players_rect.y); font::draw_text(&screen, screen_area(), font::SIZE_NORMAL, font::NORMAL_COLOR, std::to_string(width_), slider_right + horz_margin, width_rect.y); font::draw_text(&screen, screen_area(), font::SIZE_NORMAL, font::NORMAL_COLOR, std::to_string(height_), slider_right+horz_margin,height_rect.y); std::stringstream villages_str; villages_str << nvillages_ << _("/1000 tiles"); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_str.str(), slider_right+horz_margin,villages_rect.y); font::draw_text(&screen, screen_area(), font::SIZE_NORMAL, font::NORMAL_COLOR, std::to_string(castle_size_), slider_right + horz_margin, castlesize_rect.y); std::stringstream landform_str; landform_str << translation::gettext(island_size_ == 0 ? N_("Inland") : (island_size_ < max_coastal ? N_("Coastal") : N_("Island"))); font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_str.str(), slider_right+horz_margin,landform_rect.y); update_rect(xpos,ypos,width,height); v.flip(); CVideo::delay(100); events::pump(); } link_castles_ = link_castles.checked(); show_labels_ = show_labels.checked(); }
/** * Open a help dialog using a toplevel other than the default. * * This allows for complete customization of the contents, although not in a * very easy way. */ void show_help(CVideo& video, const section &toplevel_sec, const std::string& show_topic, int xloc, int yloc) { const events::event_context dialog_events_context; const gui::dialog_manager manager; CVideo& screen = video; const surface& scr = screen.getSurface(); const int width = std::min<int>(font::relative_size(1200), scr->w - font::relative_size(20)); const int height = std::min<int>(font::relative_size(850), scr->h - font::relative_size(150)); const int left_padding = font::relative_size(10); const int right_padding = font::relative_size(10); const int top_padding = font::relative_size(10); const int bot_padding = font::relative_size(10); // If not both locations were supplied, put the dialog in the middle // of the screen. if (yloc <= -1 || xloc <= -1) { xloc = scr->w / 2 - width / 2; yloc = scr->h / 2 - height / 2; } std::vector<gui::button*> buttons_ptr; gui::button close_button_(video, _("Close")); buttons_ptr.push_back(&close_button_); gui::dialog_frame f(video, _("The Battle for Wesnoth Help"), gui::dialog_frame::default_style, true, &buttons_ptr); f.layout(xloc, yloc, width, height); f.draw(); // Find all unit_types that have not been constructed yet and fill in the information // needed to create the help topics unit_types.build_all(unit_type::HELP_INDEXED); if (preferences::encountered_units().size() != size_t(last_num_encountered_units) || preferences::encountered_terrains().size() != size_t(last_num_encountered_terrains) || last_debug_state != game_config::debug || last_num_encountered_units < 0) { // More units or terrains encountered, update the contents. last_num_encountered_units = preferences::encountered_units().size(); last_num_encountered_terrains = preferences::encountered_terrains().size(); last_debug_state = game_config::debug; generate_contents(); } try { help_browser hb(video, toplevel_sec); hb.set_location(xloc + left_padding, yloc + top_padding); hb.set_width(width - left_padding - right_padding); hb.set_height(height - top_padding - bot_padding); if (show_topic != "") { hb.show_topic(show_topic); } else { hb.show_topic(default_show_topic); } hb.set_dirty(true); events::raise_draw_event(); CKey key; for (;;) { events::pump(); events::raise_process_event(); f.draw(); events::raise_draw_event(); if (key[SDLK_ESCAPE]) { // Escape quits from the dialog. return; } for (std::vector<gui::button*>::iterator button_it = buttons_ptr.begin(); button_it != buttons_ptr.end(); ++button_it) { if ((*button_it)->pressed()) { // There is only one button, close. return; } } video.flip(); CVideo::delay(10); } } catch (parse_error& e) { std::stringstream msg; msg << _("Parse error when parsing help text: ") << "'" << e.message << "'"; gui2::show_transient_message(video, "", msg.str()); } }
/** * Show credits with list of contributors. * * Names of people are shown scrolling up like in movie-credits.\n * Uses map from wesnoth or campaign as background. */ void show_about(CVideo &video, const std::string &campaign) { boost::scoped_ptr<cursor::setter> cur(new cursor::setter(cursor::WAIT)); surface& screen = video.getSurface(); if (screen == nullptr) return; // If the title is multi-line, we need to split it accordingly or we // get slight scrolling glitches in the credits screen. std::vector<std::string> text = about::get_text(campaign, true); SDL_Rect screen_rect = sdl::create_rect(0, 0, screen->w, screen->h); const surface_restorer restorer(&video, screen_rect); cur.reset(); std::vector<std::string> image_list; if(campaign.size() && !images[campaign].empty()){ image_list = utils::parenthetical_split(images[campaign], ','); } else{ image_list = utils::parenthetical_split(images_default, ','); } surface map_image, map_image_scaled; if(!image_list.empty()) { map_image = image::get_image(image_list[0]); } else { image_list.push_back(""); } if(!map_image){ image_list[0]=game_config::images::game_title_background; map_image=image::get_image(image_list[0]); } gui::button close(video,_("Close")); close.set_location((screen->w/2)-(close.width()/2), screen->h - 30); const int def_size = font::SIZE_XLARGE; const SDL_Color def_color = font::NORMAL_COLOR; //substitute in the correct control characters for '+' and '-' std::string before_header(2, ' '); before_header[0] = font::LARGE_TEXT; for(unsigned i = 0; i < text.size(); ++i) { std::string &s = text[i]; if (s.empty()) continue; char &first = s[0]; if (first == '-') first = font::SMALL_TEXT; else if (first == '+') { first = font::LARGE_TEXT; text.insert(text.begin() + i, before_header); ++i; } } text.insert(text.begin(), 10, before_header); int startline = 0; //TODO: use values proportional to screen ? // distance from top of map image to top of scrolling text const int top_margin = 60; // distance from bottom of scrolling text to bottom of map image const int bottom_margin = 40; // distance from left of scrolling text to the frame border const int text_left_padding = screen->w/32; int offset = 0; bool is_new_line = true; int first_line_height = 0; SDL_Rect frame_area; // we use a dialog to contains the text. Strange idea but at least the style // will be consistent with the titlescreen gui::dialog_frame f(video, "", gui::dialog_frame::titlescreen_style, false); // the text area's dimensions SDL_Rect text_rect = { 0, 0, 0, 0 }; // we'll retain a copy to prevent SDL_blit to change its w and h SDL_Rect text_rect_blit; surface text_surf; CKey key; bool last_escape; int image_count = 0; int scroll_speed = 4; // scroll_speed*50 = speed of scroll in pixel per second // Initially redraw all bool redraw_mapimage = true; bool update_dimensions = true; int max_text_width = 0; do { last_escape = key[SDLK_ESCAPE] != 0; // check to see if background image has changed if(text.size() && (image_count < ((startline * static_cast<int>(image_list.size())) / static_cast<int>(text.size())))){ image_count++; surface temp=image::get_image(image_list[image_count]); map_image=temp?temp:map_image; redraw_mapimage = true; } if (update_dimensions) { // rescale the background map_image_scaled = scale_surface(map_image, screen->w, screen->h); screen_rect = sdl::create_rect(0, 0, screen->w, screen->h); redraw_mapimage = true; // update the frame frame_area = sdl::create_rect( screen->w * 3 / 32 , top_margin , screen->w * 13 / 16 , screen->h - top_margin - bottom_margin); text_rect = f.layout(frame_area).interior; // update the text area text_rect.x += text_left_padding; text_rect.w -= text_left_padding; text_rect_blit = text_rect; text_surf = create_compatible_surface(screen, text_rect.w, text_rect.h); SDL_SetAlpha(text_surf, SDL_RLEACCEL, SDL_ALPHA_OPAQUE); // relocate the close button close.set_location((screen->w/2)-(close.width()/2), screen->h - 30); update_dimensions = false; } if (redraw_mapimage) { // draw map to screen, thus erasing all text sdl_blit(map_image_scaled, nullptr, screen, nullptr); update_rect(screen_rect); // redraw the dialog f.draw_background(); f.draw_border(); // cache the dialog background (alpha blending + blurred map) sdl_blit(screen, &text_rect, text_surf, nullptr); redraw_mapimage = false; } else { // redraw the saved part of the dialog where text scrolled // thus erasing all text SDL_Rect modified = sdl::create_rect(0, 0, max_text_width, text_rect.h); sdl_blit(text_surf, &modified, screen, &text_rect_blit); update_rect(text_rect); } int y = text_rect.y - offset; int line = startline; max_text_width = 0; { // clip to keep text into the frame (thus the new code block) clip_rect_setter set_clip_rect(screen, &text_rect); const int line_spacing = 5; do { // draw the text (with ellipsis if needed) // update the max_text_width for future cleaning int w = font::draw_text(&video, text_rect, def_size, def_color, text[line], text_rect.x, y).w; max_text_width = std::max<int>(max_text_width, w); // since the real drawing on screen is clipped, // we do a dummy one to get the height of the not clipped line. // (each time because special format characters may change it) const int line_height = font::draw_text(nullptr, text_rect, def_size, def_color, text[line], 0,0).h; if(is_new_line) { is_new_line = false; first_line_height = line_height + line_spacing; } line++; if(size_t(line) > text.size()-1) line = 0; y += line_height + line_spacing; } while(y < text_rect.y + text_rect.h); } // performs the actual scrolling offset += scroll_speed; if (offset>=first_line_height) { offset -= first_line_height; is_new_line = true; startline++; if(size_t(startline) == text.size()){ startline = 0; image_count = -1; } } // handle events if (key[SDLK_UP] && scroll_speed < 20) { ++scroll_speed; } if (key[SDLK_DOWN] && scroll_speed > 0) { --scroll_speed; } if (screen->w != screen_rect.w || screen->h != screen_rect.h) { update_dimensions = true; } events::pump(); events::raise_process_event(); events::raise_draw_event(); // flip screen and wait, so the text does not scroll too fast video.flip(); CVideo::delay(20); } while(!close.pressed() && (last_escape || !key[SDLK_ESCAPE])); }
/** * Open the help browser, show the variation of the unit matching. */ void show_variation_help(CVideo& video, const std::string& unit, const std::string &variation, bool hidden, int xloc, int yloc) { show_help(video, toplevel, hidden_symbol(hidden) + variation_prefix + unit + "_" + variation, xloc, yloc); video.flip(); }
/** * Open the help browser, show terrain with id terrain_id. * * If show_topic is the empty string, the default topic will be shown. */ void show_terrain_help(CVideo& video, const std::string& show_topic, bool hidden, int xloc, int yloc) { show_help(video, toplevel, hidden_symbol(hidden) + terrain_prefix + show_topic, xloc, yloc); video.flip(); }
/** * Open the help browser, show unit with id unit_id. * * If show_topic is the empty string, the default topic will be shown. */ void show_unit_help(CVideo& video, const std::string& show_topic, bool has_variations, bool hidden, int xloc, int yloc) { show_help(video, toplevel, hidden_symbol(hidden) + (has_variations ? ".." : "") + unit_prefix + show_topic, xloc, yloc); video.flip(); }
/** * Open the help browser, show topic with id show_topic. * * If show_topic is the empty string, the default topic will be shown. */ void show_help(CVideo& video, const std::string& show_topic, int xloc, int yloc) { show_help(video, toplevel, show_topic, xloc, yloc); video.flip(); }