Skip to content

Commit

Permalink
Added shadow preview for the editor rectangle fill tool (Editor tile …
Browse files Browse the repository at this point in the history
…rectangle region tool will no longer apply tiles until the mouse left button is released, and will display "ghost" tiles instead) (#1634)

Co-authored-by: Semphris <semphris@protonmail.com>
  • Loading branch information
Semphriss and Semphris committed Jan 10, 2021
1 parent e431119 commit d19a0d7
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 4 deletions.
86 changes: 82 additions & 4 deletions src/editor/overlay_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ EditorOverlayWidget::EditorOverlayWidget(Editor& editor) :
m_edited_path(nullptr),
m_last_node_marker(nullptr),
m_object_tip(),
m_obj_mouse_desync(0, 0)
m_obj_mouse_desync(0, 0),
m_rectangle_preview(new TileSelection())
{
}

Expand Down Expand Up @@ -272,6 +273,28 @@ EditorOverlayWidget::put_tile()
} // for tile x
}

void
EditorOverlayWidget::preview_rectangle()
{
Rectf dr = drag_rect();
dr.set_p1(sp_to_tp(dr.p1()).floor());
dr.set_p2(sp_to_tp(dr.p2()).floor());
bool sgn_x = m_drag_start.x < m_sector_pos.x;
bool sgn_y = m_drag_start.y < m_sector_pos.y;

m_rectangle_preview->m_tiles.clear();
m_rectangle_preview->m_width = static_cast<int>(dr.get_width()) + 1;
m_rectangle_preview->m_height = static_cast<int>(dr.get_height()) + 1;
int y_ = sgn_y ? 0 : static_cast<int>(-dr.get_height());
for (int y = static_cast<int>(dr.get_top()); y <= static_cast<int>(dr.get_bottom()); y++, y_++) {
int x_ = sgn_x ? 0 : static_cast<int>(-dr.get_width());
for (int x = static_cast<int>(dr.get_left()); x <= static_cast<int>(dr.get_right()); x++, x_++) {
m_rectangle_preview->m_tiles.push_back(m_editor.get_tiles()->pos(x_, y_));
}
}
}


void
EditorOverlayWidget::draw_rectangle()
{
Expand Down Expand Up @@ -687,7 +710,7 @@ EditorOverlayWidget::process_left_click()
break;

case 1:
draw_rectangle();
preview_rectangle();
break;

case 2:
Expand Down Expand Up @@ -812,7 +835,23 @@ EditorOverlayWidget::update_tile_selection()
bool
EditorOverlayWidget::on_mouse_button_up(const SDL_MouseButtonEvent& button)
{
if (button.button == SDL_BUTTON_LEFT)
{
if (m_editor.get_tileselect_input_type() == EditorToolboxWidget::InputType::TILE
&& m_editor.get_tileselect_select_mode() == 1)
{
if (m_dragging)
{
draw_rectangle();
m_rectangle_preview->m_tiles.clear();
}
}
}

m_dragging = false;

// Return true anyways, because that's how it worked when this function only
// had `m_dragging = false;` in its body.
return true;
}

Expand Down Expand Up @@ -853,7 +892,7 @@ EditorOverlayWidget::on_mouse_motion(const SDL_MouseMotionEvent& motion)
put_tile();
break;
case 1:
draw_rectangle();
preview_rectangle();
break;
default:
break;
Expand Down Expand Up @@ -944,7 +983,7 @@ EditorOverlayWidget::draw_tile_tip(DrawingContext& context)

Vector screen_corner = context.get_cliprect().p2() +
m_editor.get_sector()->get_camera().get_translation();
Vector drawn_tile = m_hovered_tile;
Vector drawn_tile = m_hovered_tile; // FIXME: Why is this initialised if it's going to be overwritten right below?
auto tiles = m_editor.get_tiles();

for (drawn_tile.x = static_cast<float>(tiles->m_width) - 1.0f; drawn_tile.x >= 0.0f; drawn_tile.x--) {
Expand Down Expand Up @@ -973,6 +1012,44 @@ EditorOverlayWidget::draw_tile_tip(DrawingContext& context)
}
}

void
EditorOverlayWidget::draw_rectangle_preview(DrawingContext& context)
{
auto tilemap = m_editor.get_selected_tilemap();
if (!tilemap) {
return;
}

if (m_rectangle_preview->empty())
return;

Vector screen_corner = context.get_cliprect().p2() +
m_editor.get_sector()->get_camera().get_translation();
Vector drawn_tile;
Vector corner(std::min(sp_to_tp(m_drag_start).x, m_hovered_tile.x),
std::min(sp_to_tp(m_drag_start).y, m_hovered_tile.y));
auto tiles = m_rectangle_preview.get();

for (drawn_tile.x = static_cast<float>(tiles->m_width) - 1.0f; drawn_tile.x >= 0.0f; drawn_tile.x--) {
for (drawn_tile.y = static_cast<float>(tiles->m_height) - 1.0f; drawn_tile.y >= 0.0f; drawn_tile.y--) {
Vector on_tile = corner + drawn_tile;

if (on_tile.x < 0 ||
on_tile.y < 0 ||
on_tile.x >= static_cast<float>(tilemap->get_width()) ||
on_tile.y >= static_cast<float>(tilemap->get_height()) ||
on_tile.x >= ceilf(screen_corner.x / 32) ||
on_tile.y >= ceilf(screen_corner.y / 32)) {
continue;
}
uint32_t tile_id = tiles->pos(static_cast<int>(drawn_tile.x), static_cast<int>(drawn_tile.y));
draw_tile(context.color(), *m_editor.get_tileset(), tile_id,
align_to_tilemap(on_tile) - m_editor.get_sector()->get_camera().get_translation(),
LAYER_GUI-11, Color(1, 1, 1, 0.5));
}
}
}

void
EditorOverlayWidget::draw_tile_grid(DrawingContext& context, const Color& line_color, int tile_size)
{
Expand Down Expand Up @@ -1058,6 +1135,7 @@ void
EditorOverlayWidget::draw(DrawingContext& context)
{
draw_tile_tip(context);
draw_rectangle_preview(context);
draw_path(context);

if (render_grid) {
Expand Down
5 changes: 5 additions & 0 deletions src/editor/overlay_widget.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <SDL.h>

#include "control/input_manager.hpp"
#include "editor/tile_selection.hpp"
#include "editor/widget.hpp"
#include "math/vector.hpp"
#include "object/tilemap.hpp"
Expand Down Expand Up @@ -81,6 +82,7 @@ class EditorOverlayWidget final : public Widget
void input_autotile_corner(const Vector& corner, uint32_t tile, const Vector& override_pos = Vector(-1.f, -1.f));
void put_tile();
void draw_rectangle();
void preview_rectangle();
bool check_tiles_for_fill(uint32_t replace_tile, uint32_t target_tile, uint32_t third_tile) const;
void fill();
void put_object();
Expand All @@ -100,6 +102,7 @@ class EditorOverlayWidget final : public Widget
void draw_tile_grid(DrawingContext&, const Color& line_color, int tile_size = 32);
void draw_tilemap_border(DrawingContext&);
void draw_path(DrawingContext&);
void draw_rectangle_preview(DrawingContext& context);

void process_left_click();
void process_right_click();
Expand Down Expand Up @@ -136,6 +139,8 @@ class EditorOverlayWidget final : public Widget
std::unique_ptr<Tip> m_object_tip;
Vector m_obj_mouse_desync;

std::unique_ptr<TileSelection> m_rectangle_preview;

private:
EditorOverlayWidget(const EditorOverlayWidget&) = delete;
EditorOverlayWidget& operator=(const EditorOverlayWidget&) = delete;
Expand Down

0 comments on commit d19a0d7

Please sign in to comment.