Added the ability to resize the map.
This commit is contained in:
parent
0946c4b945
commit
9ce185a2f0
10 changed files with 245 additions and 42 deletions
|
@ -117,8 +117,8 @@ shift=no
|
|||
[hotkey]
|
||||
command="editfillselection"
|
||||
key="f"
|
||||
ctrl=yes
|
||||
alt=no
|
||||
ctrl=no
|
||||
alt=yes
|
||||
shift=no
|
||||
[/hotkey]
|
||||
|
||||
|
@ -162,6 +162,22 @@ alt=no
|
|||
shift=no
|
||||
[/hotkey]
|
||||
|
||||
[hotkey]
|
||||
command="editresize"
|
||||
key="r"
|
||||
ctrl=yes
|
||||
alt=yes
|
||||
shift=no
|
||||
[/hotkey]
|
||||
|
||||
[hotkey]
|
||||
command="fullscreen"
|
||||
key="f"
|
||||
ctrl=yes
|
||||
alt=no
|
||||
shift=no
|
||||
[/hotkey]
|
||||
|
||||
[resolution]
|
||||
width=800
|
||||
height=600
|
||||
|
@ -175,7 +191,7 @@ height=600
|
|||
[menu]
|
||||
title=main_menu
|
||||
image=lite
|
||||
items=editnewmap,editloadmap,editrevert,undo,redo,editsavemap,editsaveas,preferences,togglegrid,editquit
|
||||
items=editnewmap,editloadmap,editresize,editrevert,undo,redo,editsavemap,editsaveas,preferences,togglegrid,editquit
|
||||
rect=3,1,107,22
|
||||
xanchor=fixed
|
||||
yanchor=fixed
|
||||
|
|
|
@ -494,6 +494,7 @@ action_editcut="Cut"
|
|||
action_editcopy="Copy"
|
||||
action_editpaste="Paste"
|
||||
action_editrevert="Revert from Disk"
|
||||
action_editresize="Resize Map"
|
||||
save_hotkeys_button="Save Hotkeys"
|
||||
change_hotkey_button="Change Hotkey"
|
||||
hotkeys_dialog="Hotkey Settings"
|
||||
|
|
|
@ -139,7 +139,17 @@ void map_editor::handle_keyboard_event(const SDL_KeyboardEvent &event,
|
|||
set_abort();
|
||||
}
|
||||
else {
|
||||
const bool old_fullscreen = preferences::fullscreen();
|
||||
const std::pair<int, int> old_resolution = preferences::resolution();
|
||||
hotkey::key_event(gui_, event, this);
|
||||
// A key event may change the video mode. The redraw
|
||||
// functionality inside the preferences module does not
|
||||
// redraw our palettes so we need to check if the mode has
|
||||
// changed and if so redraw everything.
|
||||
if (preferences::fullscreen() != old_fullscreen
|
||||
|| old_resolution != preferences::resolution()) {
|
||||
redraw_everything();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,13 +351,25 @@ void map_editor::edit_revert() {
|
|||
}
|
||||
}
|
||||
|
||||
void map_editor::edit_resize() {
|
||||
const std::pair<unsigned, unsigned> new_size =
|
||||
resize_dialog(gui_, map_.x(), map_.y());
|
||||
if (new_size.first != 0) {
|
||||
const std::string resized_map =
|
||||
resize_map(map_, new_size.first, new_size.second, palette_.selected_terrain());
|
||||
if (resized_map != "") {
|
||||
throw new_map_exception(resized_map, filename_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string map_editor::load_map(const std::string filename) {
|
||||
bool load_successful = true;
|
||||
std::string msg;
|
||||
std::string msg = "'";
|
||||
std::string new_map;
|
||||
if (!file_exists(filename) || is_directory(filename)) {
|
||||
load_successful = false;
|
||||
msg = filename + " does not exist or can't be read as a file.";
|
||||
msg += filename + "' does not exist or can't be read as a file.";
|
||||
}
|
||||
else {
|
||||
try {
|
||||
|
@ -414,6 +436,7 @@ bool map_editor::can_execute_command(hotkey::HOTKEY_COMMAND command) const {
|
|||
case hotkey::HOTKEY_EDIT_CUT:
|
||||
case hotkey::HOTKEY_EDIT_PASTE:
|
||||
case hotkey::HOTKEY_EDIT_REVERT:
|
||||
case hotkey::HOTKEY_EDIT_RESIZE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -490,8 +513,10 @@ void map_editor::redo() {
|
|||
|
||||
void map_editor::preferences() {
|
||||
preferences_dialog(gui_, prefs_);
|
||||
// Sizes and stuff may have changed, we need to redraw and
|
||||
// recalculate everything if that is the case.
|
||||
redraw_everything();
|
||||
}
|
||||
|
||||
void map_editor::redraw_everything() {
|
||||
adjust_sizes(gui_, size_specs_);
|
||||
palette_.adjust_size();
|
||||
brush_.adjust_size();
|
||||
|
|
|
@ -131,7 +131,8 @@ public:
|
|||
/// saved.
|
||||
bool changed_since_save() const;
|
||||
|
||||
|
||||
/// Recalculate layout and redraw everything.
|
||||
void redraw_everything();
|
||||
|
||||
// Methods inherited from command_executor. Used to perform
|
||||
// operations on menu/hotkey commands.
|
||||
|
@ -153,6 +154,7 @@ public:
|
|||
virtual void edit_copy();
|
||||
virtual void edit_paste();
|
||||
virtual void edit_revert();
|
||||
virtual void edit_resize();
|
||||
|
||||
virtual bool can_execute_command(hotkey::HOTKEY_COMMAND command) const;
|
||||
|
||||
|
|
|
@ -28,6 +28,14 @@
|
|||
|
||||
#include "editor_dialogs.hpp"
|
||||
|
||||
|
||||
namespace {
|
||||
const int map_min_height = 20;
|
||||
const int map_min_width = 20;
|
||||
const int map_max_height = 200;
|
||||
const int map_max_width = 200;
|
||||
}
|
||||
|
||||
namespace map_editor {
|
||||
|
||||
bool confirm_modification_disposal(display& disp) {
|
||||
|
@ -96,20 +104,16 @@ std::string new_map_dialog(display& disp, gamemap::TERRAIN fill_terrain,
|
|||
const int slider_right = xpos + width - horz_margin - right_space;
|
||||
SDL_Rect slider_rect = { slider_left,width_rect.y,slider_right-slider_left,width_rect.h};
|
||||
|
||||
const int min_width = 20;
|
||||
const int max_width = 200;
|
||||
const int max_height = 200;
|
||||
|
||||
slider_rect.y = width_rect.y;
|
||||
gui::slider width_slider(disp,slider_rect);
|
||||
width_slider.set_min(min_width);
|
||||
width_slider.set_max(max_width);
|
||||
width_slider.set_min(map_min_width);
|
||||
width_slider.set_max(map_max_width);
|
||||
width_slider.set_value(map_width);
|
||||
|
||||
slider_rect.y = height_rect.y;
|
||||
gui::slider height_slider(disp,slider_rect);
|
||||
height_slider.set_min(min_width);
|
||||
height_slider.set_max(max_height);
|
||||
height_slider.set_min(map_min_height);
|
||||
height_slider.set_max(map_max_height);
|
||||
height_slider.set_value(map_height);
|
||||
|
||||
const config* const cfg =
|
||||
|
@ -118,16 +122,11 @@ std::string new_map_dialog(display& disp, gamemap::TERRAIN fill_terrain,
|
|||
generator.assign(create_map_generator("", cfg));
|
||||
|
||||
for(bool draw = true;; draw = false) {
|
||||
int mousex, mousey;
|
||||
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
|
||||
|
||||
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
|
||||
|
||||
if(cancel_button.process(mousex,mousey,left_button)) {
|
||||
if(cancel_button.pressed()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if(new_map_button.process(mousex,mousey,left_button)) {
|
||||
if(new_map_button.pressed()) {
|
||||
draw = true;
|
||||
if ((confirmation_needed &&
|
||||
confirm_modification_disposal(disp))
|
||||
|
@ -145,14 +144,14 @@ std::string new_map_dialog(display& disp, gamemap::TERRAIN fill_terrain,
|
|||
return map_str.str();
|
||||
}
|
||||
}
|
||||
if(random_map_setting_button.process(mousex,mousey,left_button)) {
|
||||
if(random_map_setting_button.pressed()) {
|
||||
draw = true;
|
||||
if (generator.get()->allow_user_config()) {
|
||||
generator.get()->user_config(disp);
|
||||
}
|
||||
}
|
||||
|
||||
if(random_map_button.process(mousex,mousey,left_button)) {
|
||||
if(random_map_button.pressed()) {
|
||||
draw = true;
|
||||
if ((confirmation_needed
|
||||
&& confirm_modification_disposal(disp))
|
||||
|
@ -199,8 +198,8 @@ std::string new_map_dialog(display& disp, gamemap::TERRAIN fill_terrain,
|
|||
random_map_setting_button.set_dirty();
|
||||
cancel_button.set_dirty();
|
||||
|
||||
width_slider.set_min(min_width);
|
||||
height_slider.set_min(min_width);
|
||||
width_slider.set_min(map_min_width);
|
||||
height_slider.set_min(map_min_height);
|
||||
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
@ -209,7 +208,7 @@ std::string new_map_dialog(display& disp, gamemap::TERRAIN fill_terrain,
|
|||
update_rect(xpos,ypos,width,height);
|
||||
}
|
||||
disp.update_display();
|
||||
SDL_Delay(10);
|
||||
SDL_Delay(20);
|
||||
events::pump();
|
||||
}
|
||||
}
|
||||
|
@ -324,16 +323,11 @@ void preferences_dialog(display &disp, config &prefs) {
|
|||
bool redraw_all = true;
|
||||
|
||||
for(;;) {
|
||||
int mousex, mousey;
|
||||
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
|
||||
|
||||
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
|
||||
|
||||
if(close_button.process(mousex,mousey,left_button)) {
|
||||
if(close_button.pressed()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(fullscreen_button.process(mousex,mousey,left_button)) {
|
||||
if(fullscreen_button.pressed()) {
|
||||
//the underlying frame buffer is changing, so cancel
|
||||
//the surface restorer restoring the frame buffer state
|
||||
restorer.cancel();
|
||||
|
@ -359,11 +353,11 @@ void preferences_dialog(display &disp, config &prefs) {
|
|||
redraw_all = false;
|
||||
}
|
||||
|
||||
if(grid_button.process(mousex,mousey,left_button)) {
|
||||
if(grid_button.pressed()) {
|
||||
preferences::set_grid(grid_button.checked());
|
||||
}
|
||||
|
||||
if(resolution_button.process(mousex,mousey,left_button)) {
|
||||
if(resolution_button.pressed()) {
|
||||
const bool mode_changed = preferences::show_video_mode_dialog(disp);
|
||||
if(mode_changed) {
|
||||
//the underlying frame buffer is changing, so cancel
|
||||
|
@ -373,7 +367,7 @@ void preferences_dialog(display &disp, config &prefs) {
|
|||
break;
|
||||
}
|
||||
|
||||
if(hotkeys_button.process(mousex,mousey,left_button)) {
|
||||
if(hotkeys_button.pressed()) {
|
||||
preferences::show_hotkeys_dialog(disp, &prefs);
|
||||
break;
|
||||
}
|
||||
|
@ -390,6 +384,123 @@ void preferences_dialog(display &disp, config &prefs) {
|
|||
}
|
||||
}
|
||||
|
||||
std::pair<unsigned, unsigned>
|
||||
resize_dialog(display &disp, const unsigned curr_w, const unsigned curr_h) {
|
||||
const events::resize_lock prevent_resizing;
|
||||
const events::event_context dialog_events_context;
|
||||
|
||||
int map_width(curr_w), map_height(curr_h);
|
||||
const int width = 600;
|
||||
const int height = 200;
|
||||
const int xpos = disp.x()/2 - width/2;
|
||||
const int ypos = disp.y()/2 - height/2;
|
||||
const int horz_margin = 5;
|
||||
const int vertical_margin = 20;
|
||||
const int button_padding = 20;
|
||||
|
||||
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 title_rect = font::draw_text(NULL,disp.screen_area(),24,font::NORMAL_COLOUR,
|
||||
"Resize Map",0,0);
|
||||
|
||||
const std::string& width_label = string_table["map_width"] + ":";
|
||||
const std::string& height_label = string_table["map_height"] + ":";
|
||||
|
||||
SDL_Rect width_rect = font::draw_text(NULL, disp.screen_area(), 14, font::NORMAL_COLOUR,
|
||||
width_label, 0, 0);
|
||||
SDL_Rect height_rect = font::draw_text(NULL, disp.screen_area(), 14, font::NORMAL_COLOUR,
|
||||
height_label, 0, 0);
|
||||
|
||||
const int text_right = xpos + horz_margin +
|
||||
maximum<int>(width_rect.w,height_rect.w);
|
||||
|
||||
width_rect.x = text_right - width_rect.w;
|
||||
height_rect.x = text_right - height_rect.w;
|
||||
|
||||
width_rect.y = ypos + title_rect.h + vertical_margin*2;
|
||||
height_rect.y = width_rect.y + width_rect.h + vertical_margin;
|
||||
|
||||
gui::button cancel_button(disp,"Cancel");
|
||||
gui::button ok_button(disp,"Ok");
|
||||
|
||||
cancel_button.set_location(xpos + width - cancel_button.width() - horz_margin,
|
||||
ypos + height - cancel_button.height()-14);
|
||||
|
||||
ok_button.set_location(xpos + width - cancel_button.width() - horz_margin
|
||||
- ok_button.width() - button_padding,
|
||||
ypos + height - ok_button.height()-14);
|
||||
|
||||
const int right_space = 100;
|
||||
const int slider_left = text_right + 10;
|
||||
const int slider_right = xpos + width - horz_margin - right_space;
|
||||
SDL_Rect slider_rect = { slider_left,width_rect.y,slider_right-slider_left,width_rect.h};
|
||||
|
||||
slider_rect.y = width_rect.y;
|
||||
gui::slider width_slider(disp,slider_rect);
|
||||
width_slider.set_min(map_min_width);
|
||||
width_slider.set_max(map_max_width);
|
||||
width_slider.set_value(map_width);
|
||||
|
||||
slider_rect.y = height_rect.y;
|
||||
gui::slider height_slider(disp,slider_rect);
|
||||
height_slider.set_min(map_min_height);
|
||||
height_slider.set_max(map_max_height);
|
||||
height_slider.set_value(map_height);
|
||||
for(bool draw = true;; draw = false) {
|
||||
if(cancel_button.pressed()) {
|
||||
return std::make_pair((unsigned)0, (unsigned)0);
|
||||
}
|
||||
if (width_slider.value() != map_width
|
||||
|| height_slider.value() != map_height) {
|
||||
draw = true;
|
||||
}
|
||||
if (draw) {
|
||||
map_width = width_slider.value();
|
||||
map_height = height_slider.value();
|
||||
gui::draw_dialog_frame(xpos,ypos,width,height,disp);
|
||||
title_rect = font::draw_text(&disp,disp.screen_area(),24,font::NORMAL_COLOUR,
|
||||
"Resize Map",xpos+(width-title_rect.w)/2,ypos+10);
|
||||
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,
|
||||
width_label,width_rect.x,width_rect.y);
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,
|
||||
height_label,height_rect.x,height_rect.y);
|
||||
|
||||
std::stringstream width_str;
|
||||
width_str << map_width;
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,width_str.str(),
|
||||
slider_right+horz_margin,width_rect.y);
|
||||
|
||||
std::stringstream height_str;
|
||||
height_str << map_height;
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,height_str.str(),
|
||||
slider_right+horz_margin,height_rect.y);
|
||||
|
||||
}
|
||||
if (ok_button.pressed()) {
|
||||
return std::make_pair((unsigned)map_width, (unsigned)map_height);
|
||||
}
|
||||
cancel_button.set_dirty();
|
||||
ok_button.set_dirty();
|
||||
|
||||
width_slider.set_min(map_min_width);
|
||||
height_slider.set_min(map_min_height);
|
||||
|
||||
events::raise_process_event();
|
||||
events::raise_draw_event();
|
||||
|
||||
if (draw) {
|
||||
update_rect(xpos,ypos,width,height);
|
||||
}
|
||||
disp.update_display();
|
||||
SDL_Delay(20);
|
||||
events::pump();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,12 @@ std::string load_map_dialog(display &disp);
|
|||
/// editor.
|
||||
void preferences_dialog(display &disp, config &prefs);
|
||||
|
||||
/// Show a dialog asking for the new size of the map. Return the chosen
|
||||
/// width and height. Checks are made to see that the desired values
|
||||
/// will result in a feasible map.
|
||||
std::pair<unsigned, unsigned>
|
||||
resize_dialog(display &disp, const unsigned curr_w, const unsigned curr_h);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "../map.hpp"
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "map_manip.hpp"
|
||||
|
||||
|
@ -97,8 +98,32 @@ get_component(const gamemap &map, const gamemap::location &start_loc) {
|
|||
return filled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string resize_map(const gamemap &map, const unsigned new_w,
|
||||
const unsigned new_h, const gamemap::TERRAIN fill_with) {
|
||||
std::string str_map = map.write();
|
||||
std::vector<std::string> lines = config::split(str_map, '\n');
|
||||
bool map_changed = false;
|
||||
const unsigned old_w = (unsigned)map.x();
|
||||
const unsigned old_h = (unsigned)map.y();
|
||||
if (old_h != new_h) {
|
||||
const std::string one_row(old_w, fill_with);
|
||||
lines.resize(new_h, one_row);
|
||||
map_changed = true;
|
||||
}
|
||||
if (new_w != old_w) {
|
||||
for (std::vector<std::string>::iterator it = lines.begin();
|
||||
it != lines.end(); it++) {
|
||||
(*it).resize(new_w, fill_with);
|
||||
}
|
||||
map_changed = true;
|
||||
}
|
||||
if (map_changed) {
|
||||
return config::join(lines, '\n');
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
namespace map_editor {
|
||||
|
||||
/// Return the tiles that are within radius from the location.
|
||||
std::vector<gamemap::location> get_tiles(const gamemap &map,
|
||||
const gamemap::location& a,
|
||||
const unsigned int radius);
|
||||
|
@ -33,9 +34,19 @@ typedef std::vector<std::pair<gamemap::location, gamemap::TERRAIN> > terrain_log
|
|||
void flood_fill(gamemap &map, const gamemap::location &start_loc,
|
||||
const gamemap::TERRAIN fill_with, terrain_log *log = NULL);
|
||||
|
||||
/// The the area that would be flood filled if a flood fill was requested.
|
||||
/// Return the area that would be flood filled if a flood fill was
|
||||
/// requested.
|
||||
std::set<gamemap::location>
|
||||
get_component(const gamemap &map, const gamemap::location &start_loc);
|
||||
|
||||
/// Return the string representation of the map after it has been
|
||||
/// resized to new_w X new_h. If the new dimensions are smaller than the
|
||||
/// current ones, the map will be cropped from the bottom and from the
|
||||
/// right. If the map becomes larger than the current dimensions, the
|
||||
/// new map area appeard at the bottom and/or the right and is filled
|
||||
/// with the terrain fill_with.
|
||||
std::string resize_map(const gamemap &map, const unsigned new_w,
|
||||
const unsigned new_h, const gamemap::TERRAIN fill_with);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ HOTKEY_COMMAND string_to_command(const std::string& str)
|
|||
m.insert(val("editcopy",HOTKEY_EDIT_COPY));
|
||||
m.insert(val("editpaste",HOTKEY_EDIT_PASTE));
|
||||
m.insert(val("editrevert",HOTKEY_EDIT_REVERT));
|
||||
m.insert(val("editresize",HOTKEY_EDIT_RESIZE));
|
||||
m.insert(val("delayshroud",HOTKEY_DELAY_SHROUD));
|
||||
m.insert(val("updateshroud",HOTKEY_UPDATE_SHROUD));
|
||||
m.insert(val("continue",HOTKEY_CONTINUE_MOVE));
|
||||
|
@ -467,6 +468,10 @@ void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* ex
|
|||
if(executor)
|
||||
executor->edit_revert();
|
||||
break;
|
||||
case HOTKEY_EDIT_RESIZE:
|
||||
if(executor)
|
||||
executor->edit_resize();
|
||||
break;
|
||||
default:
|
||||
std::cerr << "command_executor: unknown command number " << command << ", ignoring.\n";
|
||||
break;
|
||||
|
|
|
@ -43,7 +43,7 @@ enum HOTKEY_COMMAND { HOTKEY_CYCLE_UNITS, HOTKEY_END_UNIT_TURN, HOTKEY_LEADER,
|
|||
HOTKEY_EDIT_SAVE_AS, HOTKEY_EDIT_SET_START_POS,
|
||||
HOTKEY_EDIT_NEW_MAP, HOTKEY_EDIT_LOAD_MAP, HOTKEY_EDIT_FLOOD_FILL,
|
||||
HOTKEY_EDIT_FILL_SELECTION, HOTKEY_EDIT_CUT, HOTKEY_EDIT_COPY,
|
||||
HOTKEY_EDIT_PASTE, HOTKEY_EDIT_REVERT,
|
||||
HOTKEY_EDIT_PASTE, HOTKEY_EDIT_REVERT, HOTKEY_EDIT_RESIZE,
|
||||
HOTKEY_NULL };
|
||||
|
||||
struct hotkey_item {
|
||||
|
@ -132,6 +132,7 @@ public:
|
|||
virtual void edit_copy() {}
|
||||
virtual void edit_paste() {}
|
||||
virtual void edit_revert() {}
|
||||
virtual void edit_resize() {}
|
||||
|
||||
//Gets the action's image (if any). Displayed left of the action text in menus.
|
||||
virtual std::string get_action_image(hotkey::HOTKEY_COMMAND command) const { return ""; }
|
||||
|
|
Loading…
Add table
Reference in a new issue