tile_selection.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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_selection.hpp"
  17. #include <ClanLib/Display/display.h>
  18. #include <iostream>
  19. #include "math.hpp"
  20. #include "tileset.hpp"
  21. class TileSelectionImpl
  22. {
  23. public:
  24. TilemapLayer tilemap;
  25. CL_Point start_pos;
  26. CL_Rect selection;
  27. bool active;
  28. };
  29. TileSelection::TileSelection()
  30. : impl(new TileSelectionImpl())
  31. {
  32. impl->active = false;
  33. }
  34. TileSelection::~TileSelection()
  35. {
  36. }
  37. void
  38. TileSelection::start(TilemapLayer tilemap_, const CL_Point& pos)
  39. {
  40. impl->tilemap = tilemap_;
  41. impl->active = true;
  42. impl->start_pos = pos;
  43. update(impl->start_pos);
  44. }
  45. void
  46. TileSelection::update(const CL_Point& pos)
  47. {
  48. impl->selection = CL_Rect(std::min(impl->start_pos.x, pos.x),
  49. std::min(impl->start_pos.y, pos.y),
  50. std::max(impl->start_pos.x, pos.x) + 1,
  51. std::max(impl->start_pos.y, pos.y) + 1);
  52. }
  53. bool
  54. TileSelection::is_active()
  55. {
  56. return impl->active;
  57. }
  58. void
  59. TileSelection::clear()
  60. {
  61. impl->selection = CL_Rect();
  62. impl->active = false;
  63. }
  64. void
  65. TileSelection::draw(const CL_Color& color)
  66. {
  67. int tile_size = impl->tilemap.get_tileset().get_tile_size();
  68. CL_Display::fill_rect(CL_Rect(impl->selection.left * tile_size,
  69. impl->selection.top * tile_size,
  70. impl->selection.right * tile_size,
  71. impl->selection.bottom * tile_size),
  72. color);
  73. }
  74. TileBrush
  75. TileSelection::get_brush(const Field<int>& field) const
  76. {
  77. CL_Rect sel = impl->selection;
  78. sel.normalize();
  79. if (sel.left > field.get_width() - 1
  80. || sel.top > field.get_height() - 1
  81. || sel.right <= 0
  82. || sel.bottom <= 0)
  83. { // Selection is empty
  84. std::cout << "Error: Invalid selection" << std::endl;
  85. TileBrush brush(1, 1);
  86. brush.at(0, 0) = 0;
  87. brush.set_opaque();
  88. return brush;
  89. }
  90. else
  91. { // Selection is valid
  92. // Cut the selection to the field size
  93. sel.left = Math::max(0, sel.left);
  94. sel.top = Math::max(0, sel.top);
  95. sel.right = Math::min(sel.right, field.get_width());
  96. sel.bottom = Math::min(sel.bottom, field.get_height());
  97. TileBrush brush(sel.get_width(),
  98. sel.get_height());
  99. for(int y = sel.top; y < sel.bottom; ++y)
  100. for(int x = sel.left; x < sel.right; ++x)
  101. {
  102. brush.at(x - sel.left,
  103. y - sel.top) = field.at(x, y);
  104. }
  105. return brush;
  106. }
  107. }
  108. CL_Rect
  109. TileSelection::get_rect() const
  110. {
  111. CL_Rect sel = impl->selection;
  112. sel.normalize();
  113. return sel;
  114. }
  115. /* EOF */