impl multi selections
This commit is contained in:
334
src/main.c
334
src/main.c
@@ -84,6 +84,23 @@ void project_point_to_segment(ImVec2 *out, const ImVec2 *v1, const ImVec2 *v2,
|
|||||||
out->y = v1->y + frac * b.y;
|
out->y = v1->y + frac * b.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vec2_move(ImVec2 *vec, const ImVec2 *delta) {
|
||||||
|
vec->x += delta->x;
|
||||||
|
vec->y += delta->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vec2_is_in_area(const ImVec2 *vec, const ImVec2 *point_a,
|
||||||
|
const ImVec2 *point_b) {
|
||||||
|
float a_to_vec_delta_x = vec->x - point_a->x;
|
||||||
|
float b_to_vec_delta_x = vec->x - point_b->x;
|
||||||
|
float a_to_vec_delta_y = vec->y - point_a->y;
|
||||||
|
float b_to_vec_delta_y = vec->y - point_b->y;
|
||||||
|
return (a_to_vec_delta_x >= 0 && b_to_vec_delta_x <= 0 ||
|
||||||
|
b_to_vec_delta_x >= 0 && a_to_vec_delta_x <= 0) &&
|
||||||
|
(a_to_vec_delta_y >= 0 && b_to_vec_delta_y <= 0 ||
|
||||||
|
b_to_vec_delta_y >= 0 && a_to_vec_delta_y <= 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_mouse_click(const ImVec2 *mouse_down_pos, const ImVec2 *mouse_up_pos) {
|
bool is_mouse_click(const ImVec2 *mouse_down_pos, const ImVec2 *mouse_up_pos) {
|
||||||
if (igIsMouseReleased_Nil(ImGuiMouseButton_Left)) {
|
if (igIsMouseReleased_Nil(ImGuiMouseButton_Left)) {
|
||||||
return vec2_distance_sqr(mouse_up_pos, mouse_down_pos) <= CLICK_THRESHOLD;
|
return vec2_distance_sqr(mouse_up_pos, mouse_down_pos) <= CLICK_THRESHOLD;
|
||||||
@@ -189,7 +206,11 @@ void point_list_free(point_list_t *list) { free(list->items); }
|
|||||||
// struct: entity
|
// struct: entity
|
||||||
// ===========================
|
// ===========================
|
||||||
|
|
||||||
typedef enum { entity_flag_rect = 1, entity_flag_path = 1 << 1 } entity_flag_t;
|
typedef enum {
|
||||||
|
entity_flag_rect = 1 << 0,
|
||||||
|
entity_flag_path = 1 << 1,
|
||||||
|
entity_flag_selected = 1 << 2,
|
||||||
|
} entity_flag_t;
|
||||||
|
|
||||||
typedef struct entity {
|
typedef struct entity {
|
||||||
entity_flag_t flags;
|
entity_flag_t flags;
|
||||||
@@ -200,6 +221,11 @@ typedef struct entity {
|
|||||||
struct entity *prev;
|
struct entity *prev;
|
||||||
} entity_t;
|
} entity_t;
|
||||||
|
|
||||||
|
typedef struct selected_entity {
|
||||||
|
entity_t *entity;
|
||||||
|
struct selected_entity *next;
|
||||||
|
} selected_entity_t;
|
||||||
|
|
||||||
// ===========================
|
// ===========================
|
||||||
// struct: game state
|
// struct: game state
|
||||||
// ===========================
|
// ===========================
|
||||||
@@ -214,7 +240,8 @@ typedef struct {
|
|||||||
ImFont *fa_font;
|
ImFont *fa_font;
|
||||||
|
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
entity_t *entites;
|
|
||||||
|
entity_t *entities;
|
||||||
entity_t *freed_entity;
|
entity_t *freed_entity;
|
||||||
|
|
||||||
sg_pass_action pass_action;
|
sg_pass_action pass_action;
|
||||||
@@ -225,25 +252,22 @@ typedef struct {
|
|||||||
ImVec2 drag_start;
|
ImVec2 drag_start;
|
||||||
ImVec2 last_mouse_pos;
|
ImVec2 last_mouse_pos;
|
||||||
entity_t *selected_entity;
|
entity_t *selected_entity;
|
||||||
|
bool is_area_selecting;
|
||||||
|
size_t selected_entities_count;
|
||||||
|
bool has_selected_entities;
|
||||||
|
|
||||||
toolbox_button_kind_t selected_toolbox_button;
|
toolbox_button_kind_t selected_toolbox_button;
|
||||||
} state_t;
|
} state_t;
|
||||||
|
|
||||||
entity_t *entity_alloc(state_t *state, size_t point_count) {
|
entity_t *entity_alloc(state_t *state, size_t point_count) {
|
||||||
printf("entity_alloc\n");
|
|
||||||
|
|
||||||
entity_t *entity = state->freed_entity;
|
entity_t *entity = state->freed_entity;
|
||||||
if (entity) {
|
if (entity) {
|
||||||
printf("recycling entity\n");
|
|
||||||
state->freed_entity = state->freed_entity->next;
|
state->freed_entity = state->freed_entity->next;
|
||||||
} else {
|
} else {
|
||||||
printf("pushing to arena\n");
|
|
||||||
entity = arena_push(state->arena, sizeof(entity_t));
|
entity = arena_push(state->arena, sizeof(entity_t));
|
||||||
entity->points = point_list_alloc(point_count);
|
entity->points = point_list_alloc(point_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("entity alloced\n");
|
|
||||||
|
|
||||||
entity->next = NULL;
|
entity->next = NULL;
|
||||||
entity->prev = NULL;
|
entity->prev = NULL;
|
||||||
|
|
||||||
@@ -263,16 +287,16 @@ void entity_free(entity_t *entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void push_entity(state_t *state, entity_t *entity) {
|
void push_entity(state_t *state, entity_t *entity) {
|
||||||
entity->next = state->entites;
|
entity->next = state->entities;
|
||||||
if (state->entites) {
|
if (state->entities) {
|
||||||
state->entites->prev = entity;
|
state->entities->prev = entity;
|
||||||
}
|
}
|
||||||
state->entites = entity;
|
state->entities = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_entity(state_t *state, entity_t *entity) {
|
void remove_entity(state_t *state, entity_t *entity) {
|
||||||
if (state->entites == entity) {
|
if (state->entities == entity) {
|
||||||
state->entites = entity->next;
|
state->entities = entity->next;
|
||||||
}
|
}
|
||||||
if (entity->prev) {
|
if (entity->prev) {
|
||||||
entity->prev->next = entity->next;
|
entity->prev->next = entity->next;
|
||||||
@@ -281,7 +305,7 @@ void remove_entity(state_t *state, entity_t *entity) {
|
|||||||
entity->next->prev = entity->prev;
|
entity->next->prev = entity->prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->entites == NULL) {
|
if (state->entities == NULL) {
|
||||||
for (entity_t *entity = state->freed_entity; entity != NULL;
|
for (entity_t *entity = state->freed_entity; entity != NULL;
|
||||||
entity = entity->next) {
|
entity = entity->next) {
|
||||||
entity_free(entity);
|
entity_free(entity);
|
||||||
@@ -294,6 +318,15 @@ void remove_entity(state_t *state, entity_t *entity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remove_selected_entites(state_t *state) {
|
||||||
|
for (entity_t *entity = state->entities; entity != NULL;
|
||||||
|
entity = entity->next) {
|
||||||
|
if (entity->flags & entity_flag_selected) {
|
||||||
|
remove_entity(state, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void create_entity(state_t *state) {
|
void create_entity(state_t *state) {
|
||||||
const ImGuiIO *io = igGetIO();
|
const ImGuiIO *io = igGetIO();
|
||||||
|
|
||||||
@@ -319,7 +352,11 @@ void create_entity(state_t *state) {
|
|||||||
entity_t *entity = entity_alloc(state, 2);
|
entity_t *entity = entity_alloc(state, 2);
|
||||||
entity->flags = entity_flag_rect;
|
entity->flags = entity_flag_rect;
|
||||||
*point_list_push(&entity->points) = state->drag_start;
|
*point_list_push(&entity->points) = state->drag_start;
|
||||||
|
*point_list_push(&entity->points) =
|
||||||
|
(ImVec2){io->MousePos.x, state->drag_start.y};
|
||||||
*point_list_push(&entity->points) = io->MousePos;
|
*point_list_push(&entity->points) = io->MousePos;
|
||||||
|
*point_list_push(&entity->points) =
|
||||||
|
(ImVec2){state->drag_start.x, io->MousePos.y};
|
||||||
push_entity(state, entity);
|
push_entity(state, entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,14 +365,81 @@ void create_entity(state_t *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_t *find_selected_entity(entity_t *entities, const ImVec2 *mouse_pos) {
|
typedef struct {
|
||||||
for (entity_t *entity = entities; entity != NULL; entity = entity->next) {
|
entity_t *selected_entity;
|
||||||
|
bool should_clear_prev_selection;
|
||||||
|
} select_single_entity_result_t;
|
||||||
|
|
||||||
|
void select_entity_near_mouse(select_single_entity_result_t *result,
|
||||||
|
state_t *state, const ImVec2 *mouse_pos) {
|
||||||
|
size_t selected_entities_count = 0;
|
||||||
|
bool should_clear_prev_selection = true;
|
||||||
|
|
||||||
|
for (entity_t *entity = state->entities; entity != NULL;
|
||||||
|
entity = entity->next) {
|
||||||
|
const bool is_prev_selected = entity->flags & entity_flag_selected;
|
||||||
|
|
||||||
if (entity->flags & entity_flag_rect) {
|
if (entity->flags & entity_flag_rect) {
|
||||||
ImVec2 *top_left = &entity->points.items[0];
|
ImVec2 *top_left = &entity->points.items[0];
|
||||||
ImVec2 *bottom_right = &entity->points.items[1];
|
ImVec2 *bottom_right = &entity->points.items[2];
|
||||||
|
|
||||||
if (mouse_pos->x >= top_left->x && mouse_pos->x <= bottom_right->x &&
|
if (vec2_is_in_area(mouse_pos, top_left, bottom_right)) {
|
||||||
mouse_pos->y >= top_left->y && mouse_pos->y <= bottom_right->y) {
|
if (is_prev_selected) {
|
||||||
|
should_clear_prev_selection = false;
|
||||||
|
} else {
|
||||||
|
entity->flags |= entity_flag_selected;
|
||||||
|
}
|
||||||
|
selected_entities_count++;
|
||||||
|
} else if (is_prev_selected) {
|
||||||
|
if (should_clear_prev_selection) {
|
||||||
|
entity->flags &= ~entity_flag_selected;
|
||||||
|
} else {
|
||||||
|
selected_entities_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (entity->flags & entity_flag_path) {
|
||||||
|
for (size_t i = 1; i < entity->points.length; ++i) {
|
||||||
|
ImVec2 *current_point = &entity->points.items[i];
|
||||||
|
ImVec2 *last_point = &entity->points.items[i - 1];
|
||||||
|
|
||||||
|
ImVec2 mouse_pos_proj;
|
||||||
|
project_point_to_segment(&mouse_pos_proj, last_point, current_point,
|
||||||
|
mouse_pos);
|
||||||
|
|
||||||
|
ImVec2 mouse_pos_delta_to_segment = {mouse_pos_proj.x - mouse_pos->x,
|
||||||
|
mouse_pos_proj.y - mouse_pos->y};
|
||||||
|
|
||||||
|
float magnitude_sqr = vec2_magnitude_sqr(&mouse_pos_delta_to_segment);
|
||||||
|
if (magnitude_sqr <= SELECT_THRESHOLD) {
|
||||||
|
if (is_prev_selected) {
|
||||||
|
should_clear_prev_selection = false;
|
||||||
|
} else {
|
||||||
|
entity->flags |= entity_flag_selected;
|
||||||
|
}
|
||||||
|
selected_entities_count++;
|
||||||
|
break;
|
||||||
|
} else if (is_prev_selected) {
|
||||||
|
if (should_clear_prev_selection) {
|
||||||
|
entity->flags &= ~entity_flag_selected;
|
||||||
|
} else {
|
||||||
|
selected_entities_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state->selected_entities_count = selected_entities_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity_t *find_entity_near_mouse(state_t *state, const ImVec2 *mouse_pos) {
|
||||||
|
for (entity_t *entity = state->entities; entity != NULL;
|
||||||
|
entity = entity->next) {
|
||||||
|
if (entity->flags & entity_flag_rect) {
|
||||||
|
ImVec2 *top_left = &entity->points.items[0];
|
||||||
|
ImVec2 *bottom_right = &entity->points.items[2];
|
||||||
|
|
||||||
|
if (vec2_is_in_area(mouse_pos, top_left, bottom_right)) {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
} else if (entity->flags & entity_flag_path) {
|
} else if (entity->flags & entity_flag_path) {
|
||||||
@@ -361,6 +465,31 @@ entity_t *find_selected_entity(entity_t *entities, const ImVec2 *mouse_pos) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void select_entities_in_area(state_t *state, const ImVec2 *top_left,
|
||||||
|
const ImVec2 *bottom_right) {
|
||||||
|
bool has_selected_entities = false;
|
||||||
|
|
||||||
|
for (entity_t *entity = state->entities; entity != NULL;
|
||||||
|
entity = entity->next) {
|
||||||
|
const size_t no_of_points = entity->points.length;
|
||||||
|
bool found = false;
|
||||||
|
for (size_t i = 0; i < no_of_points; ++i) {
|
||||||
|
if (vec2_is_in_area(entity->points.items + i, top_left, bottom_right)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
has_selected_entities = true;
|
||||||
|
entity->flags |= entity_flag_selected;
|
||||||
|
} else {
|
||||||
|
entity->flags &= ~entity_flag_selected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state->selected_entities_count = has_selected_entities;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// theme
|
// theme
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -448,7 +577,7 @@ static void frame(void) {
|
|||||||
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||||
|
|
||||||
ImDrawList *draw_list = igGetWindowDrawList();
|
ImDrawList *draw_list = igGetWindowDrawList();
|
||||||
struct ImGuiIO *io = igGetIO();
|
ImGuiIO *io = igGetIO();
|
||||||
|
|
||||||
igInvisibleButton("canvas", viewport->WorkSize, ImGuiButtonFlags_None);
|
igInvisibleButton("canvas", viewport->WorkSize, ImGuiButtonFlags_None);
|
||||||
|
|
||||||
@@ -468,26 +597,124 @@ static void frame(void) {
|
|||||||
state.is_prev_dragging = false;
|
state.is_prev_dragging = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImVec2 move_entity_by = {0, 0};
|
||||||
|
bool is_moving_entities = false;
|
||||||
|
entity_t *selected_entity = NULL;
|
||||||
|
bool should_clear_prev_selections = false;
|
||||||
|
|
||||||
switch (state.selected_toolbox_button) {
|
switch (state.selected_toolbox_button) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case toolbox_button_select: {
|
case toolbox_button_select: {
|
||||||
if (state.is_dragging && !state.is_prev_dragging) {
|
if (state.is_dragging) {
|
||||||
state.selected_entity =
|
if (!state.is_prev_dragging) {
|
||||||
find_selected_entity(state.entites, &io->MousePos);
|
selected_entity = find_entity_near_mouse(&state, &io->MousePos);
|
||||||
} else if (state.is_dragging && state.selected_entity) {
|
if (selected_entity) {
|
||||||
float delta_x = io->MousePos.x - state.last_mouse_pos.x;
|
if ((selected_entity->flags & entity_flag_selected) == 0) {
|
||||||
float delta_y = io->MousePos.y - state.last_mouse_pos.y;
|
should_clear_prev_selections = true;
|
||||||
const size_t no_of_points = state.selected_entity->points.length;
|
selected_entity->flags |= entity_flag_selected;
|
||||||
for (size_t i = 0; i < no_of_points; ++i) {
|
}
|
||||||
ImVec2 *pt = state.selected_entity->points.items + i;
|
state.has_selected_entities = true;
|
||||||
pt->x += delta_x;
|
} else {
|
||||||
pt->y += delta_y;
|
should_clear_prev_selections = true;
|
||||||
|
state.has_selected_entities = false;
|
||||||
|
}
|
||||||
|
} else if (state.has_selected_entities && !state.is_area_selecting) {
|
||||||
|
selected_entity = find_entity_near_mouse(&state, &io->MousePos);
|
||||||
|
if (selected_entity && selected_entity->flags & entity_flag_selected) {
|
||||||
|
is_moving_entities = true;
|
||||||
|
move_entity_by.x = io->MousePos.x - state.last_mouse_pos.x;
|
||||||
|
move_entity_by.y = io->MousePos.y - state.last_mouse_pos.y;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.is_area_selecting = true;
|
||||||
|
select_entities_in_area(&state, &state.drag_start, &io->MousePos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (state.is_area_selecting) {
|
||||||
|
state.is_area_selecting = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (igIsKeyPressed_Bool(ImGuiKey_Backspace, false)) {
|
||||||
|
remove_selected_entites(&state);
|
||||||
|
state.has_selected_entities = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//======= draw entities to canvas =========
|
||||||
|
|
||||||
|
for (entity_t *entity = state.entities; entity != NULL;
|
||||||
|
entity = entity->next) {
|
||||||
|
bool is_selected;
|
||||||
|
if (should_clear_prev_selections && entity != selected_entity) {
|
||||||
|
is_selected = false;
|
||||||
|
entity->flags &= ~entity_flag_selected;
|
||||||
|
} else {
|
||||||
|
is_selected = entity->flags & entity_flag_selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->flags & entity_flag_path) {
|
||||||
|
for (size_t i = 1; i < entity->points.length; ++i) {
|
||||||
|
ImVec2 *current_point = &entity->points.items[i];
|
||||||
|
ImVec2 *last_point = &entity->points.items[i - 1];
|
||||||
|
|
||||||
|
if (is_selected) {
|
||||||
|
if (i == 1) {
|
||||||
|
vec2_move(last_point, &move_entity_by);
|
||||||
|
}
|
||||||
|
vec2_move(current_point, &move_entity_by);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImU32 color =
|
||||||
|
(entity->flags & entity_flag_selected) ? 0xFF0000FF : 0xFFFFFFFF;
|
||||||
|
ImDrawList_AddLine(draw_list, *last_point, *current_point, color, 2);
|
||||||
|
}
|
||||||
|
} else if (entity->flags & entity_flag_rect) {
|
||||||
|
if (is_selected) {
|
||||||
|
vec2_move(entity->points.items, &move_entity_by);
|
||||||
|
vec2_move(entity->points.items + 2, &move_entity_by);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImDrawList_AddRectFilled(draw_list, entity->points.items[0],
|
||||||
|
entity->points.items[2], 0xFFFFFFFF, 0.0,
|
||||||
|
ImDrawFlags_None);
|
||||||
|
|
||||||
|
if (is_selected) {
|
||||||
|
ImDrawList_AddRect(draw_list, entity->points.items[0],
|
||||||
|
entity->points.items[2],
|
||||||
|
igGetColorU32_Vec4((ImVec4){0.537, 0.706, 1, 1}),
|
||||||
|
0.0, ImDrawFlags_None, 2.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
igSetNextWindowPos((ImVec2){io->DisplaySize.x * 0.5, 16}, ImGuiCond_Always,
|
||||||
|
(ImVec2){0.5, 0});
|
||||||
|
|
||||||
|
toolbox_window();
|
||||||
|
|
||||||
|
switch (state.selected_toolbox_button) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case toolbox_button_select: {
|
||||||
|
if (state.is_dragging && state.is_prev_dragging && !is_moving_entities) {
|
||||||
|
ImDrawList_AddRect(draw_list, state.drag_start, io->MousePos, 0xFFFFFFFF,
|
||||||
|
0.0f, ImDrawFlags_None, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case toolbox_button_rectangle:
|
||||||
|
if (state.is_dragging) {
|
||||||
|
ImDrawList_AddRectFilled(draw_list, state.drag_start, io->MousePos,
|
||||||
|
0xFFFFFFFF, 0.0f, ImDrawFlags_None);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case toolbox_button_draw: {
|
case toolbox_button_draw: {
|
||||||
if (state.is_dragging && (state.last_mouse_pos.x != io->MousePos.x ||
|
if (state.is_dragging && (state.last_mouse_pos.x != io->MousePos.x ||
|
||||||
@@ -502,51 +729,8 @@ static void frame(void) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case toolbox_button_rectangle:
|
|
||||||
if (state.is_dragging) {
|
|
||||||
ImDrawList_AddRectFilled(draw_list, state.drag_start, io->MousePos,
|
|
||||||
0xFFFFFFFF, 0.0f, ImDrawFlags_None);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (igIsKeyPressed_Bool(ImGuiKey_Backspace, false)) {
|
|
||||||
if (state.selected_entity) {
|
|
||||||
remove_entity(&state, state.selected_entity);
|
|
||||||
state.selected_entity = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//======= draw entities to canvas =========
|
|
||||||
|
|
||||||
for (entity_t *entity = state.entites; entity != NULL;
|
|
||||||
entity = entity->next) {
|
|
||||||
if (entity->flags & entity_flag_path) {
|
|
||||||
for (size_t i = 1; i < entity->points.length; ++i) {
|
|
||||||
ImVec2 *current_point = &entity->points.items[i];
|
|
||||||
ImVec2 *last_point = &entity->points.items[i - 1];
|
|
||||||
ImU32 color = entity == state.selected_entity ? 0xFF0000FF : 0xFFFFFFFF;
|
|
||||||
ImDrawList_AddLine(draw_list, *last_point, *current_point, color, 2);
|
|
||||||
}
|
|
||||||
} else if (entity->flags & entity_flag_rect) {
|
|
||||||
ImDrawList_AddRectFilled(draw_list, entity->points.items[0],
|
|
||||||
entity->points.items[1], 0xFFFFFFFF, 0.0,
|
|
||||||
ImDrawFlags_None);
|
|
||||||
|
|
||||||
if (state.selected_entity == entity) {
|
|
||||||
ImDrawList_AddRect(draw_list, entity->points.items[0],
|
|
||||||
entity->points.items[1],
|
|
||||||
igGetColorU32_Vec4((ImVec4){0.537, 0.706, 1, 1}),
|
|
||||||
0.0, ImDrawFlags_None, 2.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
igSetNextWindowPos((ImVec2){io->DisplaySize.x * 0.5, 16}, ImGuiCond_Always,
|
|
||||||
(ImVec2){0.5, 0});
|
|
||||||
|
|
||||||
toolbox_window();
|
|
||||||
|
|
||||||
state.last_mouse_pos = io->MousePos;
|
state.last_mouse_pos = io->MousePos;
|
||||||
|
|
||||||
igShowMetricsWindow(NULL);
|
igShowMetricsWindow(NULL);
|
||||||
|
Reference in New Issue
Block a user