tile_selector.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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 "tile_selector.hpp"
  17. #include <iostream>
  18. #include <ClanLib/display.h>
  19. #include "math.hpp"
  20. #include "tile.hpp"
  21. #include "tile_brush.hpp"
  22. #include "tools/tilemap_paint_tool.hpp"
  23. TileSelector::TileSelector(const CL_Rect& rect, CL_Component* parent) :
  24. CL_Component(rect, parent),
  25. width(1)
  26. {
  27. index = 0;
  28. slots.connect(sig_paint(), this, &TileSelector::draw);
  29. slots.connect(sig_mouse_move(), this, &TileSelector::mouse_move);
  30. slots.connect(sig_mouse_down(), this, &TileSelector::mouse_down);
  31. slots.connect(sig_mouse_up (), this, &TileSelector::mouse_up);
  32. scale = 1.0f;
  33. mouse_over_tile = -1;
  34. scrolling = false;
  35. region_select = false;
  36. offset = 0;
  37. }
  38. TileSelector::~TileSelector()
  39. {
  40. std::cout << "~TileSelector()" << std::endl;
  41. }
  42. CL_Rect
  43. TileSelector::get_selection()
  44. {
  45. CL_Rect selection(current_pos.x, current_pos.y,
  46. region_select_start.x, region_select_start.y);
  47. selection.normalize();
  48. selection.right += 1;
  49. selection.bottom += 1;
  50. selection.left = Math::mid(0, selection.left, width);
  51. selection.right = Math::mid(0, selection.right, width);
  52. selection.top = Math::max(0, selection.top);
  53. return selection;
  54. }
  55. void
  56. TileSelector::mouse_up(const CL_InputEvent& event)
  57. {
  58. if (event.id == CL_MOUSE_MIDDLE)
  59. {
  60. scrolling = false;
  61. release_mouse();
  62. }
  63. else if (event.id == CL_MOUSE_RIGHT)
  64. {
  65. release_mouse();
  66. region_select = false;
  67. CL_Rect selection = get_selection();
  68. //selection.bottom = Math::mid(0, selection.right, width);
  69. TileBrush brush(selection.get_width(), selection.get_height());
  70. brush.set_transparent();
  71. for(int y = 0; y < selection.get_height(); ++y)
  72. for(int x = 0; x < selection.get_width(); ++x)
  73. {
  74. int tile = (selection.top + y) * width + (selection.left + x);
  75. if (tile >= 0 && tile < int(tiles.size()))
  76. brush.at(x, y) = tiles[tile];
  77. else
  78. brush.at(x, y) = 0;
  79. }
  80. TileMapPaintTool::current().set_brush(brush);
  81. }
  82. }
  83. void
  84. TileSelector::mouse_down(const CL_InputEvent& event)
  85. {
  86. if (event.id == CL_MOUSE_LEFT)
  87. {
  88. TileBrush brush(1, 1);
  89. brush.set_opaque();
  90. if (mouse_over_tile >= 0 && mouse_over_tile < int(tiles.size()))
  91. brush.at(0, 0) = tiles[mouse_over_tile];
  92. else
  93. brush.at(0, 0) = 0;
  94. TileMapPaintTool::current().set_brush(brush);
  95. }
  96. else if (event.id == CL_MOUSE_RIGHT)
  97. {
  98. region_select = true;
  99. region_select_start = current_pos;
  100. capture_mouse();
  101. }
  102. else if (event.id == CL_MOUSE_MIDDLE)
  103. {
  104. scrolling = true;
  105. mouse_pos = event.mouse_pos;
  106. old_offset = offset;
  107. capture_mouse();
  108. }
  109. else if (event.id == CL_MOUSE_WHEEL_UP)
  110. {
  111. offset -= static_cast<int>(tileset.get_tile_size()*scale);
  112. if (offset < 0)
  113. offset = 0;
  114. }
  115. else if (event.id == CL_MOUSE_WHEEL_DOWN)
  116. {
  117. offset += static_cast<int>(tileset.get_tile_size()*scale);
  118. }
  119. }
  120. CL_Point
  121. TileSelector::get_mouse_tile_pos(const CL_InputEvent& event)
  122. {
  123. return CL_Point(event.mouse_pos.x/static_cast<int>(tileset.get_tile_size()*scale),
  124. (event.mouse_pos.y+offset)/static_cast<int>(tileset.get_tile_size()*scale));
  125. }
  126. void
  127. TileSelector::mouse_move(const CL_InputEvent& event)
  128. {
  129. CL_Point pos = get_mouse_tile_pos(event);
  130. current_pos = pos;
  131. mouse_over_tile = pos.y * width + pos.x;
  132. if (scrolling)
  133. {
  134. offset = old_offset + (mouse_pos.y - event.mouse_pos.y);
  135. if (offset < 0)
  136. offset = 0;
  137. }
  138. }
  139. void
  140. TileSelector::draw()
  141. {
  142. CL_Display::push_cliprect(get_screen_rect());
  143. CL_Display::push_modelview();
  144. CL_Display::add_translate(get_screen_x(), get_screen_y());
  145. CL_Display::add_translate(0, -offset);
  146. const TileBrush& brush = TileMapPaintTool::current().get_brush();
  147. int start_row = offset / int(tileset.get_tile_size() * scale);
  148. int end_row = start_row + (get_screen_rect().get_height() / int(tileset.get_tile_size() * scale));
  149. int end_index = std::min(end_row*width, int(tiles.size()));
  150. // Draw tiles
  151. for(int i = (start_row*width); i < end_index; ++i)
  152. {
  153. int x = i % width;
  154. int y = i / width;
  155. Tile* tile = tileset.create(tiles[i]);
  156. CL_Rect rect(CL_Point(static_cast<int>(x * tileset.get_tile_size()*scale),
  157. static_cast<int>(y * tileset.get_tile_size()*scale)),
  158. CL_Size(static_cast<int>(tileset.get_tile_size()*scale),
  159. static_cast<int>(tileset.get_tile_size()*scale)));
  160. if (tile)
  161. {
  162. CL_Sprite sprite = tile->get_sprite();
  163. sprite.set_scale(scale, scale);
  164. sprite.draw(static_cast<int>(x * tileset.get_tile_size()*scale),
  165. static_cast<int>(y * tileset.get_tile_size()*scale));
  166. // Use grid in the tileselector
  167. //CL_Display::draw_rect(rect, CL_Color(0,0,0,128));
  168. }
  169. if (brush.get_width() == 1 && brush.get_height() == 1
  170. && brush.at(0, 0) == tiles[i])
  171. {
  172. CL_Display::fill_rect(rect,
  173. CL_Color(0,0,255, 100));
  174. }
  175. else if (mouse_over_tile == int(i) && has_mouse_over())
  176. {
  177. CL_Display::fill_rect(rect, CL_Color(0,0,255, 20));
  178. }
  179. }
  180. if (region_select)
  181. {
  182. CL_Rect rect = get_selection();
  183. rect.top *= static_cast<int>(tileset.get_tile_size()*scale);
  184. rect.bottom *= static_cast<int>(tileset.get_tile_size()*scale);
  185. rect.left *= static_cast<int>(tileset.get_tile_size()*scale);
  186. rect.right *= static_cast<int>(tileset.get_tile_size()*scale);
  187. CL_Display::fill_rect(rect, CL_Color(0,0,255, 100));
  188. }
  189. CL_Display::pop_modelview();
  190. CL_Display::pop_cliprect();
  191. }
  192. void
  193. TileSelector::set_scale(float s)
  194. {
  195. scale = s;
  196. width = static_cast<int>(get_width()/(tileset.get_tile_size() * scale));
  197. }
  198. TileSelector::Tiles
  199. TileSelector::get_tiles() const
  200. {
  201. return tiles;
  202. }
  203. void
  204. TileSelector::set_tileset(Tileset t)
  205. {
  206. tileset = t;
  207. // Recalc the number of tiles in a row
  208. width = static_cast<int>(get_width()/(tileset.get_tile_size() * scale));
  209. }
  210. void
  211. TileSelector::set_tiles(const Tiles& t)
  212. {
  213. tiles = t;
  214. offset = 0;
  215. }
  216. /* EOF */