editor2: drag actions create one large undo action...
...instead of one undo per new hex the mouse is moved on
This commit is contained in:
parent
9323a46652
commit
24d96251e3
6 changed files with 118 additions and 45 deletions
|
@ -85,18 +85,30 @@ bool editor_action_area::add_location(const gamemap::location& loc)
|
|||
{
|
||||
return area_.insert(loc).second;
|
||||
}
|
||||
void editor_action_area::add_locations(const std::set<gamemap::location>& locs)
|
||||
{
|
||||
area_.insert(locs.begin(), locs.end());
|
||||
}
|
||||
void editor_action_area::extend(const editor_map& map, const std::set<gamemap::location>& locs)
|
||||
{
|
||||
area_.insert(locs.begin(), locs.end());
|
||||
}
|
||||
|
||||
void editor_action_paste::extend(const editor_map& map, const std::set<gamemap::location>& locs)
|
||||
{
|
||||
paste_.add_tiles(map, locs);
|
||||
}
|
||||
editor_action_paste* editor_action_paste::perform(map_context& mc) const
|
||||
{
|
||||
map_fragment mf(mc.get_map(), paste_.get_offset_area(loc_));
|
||||
std::auto_ptr<editor_action_paste> undo(new editor_action_paste(gamemap::location(0,0), mf));
|
||||
map_fragment mf(mc.get_map(), paste_.get_offset_area(offset_));
|
||||
std::auto_ptr<editor_action_paste> undo(new editor_action_paste(mf));
|
||||
perform_without_undo(mc);
|
||||
return undo.release();
|
||||
}
|
||||
void editor_action_paste::perform_without_undo(map_context& mc) const
|
||||
{
|
||||
paste_.paste_into(mc.get_map(), loc_);
|
||||
mc.add_changed_location(paste_.get_offset_area(loc_));
|
||||
paste_.paste_into(mc.get_map(), offset_);
|
||||
mc.add_changed_location(paste_.get_offset_area(offset_));
|
||||
mc.set_needs_terrain_rebuild();
|
||||
}
|
||||
|
||||
|
@ -115,7 +127,7 @@ void editor_action_paint_hex::perform_without_undo(map_context& mc) const
|
|||
editor_action_paste* editor_action_paint_area::perform(map_context& mc) const
|
||||
{
|
||||
map_fragment mf(mc.get_map(), area_);
|
||||
std::auto_ptr<editor_action_paste> undo(new editor_action_paste(gamemap::location(0,0), mf));
|
||||
std::auto_ptr<editor_action_paste> undo(new editor_action_paste(mf));
|
||||
perform_without_undo(mc);
|
||||
return undo.release();
|
||||
}
|
||||
|
@ -309,7 +321,7 @@ void editor_action_plot_route::perform_without_undo(map_context& /*mc*/) const
|
|||
editor_action_paste* editor_action_shuffle_area::perform(map_context& mc) const
|
||||
{
|
||||
map_fragment mf(mc.get_map(), area_);
|
||||
std::auto_ptr<editor_action_paste> undo(new editor_action_paste(gamemap::location(0,0), mf));
|
||||
std::auto_ptr<editor_action_paste> undo(new editor_action_paste(mf));
|
||||
perform_without_undo(mc);
|
||||
return undo.release();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,15 @@ class editor_action_whole_map : public editor_action
|
|||
editor_map m_;
|
||||
};
|
||||
|
||||
class editor_action_extendable : public editor_action
|
||||
{
|
||||
public:
|
||||
editor_action_extendable()
|
||||
{
|
||||
}
|
||||
virtual void extend(const editor_map& map, const std::set<gamemap::location>& locs) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Container action wrapping several actions into one.
|
||||
* The actions are performed in the order they are added,.
|
||||
|
@ -101,7 +110,7 @@ class editor_action_location_terrain : public editor_action_location
|
|||
/**
|
||||
* Base class for area-affecting actions
|
||||
*/
|
||||
class editor_action_area : public editor_action
|
||||
class editor_action_area : public editor_action_extendable
|
||||
{
|
||||
public:
|
||||
editor_action_area(const std::set<gamemap::location>& area)
|
||||
|
@ -109,6 +118,8 @@ class editor_action_area : public editor_action
|
|||
{
|
||||
}
|
||||
bool add_location(const gamemap::location& loc);
|
||||
void add_locations(const std::set<gamemap::location>& locs);
|
||||
void extend(const editor_map& map, const std::set<gamemap::location>& locs);
|
||||
protected:
|
||||
std::set<gamemap::location> area_;
|
||||
};
|
||||
|
@ -116,16 +127,18 @@ class editor_action_area : public editor_action
|
|||
/**
|
||||
* Paste a map fragment into the map. No offset is used.
|
||||
*/
|
||||
class editor_action_paste : public editor_action_location
|
||||
class editor_action_paste : public editor_action_extendable
|
||||
{
|
||||
public:
|
||||
editor_action_paste(const gamemap::location& loc, const map_fragment& paste)
|
||||
: editor_action_location(loc), paste_(paste)
|
||||
editor_action_paste(const map_fragment& paste, const gamemap::location& offset = gamemap::location(0,0))
|
||||
: offset_(offset), paste_(paste)
|
||||
{
|
||||
}
|
||||
editor_action_paste* perform(map_context& mc) const;
|
||||
void perform_without_undo(map_context& mc) const;
|
||||
void extend(const editor_map& map, const std::set<gamemap::location>& locs);
|
||||
protected:
|
||||
gamemap::location offset_;
|
||||
map_fragment paste_;
|
||||
};
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ map_fragment::map_fragment()
|
|||
|
||||
map_fragment::map_fragment(const gamemap& map, const std::set<gamemap::location>& area)
|
||||
{
|
||||
foreach (const gamemap::location& loc, area) {
|
||||
add_tile(map, loc);
|
||||
}
|
||||
add_tiles(map, area);
|
||||
}
|
||||
|
||||
void map_fragment::add_tile(const gamemap& map, const gamemap::location& loc)
|
||||
|
@ -36,6 +34,13 @@ void map_fragment::add_tile(const gamemap& map, const gamemap::location& loc)
|
|||
items_.push_back(tile_info(map, loc));
|
||||
}
|
||||
|
||||
void map_fragment::add_tiles(const gamemap& map, const std::set<gamemap::location>& locs)
|
||||
{
|
||||
foreach (const gamemap::location& loc, locs) {
|
||||
add_tile(map, loc);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<gamemap::location> map_fragment::get_area() const
|
||||
{
|
||||
std::set<gamemap::location> result;
|
||||
|
|
|
@ -63,6 +63,11 @@ class map_fragment
|
|||
*/
|
||||
void add_tile(const gamemap& map, const gamemap::location& loc);
|
||||
|
||||
/**
|
||||
* Add many locations and pull their info from the map.
|
||||
*/
|
||||
void add_tiles(const gamemap& map, const std::set<gamemap::location>& loc);
|
||||
|
||||
/**
|
||||
* Get the tile_info vector.
|
||||
*/
|
||||
|
|
|
@ -25,6 +25,31 @@
|
|||
|
||||
namespace editor2 {
|
||||
|
||||
class A
|
||||
{
|
||||
void doA(int);
|
||||
void doStuffThenA(int);
|
||||
template<void (A::*foo)(int)>
|
||||
void doStuffThenFoo(int);
|
||||
};
|
||||
|
||||
void A::doA(int)
|
||||
{
|
||||
}
|
||||
|
||||
void A::doStuffThenA(int a)
|
||||
{
|
||||
doStuffThenFoo<&A::doA>(a);
|
||||
}
|
||||
|
||||
template<void (A::*foo)(int)>
|
||||
void A::doStuffThenFoo(int a)
|
||||
{
|
||||
//doStuff
|
||||
(this->*foo)(a);
|
||||
}
|
||||
|
||||
|
||||
void mouse_action::move(editor_display& disp, const gamemap::location& hex)
|
||||
{
|
||||
if (hex != previous_move_hex_) {
|
||||
|
@ -126,32 +151,16 @@ editor_action* brush_drag_mouse_action::click_right(editor_display& disp, int x,
|
|||
}
|
||||
|
||||
editor_action* brush_drag_mouse_action::drag_left(editor_display& disp,
|
||||
int x, int y, bool& /*partial*/, editor_action* /*last_undo*/)
|
||||
int x, int y, bool& partial, editor_action* last_undo)
|
||||
{
|
||||
gamemap::location hex = disp.hex_clicked_on(x, y);
|
||||
move(disp, hex);
|
||||
if (hex != previous_drag_hex_) {
|
||||
editor_action* a = click_perform_left(disp, affected_hexes(disp, hex));
|
||||
previous_drag_hex_ = hex;
|
||||
return a;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
return drag_generic<&brush_drag_mouse_action::click_perform_left>(disp, x, y, partial, last_undo);
|
||||
}
|
||||
|
||||
editor_action* brush_drag_mouse_action::drag_right(editor_display& disp,
|
||||
int x, int y, bool& /*partial*/, editor_action* /*last_undo*/)
|
||||
int x, int y, bool& partial, editor_action* last_undo)
|
||||
{
|
||||
gamemap::location hex = disp.hex_clicked_on(x, y);
|
||||
move(disp, hex);
|
||||
if (hex != previous_drag_hex_) {
|
||||
editor_action* a = click_perform_right(disp, affected_hexes(disp, hex));
|
||||
previous_drag_hex_ = hex;
|
||||
return a;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return drag_generic<&brush_drag_mouse_action::click_perform_right>(disp, x, y, partial, last_undo);
|
||||
}
|
||||
|
||||
editor_action* brush_drag_mouse_action::drag_end(
|
||||
editor_display& /*disp*/, int /*x*/, int /*y*/)
|
||||
|
@ -159,6 +168,29 @@ editor_action* brush_drag_mouse_action::drag_end(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
template <editor_action_extendable* (brush_drag_mouse_action::*perform_func)(editor_display&, const std::set<gamemap::location>&)>
|
||||
editor_action* brush_drag_mouse_action::drag_generic(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo)
|
||||
{
|
||||
gamemap::location hex = disp.hex_clicked_on(x, y);
|
||||
move(disp, hex);
|
||||
if (hex != previous_drag_hex_) {
|
||||
std::set<gamemap::location> current_step_locs = affected_hexes(disp, hex);
|
||||
editor_action_extendable* last_undo_x = dynamic_cast<editor_action_extendable*>(last_undo);
|
||||
LOG_ED << "Last undo is " << last_undo << " and as x " << last_undo_x << "\n";
|
||||
if (last_undo_x != NULL) {
|
||||
last_undo_x->extend(disp.map(), current_step_locs);
|
||||
partial = true;
|
||||
} else {
|
||||
WRN_ED << "last undo in drag was not an editor_action_extendable\n";
|
||||
}
|
||||
editor_action* a = (this->*perform_func)(disp, affected_hexes(disp, hex));
|
||||
previous_drag_hex_ = hex;
|
||||
return a;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const brush& brush_drag_mouse_action::get_brush()
|
||||
{
|
||||
assert(brush_);
|
||||
|
@ -167,13 +199,13 @@ const brush& brush_drag_mouse_action::get_brush()
|
|||
}
|
||||
|
||||
|
||||
editor_action* mouse_action_paint::click_perform_left(
|
||||
editor_action_extendable* mouse_action_paint::click_perform_left(
|
||||
editor_display& /*disp*/, const std::set<gamemap::location>& hexes)
|
||||
{
|
||||
return new editor_action_paint_area(hexes, terrain_left_, has_alt_modifier());
|
||||
}
|
||||
|
||||
editor_action* mouse_action_paint::click_perform_right(
|
||||
editor_action_extendable* mouse_action_paint::click_perform_right(
|
||||
editor_display& /*disp*/, const std::set<gamemap::location>& hexes)
|
||||
{
|
||||
return new editor_action_paint_area(hexes, terrain_right_, has_alt_modifier());
|
||||
|
@ -198,13 +230,13 @@ editor_action* mouse_action_select::key_event(
|
|||
return ret;
|
||||
}
|
||||
|
||||
editor_action* mouse_action_select::click_perform_left(
|
||||
editor_action_extendable* mouse_action_select::click_perform_left(
|
||||
editor_display& /*disp*/, const std::set<gamemap::location>& hexes)
|
||||
{
|
||||
return new editor_action_select(hexes);
|
||||
}
|
||||
|
||||
editor_action* mouse_action_select::click_perform_right(
|
||||
editor_action_extendable* mouse_action_select::click_perform_right(
|
||||
editor_display& /*disp*/, const std::set<gamemap::location>& hexes)
|
||||
{
|
||||
return new editor_action_deselect(hexes);
|
||||
|
@ -220,7 +252,7 @@ std::set<gamemap::location> mouse_action_paste::affected_hexes(
|
|||
editor_action* mouse_action_paste::click_left(editor_display& disp, int x, int y)
|
||||
{
|
||||
gamemap::location hex = disp.hex_clicked_on(x, y);
|
||||
editor_action_paste* a = new editor_action_paste(hex, paste_);
|
||||
editor_action_paste* a = new editor_action_paste(paste_, hex);
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
|
@ -141,12 +141,12 @@ public:
|
|||
/**
|
||||
* The actual action function which is called by click() and drag(). Derived classes override this instead of click() and drag().
|
||||
*/
|
||||
virtual editor_action* click_perform_left(editor_display& disp, const std::set<gamemap::location>& hexes) = 0;
|
||||
virtual editor_action_extendable* click_perform_left(editor_display& disp, const std::set<gamemap::location>& hexes) = 0;
|
||||
|
||||
/**
|
||||
* The actual action function which is called by click() and drag(). Derived classes override this instead of click() and drag().
|
||||
*/
|
||||
virtual editor_action* click_perform_right(editor_display& disp, const std::set<gamemap::location>& hexes) = 0;
|
||||
virtual editor_action_extendable* click_perform_right(editor_display& disp, const std::set<gamemap::location>& hexes) = 0;
|
||||
|
||||
/**
|
||||
* Calls click_perform_left()
|
||||
|
@ -177,6 +177,9 @@ public:
|
|||
editor_action* drag_end(editor_display& disp, int x, int y);
|
||||
|
||||
protected:
|
||||
template <editor_action_extendable* (brush_drag_mouse_action::*perform_func)(editor_display&, const std::set<gamemap::location>&)>
|
||||
editor_action* drag_generic(editor_display& disp, int x, int y, bool& partial, editor_action* last_undo);
|
||||
|
||||
/** Brush accessor */
|
||||
const brush& get_brush();
|
||||
|
||||
|
@ -185,6 +188,9 @@ protected:
|
|||
* @todo keep a set of all "visited" locations to reduce action count in long drags that hit the same hexes multiple times?
|
||||
*/
|
||||
gamemap::location previous_drag_hex_;
|
||||
|
||||
editor_action* foo(editor_display&, const std::set<gamemap::location>&) {return NULL;}
|
||||
editor_action* bar(editor_display&, const std::set<gamemap::location>&) {return NULL;}
|
||||
private:
|
||||
/**
|
||||
* Current brush handle. Currently a pointer-to-pointer with full constness.
|
||||
|
@ -210,12 +216,12 @@ public:
|
|||
/**
|
||||
* Create an appropriate editor_action and return it
|
||||
*/
|
||||
editor_action* click_perform_left(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
editor_action_extendable* click_perform_left(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
|
||||
/**
|
||||
* Create an appropriate editor_action and return it
|
||||
*/
|
||||
editor_action* click_perform_right(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
editor_action_extendable* click_perform_right(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
|
||||
bool uses_terrains() const { return true; }
|
||||
protected:
|
||||
|
@ -247,12 +253,12 @@ public:
|
|||
/**
|
||||
* Left click/drag selects
|
||||
*/
|
||||
editor_action* click_perform_left(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
editor_action_extendable* click_perform_left(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
|
||||
/**
|
||||
* Right click/drag deselects
|
||||
*/
|
||||
editor_action* click_perform_right(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
editor_action_extendable* click_perform_right(editor_display& disp, const std::set<gamemap::location>& hexes);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue