editor_map.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // Flexlay - A Generic 2D Game Editor
  2. // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "editor_map.hpp"
  17. #include <ClanLib/Display/graphic_context.h>
  18. #include <assert.h>
  19. #include <iostream>
  20. #include "meta_data.hpp"
  21. class EditorMapImpl
  22. {
  23. public:
  24. /** Flag if the map got modified, used for 'Some maps are unsaved'
  25. style massages */
  26. bool modified;
  27. /** Gets incremented with each map change so that other component
  28. can update if required */
  29. int serial;
  30. typedef std::vector<Layer> Layers;
  31. Layers layers;
  32. CL_Color background_color;
  33. CL_Color foreground_color;
  34. /** Metadata attached to this map (ie. mapname, description, scripts, etc.) */
  35. MetaData metadata;
  36. typedef std::vector<Command> Commands;
  37. Commands undo_stack;
  38. Commands redo_stack;
  39. CL_Signal_v0 on_change;
  40. bool has_bounding_rect;
  41. CL_Rect bounding_rect;
  42. };
  43. EditorMap::EditorMap(bool create) :
  44. impl()
  45. {
  46. if (create)
  47. {
  48. impl.reset(new EditorMapImpl());
  49. impl->background_color = CL_Color(100, 80, 100);
  50. impl->foreground_color = CL_Color(255, 80, 255);
  51. impl->modified = false;
  52. impl->serial = 0;
  53. impl->has_bounding_rect = false;
  54. impl->bounding_rect = CL_Rect(0,0,0,0);
  55. }
  56. }
  57. void
  58. EditorMap::add_layer(const Layer& layer, int pos)
  59. {
  60. std::cout << impl << " EditorMap::add_layer" << std::endl;
  61. assert(pos == -1 || (pos >= 0 && pos < int(impl->layers.size())));
  62. if (pos == -1) // insert at last pos
  63. impl->layers.push_back(layer);
  64. else
  65. impl->layers.insert(impl->layers.begin() + pos, layer);
  66. impl->serial += 1;
  67. }
  68. void
  69. EditorMap::draw_gui(CL_GraphicContext* gc)
  70. {
  71. CL_Rect rect = get_bounding_rect();
  72. if (rect != CL_Rect(0,0,0,0))
  73. {
  74. gc->fill_rect(rect, impl->background_color);
  75. gc->draw_rect(rect, impl->foreground_color);
  76. }
  77. else
  78. {
  79. gc->clear(impl->background_color);
  80. }
  81. }
  82. void
  83. EditorMap::draw(const GraphicContextState& state, CL_GraphicContext* gc)
  84. {
  85. for(EditorMapImpl::Layers::iterator i = impl->layers.begin(); i != impl->layers.end(); ++i)
  86. (*i).draw(state, gc);
  87. gc->flush();
  88. }
  89. bool
  90. EditorMap::is_modified() const
  91. {
  92. return impl->modified;
  93. }
  94. void
  95. EditorMap::set_unmodified()
  96. {
  97. impl->modified = false;
  98. }
  99. void
  100. EditorMap::modify()
  101. {
  102. impl->modified = true;
  103. impl->serial += 1;
  104. }
  105. int
  106. EditorMap::get_serial() const
  107. {
  108. return impl->serial;
  109. }
  110. int
  111. EditorMap::get_layer_count() const
  112. {
  113. return static_cast<int>(impl->layers.size());
  114. }
  115. Layer
  116. EditorMap::get_layer(int i)
  117. {
  118. if (i >= 0 && i < static_cast<int>(impl->layers.size()))
  119. return impl->layers[i];
  120. else
  121. return Layer();
  122. }
  123. void
  124. EditorMap::set_metadata(const MetaData& obj)
  125. {
  126. impl->metadata = obj;
  127. }
  128. MetaData
  129. EditorMap::get_metadata() const
  130. {
  131. return impl->metadata;
  132. }
  133. bool
  134. EditorMap::has_bounding_rect() const
  135. {
  136. return impl->has_bounding_rect;
  137. }
  138. void
  139. EditorMap::set_bounding_rect(const CL_Rect& rect)
  140. {
  141. if (rect != CL_Rect(0,0,0,0))
  142. {
  143. impl->has_bounding_rect = true;
  144. impl->bounding_rect = rect;
  145. }
  146. else
  147. {
  148. impl->has_bounding_rect = false;
  149. impl->bounding_rect = rect;
  150. }
  151. }
  152. CL_Rect
  153. EditorMap::get_bounding_rect()
  154. {
  155. if (impl->has_bounding_rect)
  156. {
  157. return impl->bounding_rect;
  158. }
  159. else
  160. {
  161. bool init = false;
  162. CL_Rect rect(0,0,0,0);
  163. for(EditorMapImpl::Layers::iterator i = impl->layers.begin(); i != impl->layers.end(); ++i)
  164. {
  165. if (i->has_bounding_rect())
  166. {
  167. if (!init)
  168. {
  169. rect = i->get_bounding_rect();
  170. init = true;
  171. }
  172. else
  173. {
  174. CL_Rect other = i->get_bounding_rect();
  175. rect.top = std::min(rect.top, other.top);
  176. rect.bottom = std::max(rect.bottom, other.bottom);
  177. rect.left = std::min(rect.left, other.left);
  178. rect.right = std::max(rect.right, other.right);
  179. }
  180. }
  181. }
  182. return rect;
  183. }
  184. }
  185. void
  186. EditorMap::set_background_color(const CL_Color& color)
  187. {
  188. impl-> background_color = color;
  189. }
  190. void
  191. EditorMap::execute(Command command)
  192. {
  193. impl->redo_stack.clear();
  194. command.execute();
  195. impl->undo_stack.push_back(command);
  196. impl->on_change();
  197. }
  198. void
  199. EditorMap::undo()
  200. {
  201. if (!impl->undo_stack.empty())
  202. {
  203. Command command = impl->undo_stack.back();
  204. impl->undo_stack.pop_back();
  205. command.undo();
  206. impl->redo_stack.push_back(command);
  207. impl->on_change();
  208. }
  209. }
  210. void
  211. EditorMap::redo()
  212. {
  213. if (!impl->redo_stack.empty())
  214. {
  215. Command command = impl->redo_stack.back();
  216. impl->redo_stack.pop_back();
  217. command.redo();
  218. impl->undo_stack.push_back(command);
  219. impl->on_change();
  220. }
  221. }
  222. int
  223. EditorMap::undo_stack_size()
  224. {
  225. return impl->undo_stack.size();
  226. }
  227. int
  228. EditorMap::redo_stack_size()
  229. {
  230. return impl->redo_stack.size();
  231. }
  232. CL_Signal_v0&
  233. EditorMap::sig_change()
  234. {
  235. return impl->on_change;
  236. }
  237. /* EOF */