]> git.lizzy.rs Git - nothing.git/commitdiff
(#1139) Implement Move snap for Label Layer
authorrexim <reximkut@gmail.com>
Sun, 24 Nov 2019 19:51:35 +0000 (02:51 +0700)
committerrexim <reximkut@gmail.com>
Sun, 24 Nov 2019 19:51:35 +0000 (02:51 +0700)
src/config.h
src/game/level/level_editor/label_layer.c
src/game/level/level_editor/rect_layer.c
src/math/rect.h

index d1610ea6e9f224f160b312badeaa2f2268e32d71..c5bf63c497a422daec2d7d03321ab84afc989922 100644 (file)
@@ -17,4 +17,6 @@
 
 #define ENTITY_MAX_ID_SIZE 36
 
+#define SNAPPING_THRESHOLD 10.0f
+
 #endif  // CONFIG_H_
index 7743f96476cf1c703f1de85afff49e1b2cb273fc..7c640814134e52adbc8ce0410bb3215514fec476 100644 (file)
@@ -16,6 +16,7 @@
 #include "color_picker.h"
 #include "ui/edit_field.h"
 #include "math/extrema.h"
+#include "config.h"
 
 #define LABEL_LAYER_SELECTION_THICCNESS 5.0f
 
@@ -389,6 +390,7 @@ int label_layer_render(const LabelLayer *label_layer,
             }
         }
 
+        // TODO: Label Selection has to be internal (just like in Rect Layer)
         // Label Selection
         if (active && label_layer->selection == (int) i) {
             Rect selection =
@@ -675,6 +677,38 @@ int label_layer_idle_event(LabelLayer *label_layer,
     return 0;
 }
 
+static
+void snap_inter_position(LabelLayer *label_layer, float snap_threshold)
+{
+    trace_assert(label_layer);
+    trace_assert(label_layer->selection >= 0);
+    trace_assert(label_layer->state == LABEL_LAYER_MOVE);
+
+    const size_t n = dynarray_count(label_layer->positions);
+    Vec2f *positions = dynarray_data(label_layer->positions);
+
+    Rect a = boundary_of_element(
+        label_layer,
+        (size_t) label_layer->selection,
+        label_layer->inter_position);
+
+    for (size_t i = 0; i < n; ++i) {
+        if (i == (size_t) label_layer->selection) continue;
+
+        const Rect b = boundary_of_element(label_layer, i, positions[i]);
+
+        if (segment_overlap(vec(a.x, a.x + a.w), vec(b.x,  b.x + b.w))) {
+            snap_seg2seg(&label_layer->inter_position.y,
+                         b.y, a.h, b.h, snap_threshold);
+        }
+
+        if (segment_overlap(vec(a.y, a.y + a.h), vec(b.y,  b.y  + b.h))) {
+            snap_seg2seg(&label_layer->inter_position.x,
+                         b.x, a.w, b.w, snap_threshold);
+        }
+    }
+}
+
 static
 int label_layer_move_event(LabelLayer *label_layer,
                            const SDL_Event *event,
@@ -712,6 +746,8 @@ int label_layer_move_event(LabelLayer *label_layer,
                 label_layer->inter_position = vec(label_pos.x, mouse_pos.y);
             }
         }
+
+        snap_inter_position(label_layer, SNAPPING_THRESHOLD);
     } break;
 
     case SDL_MOUSEBUTTONUP: {
index e9d67558d77e3c431b1958201c41af3eec116a5f..79634c8cb01f73d62c453fd0cecbec33bc026947 100644 (file)
@@ -24,7 +24,6 @@
 #define CREATE_AREA_THRESHOLD 10.0
 #define RECT_LAYER_GRID_ROWS 3
 #define RECT_LAYER_GRID_COLUMNS 4
-#define SNAPPING_THRESHOLD 10.0f
 
 static int clipboard = 0;
 static Rect clipboard_rect;
index 799021479551a1b8e4188df2d5e30982d3a92041..fd13822285a74eacd764d08cf5ca968d133eedd1 100644 (file)
@@ -130,14 +130,15 @@ void snap_var(float *x,        // the value we are snapping
               float yo,        // y offset
               float st)        // snap threshold
 {
-    if (fabsf((*x + xo) - (y + yo)) < st)
+    if (fabsf((*x + xo) - (y + yo)) < st) {
         *x = y + yo - xo;
+    }
 }
 
 static inline
 void snap_var2seg(float *x, float y,
-               float xo, float yo,
-               float st)
+                  float xo, float yo,
+                  float st)
 {
     snap_var(x, y, xo,  0, st);
     snap_var(x, y, xo, yo, st);
@@ -152,5 +153,4 @@ void snap_seg2seg(float *x, float y, float xo, float yo, float st)
     snap_var(x, y, xo, yo, st);
 }
 
-
 #endif  // RECT_H_