paint: select tool

This commit is contained in:
luboslenco
2026-06-05 00:41:18 +02:00
parent 0cf5ec0635
commit 421411a9f3
7 changed files with 90 additions and 5 deletions
+63
View File
@@ -448,6 +448,19 @@ void base_render(void *_) {
draw_end();
}
// Select tool rectangle mask
if (g_context->select_active || g_context->select_dragging) {
f32 x1 = g_context->select_x1 * sys_w() + sys_x();
f32 y1 = g_context->select_y1 * sys_h() + sys_y();
f32 x2 = g_context->select_x2 * sys_w() + sys_x();
f32 y2 = g_context->select_y2 * sys_h() + sys_y();
draw_begin(NULL, false, 0);
draw_set_color(g_context->select_dragging ? 0xffffffff : 0xaaffffff);
draw_rect(x1, y1, x2 - x1, y2 - y1, 1.0);
draw_set_color(0xffffffff);
draw_end();
}
bool using_menu = ui_menu_show && mouse_y > ui_header_h;
base_ui_enabled = !ui_box_show && !using_menu && ui->combo_selected_handle == NULL;
@@ -860,6 +873,49 @@ void ui_base_update_ui() {
g_context->brush_stencil_y += (old_h - new_h) / (float)base_h() / 2.0;
}
// Select tool
if (g_context->tool == TOOL_TYPE_SELECT) {
if (base_ui_enabled && !base_is_dragging && !base_is_resizing) {
f32 mx = mouse_view_x();
f32 my = mouse_view_y();
bool in_viewport = mx < sys_w() && mx > 0 && my < sys_h() && my > 0;
if (mouse_started("left") && in_viewport) {
g_context->select_dragging = true;
g_context->select_start_x = mx / (float)sys_w();
g_context->select_start_y = my / (float)sys_h();
g_context->select_x1 = g_context->select_start_x;
g_context->select_y1 = g_context->select_start_y;
g_context->select_x2 = g_context->select_start_x;
g_context->select_y2 = g_context->select_start_y;
}
if (g_context->select_dragging && mouse_down("left")) {
f32 cx = math_max(0.0, math_min(1.0, mx / (float)sys_w()));
f32 cy = math_max(0.0, math_min(1.0, my / (float)sys_h()));
g_context->select_x1 = math_min(g_context->select_start_x, cx);
g_context->select_y1 = math_min(g_context->select_start_y, cy);
g_context->select_x2 = math_max(g_context->select_start_x, cx);
g_context->select_y2 = math_max(g_context->select_start_y, cy);
}
if (g_context->select_dragging && mouse_released("left")) {
g_context->select_dragging = false;
f32 dx = math_abs(g_context->select_x2 - g_context->select_x1) * sys_w();
f32 dy = math_abs(g_context->select_y2 - g_context->select_y1) * sys_h();
bool was_active = g_context->select_active;
// Drag to enable, click to cancel
g_context->select_active = dx > 3 && dy > 3;
if (was_active != g_context->select_active) {
make_material_parse_paint_material(false);
}
}
}
}
else {
g_context->select_dragging = false;
}
bool set_clone_source =
g_context->tool == TOOL_TYPE_CLONE &&
operator_shortcut(string("%s+%s", any_map_get(config_keymap, "set_clone_source"), any_map_get(config_keymap, "action_paint")), SHORTCUT_TYPE_DOWN);
@@ -883,6 +939,10 @@ void ui_base_update_ui() {
down = false;
}
if (g_context->tool == TOOL_TYPE_SELECT) {
down = false;
}
if (down) {
i32 mx = mouse_view_x();
i32 my = mouse_view_y();
@@ -1199,6 +1259,9 @@ void ui_base_update(void *_) {
else if (operator_shortcut(any_map_get(config_keymap, "tool_cursor"), SHORTCUT_TYPE_STARTED)) {
context_select_tool(TOOL_TYPE_CURSOR);
}
else if (operator_shortcut(any_map_get(config_keymap, "tool_select"), SHORTCUT_TYPE_STARTED)) {
context_select_tool(TOOL_TYPE_SELECT);
}
else if (operator_shortcut(any_map_get(config_keymap, "swap_brush_eraser"), SHORTCUT_TYPE_STARTED)) {
context_select_tool(g_context->tool == TOOL_TYPE_BRUSH ? TOOL_TYPE_ERASER : TOOL_TYPE_BRUSH);
}
+4 -3
View File
@@ -234,7 +234,8 @@ typedef enum {
TOOL_TYPE_PICKER = 9,
TOOL_TYPE_MATERIAL = 10,
TOOL_TYPE_CURSOR = 11,
TOOL_TYPE_BAKE = 12, // Hidden, used by Bake Texture node
TOOL_TYPE_SELECT = 12,
TOOL_TYPE_BAKE = 13, // Hidden, used by Bake Texture node
} tool_type_t;
typedef enum {
@@ -320,9 +321,9 @@ typedef enum {
ICON_TEXT_PREVIEW = 18,
ICON_PROPERTIES = 19,
ICON_FOLDER_OPEN = 20,
ICON_EMPTY = 21,
ICON_BAKE = 21,
ICON_SMUDGE = 22,
ICON_BAKE = 23,
ICON_SELECT = 23,
ICON_MENU = 24,
ICON_FILE_NEW = 25,
ICON_FOLDER = 26,
+1
View File
@@ -100,6 +100,7 @@ any_map_t *keymap_get_default() {
any_map_set(keymap, "tool_colorid", "c");
any_map_set(keymap, "tool_picker", "v");
any_map_set(keymap, "tool_cursor", "r");
any_map_set(keymap, "tool_select", "m");
any_map_set(keymap, "tool_material", "");
any_map_set(keymap, "swap_brush_eraser", "");
return keymap;
+4 -2
View File
@@ -313,8 +313,9 @@ void _kickstart() {
_tr("Picker"),
_tr("Material"),
_tr("Cursor"),
_tr("Select"),
},
12);
13);
gc_root(ui_toolbar_tool_names);
ui_toolbar_tooltip_extras = any_array_create_from_raw(
@@ -331,8 +332,9 @@ void _kickstart() {
"",
"",
"",
"",
},
12);
13);
gc_root(ui_toolbar_tooltip_extras);
uniforms_ext_ortho_p = mat4_ortho(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);
+7
View File
@@ -219,6 +219,13 @@ node_shader_context_t *make_paint_run(material_t *data, material_context_t *matc
node_shader_write_frag(kong, "bsp.x *= constants.aspect_ratio;");
node_shader_write_frag(kong, "bsp = bsp * 0.5 + 0.5;");
// Select tool mask
if (g_context->select_active) {
node_shader_add_constant(kong, "select_mask: float4", "_select_mask");
node_shader_write_frag(kong, "if (sp.x < constants.select_mask.x || sp.x > constants.select_mask.z || sp.y < constants.select_mask.y || sp.y > "
"constants.select_mask.w) { discard; }");
}
node_shader_add_texture(kong, "gbufferD", NULL);
kong->frag_out = "float4[4]";
+8
View File
@@ -295,6 +295,14 @@ typedef struct context {
f32 decal_x;
f32 decal_y;
bool decal_camera_align;
bool select_active; // Select tool
bool select_dragging;
f32 select_start_x;
f32 select_start_y;
f32 select_x1;
f32 select_y1;
f32 select_x2;
f32 select_y2;
bool write_icon_on_export;
struct gpu_texture *text_tool_image;
char *text_tool_text;
+3
View File
@@ -279,6 +279,9 @@ vec4_t uniforms_ext_vec4_link(object_t *object, material_data_t *mat, char *link
}
return v;
}
else if (string_equals(link, "_select_mask")) {
return (vec4_t){g_context->select_x1, g_context->select_y1, g_context->select_x2, g_context->select_y2};
}
return vec4_nan();
}