diff --git a/src/Editor/canvas.cpp b/src/Editor/canvas.cpp index a36d89e..5415e0d 100644 --- a/src/Editor/canvas.cpp +++ b/src/Editor/canvas.cpp @@ -27,14 +27,16 @@ where the level is displayed #include "bar.hpp" #include "editor.hpp" +#include "input.hpp" #include "../level.hpp" #include "../style.hpp" #include "../window.hpp" -void Canvas::setReferences(Window * w, Editor * e, Bar * b, Style * s, Level * l) +void Canvas::setReferences(Window * w, Editor * e, Editor_input * i, Bar * b, Style * s, Level * l) { window_ptr = w; editor_ptr = e; + input_ptr = i; bar_ptr = b; style_ptr = s; level_ptr = l; @@ -181,23 +183,78 @@ void Canvas::draw() SDL_SetRenderDrawColor(window_ptr->screen_renderer, 0, 0, 0, 255); - //Draw dotted lines on the level border + //START - Draw dotted lines on the level border + enum whichBorder { none, top, bottom, left, right }; + whichBorder hoverBorder = none; + if (input_ptr->resizingLevel == false) // only highlight borders on hover if not resizing + { + if (input_ptr->mouse_x <= 8 && input_ptr->mouse_x >= -8) + { + hoverBorder = left; + } + else if (input_ptr->mouse_x >= level_ptr->width - 8 && input_ptr->mouse_x <= level_ptr->width + 8) + { + hoverBorder = right; + } + else if (input_ptr->mouse_y <= 8 && input_ptr->mouse_y >= -8) + { + hoverBorder = top; + } + else if (input_ptr->mouse_y >= level_ptr->height - 8 && input_ptr->mouse_y <= level_ptr->height + 8) + { + hoverBorder = bottom; + } + } + bool highlight = false; if (scroll_x <= 0 && (scroll_x * zoom) + window_ptr->width - 1 >= 0) { - draw_dashed_level_border(vertical, ((0 - scroll_x) * zoom) - scrollOffset_x - 1, scroll_y * zoom + scrollOffset_y); + if (input_ptr->resizingLevel == false || input_ptr->resizingWhich != Editor_input::whichBorder::left) + { + if (hoverBorder == left) + highlight = true; + draw_dashed_level_border(vertical, ((0 - scroll_x) * zoom) - scrollOffset_x - 1, scroll_y * zoom + scrollOffset_y, highlight); + highlight = false; + } } if (scroll_x <= level_ptr->width && scroll_x + (window_ptr->width / zoom) - 1 >= level_ptr->width) { - draw_dashed_level_border(vertical, ((level_ptr->width - scroll_x) * zoom) - scrollOffset_x, scroll_y * zoom + scrollOffset_y); + if (input_ptr->resizingLevel == false || input_ptr->resizingWhich != Editor_input::whichBorder::right) + { + if (hoverBorder == right) + highlight = true; + draw_dashed_level_border(vertical, ((level_ptr->width - scroll_x) * zoom) - scrollOffset_x, scroll_y * zoom + scrollOffset_y, highlight); + highlight = false; + } } if (scroll_y <= 0 && (scroll_y * zoom) + window_ptr->height - 1 >= 0) { - draw_dashed_level_border(horizontal, ((0 - scroll_y) * zoom) - 1 - scrollOffset_y, scroll_x * zoom + scrollOffset_x); + if (input_ptr->resizingLevel == false || input_ptr->resizingWhich != Editor_input::whichBorder::top) + { + if (hoverBorder == top) + highlight = true; + draw_dashed_level_border(horizontal, ((0 - scroll_y) * zoom) - 1 - scrollOffset_y, scroll_x * zoom + scrollOffset_x, highlight); + highlight = false; + } } if (scroll_y <= level_ptr->height && scroll_y + (window_ptr->height / zoom) - 1 >= level_ptr->height) { - draw_dashed_level_border(horizontal, ((level_ptr->height - scroll_y) * zoom) - scrollOffset_y, scroll_x * zoom + scrollOffset_x); + if (input_ptr->resizingLevel == false || input_ptr->resizingWhich != Editor_input::whichBorder::bottom) + { + if (hoverBorder == bottom) + highlight = true; + draw_dashed_level_border(horizontal, ((level_ptr->height - scroll_y) * zoom) - scrollOffset_y, scroll_x * zoom + scrollOffset_x, highlight); + highlight = false; + } } + if (input_ptr->resizingLevel) // draw the one border we are currently resizing + { + if (input_ptr->resizingWhich == Editor_input::whichBorder::left || input_ptr->resizingWhich == Editor_input::whichBorder::right) + draw_dashed_level_border(vertical, (input_ptr->resizingNewPos - scroll_x) * zoom - scrollOffset_x, scroll_y * zoom + scrollOffset_y, true); + if (input_ptr->resizingWhich == Editor_input::whichBorder::top || input_ptr->resizingWhich == Editor_input::whichBorder::bottom) + draw_dashed_level_border(horizontal, (input_ptr->resizingNewPos - scroll_y) * zoom - scrollOffset_y, scroll_x * zoom + scrollOffset_x, true); + } + + //END - Draw dotted lines on the level border SDL_SetRenderTarget(window_ptr->screen_renderer, NULL); @@ -241,11 +298,14 @@ void Canvas::drawHeldObject(int holdingType, int holdingID, int x, int y) style_ptr->draw_object_texture(window_ptr, drawX, drawY, holdingType, drawID, zoom, NULL); } -void Canvas::draw_dashed_level_border(borderType type, int pos, int offset) +void Canvas::draw_dashed_level_border(borderType type, int pos, int offset, bool highlight) { //We have an offset so the lines don't scroll out of synch with the view when scrolling int initialOffset = offset % 20; - SDL_SetRenderDrawColor(window_ptr->screen_renderer, 200, 200, 200, 255); + int rendColour = 200; + if (highlight) + rendColour = 250; + SDL_SetRenderDrawColor(window_ptr->screen_renderer, rendColour, rendColour, rendColour, 255); int end, x1, y1, x2, y2; if (type == horizontal) { diff --git a/src/Editor/canvas.hpp b/src/Editor/canvas.hpp index 178ab07..2f2e578 100644 --- a/src/Editor/canvas.hpp +++ b/src/Editor/canvas.hpp @@ -25,6 +25,7 @@ class Window; class Editor; +class Editor_input; class Bar; class Style; class Level; @@ -35,6 +36,7 @@ class Canvas Window * window_ptr; Editor * editor_ptr; + Editor_input * input_ptr; Bar * bar_ptr; Style * style_ptr; Level * level_ptr; @@ -49,7 +51,7 @@ class Canvas Sint32 mouse_remainder_x, mouse_remainder_y; bool backgroundOnly; - void setReferences(Window * w, Editor * e, Bar * b, Style * s, Level * l); + void setReferences(Window * w, Editor * e, Editor_input * i, Bar * b, Style * s, Level * l); void load(void); void resize(int h); @@ -65,7 +67,7 @@ class Canvas void drawHeldObject(int holdingType, int holdingID, int x, int y); enum borderType { horizontal, vertical }; - void draw_dashed_level_border(borderType type, int pos, int offset); + void draw_dashed_level_border(borderType type, int pos, int offset, bool highlight); Canvas(void) { /* nothing to do */ } diff --git a/src/Editor/editor.cpp b/src/Editor/editor.cpp index 779ea23..15814e3 100644 --- a/src/Editor/editor.cpp +++ b/src/Editor/editor.cpp @@ -42,7 +42,7 @@ bool Editor::load( int n, Window * w ) { window_ptr = w; bar.setReferences(window_ptr, this, &canvas, &style); - canvas.setReferences(window_ptr, this, &bar, &style, &level); + canvas.setReferences(window_ptr, this, &editor_input, &bar, &style, &level); editor_input.setReferences(window_ptr, this, &bar, &canvas, &style, &level); level.load(n); tribe.load(level.tribe); @@ -69,6 +69,8 @@ bool Editor::select( signed int x, signed int y, bool modify_selection ) if (temp.i == -1) // selected nothing { selection.clear(); + canvas.redraw = true; + return false; } else { @@ -86,9 +88,9 @@ bool Editor::select( signed int x, signed int y, bool modify_selection ) else selection.insert(temp); } + canvas.redraw = true; + return true; } - - return canvas.redraw = true; } bool Editor::select_none( void ) diff --git a/src/Editor/input.cpp b/src/Editor/input.cpp index 7562dc3..d909d2f 100644 --- a/src/Editor/input.cpp +++ b/src/Editor/input.cpp @@ -45,15 +45,23 @@ void Editor_input::setReferences(Window * w, Editor * e, Bar * b, Canvas * c, St void Editor_input::load(void) { mouse_prev_x = mouse_prev_y = 0; + dragging = false; + leftScrollButtonHolding = false; rightScrollButtonHolding = false; scrollBarHolding = false; scrollBarHoldingOffset = 0; scrollBarShifting = false; - movingView = false; + holdingID = -1; holdingType = -1; + + movingView = false; + + resizingLevel = false; + resizingNewPos = 0; + resizingWhich = none; } void Editor_input::handleEvents(SDL_Event event) @@ -65,7 +73,6 @@ void Editor_input::handleEvents(SDL_Event event) // Due to zooming we can't rely on the mouse's position in the window to map correctly // So we need to create our own variables instead // These ones give the real x co-ordinate of the level, ignoring zoom and scroll - Sint32 mouse_x, mouse_y; mouse_x = (mouse_x_window / canvas_ptr->zoom) + canvas_ptr->scroll_x; mouse_y = (mouse_y_window / canvas_ptr->zoom) + canvas_ptr->scroll_y; @@ -100,6 +107,48 @@ void Editor_input::handleEvents(SDL_Event event) { canvas_ptr->scroll(mouse_prev_x - mouse_x_window, mouse_prev_y - mouse_y_window, false); } + if (e.state & SDL_BUTTON(SDL_BUTTON_LEFT) && resizingLevel) + { + switch (resizingWhich) + { + case (top) : + { + resizingNewPos = mouse_y - (mouse_y % 4); + if (level_ptr->height - resizingNewPos > 400) + resizingNewPos = level_ptr->height - 400; + if (level_ptr->height - resizingNewPos < 160) + resizingNewPos = level_ptr->height - 160; + break; + } + case (bottom) : + { + resizingNewPos = mouse_y - (mouse_y % 4); + if (resizingNewPos > 400) + resizingNewPos = 400; + if (resizingNewPos < 160) + resizingNewPos = 160; + break; + } + case (left) : + { + resizingNewPos = mouse_x - (mouse_x % 8); + if (level_ptr->width - resizingNewPos > 2048) + resizingNewPos = level_ptr->width - 2048; + if (level_ptr->width - resizingNewPos < 320) + resizingNewPos = level_ptr->width - 320; + break; + } + case (right) : + { + resizingNewPos = mouse_x - (mouse_x % 8); + if (resizingNewPos > 2048) + resizingNewPos = 2048; + if (resizingNewPos < 320) + resizingNewPos = 320; + break; + } + } + } mouse_prev_x = mouse_x_window; mouse_prev_y = mouse_y_window; @@ -130,7 +179,35 @@ void Editor_input::handleEvents(SDL_Event event) } else { - editor_ptr->select(mouse_x, mouse_y, ctrl_down); + bool selectedSomething = editor_ptr->select(mouse_x, mouse_y, ctrl_down); + if (!selectedSomething) + { + // grab level borders + if (mouse_x <= 8 && mouse_x >= -8) + { + resizingLevel = true; + resizingNewPos = 0; + resizingWhich = left; + } + else if (mouse_x >= level_ptr->width - 8 && mouse_x <= level_ptr->width + 8) + { + resizingLevel = true; + resizingNewPos = level_ptr->width; + resizingWhich = right; + } + else if (mouse_y <= 8 && mouse_y >= -8) + { + resizingLevel = true; + resizingNewPos = 0; + resizingWhich = top; + } + else if (mouse_y >= level_ptr->height - 8 && mouse_y <= level_ptr->height + 8) + { + resizingLevel = true; + resizingNewPos = level_ptr->height; + resizingWhich = bottom; + } + } } } else if (mouse_x_window < BAR_HEIGHT) @@ -202,6 +279,38 @@ void Editor_input::handleEvents(SDL_Event event) rightScrollButtonHolding = false; scrollBarHolding = false; scrollBarShifting = false; + if (resizingLevel) + { + switch (resizingWhich) + { + case (top) : + { + level_ptr->resizeLevel(0, -resizingNewPos, true); + canvas_ptr->scroll(0, -resizingNewPos * canvas_ptr->zoom, false); + break; + } + case (bottom) : + { + level_ptr->resizeLevel(0, resizingNewPos - level_ptr->height, false); + break; + } + case (left) : + { + level_ptr->resizeLevel(-resizingNewPos, 0, true); + canvas_ptr->scroll(-resizingNewPos * canvas_ptr->zoom, 0, false); + break; + } + case (right) : + { + level_ptr->resizeLevel(resizingNewPos - level_ptr->width, 0, false); + break; + } + } + resizingLevel = false; + resizingWhich = none; + resizingNewPos = 0; + canvas_ptr->redraw = true; + } } if (e.button == SDL_BUTTON_RIGHT) { diff --git a/src/Editor/input.hpp b/src/Editor/input.hpp index 676eb7b..3ef8a67 100644 --- a/src/Editor/input.hpp +++ b/src/Editor/input.hpp @@ -43,14 +43,24 @@ class Editor_input bool redraw; + int mouse_x, mouse_y; Sint32 mouse_prev_x, mouse_prev_y; - bool dragging, leftScrollButtonHolding, rightScrollButtonHolding; + + bool dragging; + + bool leftScrollButtonHolding, rightScrollButtonHolding; bool scrollBarHolding, scrollBarShifting; int scrollBarHoldingOffset; - bool movingView; int holdingID, holdingType; + bool movingView; + + enum whichBorder {none, top, bottom, left, right}; + bool resizingLevel; + int resizingNewPos; + whichBorder resizingWhich; + void setReferences(Window * w, Editor * e, Bar * b, Canvas * c, Style * s, Level * l); void load(void); diff --git a/src/level.cpp b/src/level.cpp index 1dc6ec1..ac91259 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -276,4 +276,25 @@ bool Level::save_objects(int type, const string &filename) cout << "wrote " << object[type].size() << " objects to '" << filename << "'" << endl; f.close(); return true; +} + +void Level::resizeLevel(int delta_x, int delta_y, bool shiftLevel) +{ + width += delta_x; + height += delta_y; + if (shiftLevel) + { + for (vector::iterator i = object[PERM].begin(); i != object[PERM].end(); ++i) + { + Object &o = *i; + o.x += delta_x; + o.y += delta_y; + } + for (vector::iterator i = object[TEMP].begin(); i != object[TEMP].end(); ++i) + { + Object &o = *i; + o.x += delta_x; + o.y += delta_y; + } + } } \ No newline at end of file diff --git a/src/level.hpp b/src/level.hpp index bbd6dd3..cbd1f8b 100644 --- a/src/level.hpp +++ b/src/level.hpp @@ -83,6 +83,8 @@ class Level bool save_level(const std::string &filename); bool save_objects(int type, const std::string &path, const std::string &name, unsigned int n); bool save_objects(int type, const std::string &filename); + + void resizeLevel(int delta_x, int delta_y, bool shiftLevel); Level( void ) { /* nothing to do */ }