#include "ui/edit_field.h"
#include "undo_history.h"
#include "game/level/action.h"
+#include "action_picker.h"
#define RECT_LAYER_SELECTION_THICCNESS 10.0f
#define RECT_LAYER_ID_LABEL_SIZE vec(3.0f, 3.0f)
#define CREATE_AREA_THRESHOLD 10.0
+#define RECT_LAYER_GRID_ROWS 3
+#define RECT_LAYER_GRID_COLUMNS 4
static int clipboard = 0;
static Rect clipboard_rect;
Dynarray *colors;
Dynarray *actions;
ColorPicker color_picker;
+ ActionPicker action_picker;
Vec2f create_begin;
Vec2f create_end;
int selection;
- Vec2f move_anchor;
+ Vec2f move_anchor; // The mouse offset from the left-top
+ // corner of the rect during moving it
Edit_field *id_edit_field;
Color inter_color;
Rect inter_rect;
int id_name_counter;
const char *id_name_prefix;
+ Grid *grid;
};
typedef enum {
static Rect rect_layer_resize_anchor(const Camera *camera, Rect boundary_rect)
{
- const Rect overlay_rect =
- rect_pad(
- camera_rect(camera, boundary_rect),
- RECT_LAYER_SELECTION_THICCNESS * 0.5f);
-
+ const Rect overlay_rect = camera_rect(camera, boundary_rect);
return rect(
overlay_rect.x + overlay_rect.w,
overlay_rect.y + overlay_rect.h,
- RECT_LAYER_SELECTION_THICCNESS * 2.0f,
- RECT_LAYER_SELECTION_THICCNESS * 2.0f);
+ RECT_LAYER_SELECTION_THICCNESS * 2.0,
+ RECT_LAYER_SELECTION_THICCNESS * 2.0);
}
static int rect_layer_delete_rect_at(RectLayer *layer,
switch (event->type) {
case SDL_MOUSEMOTION: {
- Vec2f position = vec_sub(
+ const Uint8 *state = SDL_GetKeyboardState(NULL);
+ const Vec2f mouse_pos = vec_sub(
camera_map_screen(
camera,
event->button.x,
event->button.y),
layer->move_anchor);
- trace_assert(layer->selection >= 0);
+ if (!(state[SDL_SCANCODE_LCTRL] || state[SDL_SCANCODE_RCTRL])) {
+ layer->inter_rect.x = mouse_pos.x;
+ layer->inter_rect.y = mouse_pos.y;
+ } else {
+ const Vec2f rect_pos = rect_position(rects[layer->selection]);
+
+ const float dx = fabsf(rect_pos.x - mouse_pos.x);
+ const float dy = fabsf(rect_pos.y - mouse_pos.y);
- layer->inter_rect.x = position.x;
- layer->inter_rect.y = position.y;
+ if (dx > dy) {
+ layer->inter_rect.x = mouse_pos.x;
+ layer->inter_rect.y = rect_pos.y;
+ } else {
+ layer->inter_rect.x = rect_pos.x;
+ layer->inter_rect.y = mouse_pos.y;
+ }
+ }
} break;
case SDL_MOUSEBUTTONUP: {
RETURN_LT(lt, NULL);
}
+ layer->grid =
+ PUSH_LT(
+ lt,
+ nth_calloc(
+ 1,
+ sizeof(Grid) + sizeof(Widget*) * RECT_LAYER_GRID_ROWS * RECT_LAYER_GRID_COLUMNS),
+ free);
+ if (layer->grid == NULL) {
+ RETURN_LT(lt, NULL);
+ }
+ layer->grid->rows = RECT_LAYER_GRID_ROWS;
+ layer->grid->columns = RECT_LAYER_GRID_COLUMNS;
+ grid_put_widget(layer->grid, &layer->action_picker.widget, 0, RECT_LAYER_GRID_COLUMNS - 1);
+
layer->color_picker = create_color_picker_from_rgba(rgba(1.0f, 0.0f, 0.0f, 1.0f));
layer->selection = -1;
layer->id_name_prefix = id_name_prefix;
dynarray_push(layer->ids, id);
dynarray_push(layer->colors, &color);
- Action action = {0};
+ Action action = {
+ .type = ACTION_NONE,
+ .entity_id = {0}
+ };
if (sscanf(line, "%d%n", (int*)&action.type, &n) > 0) {
line += n;
}
}
+ // Main Rectangle
if (camera_fill_rect(
camera,
rect,
rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f))) < 0) {
return -1;
}
+ }
- // Selection Overlay
- if (active && (size_t) layer->selection == i) {
- const Rect overlay_rect =
- rect_pad(
- camera_rect(camera, rect),
- RECT_LAYER_SELECTION_THICCNESS * 0.5f);
- const Color overlay_color = color_invert(color);
+ // Selection Overlay
+ if (active && layer->selection >= 0) {
+ Rect rect = rects[layer->selection];
+ Color color = colors[layer->selection];
- // Main Rectangle
- if (camera_fill_rect(
- camera,
- rect,
- color_scale(
- color,
- rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f))) < 0) {
- return -1;
- }
+ if (layer->state == RECT_LAYER_RESIZE || layer->state == RECT_LAYER_MOVE) {
+ rect = layer->inter_rect;
+ }
+
+ if (layer->state == RECT_LAYER_RECOLOR) {
+ color = layer->inter_color;
+ }
+
+ const Rect overlay_rect =
+ rect_pad(
+ camera_rect(camera, rect),
+ -RECT_LAYER_SELECTION_THICCNESS * 0.5f);
+ const Color overlay_color = color_invert(color);
+
+ // Selection
+ if (camera_draw_thicc_rect_screen(
+ camera,
+ overlay_rect,
+ overlay_color,
+ RECT_LAYER_SELECTION_THICCNESS) < 0) {
+ return -1;
+ }
+
+ const Vec2f rect_id_pos = vec_sub(
+ rect_position(rect),
+ vec_mult(
+ RECT_LAYER_ID_LABEL_SIZE,
+ vec(0.0f, FONT_CHAR_HEIGHT)));
- if (camera_draw_thicc_rect_screen(
+ // Rectangle Id
+ if (layer->state == RECT_LAYER_ID_RENAME) {
+ // ID renaming Edit Field
+ if (edit_field_render_world(
+ layer->id_edit_field,
camera,
- overlay_rect,
- overlay_color,
- RECT_LAYER_SELECTION_THICCNESS) < 0) {
+ rect_id_pos) < 0) {
return -1;
}
-
- // Rectangle Id
- if (layer->state == RECT_LAYER_ID_RENAME) {
- // ID renaming Edit Field
- if (edit_field_render_world(
- layer->id_edit_field,
- camera,
- rect_position(rect)) < 0) {
- return -1;
- }
- } else {
- // Id text
- if (camera_render_text(
- camera,
- ids + layer->selection * ENTITY_MAX_ID_SIZE,
- RECT_LAYER_ID_LABEL_SIZE,
- color_invert(color),
- rect_position(rect)) < 0) {
- return -1;
- }
- }
-
- // Resize Anchor
- if (camera_fill_rect_screen(
+ } else {
+ // Id text
+ if (camera_render_text(
camera,
- rect_layer_resize_anchor(camera, rect),
- overlay_color) < 0) {
+ ids + layer->selection * ENTITY_MAX_ID_SIZE,
+ RECT_LAYER_ID_LABEL_SIZE,
+ color_invert(color),
+ rect_id_pos) < 0) {
return -1;
}
}
+
+ // Resize Anchor
+ if (camera_fill_rect_screen(
+ camera,
+ rect_layer_resize_anchor(camera, rect),
+ overlay_color) < 0) {
+ return -1;
+ }
}
// Proto Rectangle
trace_assert(event);
trace_assert(undo_history);
+ switch (event->type) {
+ case SDL_WINDOWEVENT: {
+ switch (event->window.event) {
+ case SDL_WINDOWEVENT_RESIZED: {
+ grid_relayout(layer->grid, rect(0.0f, 0.0f,
+ (float) event->window.data1,
+ (float) event->window.data2));
+ } break;
+ }
+ } break;
+ }
+
switch (layer->state) {
case RECT_LAYER_IDLE:
return rect_layer_event_idle(layer, event, camera, undo_history);