diff --git a/base/sources/iron_ui_nodes.c b/base/sources/iron_ui_nodes.c index 355d9737..9b276b35 100644 --- a/base/sources/iron_ui_nodes.c +++ b/base/sources/iron_ui_nodes.c @@ -33,6 +33,7 @@ void (*ui_nodes_on_canvas_released)(void) = NULL; void (*ui_nodes_on_socket_released)(int) = NULL; void (*ui_nodes_on_link_drag)(int, bool) = NULL; void (*ui_nodes_on_node_remove)(ui_node_t *) = NULL; +void (*ui_nodes_on_node_changed)(ui_node_t *) = NULL; bool ui_nodes_grid_snap = true; int ui_nodes_grid_snap_w = 40; @@ -311,6 +312,9 @@ void ui_remove_node(ui_node_t *n, ui_node_canvas_t *canvas) { ui_node_link_t *l = canvas->links->buffer[i]; if (l->from_id == n->id || l->to_id == n->id) { ui_remove_link_at(canvas, i); + if (ui_nodes_on_node_changed != NULL && l->from_id == n->id) { + ui_nodes_on_node_changed(ui_get_node(canvas->nodes, l->to_id)); + } } else { i++; @@ -806,7 +810,13 @@ void ui_node_draw(ui_node_t *node, ui_node_canvas_t *canvas) { ny += lineh * 0.5; if (!(node->flags & NODE_FLAG_COLLAPSED)) { + bool _changed = current->changed; + current->changed = false; ui_node_draw_body(node, canvas, nx, ny); + if (ui_nodes_on_node_changed != NULL && current->changed) { + ui_nodes_on_node_changed(node); + } + current->changed = _changed || current->changed; } current->_x = ui_x; @@ -1046,6 +1056,9 @@ void ui_node_canvas(ui_nodes_t *nodes, ui_node_canvas_t *canvas) { l->to_id = l->to_socket = -1; current_nodes->link_drag_id = l->id; current_nodes->is_new_link = false; + if (ui_nodes_on_node_changed != NULL) { + ui_nodes_on_node_changed(node); + } break; } } @@ -1081,12 +1094,18 @@ void ui_node_canvas(ui_nodes_t *nodes, ui_node_canvas_t *canvas) { link_drag->to_id = current_nodes->snap_to_id; link_drag->to_socket = current_nodes->snap_socket; current->changed = true; + if (ui_nodes_on_node_changed != NULL) { + ui_nodes_on_node_changed(ui_get_node(canvas->nodes, link_drag->to_id)); + } } else if (current_nodes->snap_from_id != -1) { // Connect to output ui_node_link_t *link_drag = ui_get_link(canvas->links, current_nodes->link_drag_id); link_drag->from_id = current_nodes->snap_from_id; link_drag->from_socket = current_nodes->snap_socket; current->changed = true; + if (ui_nodes_on_node_changed != NULL) { + ui_nodes_on_node_changed(ui_get_node(canvas->nodes, link_drag->to_id)); + } } else if (current_nodes->link_drag_id != -1) { // Remove dragged link current->changed = true; @@ -1353,6 +1372,8 @@ void ui_node_canvas(ui_nodes_t *nodes, ui_node_canvas_t *canvas) { bool hide = (current->input_started || current->input_started_r) && (current->input_x - wx < ui_popup_x - 6 || current->input_x - wx > ui_popup_x + ui_popup_w + 6 || current->input_y - wy < ui_popup_y - 6 || current->input_y - wy > ui_popup_y + ui_popup_h * UI_SCALE() + 6); if (hide || current->is_escape_down) { ui_popup_commands = NULL; + ui_nodes_on_node_changed(ui_get_node(canvas->nodes, ui_popup_handle_node_id)); + current->changed = false; } } } diff --git a/base/sources/iron_ui_nodes.h b/base/sources/iron_ui_nodes.h index f024b5ab..9882d685 100644 --- a/base/sources/iron_ui_nodes.h +++ b/base/sources/iron_ui_nodes.h @@ -138,6 +138,7 @@ extern void (*ui_nodes_on_canvas_released)(void); extern void (*ui_nodes_on_socket_released)(int); extern void (*ui_nodes_on_link_drag)(int, bool); extern void (*ui_nodes_on_node_remove)(ui_node_t *); +extern void (*ui_nodes_on_node_changed)(ui_node_t *); extern bool ui_nodes_grid_snap; void ui_node_canvas_encode(ui_node_canvas_t *canvas); diff --git a/base/sources/ts/iron.ts b/base/sources/ts/iron.ts index 6d8a1c23..58c6f431 100644 --- a/base/sources/ts/iron.ts +++ b/base/sources/ts/iron.ts @@ -686,6 +686,7 @@ declare let ui_on_border_hover: any; declare let ui_on_tab_drop: any; declare let ui_nodes_on_link_drag: any; declare let ui_nodes_on_node_remove: any; +declare let ui_nodes_on_node_changed: any; declare let ui_nodes_on_socket_released: any; declare let ui_nodes_on_canvas_released: any; declare let ui_nodes_on_canvas_control: any; diff --git a/paint/sources/context.ts b/paint/sources/context.ts index a0ee12fa..e6fb7f5b 100644 --- a/paint/sources/context.ts +++ b/paint/sources/context.ts @@ -4,21 +4,16 @@ type context_t = { paint_object?: mesh_object_t; merged_object?: mesh_object_t; merged_object_is_atlas?: bool; - ddirty?: i32; pdirty?: i32; rdirty?: i32; brush_blend_dirty?: bool; - node_preview_socket?: i32; - split_view?: bool; view_index?: i32; view_index_last?: i32; - swatch?: swatch_color_t; picked_color?: swatch_color_t; color_picker_callback?: (sc: swatch_color_t)=>void; - default_irradiance?: f32_array_t; default_radiance?: gpu_texture_t; default_radiance_mipmaps?: gpu_texture_t[]; @@ -34,24 +29,20 @@ type context_t = { light_angle?: f32; cull_backfaces?: bool; texture_filter?: bool; - format_type?: texture_ldr_format_t; format_quality?: f32; layers_destination?: export_destination_t; split_by?: split_type_t; parse_transform?: bool; parse_vcols?: bool; - select_time?: f32; viewport_mode?: viewport_mode_t; render_mode?: render_mode_t; - viewport_shader?: any; // JSValue * -> (ns: node_shader_t)=>void; hscale_was_changed?: bool; export_mesh_format?: mesh_format_t; export_mesh_index?: i32; pack_assets_on_export?: bool; - paint_vec?: vec4_t; last_paint_x?: f32; last_paint_y?: f32; @@ -62,19 +53,16 @@ type context_t = { clone_start_y?: f32; clone_delta_x?: f32; clone_delta_y?: f32; - show_compass?: bool; project_type?: i32; project_aspect_ratio?: i32; project_objects?: mesh_object_t[]; - last_paint_vec_x?: f32; last_paint_vec_y?: f32; prev_paint_vec_x?: f32; prev_paint_vec_y?: f32; frame?: i32; paint2d_view?: bool; - brush_locked?: bool; camera_type?: camera_type_t; cam_handle?: ui_handle_t; @@ -87,16 +75,14 @@ type context_t = { last_status_position?: i32; camera_controls?: camera_controls_t; pen_painting_only?: bool; - material?: slot_material_t; layer?: slot_layer_t; brush?: slot_brush_t; font?: slot_font_t; tool?: tool_type_t; - layer_preview_dirty?: bool; layers_preview_dirty?: bool; - node_preview_dirty?: bool; + node_preview_socket?: i32; node_preview_map?: map_t; node_preview_name?: string; node_previews?: map_t; @@ -104,11 +90,9 @@ type context_t = { selected_node_preview: bool; mask_preview_rgba32?: gpu_texture_t; mask_preview_last?: slot_layer_t; - colorid_picked?: bool; material_preview?: bool; saved_camera?: mat4_t; - color_picker_previous_tool?: tool_type_t; materialid_picked?: i32; uvx_picked?: f32; @@ -122,32 +106,25 @@ type context_t = { norx_picked?: f32; nory_picked?: f32; norz_picked?: f32; - draw_wireframe?: bool; wireframe_handle?: ui_handle_t; draw_texels?: bool; texels_handle?: ui_handle_t; - colorid_handle?: ui_handle_t; layers_export?: export_mode_t; - decal_image?: gpu_texture_t; decal_preview?: bool; decal_x?: f32; decal_y?: f32; - // cache_draws?: bool; write_icon_on_export?: bool; - text_tool_image?: gpu_texture_t; text_tool_text?: string; particle_material?: material_data_t; - layer_filter?: i32; brush_output_node_inst?: brush_output_node_t; run_brush?: (self: any, i: i32)=>void; parse_brush_inputs?: (self: any)=>void; - gizmo?: object_t; gizmo_translate_x?: object_t; gizmo_translate_y?: object_t; @@ -171,7 +148,6 @@ type context_t = { rotate_x?: bool; rotate_y?: bool; rotate_z?: bool; - brush_nodes_radius?: f32; brush_nodes_opacity?: f32; brush_mask_image?: gpu_texture_t; @@ -188,7 +164,6 @@ type context_t = { brush_nodes_angle?: f32; brush_nodes_hardness?: f32; brush_directional?: bool; - brush_radius?: f32; brush_radius_handle?: ui_handle_t; brush_scale_x?: f32; @@ -220,31 +195,24 @@ type context_t = { bake_curv_offset?: f32; bake_curv_smooth?: i32; bake_high_poly?: i32; - xray?: bool; sym_x?: bool; sym_y?: bool; sym_z?: bool; fill_type_handle?: ui_handle_t; - paint2d?: bool; - maximized_sidebar_width?: i32; drag_dest?: i32; - coords?: vec4_t; start_x?: f32; start_y?: f32; - lock_begin?: bool; lock_x?: bool; lock_y?: bool; lock_start_x?: f32; lock_start_y?: f32; registered?: bool; - selected_object?: object_t; - particle_hit_x?: f32; particle_hit_y?: f32; particle_hit_z?: f32; @@ -264,7 +232,6 @@ function context_create(): context_t { c.pdirty = 0; // paint c.rdirty = 0; // render c.brush_blend_dirty = true; - c.node_preview_socket = 0; c.split_view = false; c.view_index = -1; c.view_index_last = -1; @@ -322,10 +289,9 @@ function context_create(): context_t { c.last_status_position = 0; c.camera_controls = camera_controls_t.ORBIT; c.pen_painting_only = false; // Reject painting with finger when using pen - c.layer_preview_dirty = true; c.layers_preview_dirty = false; - c.node_preview_dirty = false; + c.node_preview_socket = 0; c.node_preview_name = ""; c.node_preview_map = map_create(); c.selected_node_preview = true; @@ -389,7 +355,6 @@ function context_create(): context_t { c.brush_nodes_angle = 0.0; c.brush_nodes_hardness = 1.0; c.brush_directional = false; - c.brush_radius_handle = ui_handle_create(); c.brush_scale_x = 1.0; c.brush_decal_mask_radius = 0.5; @@ -431,7 +396,6 @@ function context_create(): context_t { c.paint2d = false; c.maximized_sidebar_width = 0; c.drag_dest = 0; - return c; } diff --git a/paint/sources/ui_nodes.ts b/paint/sources/ui_nodes.ts index 2979f7e6..8a07c948 100644 --- a/paint/sources/ui_nodes.ts +++ b/paint/sources/ui_nodes.ts @@ -51,11 +51,13 @@ let _ui_nodes_hval3: ui_handle_t = ui_handle_create(); let _ui_nodes_on_canvas_released_selected: ui_node_t; let _ui_nodes_node_search_first: bool; let _ui_nodes_node_search_done: ()=>void; +let ui_nodes_node_changed: ui_node_t = null; function ui_viewnodes_init() { ui_nodes_preview_image = ui_nodes_get_node_preview_image; ui_nodes_on_link_drag = ui_viewnodes_on_link_drag; ui_nodes_on_node_remove = ui_viewnodes_on_node_remove; + ui_nodes_on_node_changed = ui_viewnodes_on_node_changed; ui_nodes_on_socket_released = ui_viewnodes_on_socket_released; ui_nodes_on_canvas_released = ui_viewnodes_on_canvas_released; ui_nodes_on_canvas_control = ui_viewnodes_on_canvas_control; @@ -71,6 +73,10 @@ function ui_viewnodes_on_node_remove(n: ui_node_t) { } } +function ui_viewnodes_on_node_changed(n: ui_node_t) { + ui_nodes_node_changed = n; +} + function ui_viewnodes_on_link_drag(link_drag_id: i32, is_new_link: bool) { if (!is_new_link) { return; @@ -133,7 +139,7 @@ function ui_viewnodes_on_link_drag(link_drag_id: i32, is_new_link: bool) { // Selecting which node socket to preview else if (ui_nodes.nodes_selected_id.length > 0 && node.id == ui_nodes.nodes_selected_id[0]) { context_raw.node_preview_socket = link_drag.from_id > -1 ? link_drag.from_socket : 0; - context_raw.node_preview_dirty = true; + ui_nodes_node_changed = node; } } @@ -254,7 +260,7 @@ function ui_viewnodes_on_socket_released(socket_id: i32) { let i: i32 = array_index_of(node.outputs, socket); if (i > -1) { context_raw.node_preview_socket = i; - context_raw.node_preview_dirty = true; + ui_nodes_node_changed = node; } } } @@ -777,28 +783,33 @@ function ui_nodes_recompile() { } ui_base_hwnds[tab_area_t.SIDEBAR0].redraws = 2; - context_raw.node_preview_dirty = true; - ui_nodes_recompile_mat_final = false; } } +function ui_nodes_get_linked_nodes(linked_nodes: ui_node_t[], n: ui_node_t, c: ui_node_canvas_t) { + if (array_index_of(linked_nodes, n) == -1 && (n.flags & _ui_node_flag_t.PREVIEW)) { + array_push(linked_nodes, n); + } + for (let i: i32 = 0; i < c.links.length; ++i) { + let l: ui_node_link_t = c.links[i]; + if (l.from_id == n.id) { + let nn: ui_node_t = ui_get_node(c.nodes, l.to_id); + ui_nodes_get_linked_nodes(linked_nodes, nn, c); + } + } +} + function ui_nodes_render() { ui_nodes_recompile(); - // Node preview - let nodes: ui_nodes_t = ui_nodes_get_nodes(); - if (nodes.nodes_selected_id.length > 0 && nodes.nodes_selected_id[0] != ui_nodes_last_node_selected_id) { - ui_nodes_last_node_selected_id = nodes.nodes_selected_id[0]; - context_raw.node_preview_dirty = true; - context_raw.node_preview_socket = 0; - } + let ui_nodes: ui_nodes_t = ui_nodes_get_nodes(); // Remove dragged link when mouse is released out of the node viewport let c: ui_node_canvas_t = ui_nodes_get_canvas(true); - if (ui_nodes_release_link && nodes.link_drag_id != -1) { - array_remove(c.links, ui_get_link(c.links, nodes.link_drag_id)); - nodes.link_drag_id = -1; + if (ui_nodes_release_link && ui_nodes.link_drag_id != -1) { + array_remove(c.links, ui_get_link(c.links, ui_nodes.link_drag_id)); + ui_nodes.link_drag_id = -1; } ui_nodes_release_link = ui.input_released; @@ -808,7 +819,6 @@ function ui_nodes_render() { ui.input_enabled = base_ui_enabled; - let ui_nodes: ui_nodes_t = ui_nodes_get_nodes(); if (ui_nodes_last_zoom != ui_nodes.zoom) { ui_nodes_last_zoom = ui_nodes.zoom; ui_nodes_grid_redraw = true; @@ -822,8 +832,34 @@ function ui_nodes_render() { ui_nodes_grid_redraw = false; } - if (context_raw.selected_node_preview && context_raw.node_preview_dirty) { - ui_nodes_make_node_preview(); + // Selected node preview + if (ui_nodes.nodes_selected_id.length > 0 && ui_nodes.nodes_selected_id[0] != ui_nodes_last_node_selected_id) { + ui_nodes_last_node_selected_id = ui_nodes.nodes_selected_id[0]; + let sel: ui_node_t = ui_get_node(c.nodes, ui_nodes.nodes_selected_id[0]); + context_raw.node_preview_socket = 0; + ui_nodes_make_node_preview(sel); + } + else if (ui_nodes.nodes_selected_id.length == 0) { + ui_nodes_last_node_selected_id = -1; + } + + // Update node previews + if (ui_nodes_node_changed != null && !ui.input_down) { + let linked_nodes: ui_node_t[] = []; + ui_nodes_get_linked_nodes(linked_nodes, ui_nodes_node_changed, c); + + let sel: ui_node_t = ui_nodes.nodes_selected_id.length > 0 ? ui_get_node(c.nodes, ui_nodes.nodes_selected_id[0]) : null; + if (sel != null && array_index_of(linked_nodes, sel) == -1) { + array_push(linked_nodes, sel); + } + + let _node_preview_socket: i32 = context_raw.node_preview_socket; + for (let i: i32 = 0; i < linked_nodes.length; ++i) { + context_raw.node_preview_socket = linked_nodes[i] == sel ? _node_preview_socket : 0; + ui_nodes_make_node_preview(linked_nodes[i]); + } + context_raw.node_preview_socket = _node_preview_socket; + ui_nodes_node_changed = null; } // Start with UI @@ -886,7 +922,7 @@ function ui_nodes_render() { // Grid draw_set_color(0xffffffff); - let step: f32 = ui_nodes_grid_cell_w * nodes.zoom; + let step: f32 = ui_nodes_grid_cell_w * ui_nodes.zoom; let x: f32 = math_fmod(UI_NODES_PAN_X(), step) - step; let y: f32 = math_fmod(UI_NODES_PAN_Y(), step) - step; draw_image(ui_nodes_grid, x, y); @@ -905,13 +941,13 @@ function ui_nodes_render() { ui.window_border_top = ui_header_h * 2; ui.window_border_bottom = config_raw.layout[layout_size_t.STATUS_H]; - ui_node_canvas(nodes, c); + ui_node_canvas(ui_nodes, c); ui.input_enabled = _input_enabled; - if (nodes.color_picker_callback != null) { + if (ui_nodes.color_picker_callback != null) { context_raw.color_picker_previous_tool = context_raw.tool; context_select_tool(tool_type_t.PICKER); - _ui_nodes_render_tmp = nodes.color_picker_callback; + _ui_nodes_render_tmp = ui_nodes.color_picker_callback; context_raw.color_picker_callback = function (color: swatch_color_t) { _ui_nodes_render_tmp(color.base); @@ -922,7 +958,7 @@ function ui_nodes_render() { ui_nodes_canvas_changed(); } }; - nodes.color_picker_callback = null; + ui_nodes.color_picker_callback = null; } // Remove nodes with unknown id for this canvas type @@ -954,7 +990,7 @@ function ui_nodes_render() { } if (!found) { ui_remove_node(canvas_node, c); - array_remove(nodes.nodes_selected_id, canvas_node.id); + array_remove(ui_nodes.nodes_selected_id, canvas_node.id); i--; } } @@ -978,8 +1014,8 @@ function ui_nodes_render() { ui_nodes_uichanged_last = ui.changed; // Node previews - if (context_raw.selected_node_preview && nodes.nodes_selected_id.length > 0) { - let sel: ui_node_t = ui_get_node(c.nodes, nodes.nodes_selected_id[0]); + if (context_raw.selected_node_preview && ui_nodes.nodes_selected_id.length > 0) { + let sel: ui_node_t = ui_get_node(c.nodes, ui_nodes.nodes_selected_id[0]); let img: gpu_texture_t = ui_nodes_get_node_preview_image(sel); if (img != null && !(sel.flags & _ui_node_flag_t.PREVIEW)) { let tw: f32 = 128 * UI_SCALE(); @@ -1417,6 +1453,7 @@ function ui_nodes_make_node(n: ui_node_t, nodes: ui_nodes_t, canvas: ui_node_can array_push(node.buttons, but); } + ui_nodes_node_changed = node; return node; } @@ -1459,17 +1496,7 @@ function ui_nodes_make_group_node(group_canvas: ui_node_canvas_t, nodes: ui_node return node; } -function ui_nodes_make_node_preview() { - let ui_nodes: ui_nodes_t = ui_nodes_get_nodes(); - if (ui_nodes.nodes_selected_id.length == 0) { - return; - } - - let nodes: ui_node_t[] = ui_nodes_get_canvas().nodes; - let node: ui_node_t = ui_get_node(nodes, ui_nodes.nodes_selected_id[0]); - if (node == null) { - return; - } +function ui_nodes_make_node_preview(node: ui_node_t) { context_raw.node_preview_name = node.name; if (node.type == "LAYER" || @@ -1479,6 +1506,7 @@ function ui_nodes_make_node_preview() { return; } + let nodes: ui_node_t[] = ui_nodes_get_canvas().nodes; if (array_index_of(nodes, node) == -1) { return; } @@ -1489,7 +1517,6 @@ function ui_nodes_make_node_preview() { map_set(context_raw.node_preview_map, node, img); } - context_raw.node_preview_dirty = false; ui_nodes_hwnd.redraws = 2; util_render_make_node_preview(ui_nodes_get_canvas(), node, img); }