minimap.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 "minimap.hpp"
  17. #include <iostream>
  18. #include <ClanLib/Display/display.h>
  19. #include <ClanLib/Display/surface.h>
  20. #include <ClanLib/Display/pixel_format.h>
  21. #include <ClanLib/Display/pixel_buffer.h>
  22. #include "tile.hpp"
  23. #include "tileset.hpp"
  24. #include "editor_map.hpp"
  25. #include "editor_map_component.hpp"
  26. #include "tilemap_layer.hpp"
  27. #include "lib/workspace.hpp"
  28. class MinimapImpl
  29. {
  30. public:
  31. std::vector<CL_Slot> slots;
  32. bool drag_active;
  33. int last_serial;
  34. EditorMap editor_map;
  35. EditorMapComponent* parent;
  36. CL_Surface minimap_surface;
  37. MinimapImpl()
  38. : editor_map(false)
  39. {}
  40. void update_minimap_surface();
  41. };
  42. Minimap::Minimap(EditorMapComponent* p, const CL_Rect& rect,
  43. CL_Component* parent)
  44. : CL_Component(rect, parent),
  45. impl(new MinimapImpl())
  46. {
  47. impl->slots.push_back(sig_paint().connect(this, &Minimap::draw));
  48. impl->slots.push_back(sig_mouse_move().connect(this, &Minimap::mouse_move));
  49. impl->slots.push_back(sig_mouse_down().connect(this, &Minimap::mouse_down));
  50. impl->slots.push_back(sig_mouse_up().connect(this, &Minimap::mouse_up));
  51. impl->parent = p ? p : EditorMapComponent::current();
  52. impl->drag_active = false;
  53. impl->last_serial = -1;
  54. }
  55. void
  56. Minimap::draw()
  57. {
  58. if (impl->parent->get_workspace().get_map().is_null()) return;
  59. if (!impl->parent || impl->parent->get_workspace().is_null())
  60. return;
  61. CL_Display::push_cliprect(get_screen_rect());
  62. CL_Display::push_translate(get_screen_x(), get_screen_y());
  63. // FIXME: Do this only on map changes
  64. if (impl->last_serial != impl->parent->get_workspace().get_map().get_serial())
  65. // || editor_map != parent->get_workspace().get_map())
  66. {
  67. impl->update_minimap_surface();
  68. impl->last_serial = impl->parent->get_workspace().get_map().get_serial();
  69. impl->editor_map = impl->parent->get_workspace().get_map();
  70. }
  71. if (1)
  72. { // Draw background color
  73. CL_Display::fill_rect(CL_Rect(CL_Point(0, 0),
  74. CL_Size(get_width(),
  75. get_height())),
  76. CL_Color(200, 200, 200, 225));
  77. }
  78. // FIXME: This doesn't work all that well
  79. TilemapLayer tilemap = TilemapLayer::current();
  80. if (!tilemap.is_null() && tilemap.get_height() != 0 && tilemap.get_width() != 0)
  81. {
  82. int tile_size = tilemap.get_tileset().get_tile_size();
  83. int map_width = tilemap.get_width() * tile_size;
  84. int map_height = tilemap.get_height() * tile_size;
  85. CL_Size small_tile(tile_size * get_width() / map_width + 1,
  86. tile_size * get_height() / map_height + 1);
  87. Field<int>* field = tilemap.get_field();
  88. // FIXME: No current tileset
  89. if (0)
  90. {
  91. for(int y = 0; y < field->get_height(); ++y)
  92. for(int x = 0; x < field->get_width(); ++x)
  93. {
  94. Tile* tile = tilemap.get_tileset().create(field->at(x, y));
  95. if (tile)
  96. CL_Display::fill_rect(CL_Rect(CL_Point((x * tile_size) * get_width() / map_width,
  97. (y * tile_size) * get_height() / map_height),
  98. small_tile),
  99. tile->get_color());
  100. CL_Display::flush();
  101. }
  102. }
  103. impl->minimap_surface.draw(CL_Rect(CL_Point(0, 0),
  104. CL_Size(get_width(), get_height())));
  105. // Draw cursor
  106. CL_Rect rect(impl->parent->get_clip_rect());
  107. CL_Rect screen_rect(CL_Point(rect.left * get_width() / map_width,
  108. rect.top * get_height() / map_height),
  109. CL_Size(rect.get_width() * get_width() /map_width,
  110. rect.get_height()* get_height()/map_height));
  111. CL_Display::fill_rect(screen_rect,
  112. CL_Color(255, 255, 0, 50));
  113. CL_Display::draw_rect(screen_rect,
  114. CL_Color(0, 0, 0));
  115. }
  116. CL_Display::pop_modelview();
  117. CL_Display::pop_cliprect();
  118. }
  119. void
  120. MinimapImpl::update_minimap_surface()
  121. {
  122. // FIXME: This doesn't work all that well
  123. TilemapLayer tilemap = TilemapLayer::current();
  124. if (!tilemap.is_null())
  125. {
  126. Field<int>* field = tilemap.get_field();
  127. CL_PixelBuffer buffer(tilemap.get_width(), tilemap.get_height(),
  128. tilemap.get_width()*4, CL_PixelFormat::rgba8888);
  129. int map_width = tilemap.get_width();
  130. int map_height = tilemap.get_height();
  131. // FIXME: No Tileset::current()
  132. unsigned char* buf = static_cast<unsigned char*>(buffer.get_data());
  133. for(int y = 0; y < map_height; ++y)
  134. for(int x = 0; x < map_width; ++x)
  135. {
  136. Tile* tile = tilemap.get_tileset().create(field->at(x, y));
  137. if (tile)
  138. {
  139. buf[4*(x + y * map_width) + 3] = tile->get_color().get_red();
  140. buf[4*(x + y * map_width) + 2] = tile->get_color().get_green();
  141. buf[4*(x + y * map_width) + 1] = tile->get_color().get_blue();
  142. buf[4*(x + y * map_width) + 0] = tile->get_color().get_alpha();
  143. }
  144. else
  145. {
  146. buf[4*(x + y * map_width) + 0] = 0;
  147. buf[4*(x + y * map_width) + 1] = 0;
  148. buf[4*(x + y * map_width) + 2] = 0;
  149. buf[4*(x + y * map_width) + 3] = 0;
  150. }
  151. }
  152. minimap_surface = CL_Surface(buffer);
  153. }
  154. }
  155. void
  156. Minimap::mouse_move(const CL_InputEvent& event)
  157. {
  158. // FIXME: This doesn't work all that well
  159. TilemapLayer tilemap = TilemapLayer::current();
  160. if (!tilemap.is_null())
  161. {
  162. int tile_size = tilemap.get_tileset().get_tile_size();
  163. int map_width = tilemap.get_width() * tile_size;
  164. int map_height = tilemap.get_height() * tile_size;
  165. if (impl->drag_active)
  166. impl->parent->move_to(event.mouse_pos.x * map_width / get_width(),
  167. event.mouse_pos.y * map_height / get_height());
  168. }
  169. }
  170. void
  171. Minimap::mouse_down(const CL_InputEvent& event)
  172. {
  173. // FIXME: This doesn't work all that well
  174. TilemapLayer tilemap = TilemapLayer::current();
  175. if (!tilemap.is_null())
  176. {
  177. int tile_size = tilemap.get_tileset().get_tile_size();
  178. int map_width = tilemap.get_width() * tile_size;
  179. int map_height = tilemap.get_height() * tile_size;
  180. impl->parent->move_to(event.mouse_pos.x * map_width / get_width(),
  181. event.mouse_pos.y * map_height / get_height());
  182. impl->drag_active = true;
  183. capture_mouse();
  184. }
  185. }
  186. void
  187. Minimap::mouse_up (const CL_InputEvent& event)
  188. {
  189. TilemapLayer tilemap = TilemapLayer::current();
  190. if (!tilemap.is_null())
  191. {
  192. impl->drag_active = false;
  193. release_mouse();
  194. }
  195. }
  196. void
  197. Minimap::update_minimap()
  198. {
  199. impl->update_minimap_surface();
  200. }
  201. /* EOF */