Editor2: remove map flipping...

... Add clipboard flipping. Also fix a map_fragment issue.
This commit is contained in:
Tomasz Śniatowski 2008-09-23 19:14:39 +01:00
parent 956b4d7f4d
commit 6dbfc61efe
12 changed files with 132 additions and 103 deletions

View file

@ -6,6 +6,8 @@ Version 1.5.4+svn:
effects without having to close the settings dialog. The preferences
are shared with the old editor.
* Auto update transitions option is stored in the preferences
* Removed map flipping
* Added clipboard flipping
* Graphics:
* New or updated unit frames: Walking Corpse swimmer, Soulless swimmer
* Language and i18n:

View file

@ -130,7 +130,7 @@
id=menu-editor-edit
title= _ "Edit"
image=lite
items=undo,redo,editor-cut,editor-copy,editor-paste,editor-select-all,editor-select-inverse,editor-select-none,editor-selection-fill,editor-selection-rotate,editor-selection-flip,editor-selection-generate,editor-selection-randomize,editor-clipboard-rotate-cw,editor-clipboard-rotate-ccw
items=undo,redo,editor-cut,editor-copy,editor-paste,editor-select-all,editor-select-inverse,editor-select-none,editor-selection-fill,editor-selection-rotate,editor-selection-flip,editor-selection-generate,editor-selection-randomize,editor-clipboard-rotate-cw,editor-clipboard-rotate-ccw,editor-clipboard-flip-horizontal,editor-clipboard-flip-vertical
rect="+2,=,+100,="
xanchor=fixed
yanchor=fixed
@ -140,7 +140,7 @@
id=menu-editor-map
title= _ "Map"
image=lite
items=editor-map-resize,editor-map-rotate,editor-map-flip-x,editor-map-flip-y,editor-map-generate,editor-refresh,editor-update-transitions,editor-auto-update-transitions,editor-refresh-image-cache,editor-draw-coordinates,editor-draw-terrain-codes
items=editor-map-resize,editor-map-rotate,editor-map-generate,editor-refresh,editor-update-transitions,editor-auto-update-transitions,editor-refresh-image-cache,editor-draw-coordinates,editor-draw-terrain-codes
rect="+2,=,+100,="
xanchor=fixed
yanchor=fixed

View file

@ -6,6 +6,8 @@ Version 1.5.4+svn:
* Editor2
* Allow changing the display time of day from a preset list or to custom
values via sliders, available in the new editor settings dialog.
* Removed map flipping feature. Added clipboard flipping instead, which
works much more reliably.
* Language and translations
* updated translations: Finnish, German, Lithuanian, Slovak, Valencian.

View file

@ -344,18 +344,6 @@ void editor_action_rotate_map::perform_without_undo(map_context& /*mc*/) const
throw editor_action_not_implemented();
}
void editor_action_flip_x::perform_without_undo(map_context& mc) const
{
mc.get_map().flip_x();
mc.set_needs_reload();
}
void editor_action_flip_y::perform_without_undo(map_context& mc) const
{
mc.get_map().flip_y();
mc.set_needs_reload();
}
editor_action_paste* editor_action_plot_route::perform(map_context& /*mc*/) const
{
throw editor_action_not_implemented();

View file

@ -403,31 +403,6 @@ class editor_action_rotate_map : public editor_action
int angle_;
};
/**
* Flip the map along the X axis.
*/
class editor_action_flip_x : public editor_action
{
public:
editor_action_flip_x()
{
}
void perform_without_undo(map_context& mc) const;
};
/**
* Flip the map along the Y axis.
*/
class editor_action_flip_y : public editor_action
{
public:
editor_action_flip_y()
{
}
void perform_without_undo(map_context& mc) const;
bool require_map_reload() { return true; }
};
//plot a route between two points
class editor_action_plot_route : public editor_action_location_terrain
{

View file

@ -578,13 +578,13 @@ bool editor_controller::can_execute_command(hotkey::HOTKEY_COMMAND command, int
return !clipboard_.empty();
case HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW:
case HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW:
return !clipboard_.empty() && is_mouse_action_set(HOTKEY_EDITOR_PASTE);
case HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL:
case HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL:
return !clipboard_.empty();
case HOTKEY_EDITOR_SELECT_ALL:
case HOTKEY_EDITOR_SELECT_INVERSE:
case HOTKEY_EDITOR_SELECT_NONE:
case HOTKEY_EDITOR_MAP_RESIZE:
case HOTKEY_EDITOR_MAP_FLIP_X:
case HOTKEY_EDITOR_MAP_FLIP_Y:
case HOTKEY_EDITOR_MAP_GENERATE:
case HOTKEY_EDITOR_REFRESH:
case HOTKEY_EDITOR_UPDATE_TRANSITIONS:
@ -663,6 +663,14 @@ bool editor_controller::execute_command(hotkey::HOTKEY_COMMAND command, int inde
clipboard_.rotate_60_ccw();
update_mouse_action_highlights();
return true;
case HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL:
clipboard_.flip_horizontal();
update_mouse_action_highlights();
return true;
case HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL:
clipboard_.flip_vertical();
update_mouse_action_highlights();
return true;
case HOTKEY_EDITOR_BRUSH_NEXT:
cycle_brush();
return true;
@ -688,12 +696,6 @@ bool editor_controller::execute_command(hotkey::HOTKEY_COMMAND command, int inde
case HOTKEY_EDITOR_SELECTION_RANDOMIZE:
perform_refresh(editor_action_shuffle_area(get_map().selection()));
return true;
case HOTKEY_EDITOR_MAP_FLIP_X:
perform_refresh(editor_action_flip_x());
return true;
case HOTKEY_EDITOR_MAP_FLIP_Y:
perform_refresh(editor_action_flip_y());
return true;
case HOTKEY_EDITOR_MAP_LOAD:
load_map_dialog();
return true;

View file

@ -79,6 +79,11 @@ void editor_map::sanity_check()
++errors;
}
}
foreach (const location& loc, selection_) {
if (!on_board_with_border(loc)) {
ERR_ED << "Off-map tile in selection: " << loc << "\n";
}
}
if (errors) {
throw editor_map_integrity_error();
}
@ -128,7 +133,7 @@ bool editor_map::in_selection(const gamemap::location& loc) const
bool editor_map::add_to_selection(const gamemap::location& loc)
{
return selection_.insert(loc).second;
return on_board_with_border(loc) ? selection_.insert(loc).second : false;
}
bool editor_map::remove_from_selection(const gamemap::location& loc)
@ -166,6 +171,18 @@ bool editor_map::everything_selected() const
return static_cast<int>(selection_.size()) == total_width() * total_height();
}
void editor_map::sanitize_selection()
{
std::set<location>::iterator it = selection_.begin();
while (it != selection_.end()) {
if (on_board_with_border(*it)) {
++it;
} else {
selection_.erase(it++);
}
}
}
void editor_map::resize(int width, int height, int x_offset, int y_offset,
t_translation::t_terrain filler)
{
@ -214,52 +231,6 @@ void editor_map::resize(int width, int height, int x_offset, int y_offset,
sanity_check();
}
void editor_map::flip_x()
{
LOG_ED << "FlipX\n";
// Due to the hexes we need some mirror tricks when mirroring over the
// X axis. We resize the map and fill it. The odd columns will be extended
// with the data in row 0 the even columns are extended with the data in
// the last row
const size_t middle = (tiles_[0].size() / 2); // the middle if reached we flipped all
const size_t end = tiles_[0].size() - 1; // the last row _before_ resizing
for(size_t x = 0; x < tiles_.size(); ++x) {
if(x % 2) {
// odd lines
tiles_[x].resize(tiles_[x].size() + 1, tiles_[x][0]);
for(size_t y1 = 0, y2 = end; y1 < middle; ++y1, --y2) {
swap_starting_position(x, y1, x, y2);
std::swap(tiles_[x][y1], tiles_[x][y2]);
}
} else {
// even lines
tiles_[x].resize(tiles_[x].size() + 1, tiles_[x][end]);
for(size_t y1 = 0, y2 = end + 1; y1 < middle; ++y1, --y2) {
swap_starting_position(x, y1, x, y2);
std::swap(tiles_[x][y1], tiles_[x][y2]);
}
}
}
h_++;
total_height_++;
sanity_check();
}
void editor_map::flip_y()
{
LOG_ED << "FlipY\n";
// Flipping on the Y axis requires no resize,
// so the code is much simpler.
const size_t middle = (tiles_.size() / 2);
const size_t end = tiles_.size() - 1;
for(size_t y = 0; y < tiles_[0].size(); ++y) {
for(size_t x1 = 0, x2 = end; x1 < middle; ++x1, --x2) {
swap_starting_position(x1, y, x2, y);
std::swap(tiles_[x1][y], tiles_[x2][y]);
}
}
}
void editor_map::swap_starting_position(int x1, int y1, int x2, int y2)
{
int pos1 = is_starting_position(location(x1, y1));

View file

@ -113,6 +113,11 @@ public:
* @return true if the entire map is selected, false otherwise
*/
bool everything_selected() const;
/**
* Ensure no off-map tiles are in the selection
*/
void sanitize_selection();
/**
* Resize the map. If the filler is NONE, the border terrain will be copied

View file

@ -16,6 +16,7 @@
#include "../foreach.hpp"
#include <sstream>
#include <vector>
namespace editor2 {
@ -73,7 +74,18 @@ void map_fragment::shift(const gamemap::location& offset)
{
foreach (tile_info& ti, items_) {
ti.offset.vector_sum_assign(offset);
}
}
}
gamemap::location map_fragment::top_left_boundary() const
{
gamemap::location top_left = items_[0].offset;
for (size_t i = 1; i < items_.size(); ++i) {
const gamemap::location& loc = items_[i].offset;
if (loc.x < top_left.x) top_left.x = loc.x;
if (loc.y < top_left.y) top_left.y = loc.y;
}
return top_left;
}
gamemap::location map_fragment::center_of_bounds() const
@ -99,19 +111,32 @@ gamemap::location map_fragment::center_of_mass() const
foreach (const tile_info& ti, items_) {
sum.vector_sum_assign(ti.offset);
}
sum.x /= items_.size();
sum.y /= items_.size();
sum.x /= static_cast<int>(items_.size());
sum.y /= static_cast<int>(items_.size());
return sum;
}
void map_fragment::normalize()
{
shift(top_left_boundary().vector_negation());
}
void map_fragment::center_by_bounds()
{
shift(center_of_bounds().vector_negation());
area_.clear();
foreach (tile_info& ti, items_) {
area_.insert(ti.offset);
}
}
void map_fragment::center_by_mass()
{
shift(center_of_mass().vector_negation());
area_.clear();
foreach (tile_info& ti, items_) {
area_.insert(ti.offset);
}
}
void map_fragment::rotate_60_cw()
@ -154,10 +179,43 @@ void map_fragment::rotate_60_ccw()
}
}
void map_fragment::flip_horizontal()
{
foreach (tile_info& ti, items_) {
ti.offset.x = -ti.offset.x;
}
center_by_mass();
}
void map_fragment::flip_vertical()
{
foreach (tile_info& ti, items_) {
ti.offset.y = -ti.offset.y;
if (ti.offset.x % 2) {
ti.offset.y--;
}
}
center_by_mass();
}
bool map_fragment::empty() const
{
return items_.empty();
}
std::string map_fragment::dump() const
{
std::stringstream ss;
ss << "MF: ";
foreach (const tile_info& ti, items_) {
ss << "(" << ti.offset << ")";
}
ss << " -- ";
foreach (const gamemap::location& loc, area_) {
ss << "(" << loc << ")";
}
return ss.str();
}
} //end namespace editor2

View file

@ -93,6 +93,12 @@ class map_fragment
*/
void shift(const gamemap::location& offset);
/**
* Return a location at the top left corner of this fragment's
* bounding rectangle
*/
gamemap::location top_left_boundary() const;
/**
* Get the center of the map fragment, bounds-wise.
*/
@ -103,6 +109,11 @@ class map_fragment
*/
gamemap::location center_of_mass() const;
/**
* Shift the map fragment so that all locations have nonnegative coordinates
*/
void normalize();
/**
* Shift the map fragment so it is roughly centered around the (0,0) point, bounds-wise.
*/
@ -128,6 +139,21 @@ class map_fragment
*/
void rotate_60_ccw();
/**
* Flip the map fragment horizontally
*/
void flip_horizontal();
/**
* Flip the map fragment vertically
*/
void flip_vertical();
/**
* Debug dump to a string
*/
std::string dump() const;
protected:
/**
* The data of this map_fragment

View file

@ -163,6 +163,10 @@ const struct {
N_("Rotate Clipboard Clockwise"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW, "editor-clipboard-rotate-ccw",
N_("Rotate Clipboard Counter-Clockwise"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL, "editor-clipboard-flip-horizontal",
N_("Flip Clipboard Horizontally"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL, "editor-clipboard-flip-vertical",
N_("Flip Clipboard Vertically"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_SELECTION_ROTATE, "editor-selection-rotate",
N_("Rotate Selection"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_SELECTION_FLIP, "editor-selection-flip",
@ -177,10 +181,6 @@ const struct {
N_("Resize Map"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_MAP_ROTATE, "editor-map-rotate",
N_("Rotate Map"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_MAP_FLIP_X, "editor-map-flip-x",
N_("Flip Map along X axis"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_MAP_FLIP_Y, "editor-map-flip-y",
N_("Flip Map along Y axis"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_MAP_GENERATE, "editor-map-generate",
N_("Generate Map"), false, hotkey::SCOPE_EDITOR },
{ hotkey::HOTKEY_EDITOR_REFRESH, "editor-refresh",

View file

@ -84,11 +84,11 @@ enum HOTKEY_COMMAND {
HOTKEY_EDITOR_SELECT_ALL, HOTKEY_EDITOR_SELECT_INVERSE,
HOTKEY_EDITOR_SELECT_NONE,
HOTKEY_EDITOR_CLIPBOARD_ROTATE_CW, HOTKEY_EDITOR_CLIPBOARD_ROTATE_CCW,
HOTKEY_EDITOR_CLIPBOARD_FLIP_HORIZONTAL, HOTKEY_EDITOR_CLIPBOARD_FLIP_VERTICAL,
HOTKEY_EDITOR_SELECTION_ROTATE, HOTKEY_EDITOR_SELECTION_FLIP,
HOTKEY_EDITOR_SELECTION_FILL,
HOTKEY_EDITOR_SELECTION_GENERATE, HOTKEY_EDITOR_SELECTION_RANDOMIZE,
HOTKEY_EDITOR_MAP_RESIZE, HOTKEY_EDITOR_MAP_ROTATE,
HOTKEY_EDITOR_MAP_FLIP_X, HOTKEY_EDITOR_MAP_FLIP_Y,
HOTKEY_EDITOR_MAP_GENERATE,
HOTKEY_EDITOR_REFRESH, HOTKEY_EDITOR_UPDATE_TRANSITIONS,
HOTKEY_EDITOR_AUTO_UPDATE_TRANSITIONS,