20130313
[gdash.git] / src / cave / object / caveobjectcopypaste.cpp
blobd0e9cd036db2e3abf809d0711e08e46020655810
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "config.h"
19 #include "cave/object/caveobjectcopypaste.hpp"
21 #include <glib/gi18n.h>
23 #include "fileops/bdcffhelper.hpp"
24 #include "cave/caverendered.hpp"
25 #include "misc/printf.hpp"
26 #include "misc/logger.hpp"
27 #include "misc/util.hpp"
29 std::string CaveCopyPaste::get_bdcff() const
31 return BdcffFormat("CopyPaste") << p1 << p2 << dest << (mirror?"mirror":"nomirror") << (flip?"flip":"noflip");
34 CaveCopyPaste* CaveCopyPaste::clone_from_bdcff(const std::string &name, std::istream &is) const
36 Coordinate p1, p2, dest;
37 std::string mirror="nomirror", flip="noflip";
38 bool bmirror, bflip;
40 if (!(is >> p1 >> p2 >> dest))
41 return NULL;
42 is >> mirror >> flip;
43 if (gd_str_ascii_caseequal(mirror, "mirror"))
44 bmirror=true;
45 else
46 if (gd_str_ascii_caseequal(mirror, "nomirror"))
47 bmirror=false;
48 else {
49 bmirror=false;
50 gd_warning(CPrintf("invalid setting for copypaste mirror property: %s") % mirror);
52 if (gd_str_ascii_caseequal(flip, "flip"))
53 bflip=true;
54 else
55 if (gd_str_ascii_caseequal(flip, "noflip"))
56 bflip=false;
57 else {
58 bflip=false;
59 gd_warning(CPrintf("invalid setting for copypaste mirror property: %s") % flip);
62 CaveCopyPaste *cp=new CaveCopyPaste(p1, p2, dest);
63 cp->set_mirror_flip(bmirror, bflip);
65 return cp;
68 /// Create a copy and paste object.
69 /// Sets mirror and flip to false.
70 /// @param _p1 Corner of source area
71 /// @param _p2 Other corner of source area
72 /// @param _dest Upper left corner of destination area.
73 CaveCopyPaste::CaveCopyPaste(Coordinate _p1, Coordinate _p2, Coordinate _dest)
74 : CaveObject(GD_COPY_PASTE),
75 p1(_p1),
76 p2(_p2),
77 dest(_dest),
78 mirror(false),
79 flip(false)
83 /// Set mirror and flip coordinates.
84 /// They are initialized to false by the default constructor.
85 void CaveCopyPaste::set_mirror_flip(bool _mirror, bool _flip)
87 mirror=_mirror;
88 flip=_flip;
91 void CaveCopyPaste::draw(CaveRendered &cave) const
93 int x1=p1.x, y1=p1.y, x2=p2.x, y2=p2.y;
94 int w, h;
96 /* reorder coordinates if not drawing from northwest to southeast */
97 if (x2<x1)
98 std::swap(x1, x2);
99 if (y2<y1)
100 std::swap(y1, y2);
101 w=x2-x1+1;
102 h=y2-y1+1;
103 CaveMap<GdElementEnum> clipboard;
104 clipboard.set_size(w, h);
106 /* copy to "clipboard" */
107 for (int y=0; y<h; y++)
108 for (int x=0; x<w; x++)
109 clipboard(x, y)=cave.map(x+x1, y+y1);
111 for (int y=0; y<h; y++) {
112 int ydisp=flip?h-1-y:y;
113 for (int x=0; x<w; x++) {
114 int xdisp=mirror?w-1-x:x;
115 /* dx and dy are used here are "paste to" coordinates */
116 cave.store_rc(dest.x+xdisp, dest.y+ydisp, clipboard(x, y), this);
121 PropertyDescription const CaveCopyPaste::descriptor[] = {
122 {"", GD_TAB, 0, N_("Draw")},
123 {"", GD_TYPE_BOOLEAN_LEVELS, 0, N_("Levels"), GetterBase::create_new(&CaveCopyPaste::seen_on), N_("Levels on which this object is visible.")},
124 {"", GD_TYPE_COORDINATE, 0, N_("Start"), GetterBase::create_new(&CaveCopyPaste::p1), N_("Specifies one of the corners of the source area."), 0, 127},
125 {"", GD_TYPE_COORDINATE, 0, N_("End"), GetterBase::create_new(&CaveCopyPaste::p2), N_("Specifies one of the corners of the source area."), 0, 127},
126 {"", GD_TYPE_COORDINATE, 0, N_("Paste"), GetterBase::create_new(&CaveCopyPaste::dest), N_("Specifies the upper left corner of the destination area."), 0, 127},
127 {"", GD_TYPE_BOOLEAN, 0, N_("Mirror"), GetterBase::create_new(&CaveCopyPaste::mirror), N_("If checked, the contents will be mirrored horizontally.")},
128 {"", GD_TYPE_BOOLEAN, 0, N_("Flip"), GetterBase::create_new(&CaveCopyPaste::flip), N_("If checked, the contents will be mirrored vertically.")},
129 {NULL},
132 PropertyDescription const* CaveCopyPaste::get_description_array() const
134 return descriptor;
137 std::string CaveCopyPaste::get_coordinates_text() const
139 return SPrintf("%d,%d-%d,%d (%d,%d)") % p1.x % p1.y % p2.x % p2.y % dest.x % dest.y;
142 void CaveCopyPaste::create_drag(Coordinate current, Coordinate displacement)
144 /* p1 is set fixed. now set p2. displacement is ignored. */
145 p2=current;
146 /* set the destination to be the same area as the source; so the user can move it. */
147 dest.x=std::min(p1.x, p2.x);
148 dest.y=std::min(p1.y, p2.y);
151 void CaveCopyPaste::move(Coordinate current, Coordinate displacement)
153 /* source area is unchanged; move only destination. */
154 dest+=displacement;
157 void CaveCopyPaste::move(Coordinate displacement)
159 /* source area is unchanged; move only destination. */
160 dest+=displacement;
163 std::string CaveCopyPaste::get_description_markup() const
165 return SPrintf(_("Copy from %d,%d-%d,%d, paste to %d,%d"))
166 % p1.x % p1.y % p2.x % p2.y % dest.x % dest.y;