diff --git a/#backups/objects/o_dialog_add_node/o_dialog_add_node.yy.backup0 b/#backups/objects/o_dialog_add_node/o_dialog_add_node.yy.backup0 new file mode 100644 index 000000000..101039dc6 --- /dev/null +++ b/#backups/objects/o_dialog_add_node/o_dialog_add_node.yy.backup0 @@ -0,0 +1,1109 @@ +// 2024-04-16 11:36:08 +#event properties (no comments/etc. here are saved) +parent_index = _p_dialog; +uses_physics = false; + +#event create init +event_inherited(); + +#region data + draggable = false; + + node_target_x = 0; + node_target_y = 0; + node_called = noone; + junction_hovering = noone; + + dialog_w = PREFERENCES.dialog_add_node_w; + dialog_h = PREFERENCES.dialog_add_node_h; + + destroy_on_click_out = true; + + node_selecting = 0; + node_focusing = -1; + + node_show_connectable = true; + node_tooltip = noone; + node_tooltip_x = 0; + node_tooltip_y = 0; + + anchor = ANCHOR.left | ANCHOR.top; + node_menu_selecting = noone; + + is_global = PANEL_GRAPH.getCurrentContext() == noone; + + #region ---- category ---- + category = NODE_CATEGORY; + switch(instanceof(context)) { + case "Node_Pixel_Builder" : category = NODE_PB_CATEGORY; break; + case "Node_DynaSurf" : category = NODE_PCX_CATEGORY; break; + } + + draw_set_font(f_p0); + var maxLen = 0; + for(var i = 0; i < ds_list_size(category); i++) { + var cat = category[| i]; + + if(array_length(cat.filter) && !array_exists(cat.filter, instanceof(context))) + continue; + + var name = __txt(cat.name); + maxLen = max(maxLen, string_width(name)); + } + category_width = maxLen + ui(56); + #endregion + + function rightClick(node) { #region + if(!is_instanceof(node, NodeObject)) return; + + node_menu_selecting = node; + var fav = array_exists(global.FAV_NODES, node.node); + + var menu = [ + menuItem(fav? __txtx("add_node_remove_favourite", "Remove from favourite") : __txtx("add_node_add_favourite", "Add to favourite"), + function() { + if(!is_array(global.FAV_NODES)) global.FAV_NODES = []; + + if(array_exists(global.FAV_NODES, node_menu_selecting.node)) + array_remove(global.FAV_NODES, node_menu_selecting.node); + else + array_push(global.FAV_NODES, node_menu_selecting.node); + }, THEME.star) + ]; + + menuCall("add_node_window_manu",,, menu,, node_menu_selecting); + } #endregion + + function filtered(node) { #region + if(!node_show_connectable) return true; + if(node_called == noone && junction_hovering == noone) return true; + if(!struct_has(node, "node")) return true; + if(!struct_has(global.NODE_GUIDE, node.node)) return true; + + if(is_instanceof(node, NodeObject)) { + if(node.is_patreon_extra && !IS_PATREON) return true; + if(is_global && !node.show_in_global) return true; + } + + var io = global.NODE_GUIDE[$ node.node]; + + if(node_called) { + var call_in = node_called.connect_type == JUNCTION_CONNECT.input; + var ar = call_in? io.outputs : io.inputs; + var typ = node_called.type; + + for( var i = 0, n = array_length(ar); i < n; i++ ) { + if(!ar[i].visible) continue; + + var _in = call_in? node_called.type : ar[i].type; + var _ot = call_in? ar[i].type : node_called.type; + + if(typeCompatible(_in, _ot, false)) return true; + } + + return false; + } else if(junction_hovering) { + var to = junction_hovering.type; + var fr = junction_hovering.value_from.type; + + for( var i = 0, n = array_length(io.inputs); i < n; i++ ) { + var _in = fr; + var _ot = io.inputs[i].type; + if(!io.inputs[i].visible) continue; + + if(typeCompatible(_in, _ot, false)) return true; + } + + for( var i = 0, n = array_length(io.outputs); i < n; i++ ) { + var _in = io.outputs[i].type; + var _ot = to; + + if(typeCompatible(_in, _ot, false)) return true; + } + + return false; + } + + return false; + } #endregion + + function buildNode(_node, _param = {}) { #region + instance_destroy(); + instance_destroy(o_dialog_menubox); + + if(!_node) return; + + if(is_instanceof(context, Node_Canvas)) { + context.nodeTool = new canvas_tool_node(context, _node); + return; + } + + if(is_instanceof(_node, AddNodeItem)) { + _node.onClick({ + node_called, + junction_hovering + }); + return; + } + + var _new_node = noone; + var _inputs = 0, _outputs = 0; + + if(is_instanceof(_node, NodeObject)) { + _new_node = _node.build(node_target_x, node_target_y,, _param); + if(!_new_node) return; + + if(category == NODE_CATEGORY && _node.show_in_recent) { + array_remove(global.RECENT_NODES, _node.node); + array_insert(global.RECENT_NODES, 0, _node.node); + if(array_length(global.RECENT_NODES) > PREFERENCES.node_recents_amount) + array_pop(global.RECENT_NODES); + } + + if(is_instanceof(context, Node_Collection_Inline)) + context.addNode(_new_node); + + _inputs = _new_node.inputs; + _outputs = _new_node.outputs; + } else if(is_instanceof(_node, NodeAction)) { + var res = _node.build(node_target_x, node_target_y,, _param); + + if(_node.inputNode != noone) + _inputs = res[$ _node.inputNode].inputs; + + if(_node.outputNode != noone) + _outputs = res[$ _node.outputNode].outputs; + } else { + var _new_list = APPEND(_node.path); + _inputs = ds_list_create(); + _outputs = ds_list_create(); + + var tx = 99999; + var ty = 99999; + for( var i = 0; i < ds_list_size(_new_list); i++ ) { + tx = min(tx, _new_list[| i].x); + ty = min(tx, _new_list[| i].y); + + if(is_instanceof(context, Node_Collection_Inline) && !is_instanceof(_new_list[| i], Node_Collection_Inline)) + context.addNode(_new_list[| i]); + } + + var shx = tx - node_target_x; + var shy = ty - node_target_y; + + for( var i = 0; i < ds_list_size(_new_list); i++ ) { + _new_list[| i].x -= shx; + _new_list[| i].y -= shy; + } + + for( var i = 0; i < ds_list_size(_new_list); i++ ) { + var _in = _new_list[| i].inputs; + for( var j = 0; j < ds_list_size(_in); j++ ) { + if(_in[| j].isLeaf()) + ds_list_add(_inputs, _in[| j]); + } + + var _ot = _new_list[| i].outputs; + for( var j = 0; j < ds_list_size(_ot); j++ ) { + if(array_empty(_ot[| j].value_to)) + ds_list_add(_outputs, _ot[| j]); + } + } + + ds_list_destroy(_new_list); + } + + //try to connect + if(node_called != noone) { //dragging from junction + var _call_input = node_called.connect_type == JUNCTION_CONNECT.input; + var _node_list = _call_input? _outputs : _inputs; + for(var i = 0; i < ds_list_size(_node_list); i++) { + var _target = _node_list[| i]; + if(!_target.visible) continue; + + if(_target.auto_connect) { + if(_call_input && node_called.isConnectable(_node_list[| i])) { + node_called.setFrom(_node_list[| i]); + _new_node.x -= _new_node.w; + } else if(!_call_input && _node_list[| i].isConnectable(node_called)) + _node_list[| i].setFrom(node_called); + break; + } + } + } else if(junction_hovering != noone) { //right click on junction + var to = junction_hovering; + var from = junction_hovering.value_from; + + for( var i = 0; i < ds_list_size(_inputs); i++ ) { + var _in = _inputs[| i]; + + if(_in.auto_connect && _in.isConnectable(from)) { + _in.setFrom(from); + break; + } + } + + for( var i = 0; i < ds_list_size(_outputs); i++ ) { + var _ot = _outputs[| i]; + if(to.isConnectable(_ot)) { + to.setFrom(_ot); + break; + } + } + } + } #endregion + + catagory_pane = new scrollPane(category_width, dialog_h - ui(66), function(_y, _m) { #region catagory_pane + draw_clear_alpha(COLORS._main_text, 0); + + var ww = category_width - ui(32); + var hh = 0; + var hg = ui(28); + + var start = category == NODE_CATEGORY? -2 : 0; + + for(var i = start; i < ds_list_size(category); i++) { + var name = ""; + + if(i == -2) name = "All"; + else if(i == -1) name = "New"; + else { + var cat = category[| i]; + name = cat.name; + + if(array_length(cat.filter)) { + if(!array_exists(cat.filter, instanceof(context))) { + if(ADD_NODE_PAGE == i) + setPage(NODE_PAGE_DEFAULT); + continue; + } + draw_set_color(COLORS._main_text_accent); + } + + if(cat.color != noone) { + BLEND_OVERRIDE + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, 0, _y + hh, ww, hg, merge_color(c_white, cat.color, 0.5), 1); + BLEND_NORMAL + } + } + + var _hov = false; + + if(sHOVER && catagory_pane.hover && point_in_rectangle(_m[0], _m[1], 0, _y + hh, ww, _y + hh + hg - 1)) { + BLEND_OVERRIDE + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, 0, _y + hh, ww, hg, CDEF.main_white, 1); + BLEND_NORMAL + + _hov = true; + + if(i != ADD_NODE_PAGE && mouse_click(mb_left, sFOCUS)) { + setPage(i); + content_pane.scroll_y = 0; + content_pane.scroll_y_raw = 0; + content_pane.scroll_y_to = 0; + } + } + + var cc = COLORS._main_text_inner; + + switch(name) { + case "All" : + case "New" : + case "Favourites" : + case "Action" : + case "Custom" : + case "Extra" : + cc = merge_color(COLORS._main_text_inner, COLORS._main_text_sub, 0.75); + break; + } + + if(i == ADD_NODE_PAGE) draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_text_accent); + else draw_set_text(f_p0, fa_left, fa_center, cc); + + var _is_extra = name == "Extra"; + name = __txt(name); + + var _tx = ui(8); + var _ty = _y + hh + hg / 2; + draw_text(_tx, _ty, name); + + if(_is_extra) { + var _cx = _tx + string_width(name) + ui(4); + var _cy = _ty - string_height(name) / 2 + ui(6); + + gpu_set_colorwriteenable(1, 1, 1, 0); + draw_sprite_ext(s_patreon_supporter, 0, _cx, _cy, 1, 1, 0, _hov? COLORS._main_icon_dark : COLORS.panel_bg_clear, 1); + gpu_set_colorwriteenable(1, 1, 1, 1); + + draw_sprite_ext(s_patreon_supporter, 1, _cx, _cy, 1, 1, 0, i == ADD_NODE_PAGE? COLORS._main_text_accent : cc, 1); + } + + hh += hg; + } + + return hh; + }); #endregion + + content_pane = new scrollPane(dialog_w - category_width - ui(8), dialog_h - ui(66), function(_y, _m) { #region content_pane + draw_clear_alpha(c_white, 0); + var _hover = sHOVER && content_pane.hover; + var _list = node_list; + var hh = 0; + + if(ADD_NODE_PAGE == -2) { #region + _list = ds_list_create(); + for(var i = 0; i < ds_list_size(category); i++) { + var cat = category[| i]; + if(array_length(cat.filter) && !array_exists(cat.filter, instanceof(context))) + continue; + + for( var j = 0; j < ds_list_size(cat.list); j++ ) { + //if(is_string(cat.list[| j])) continue; + ds_list_add(_list, cat.list[| j]); + } + } + #endregion + } else if(ADD_NODE_PAGE == -1) { #region + _list = NEW_NODES; + #endregion + } else if(ADD_NODE_PAGE == NODE_PAGE_DEFAULT && category == NODE_CATEGORY) { #region + _list = ds_list_create(); + + var sug = []; + + if(node_called != noone) { + array_append(sug, nodeReleatedQuery( + node_called.connect_type == JUNCTION_CONNECT.input? "connectTo" : "connectFrom", + node_called.type + )); + } + + array_append(sug, nodeReleatedQuery("context", instanceof(context))); + + if(!array_empty(sug)) { + ds_list_add(_list, "Related"); + for( var i = 0, n = array_length(sug); i < n; i++ ) { + var k = array_safe_get_fast(sug, i); + if(k == 0) continue; + if(ds_map_exists(ALL_NODES, k)) + ds_list_add(_list, ALL_NODES[? k]); + } + } + + ds_list_add(_list, "Favourites"); + for( var i = 0, n = array_length(global.FAV_NODES); i < n; i++ ) { + var _nodeIndex = global.FAV_NODES[i]; + if(!ds_map_exists(ALL_NODES, _nodeIndex)) continue; + + var _node = ALL_NODES[? _nodeIndex]; + if(_node.show_in_recent) + ds_list_add(_list, _node); + } + + ds_list_add(_list, "Recents"); + for( var i = 0, n = array_length(global.RECENT_NODES); i < n; i++ ) { + var _nodeIndex = global.RECENT_NODES[i]; + if(!ds_map_exists(ALL_NODES, _nodeIndex)) continue; + + var _node = ALL_NODES[? _nodeIndex]; + if(_node.show_in_recent) + ds_list_add(_list, _node); + } + } #endregion + + if(_list == noone) { + setPage(NODE_PAGE_DEFAULT); + return 0; + } + + var node_count = ds_list_size(_list); + var group_labels = []; + var _hoverContent = _hover; + + if(PREFERENCES.dialog_add_node_view == 0) { #region grid + var grid_size = ui(64); + var grid_width = ui(80); + var grid_space = ui(12); + var col = floor(content_pane.surface_w / (grid_width + grid_space)); + var row = ceil(node_count / col); + var yy = _y + grid_space; + var curr_height = 0; + var cProg = 0; + hh += grid_space; + + grid_width = round(content_pane.surface_w - grid_space) / col - grid_space; + + for(var index = 0; index < node_count; index++) { + var _node = _list[| index]; + if(is_undefined(_node)) continue; + if(is_instanceof(_node, NodeObject)) { + if(_node.is_patreon_extra && !IS_PATREON) continue; + if(is_global && !_node.show_in_global) continue; + } + + if(is_string(_node)) { + if(!PREFERENCES.dialog_add_node_grouping) + continue; + hh += curr_height; + yy += curr_height; + + cProg = 0; + curr_height = 0; + + array_push(group_labels, { + y: yy, + text: __txt(_node) + }); + + hh += ui(24 + 12); + yy += ui(24 + 12); + continue; + } + + if(!filtered(_node)) continue; + + var _nx = grid_space + (grid_width + grid_space) * cProg; + var _boxx = _nx + (grid_width - grid_size) / 2; + var cc = c_white; + + if(is_instanceof(_node, NodeObject)) cc = c_white; + else if(is_instanceof(_node, NodeAction)) cc = COLORS.add_node_blend_action; + else if(is_instanceof(_node, AddNodeItem)) cc = COLORS.add_node_blend_generic; + else cc = COLORS.dialog_add_node_collection; + + BLEND_OVERRIDE + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, cc, 1); + BLEND_NORMAL + + if(_hoverContent && point_in_rectangle(_m[0], _m[1], _nx, yy, _nx + grid_width, yy + grid_size)) { + draw_sprite_stretched_ext(THEME.node_active, 0, _boxx, yy, grid_size, grid_size, COLORS._main_accent, 1); + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node); + else if(mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + if(_node.getTooltip() != "") { + if(point_in_rectangle(_m[0], _m[1], _boxx, yy, _boxx + ui(16), yy + ui(16))) { + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 1.0); + node_tooltip = _node; + node_tooltip_x = content_pane.x + _nx; + node_tooltip_y = content_pane.y + yy; + } else + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 0.5); + } + + if(is_instanceof(_node, NodeObject)) { + _node.drawGrid(_boxx, yy, _m[0], _m[1], grid_size); + } else { + var spr_x = _boxx + grid_size / 2; + var spr_y = yy + grid_size / 2; + + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) + draw_sprite_ui_uniform(_node.spr, 0, spr_x, spr_y, 0.5); + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, _boxx + grid_size - 16, yy + grid_size - 16, 1, COLORS.add_node_blend_action); + } + + var _name = _node.getName(); + + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(_boxx + grid_size / 2, yy + grid_size + 4, _name, -1, grid_width); + + var name_height = string_height_ext(_name, -1, grid_width - 4) + 8; + curr_height = max(curr_height, grid_size + grid_space + name_height); + + if(++cProg >= col) { + hh += curr_height; + yy += curr_height; + + cProg = 0; + curr_height = 0; + } + } + + if(PREFERENCES.dialog_add_node_grouping) { + var len = array_length(group_labels); + if(len) { + gpu_set_blendmode(bm_subtract); + draw_set_color(c_white); + draw_rectangle(0, 0, content_pane.surface_w, ui(16 + 24 / 2), false); + gpu_set_blendmode(bm_normal); + } + + for( var i = 0; i < len; i++ ) { + var lb = group_labels[i]; + var _yy = max(lb.y, i == len - 1? ui(8) : min(ui(8), group_labels[i + 1].y - ui(32))); + + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.group_label, 0, ui(16), _yy, content_pane.surface_w - ui(32), ui(24), c_white, 0.3); + BLEND_NORMAL; + + draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text); + draw_text(ui(16 + 16), _yy + ui(12), lb.text); + } + } + + hh += curr_height; + yy += curr_height; + #endregion + } else if(PREFERENCES.dialog_add_node_view == 1) { #region list + var list_width = content_pane.surface_w; + var list_height = ui(28); + var yy = _y + list_height / 2; + var bg_ind = 0; + hh += list_height; + + for(var i = 0; i < node_count; i++) { + var _node = _list[| i]; + if(is_undefined(_node)) continue; + if(is_instanceof(_node, NodeObject)) { + if(_node.is_patreon_extra && !IS_PATREON) continue; + if(is_global && !_node.show_in_global) continue; + } + + if(is_string(_node)) { + if(!PREFERENCES.dialog_add_node_grouping) + continue; + + hh += ui(8); + yy += ui(8); + + array_push(group_labels, { + y: yy, + text: __txt(_node) + }); + + hh += ui(32); + yy += ui(32); + continue; + } + + if(!filtered(_node)) continue; + + if(++bg_ind % 2) { + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.node_bg, 0, ui(16), yy, list_width - ui(32), list_height, c_white, 0.1); + BLEND_NORMAL; + } + + if(_hoverContent && point_in_rectangle(_m[0], _m[1], 0, yy, list_width, yy + list_height - 1)) { + if(_node.getTooltip() != "") { + node_tooltip = _node; + node_tooltip_x = content_pane.x + ui(16); + node_tooltip_y = content_pane.y + yy + } + + draw_sprite_stretched_ext(THEME.node_active, 0, ui(16), yy, list_width - ui(32), list_height, COLORS._main_accent, 1); + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node); + else if(mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + var tx = list_height + ui(52); + + if(is_instanceof(_node, NodeObject)) { + tx = _node.drawList(0, yy, _m[0], _m[1], list_height); + } else { + var spr_x = list_height / 2 + ui(44); + var spr_y = yy + list_height / 2; + + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) { + var ss = (list_height - ui(8)) / max(sprite_get_width(_node.spr), sprite_get_height(_node.spr)); + draw_sprite_ext(_node.spr, 0, spr_x, spr_y, ss, ss, 0, c_white, 1); + } + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, spr_x + list_height / 2 - 8, spr_y + list_height / 2 - 8, 0.5, COLORS.add_node_blend_action); + + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text); + draw_text_add(tx, yy + list_height / 2, _node.getName()); + } + + yy += list_height; + hh += list_height; + } + + if(PREFERENCES.dialog_add_node_grouping) { + gpu_set_blendmode(bm_subtract); + draw_set_color(c_white); + draw_rectangle(0, 0, content_pane.surface_w, ui(16 + 24 / 2), false); + gpu_set_blendmode(bm_normal); + + var len = array_length(group_labels); + for( var i = 0; i < len; i++ ) { + var lb = group_labels[i]; + var _yy = max(lb.y, i == len - 1? ui(8) : min(ui(8), group_labels[i + 1].y - ui(32))); + + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.group_label, 0, ui(16), _yy, content_pane.surface_w - ui(32), ui(24), c_white, 0.3); + BLEND_NORMAL; + + draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text); + draw_text(ui(16 + 16), _yy + ui(12), lb.text); + } + } + #endregion + } + + if(ADD_NODE_PAGE == -2) + ds_list_destroy(_list); + + return hh; + }); #endregion + + content_pane.always_scroll = true; + + #region ---- set page ---- + function setPage(pageIndex) { + ADD_NODE_PAGE = min(pageIndex, ds_list_size(category) - 1); + node_list = pageIndex < 0? noone : category[| ADD_NODE_PAGE].list; + } + + if(PREFERENCES.add_node_remember) { + content_pane.scroll_y_raw = ADD_NODE_SCROLL; + content_pane.scroll_y_to = ADD_NODE_SCROLL; + } else + ADD_NODE_PAGE = 0; + + setPage(ADD_NODE_PAGE); + #endregion + +#endregion + +#region resize + dialog_resizable = true; + dialog_w_min = ui(320); + dialog_h_min = ui(320); + dialog_w_max = ui(960); + dialog_h_max = ui(800); + + onResize = function() { + catagory_pane.resize(category_width, dialog_h - ui(66)); + content_pane.resize(dialog_w - category_width - ui(8), dialog_h - ui(66)); + search_pane.resize(dialog_w - ui(36), dialog_h - ui(66)); + + PREFERENCES.dialog_add_node_w = dialog_w; + PREFERENCES.dialog_add_node_h = dialog_h; + } +#endregion + +#region search + search_string = ""; + search_list = ds_list_create(); + keyboard_lastchar = ""; + KEYBOARD_STRING = ""; + keyboard_lastkey = -1; + + tb_search = new textBox(TEXTBOX_INPUT.text, function(str) { + search_string = string(str); + searchNodes(); + }); + tb_search.align = fa_left; + tb_search.auto_update = true; + WIDGET_CURRENT = tb_search; + + function searchNodes() { #region + ds_list_clear(search_list); + var pr_list = ds_priority_create(); + + var search_lower = string_lower(search_string); + var search_map = ds_map_create(); + + for(var i = 0; i < ds_list_size(category); i++) { + var cat = category[| i]; + + if(!struct_has(cat, "list")) + continue; + if(array_length(cat.filter) && !array_exists(cat.filter, instanceof(context))) + continue; + + var _content = cat.list; + for(var j = 0; j < ds_list_size(_content); j++) { + var _node = _content[| j]; + + if(is_string(_node)) continue; + if(ds_map_exists(search_map, _node)) continue; + + if(is_instanceof(_node, NodeObject)) { + if(_node.is_patreon_extra && !IS_PATREON) continue; + if(is_global && !_node.show_in_global) continue; + if(_node.deprecated) continue; + } + + var match = string_partial_match(string_lower(_node.getName()), search_lower); + var param = ""; + for( var k = 0; k < array_length(_node.tags); k++ ) { + var mat = string_partial_match(_node.tags[k], search_lower) - 1000; + if(mat > match) { + match = mat; + param = _node.tags[k]; + } + } + + if(match == -9999) continue; + + ds_priority_add(pr_list, [_node, param], match); + search_map[? _node] = 1; + } + } + + ds_map_destroy(search_map); + + searchCollection(pr_list, search_string, false); + + repeat(ds_priority_size(pr_list)) + ds_list_add(search_list, ds_priority_delete_max(pr_list)); + + ds_priority_destroy(pr_list); + } #endregion + + search_pane = new scrollPane(dialog_w - ui(36), dialog_h - ui(66), function(_y, _m) { + draw_clear_alpha(c_white, 0); + + var equation = string_char_at(search_string, 0) == "="; + var amo = ds_list_size(search_list); + var hh = 0; + var _hover = sHOVER && search_pane.hover; + + var grid_size = ui(64); + var grid_width = ui(80); + var grid_space = ui(16); + + if(equation) { #region + var eq = string_replace(search_string, "=", ""); + + draw_set_text(f_h5, fa_center, fa_bottom, COLORS._main_text_sub); + draw_text_line(search_pane.w / 2, search_pane.h / 2 - ui(8), + __txtx("add_node_create_equation", "Create equation") + ": " + eq, -1, search_pane.w - ui(32)); + + draw_set_text(f_p0, fa_center, fa_top, COLORS._main_text_sub); + draw_text_add(round(search_pane.w / 2), round(search_pane.h / 2 - ui(4)), + __txtx("add_node_equation_enter", "Press Enter to create equation node.")); + + if(keyboard_check_pressed(vk_enter)) + buildNode(ALL_NODES[? "Node_Equation"], { query: eq } ); + return hh; + } #endregion + + if(PREFERENCES.dialog_add_node_view == 0) { #region grid + + var col = floor(search_pane.surface_w / (grid_width + grid_space)); + var yy = _y + grid_space; + var index = 0; + var name_height = 0; + + grid_width = round(search_pane.surface_w - grid_space) / col - grid_space; + hh += (grid_space + grid_size) * 2; + + for(var i = 0; i < amo; i++) { + var s_res = search_list[| i]; + var _node = noone; + var _param = {}; + var _query = ""; + + if(is_array(s_res)) { + _node = s_res[0]; + _param.query = s_res[1]; + _query = s_res[1]; + } else + _node = s_res; + + var _nx = grid_space + (grid_width + grid_space) * index; + var _boxx = _nx + (grid_width - grid_size) / 2; + + BLEND_OVERRIDE; + if(is_instanceof(_node, NodeObject)) + draw_sprite_stretched(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size); + else if(is_instanceof(_node, NodeAction)) + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, COLORS.add_node_blend_action, 1); + else if(is_instanceof(_node, AddNodeItem)) + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, COLORS.add_node_blend_generic, 1); + else + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, COLORS.dialog_add_node_collection, 1); + BLEND_NORMAL; + + if(_hover && point_in_rectangle(_m[0], _m[1], _nx, yy, _nx + grid_width, yy + grid_size)) { + node_selecting = i; + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node, _param); + else if(struct_has(_node, "node") && mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + if(node_selecting == i) { + draw_sprite_stretched_ext(THEME.node_active, 0, _boxx, yy, grid_size, grid_size, COLORS._main_accent, 1); + if(keyboard_check_pressed(vk_enter)) + buildNode(_node, _param); + } + + if(struct_has(_node, "tooltip") && _node.getTooltip() != "") { + if(point_in_rectangle(_m[0], _m[1], _boxx, yy, _boxx + ui(16), yy + ui(16))) { + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 1.0); + node_tooltip = _node; + node_tooltip_x = search_pane.x + _nx; + node_tooltip_y = search_pane.y + yy + } else + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 0.5); + } + + if(is_instanceof(_node, NodeObject)) { + _node.drawGrid(_boxx, yy, _m[0], _m[1], grid_size, _param); + } else { + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) { + var _si = current_time * PREFERENCES.collection_preview_speed / 3000; + var _sw = sprite_get_width(_node.spr); + var _sh = sprite_get_height(_node.spr); + var _ss = ui(32) / max(_sw, _sh); + + var _sox = sprite_get_xoffset(_node.spr); + var _soy = sprite_get_yoffset(_node.spr); + + var _sx = _boxx + grid_size / 2; + var _sy = yy + grid_size / 2; + _sx += _sw * _ss / 2 - _sox * _ss; + _sy += _sh * _ss / 2 - _soy * _ss; + + draw_sprite_ext(_node.spr, _si, _sx, _sy, _ss, _ss, 0, c_white, 1); + } + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, _boxx + grid_size - 16, yy + grid_size - 16, 1, COLORS.add_node_blend_action); + } + + var _name = _node.getName(); + var _showQuery = _query != "" && is_instanceof(_node, NodeObject) && _node.createNode[0] == 0; + + draw_set_font(_showQuery? f_p3 : f_p2); + var _nmh = string_height_ext(_name, -1, grid_width); + + if(_showQuery) { + _query = string_title(_query); + var _nmy = yy + grid_size + 4; + + draw_set_text(f_p3, fa_center, fa_top, COLORS._main_text_sub); + draw_text_ext_add(_boxx + grid_size / 2, _nmy, _name, -1, grid_width); + _nmy += _nmh - ui(2); + + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(_boxx + grid_size / 2, _nmy, _query, -1, grid_width); + _nmy += string_height_ext(_query, -1, grid_width); + + } else { + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(_boxx + grid_size / 2, yy + grid_size + 4, _name, -1, grid_width); + } + + name_height = max(name_height, _nmh + ui(8)); + + if(node_focusing == i) + search_pane.scroll_y_to = -max(0, hh - search_pane.h); + + if(++index >= col) { + index = 0; + var hght = grid_size + grid_space + name_height; + name_height = 0; + hh += hght; + yy += hght; + } + } + #endregion + } else if(PREFERENCES.dialog_add_node_view == 1) { #region list + + var list_width = search_pane.surface_w; + var list_height = ui(28); + var yy = _y + list_height / 2; + hh += list_height; + + for(var i = 0; i < amo; i++) { + var s_res = search_list[| i]; + var _node = noone; + var _param = {}; + var _query = ""; + + if(is_array(s_res)) { + _node = s_res[0]; + _param.query = s_res[1]; + _query = s_res[1]; + } else + _node = s_res; + + if(i % 2) { + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.node_bg, 0, ui(4), yy, list_width - ui(8), list_height, c_white, 0.2); + BLEND_NORMAL; + } + + if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, list_width, yy + list_height - 1)) { + if(struct_has(_node, "tooltip") && _node.getTooltip() != "") { + node_tooltip = _node; + node_tooltip_x = search_pane.x + 0; + node_tooltip_y = search_pane.y + yy + } + + node_selecting = i; + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node, _param); + else if(struct_has(_node, "node") && mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + if(node_selecting == i) { + draw_sprite_stretched_ext(THEME.node_active, 0, ui(4), yy, list_width - ui(8), list_height, COLORS._main_accent, 1); + if(keyboard_check_pressed(vk_enter)) + buildNode(_node, _param); + } + + if(is_instanceof(_node, NodeObject)) { + _node.drawList(0, yy, _m[0], _m[1], list_height, _param); + } else { + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) { + var _si = current_time * PREFERENCES.collection_preview_speed / 3000; + var _sw = sprite_get_width(_node.spr); + var _sh = sprite_get_height(_node.spr); + var _ss = (list_height - ui(8)) / max(_sw, _sh); + + var _sox = sprite_get_xoffset(_node.spr); + var _soy = sprite_get_yoffset(_node.spr); + + var _sx = list_height / 2 + ui(32); + var _sy = yy + list_height / 2; + _sx += _sw * _ss / 2 - _sox * _ss; + _sy += _sh * _ss / 2 - _soy * _ss; + + draw_sprite_ext(_node.spr, _si, _sx, _sy, _ss, _ss, 0, c_white, 1); + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, _sx + list_height / 2 - 8, _sy + list_height / 2 - 8, 0.5, COLORS.add_node_blend_action); + } + + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text); + draw_text_add(list_height + ui(40), yy + list_height / 2, _node.getName()); + } + + if(node_focusing == i) search_pane.scroll_y_to = -max(0, hh - search_pane.h); + + hh += list_height; + yy += list_height; + } + #endregion + } + + node_focusing = -1; + + if(keyboard_check_pressed(vk_up)) { + node_selecting = safe_mod(node_selecting - 1 + amo, amo); + node_focusing = node_selecting; + } + + if(keyboard_check_pressed(vk_down)) { + node_selecting = safe_mod(node_selecting + 1, amo); + node_focusing = node_selecting; + } + + return hh; + }); +#endregion + +#event destroy +event_inherited(); + +WIDGET_CURRENT = noone; + +#event draw_gui init +if !ready exit; + +#region base UI + DIALOG_DRAW_BG + if(sFOCUS) DIALOG_DRAW_FOCUS +#endregion + +#region search + WIDGET_CURRENT = tb_search; + tb_search.setFocusHover(sFOCUS, sHOVER); + + if(search_string == "") { + catagory_pane.setFocusHover(sFOCUS, sHOVER); + catagory_pane.draw(dialog_x + ui(14), dialog_y + ui(52)); + + var _x = dialog_x + category_width - ui(12); + draw_sprite_stretched(THEME.ui_panel_bg, 1, _x, dialog_y + ui(52), dialog_w - category_width - ui(2), dialog_h - ui(66)); + content_pane.setFocusHover(sFOCUS, sHOVER); + content_pane.draw(_x, dialog_y + ui(52)); + + node_selecting = 0; + } else { + draw_sprite_stretched(THEME.ui_panel_bg, 1, dialog_x + ui(14), dialog_y + ui(52), dialog_w - ui(28), dialog_h - ui(66)); + search_pane.setFocusHover(sFOCUS, sHOVER); + search_pane.draw(dialog_x + ui(16), dialog_y + ui(52)); + } + + var tw = dialog_w - ui(96); + if(node_called != noone || junction_hovering != noone) + tw -= ui(32); + tb_search.draw(dialog_x + ui(14), dialog_y + ui(14), tw, ui(32), search_string, mouse_ui); + + var bx = dialog_x + dialog_w - ui(44); + var by = dialog_y + ui(16); + var b = buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, sFOCUS, sHOVER, + PREFERENCES.dialog_add_node_view? __txtx("view_list", "List view") : __txtx("view_grid", "Grid view"), + THEME.view_mode, PREFERENCES.dialog_add_node_view, COLORS._main_icon); + if(b == 2) + PREFERENCES.dialog_add_node_view = !PREFERENCES.dialog_add_node_view; + + bx -= ui(32); + var b = buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, sFOCUS, sHOVER, + PREFERENCES.dialog_add_node_grouping? __txtx("add_node_group_enabled", "Group enabled") : __txtx("add_node_group_disabled", "Group disabled"), + THEME.view_group, PREFERENCES.dialog_add_node_grouping, COLORS._main_icon); + if(b == 2) + PREFERENCES.dialog_add_node_grouping = !PREFERENCES.dialog_add_node_grouping; + + if(node_called != noone || junction_hovering != noone) { + var txt = node_show_connectable? __txtx("add_node_show_connect", "Showing connectable") : __txtx("add_node_show_all", "Showing all"); + var cc = node_show_connectable? COLORS._main_accent : COLORS._main_icon; + bx -= ui(32); + var b = buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, sFOCUS, sHOVER, txt, THEME.filter_type, node_show_connectable, cc); + if(b == 2) + node_show_connectable = !node_show_connectable; + } +#endregion + +#region tooltip + if(node_tooltip != noone) { + var ww = ui(300 + 8); + var hh = ui(16); + + var txt = node_tooltip.getTooltip(); + var spr = node_tooltip.tooltip_spr; + + draw_set_font(f_p1); + + if(spr) { + ww = ui(8) + sprite_get_width(spr); + hh = ui(8) + sprite_get_height(spr); + } else + hh = ui(16) + string_height_ext(txt, -1, ww - ui(16)); + + var x0 = min(node_tooltip_x, WIN_W - ww - ui(8)); + var x1 = node_tooltip_x + ww; + var y1 = node_tooltip_y - ui(8); + var y0 = y1 - hh; + + draw_sprite_stretched(THEME.textbox, 3, x0, y0, ww, hh); + draw_sprite_stretched(THEME.textbox, 0, x0, y0, ww, hh); + + if(spr) draw_sprite(spr, 0, x0 + ui(4), y0 + ui(4)); + + draw_set_text(f_p1, fa_left, fa_bottom, COLORS._main_text) + draw_text_line(x0 + ui(8), y1 - ui(8), txt, -1, ww - ui(16)); + } + + node_tooltip = noone; + ADD_NODE_SCROLL = content_pane.scroll_y_to; +#endregion \ No newline at end of file diff --git a/#backups/objects/o_dialog_add_node/o_dialog_add_node.yy.backup1 b/#backups/objects/o_dialog_add_node/o_dialog_add_node.yy.backup1 new file mode 100644 index 000000000..27c0ee5bb --- /dev/null +++ b/#backups/objects/o_dialog_add_node/o_dialog_add_node.yy.backup1 @@ -0,0 +1,1109 @@ +// 2024-04-16 11:31:51 +#event properties (no comments/etc. here are saved) +parent_index = _p_dialog; +uses_physics = false; + +#event create init +event_inherited(); + +#region data + draggable = false; + + node_target_x = 0; + node_target_y = 0; + node_called = noone; + junction_hovering = noone; + + dialog_w = PREFERENCES.dialog_add_node_w; + dialog_h = PREFERENCES.dialog_add_node_h; + + destroy_on_click_out = true; + + node_selecting = 0; + node_focusing = -1; + + node_show_connectable = true; + node_tooltip = noone; + node_tooltip_x = 0; + node_tooltip_y = 0; + + anchor = ANCHOR.left | ANCHOR.top; + node_menu_selecting = noone; + + is_global = PANEL_GRAPH.getCurrentContext() == noone; + + #region ---- category ---- + category = NODE_CATEGORY; + switch(instanceof(context)) { + case "Node_Pixel_Builder" : category = NODE_PB_CATEGORY; break; + case "Node_DynaSurf" : category = NODE_PCX_CATEGORY; break; + } + + draw_set_font(f_p0); + var maxLen = 0; + for(var i = 0; i < ds_list_size(category); i++) { + var cat = category[| i]; + + if(array_length(cat.filter) && !array_exists(cat.filter, instanceof(context))) + continue; + + var name = __txt(cat.name); + maxLen = max(maxLen, string_width(name)); + } + category_width = maxLen + ui(56); + #endregion + + function rightClick(node) { #region + if(!is_instanceof(node, NodeObject)) return; + + node_menu_selecting = node; + var fav = array_exists(global.FAV_NODES, node.node); + + var menu = [ + menuItem(fav? __txtx("add_node_remove_favourite", "Remove from favourite") : __txtx("add_node_add_favourite", "Add to favourite"), + function() { + if(!is_array(global.FAV_NODES)) global.FAV_NODES = []; + + if(array_exists(global.FAV_NODES, node_menu_selecting.node)) + array_remove(global.FAV_NODES, node_menu_selecting.node); + else + array_push(global.FAV_NODES, node_menu_selecting.node); + }, THEME.star) + ]; + + menuCall("add_node_window_manu",,, menu,, node_menu_selecting); + } #endregion + + function filtered(node) { #region + if(!node_show_connectable) return true; + if(node_called == noone && junction_hovering == noone) return true; + if(!struct_has(node, "node")) return true; + if(!struct_has(global.NODE_GUIDE, node.node)) return true; + + if(is_instanceof(node, NodeObject)) { + if(node.is_patreon_extra && !IS_PATREON) return true; + if(is_global && !node.show_in_global) return true; + } + + var io = global.NODE_GUIDE[$ node.node]; + + if(node_called) { + var call_in = node_called.connect_type == JUNCTION_CONNECT.input; + var ar = call_in? io.outputs : io.inputs; + var typ = node_called.type; + + for( var i = 0, n = array_length(ar); i < n; i++ ) { + if(!ar[i].visible) continue; + + var _in = call_in? node_called.type : ar[i].type; + var _ot = call_in? ar[i].type : node_called.type; + + if(typeCompatible(_in, _ot, false)) return true; + } + + return false; + } else if(junction_hovering) { + var to = junction_hovering.type; + var fr = junction_hovering.value_from.type; + + for( var i = 0, n = array_length(io.inputs); i < n; i++ ) { + var _in = fr; + var _ot = io.inputs[i].type; + if(!io.inputs[i].visible) continue; + + if(typeCompatible(_in, _ot, false)) return true; + } + + for( var i = 0, n = array_length(io.outputs); i < n; i++ ) { + var _in = io.outputs[i].type; + var _ot = to; + + if(typeCompatible(_in, _ot, false)) return true; + } + + return false; + } + + return false; + } #endregion + + function buildNode(_node, _param = {}) { #region + instance_destroy(); + instance_destroy(o_dialog_menubox); + + if(!_node) return; + + if(is_instanceof(context, Node_Canvas)) { + context.nodeTool = new canvas_tool_node(context, _node); + return; + } + + if(is_instanceof(_node, AddNodeItem)) { + _node.onClick({ + node_called, + junction_hovering + }); + return; + } + + var _new_node = noone; + var _inputs = 0, _outputs = 0; + + if(is_instanceof(_node, NodeObject)) { + _new_node = _node.build(node_target_x, node_target_y,, _param); + if(!_new_node) return; + + if(category == NODE_CATEGORY && _node.show_in_recent) { + array_remove(global.RECENT_NODES, _node.node); + array_insert(global.RECENT_NODES, 0, _node.node); + if(array_length(global.RECENT_NODES) > PREFERENCES.node_recents_amount) + array_pop(global.RECENT_NODES); + } + + if(is_instanceof(context, Node_Collection_Inline)) + context.addNode(_new_node); + + _inputs = _new_node.inputs; + _outputs = _new_node.outputs; + } else if(is_instanceof(_node, NodeAction)) { + var res = _node.build(node_target_x, node_target_y,, _param); + + if(_node.inputNode != noone) + _inputs = res[$ _node.inputNode].inputs; + + if(_node.outputNode != noone) + _outputs = res[$ _node.outputNode].outputs; + } else { + var _new_list = APPEND(_node.path); + _inputs = ds_list_create(); + _outputs = ds_list_create(); + + var tx = 99999; + var ty = 99999; + for( var i = 0; i < ds_list_size(_new_list); i++ ) { + tx = min(tx, _new_list[| i].x); + ty = min(tx, _new_list[| i].y); + + if(is_instanceof(context, Node_Collection_Inline) && !is_instanceof(_new_list[| i], Node_Collection_Inline)) + context.addNode(_new_list[| i]); + } + + var shx = tx - node_target_x; + var shy = ty - node_target_y; + + for( var i = 0; i < ds_list_size(_new_list); i++ ) { + _new_list[| i].x -= shx; + _new_list[| i].y -= shy; + } + + for( var i = 0; i < ds_list_size(_new_list); i++ ) { + var _in = _new_list[| i].inputs; + for( var j = 0; j < ds_list_size(_in); j++ ) { + if(_in[| j].isLeaf()) + ds_list_add(_inputs, _in[| j]); + } + + var _ot = _new_list[| i].outputs; + for( var j = 0; j < ds_list_size(_ot); j++ ) { + if(array_empty(_ot[| j].value_to)) + ds_list_add(_outputs, _ot[| j]); + } + } + + ds_list_destroy(_new_list); + } + + //try to connect + if(node_called != noone) { //dragging from junction + var _call_input = node_called.connect_type == JUNCTION_CONNECT.input; + var _node_list = _call_input? _outputs : _inputs; + for(var i = 0; i < ds_list_size(_node_list); i++) { + var _target = _node_list[| i]; + if(!_target.visible) continue; + + if(_target.auto_connect) { + if(_call_input && node_called.isConnectable(_node_list[| i])) { + node_called.setFrom(_node_list[| i]); + _new_node.x -= _new_node.w; + } else if(!_call_input && _node_list[| i].isConnectable(node_called)) + _node_list[| i].setFrom(node_called); + break; + } + } + } else if(junction_hovering != noone) { //right click on junction + var to = junction_hovering; + var from = junction_hovering.value_from; + + for( var i = 0; i < ds_list_size(_inputs); i++ ) { + var _in = _inputs[| i]; + + if(_in.auto_connect && _in.isConnectable(from)) { + _in.setFrom(from); + break; + } + } + + for( var i = 0; i < ds_list_size(_outputs); i++ ) { + var _ot = _outputs[| i]; + if(to.isConnectable(_ot)) { + to.setFrom(_ot); + break; + } + } + } + } #endregion + + catagory_pane = new scrollPane(category_width, dialog_h - ui(66), function(_y, _m) { #region catagory_pane + draw_clear_alpha(COLORS._main_text, 0); + + var ww = category_width - ui(32); + var hh = 0; + var hg = ui(28); + + var start = category == NODE_CATEGORY? -2 : 0; + + for(var i = start; i < ds_list_size(category); i++) { + var name = ""; + + if(i == -2) name = "All"; + else if(i == -1) name = "New"; + else { + var cat = category[| i]; + name = cat.name; + + if(array_length(cat.filter)) { + if(!array_exists(cat.filter, instanceof(context))) { + if(ADD_NODE_PAGE == i) + setPage(NODE_PAGE_DEFAULT); + continue; + } + draw_set_color(COLORS._main_text_accent); + } + + if(cat.color != noone) { + BLEND_OVERRIDE + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, 0, _y + hh, ww, hg, merge_color(c_white, cat.color, 0.5), 1); + BLEND_NORMAL + } + } + + var _hov = false; + + if(sHOVER && catagory_pane.hover && point_in_rectangle(_m[0], _m[1], 0, _y + hh, ww, _y + hh + hg - 1)) { + BLEND_OVERRIDE + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, 0, _y + hh, ww, hg, CDEF.main_white, 1); + BLEND_NORMAL + + _hov = true; + + if(i != ADD_NODE_PAGE && mouse_click(mb_left, sFOCUS)) { + setPage(i); + content_pane.scroll_y = 0; + content_pane.scroll_y_raw = 0; + content_pane.scroll_y_to = 0; + } + } + + var cc = COLORS._main_text_inner; + + switch(name) { + case "All" : + case "New" : + case "Favourites" : + case "Action" : + case "Custom" : + case "Extra" : + cc = merge_color(COLORS._main_text_inner, COLORS._main_text_sub, 0.75); + break; + } + + if(i == ADD_NODE_PAGE) draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_text_accent); + else draw_set_text(f_p0, fa_left, fa_center, cc); + + var _is_extra = name == "Extra"; + name = __txt(name); + + var _tx = ui(8); + var _ty = _y + hh + hg / 2; + draw_text(_tx, _ty, name); + + if(_is_extra) { + var _cx = _tx + string_width(name) + ui(4); + var _cy = _ty - string_height(name) / 2 + ui(6); + + gpu_set_colorwriteenable(1, 1, 1, 0); + draw_sprite_ext(s_patreon_supporter, 0, _cx, _cy, 1, 1, 0, _hov? COLORS._main_icon_dark : COLORS.panel_bg_clear, 1); + gpu_set_colorwriteenable(1, 1, 1, 1); + + draw_sprite_ext(s_patreon_supporter, 1, _cx, _cy, 1, 1, 0, i == ADD_NODE_PAGE? COLORS._main_text_accent : cc, 1); + } + + hh += hg; + } + + return hh; + }); #endregion + + content_pane = new scrollPane(dialog_w - category_width - ui(8), dialog_h - ui(66), function(_y, _m) { #region content_pane + draw_clear_alpha(c_white, 0); + var _hover = sHOVER && content_pane.hover; + var _list = node_list; + var hh = 0; + + if(ADD_NODE_PAGE == -2) { #region + _list = ds_list_create(); + for(var i = 0; i < ds_list_size(category); i++) { + var cat = category[| i]; + if(array_length(cat.filter) && !array_exists(cat.filter, instanceof(context))) + continue; + + for( var j = 0; j < ds_list_size(cat.list); j++ ) { + //if(is_string(cat.list[| j])) continue; + ds_list_add(_list, cat.list[| j]); + } + } + #endregion + } else if(ADD_NODE_PAGE == -1) { #region + _list = NEW_NODES; + #endregion + } else if(ADD_NODE_PAGE == NODE_PAGE_DEFAULT && category == NODE_CATEGORY) { #region + _list = ds_list_create(); + + var sug = []; + + if(node_called != noone) { + array_append(sug, nodeReleatedQuery( + node_called.connect_type == JUNCTION_CONNECT.input? "connectTo" : "connectFrom", + node_called.type + )); + } + + array_append(sug, nodeReleatedQuery("context", instanceof(context))); + + if(!array_empty(sug)) { + ds_list_add(_list, "Related"); + for( var i = 0, n = array_length(sug); i < n; i++ ) { + var k = array_safe_get_fast(sug, i); + if(k == 0) continue; + if(ds_map_exists(ALL_NODES, k)) + ds_list_add(_list, ALL_NODES[? k]); + } + } + + ds_list_add(_list, "Favourites"); + for( var i = 0, n = array_length(global.FAV_NODES); i < n; i++ ) { + var _nodeIndex = global.FAV_NODES[i]; + if(!ds_map_exists(ALL_NODES, _nodeIndex)) continue; + + var _node = ALL_NODES[? _nodeIndex]; + if(_node.show_in_recent) + ds_list_add(_list, _node); + } + + ds_list_add(_list, "Recents"); + for( var i = 0, n = array_length(global.RECENT_NODES); i < n; i++ ) { + var _nodeIndex = global.RECENT_NODES[i]; + if(!ds_map_exists(ALL_NODES, _nodeIndex)) continue; + + var _node = ALL_NODES[? _nodeIndex]; + if(_node.show_in_recent) + ds_list_add(_list, _node); + } + } #endregion + + if(_list == noone) { + setPage(NODE_PAGE_DEFAULT); + return 0; + } + + var node_count = ds_list_size(_list); + var group_labels = []; + var _hoverContent = _hover; + + if(PREFERENCES.dialog_add_node_view == 0) { #region grid + var grid_size = ui(64); + var grid_width = ui(80); + var grid_space = ui(12); + var col = floor(content_pane.surface_w / (grid_width + grid_space)); + var row = ceil(node_count / col); + var yy = _y + grid_space; + var curr_height = 0; + var cProg = 0; + hh += grid_space; + + grid_width = round(content_pane.surface_w - grid_space) / col - grid_space; + + for(var index = 0; index < node_count; index++) { + var _node = _list[| index]; + if(is_undefined(_node)) continue; + if(is_instanceof(_node, NodeObject)) { + if(_node.is_patreon_extra && !IS_PATREON) continue; + if(is_global && !_node.show_in_global) continue; + } + + if(is_string(_node)) { + if(!PREFERENCES.dialog_add_node_grouping) + continue; + hh += curr_height; + yy += curr_height; + + cProg = 0; + curr_height = 0; + + array_push(group_labels, { + y: yy, + text: __txt(_node) + }); + + hh += ui(24 + 12); + yy += ui(24 + 12); + continue; + } + + if(!filtered(_node)) continue; + + var _nx = grid_space + (grid_width + grid_space) * cProg; + var _boxx = _nx + (grid_width - grid_size) / 2; + var cc = c_white; + + if(is_instanceof(_node, NodeObject)) cc = c_white; + else if(is_instanceof(_node, NodeAction)) cc = COLORS.add_node_blend_action; + else if(is_instanceof(_node, AddNodeItem)) cc = COLORS.add_node_blend_generic; + else cc = COLORS.dialog_add_node_collection; + + BLEND_OVERRIDE + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, cc, 1); + BLEND_NORMAL + + if(_hoverContent && point_in_rectangle(_m[0], _m[1], _nx, yy, _nx + grid_width, yy + grid_size)) { + draw_sprite_stretched_ext(THEME.node_active, 0, _boxx, yy, grid_size, grid_size, COLORS._main_accent, 1); + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node); + else if(mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + if(_node.getTooltip() != "") { + if(point_in_rectangle(_m[0], _m[1], _boxx, yy, _boxx + ui(16), yy + ui(16))) { + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 1.0); + node_tooltip = _node; + node_tooltip_x = content_pane.x + _nx; + node_tooltip_y = content_pane.y + yy; + } else + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 0.5); + } + + if(is_instanceof(_node, NodeObject)) { + _node.drawGrid(_boxx, yy, _m[0], _m[1], grid_size); + } else { + var spr_x = _boxx + grid_size / 2; + var spr_y = yy + grid_size / 2; + + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) + draw_sprite_ui_uniform(_node.spr, 0, spr_x, spr_y, 0.5); + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, _boxx + grid_size - 16, yy + grid_size - 16, 1, COLORS.add_node_blend_action); + } + + var _name = _node.getName(); + + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(_boxx + grid_size / 2, yy + grid_size + 4, _name, -1, grid_width); + + var name_height = string_height_ext(_name, -1, grid_width - 4) + 8; + curr_height = max(curr_height, grid_size + grid_space + name_height); + + if(++cProg >= col) { + hh += curr_height; + yy += curr_height; + + cProg = 0; + curr_height = 0; + } + } + + if(PREFERENCES.dialog_add_node_grouping) { + var len = array_length(group_labels); + if(len) { + gpu_set_blendmode(bm_subtract); + draw_set_color(c_white); + draw_rectangle(0, 0, content_pane.surface_w, ui(16 + 24 / 2), false); + gpu_set_blendmode(bm_normal); + } + + for( var i = 0; i < len; i++ ) { + var lb = group_labels[i]; + var _yy = max(lb.y, i == len - 1? ui(8) : min(ui(8), group_labels[i + 1].y - ui(32))); + + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.group_label, 0, ui(16), _yy, content_pane.surface_w - ui(32), ui(24), c_white, 0.3); + BLEND_NORMAL; + + draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text); + draw_text(ui(16 + 16), _yy + ui(12), lb.text); + } + } + + hh += curr_height; + yy += curr_height; + #endregion + } else if(PREFERENCES.dialog_add_node_view == 1) { #region list + var list_width = content_pane.surface_w; + var list_height = ui(28); + var yy = _y + list_height / 2; + var bg_ind = 0; + hh += list_height; + + for(var i = 0; i < node_count; i++) { + var _node = _list[| i]; + if(is_undefined(_node)) continue; + if(is_instanceof(_node, NodeObject)) { + if(_node.is_patreon_extra && !IS_PATREON) continue; + if(is_global && !_node.show_in_global) continue; + } + + if(is_string(_node)) { + if(!PREFERENCES.dialog_add_node_grouping) + continue; + + hh += ui(8); + yy += ui(8); + + array_push(group_labels, { + y: yy, + text: __txt(_node) + }); + + hh += ui(32); + yy += ui(32); + continue; + } + + if(!filtered(_node)) continue; + + if(++bg_ind % 2) { + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.node_bg, 0, ui(16), yy, list_width - ui(32), list_height, c_white, 0.1); + BLEND_NORMAL; + } + + if(_hoverContent && point_in_rectangle(_m[0], _m[1], 0, yy, list_width, yy + list_height - 1)) { + if(_node.getTooltip() != "") { + node_tooltip = _node; + node_tooltip_x = content_pane.x + ui(16); + node_tooltip_y = content_pane.y + yy + } + + draw_sprite_stretched_ext(THEME.node_active, 0, ui(16), yy, list_width - ui(32), list_height, COLORS._main_accent, 1); + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node); + else if(mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + var tx = list_height + ui(52); + + if(is_instanceof(_node, NodeObject)) { + tx = _node.drawList(0, yy, _m[0], _m[1], list_height); + } else { + var spr_x = list_height / 2 + ui(44); + var spr_y = yy + list_height / 2; + + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) { + var ss = (list_height - ui(8)) / max(sprite_get_width(_node.spr), sprite_get_height(_node.spr)); + draw_sprite_ext(_node.spr, 0, spr_x, spr_y, ss, ss, 0, c_white, 1); + } + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, spr_x + list_height / 2 - 8, spr_y + list_height / 2 - 8, 0.5, COLORS.add_node_blend_action); + + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text); + draw_text_add(tx, yy + list_height / 2, _node.getName()); + } + + yy += list_height; + hh += list_height; + } + + if(PREFERENCES.dialog_add_node_grouping) { + gpu_set_blendmode(bm_subtract); + draw_set_color(c_white); + draw_rectangle(0, 0, content_pane.surface_w, ui(16 + 24 / 2), false); + gpu_set_blendmode(bm_normal); + + var len = array_length(group_labels); + for( var i = 0; i < len; i++ ) { + var lb = group_labels[i]; + var _yy = max(lb.y, i == len - 1? ui(8) : min(ui(8), group_labels[i + 1].y - ui(32))); + + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.group_label, 0, ui(16), _yy, content_pane.surface_w - ui(32), ui(24), c_white, 0.3); + BLEND_NORMAL; + + draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text); + draw_text(ui(16 + 16), _yy + ui(12), lb.text); + } + } + #endregion + } + + if(ADD_NODE_PAGE == -2) + ds_list_destroy(_list); + + return hh; + }); #endregion + + content_pane.always_scroll = true; + + #region ---- set page ---- + function setPage(pageIndex) { + ADD_NODE_PAGE = min(pageIndex, ds_list_size(category) - 1); + node_list = pageIndex < 0? noone : category[| ADD_NODE_PAGE].list; + } + + if(PREFERENCES.add_node_remember) { + content_pane.scroll_y_raw = ADD_NODE_SCROLL; + content_pane.scroll_y_to = ADD_NODE_SCROLL; + } else + ADD_NODE_PAGE = 0; + + setPage(ADD_NODE_PAGE); + #endregion + +#endregion + +#region resize + dialog_resizable = true; + dialog_w_min = ui(320); + dialog_h_min = ui(320); + dialog_w_max = ui(960); + dialog_h_max = ui(800); + + onResize = function() { + catagory_pane.resize(category_width, dialog_h - ui(66)); + content_pane.resize(dialog_w - category_width - ui(8), dialog_h - ui(66)); + search_pane.resize(dialog_w - ui(36), dialog_h - ui(66)); + + PREFERENCES.dialog_add_node_w = dialog_w; + PREFERENCES.dialog_add_node_h = dialog_h; + } +#endregion + +#region search + search_string = ""; + search_list = ds_list_create(); + keyboard_lastchar = ""; + KEYBOARD_STRING = ""; + keyboard_lastkey = -1; + + tb_search = new textBox(TEXTBOX_INPUT.text, function(str) { + search_string = string(str); + searchNodes(); + }); + tb_search.align = fa_left; + tb_search.auto_update = true; + WIDGET_CURRENT = tb_search; + + function searchNodes() { #region + ds_list_clear(search_list); + var pr_list = ds_priority_create(); + + var search_lower = string_lower(search_string); + var search_map = ds_map_create(); + + for(var i = 0; i < ds_list_size(category); i++) { + var cat = category[| i]; + + if(!struct_has(cat, "list")) + continue; + if(array_length(cat.filter) && !array_exists(cat.filter, instanceof(context))) + continue; + + var _content = cat.list; + for(var j = 0; j < ds_list_size(_content); j++) { + var _node = _content[| j]; + + if(is_string(_node)) continue; + if(ds_map_exists(search_map, _node)) continue; + + if(is_instanceof(_node, NodeObject)) { + if(_node.is_patreon_extra && !IS_PATREON) continue; + if(is_global && !_node.show_in_global) continue; + if(_node.deprecated) continue; + } + + var match = string_partial_match(string_lower(_node.getName()), search_lower); + var param = ""; + for( var k = 0; k < array_length(_node.tags); k++ ) { + var mat = string_partial_match(_node.tags[k], search_lower) - 1000; + if(mat > match) { + match = mat; + param = _node.tags[k]; + } + } + + if(match == -9999) continue; + + ds_priority_add(pr_list, [_node, param], match); + search_map[? _node] = 1; + } + } + + ds_map_destroy(search_map); + + searchCollection(pr_list, search_string, false); + + repeat(ds_priority_size(pr_list)) + ds_list_add(search_list, ds_priority_delete_max(pr_list)); + + ds_priority_destroy(pr_list); + } #endregion + + search_pane = new scrollPane(dialog_w - ui(36), dialog_h - ui(66), function(_y, _m) { + draw_clear_alpha(c_white, 0); + + var equation = string_char_at(search_string, 0) == "="; + var amo = ds_list_size(search_list); + var hh = 0; + var _hover = sHOVER && search_pane.hover; + + var grid_size = ui(64); + var grid_width = ui(80); + var grid_space = ui(16); + + if(equation) { #region + var eq = string_replace(search_string, "=", ""); + + draw_set_text(f_h5, fa_center, fa_bottom, COLORS._main_text_sub); + draw_text_line(search_pane.w / 2, search_pane.h / 2 - ui(8), + __txtx("add_node_create_equation", "Create equation") + ": " + eq, -1, search_pane.w - ui(32)); + + draw_set_text(f_p0, fa_center, fa_top, COLORS._main_text_sub); + draw_text_add(round(search_pane.w / 2), round(search_pane.h / 2 - ui(4)), + __txtx("add_node_equation_enter", "Press Enter to create equation node.")); + + if(keyboard_check_pressed(vk_enter)) + buildNode(ALL_NODES[? "Node_Equation"], { query: eq } ); + return hh; + } #endregion + + if(PREFERENCES.dialog_add_node_view == 0) { #region grid + + var col = floor(search_pane.surface_w / (grid_width + grid_space)); + var yy = _y + grid_space; + var index = 0; + var name_height = 0; + + grid_width = round(search_pane.surface_w - grid_space) / col - grid_space; + hh += (grid_space + grid_size) * 2; + + for(var i = 0; i < amo; i++) { + var s_res = search_list[| i]; + var _node = noone; + var _param = {}; + var _query = ""; + + if(is_array(s_res)) { + _node = s_res[0]; + _param.query = s_res[1]; + _query = s_res[1]; + } else + _node = s_res; + + var _nx = grid_space + (grid_width + grid_space) * index; + var _boxx = _nx + (grid_width - grid_size) / 2; + + BLEND_OVERRIDE; + if(is_instanceof(_node, NodeObject)) + draw_sprite_stretched(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size); + else if(is_instanceof(_node, NodeAction)) + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, COLORS.add_node_blend_action, 1); + else if(is_instanceof(_node, AddNodeItem)) + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, COLORS.add_node_blend_generic, 1); + else + draw_sprite_stretched_ext(THEME.node_bg, 0, _boxx, yy, grid_size, grid_size, COLORS.dialog_add_node_collection, 1); + BLEND_NORMAL; + + if(_hover && point_in_rectangle(_m[0], _m[1], _nx, yy, _nx + grid_width, yy + grid_size)) { + node_selecting = i; + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node, _param); + else if(struct_has(_node, "node") && mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + if(node_selecting == i) { + draw_sprite_stretched_ext(THEME.node_active, 0, _boxx, yy, grid_size, grid_size, COLORS._main_accent, 1); + if(keyboard_check_pressed(vk_enter)) + buildNode(_node, _param); + } + + if(struct_has(_node, "tooltip") && _node.getTooltip() != "") { + if(point_in_rectangle(_m[0], _m[1], _boxx, yy, _boxx + ui(16), yy + ui(16))) { + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 1.0); + node_tooltip = _node; + node_tooltip_x = search_pane.x + _nx; + node_tooltip_y = search_pane.y + yy + } else + draw_sprite_ui_uniform(THEME.info, 0, _boxx + ui(8), yy + ui(8), 0.7, COLORS._main_icon, 0.5); + } + + if(is_instanceof(_node, NodeObject)) { + _node.drawGrid(_boxx, yy, _m[0], _m[1], grid_size, _param); + } else { + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) { + var _si = current_time * PREFERENCES.collection_preview_speed / 3000; + var _sw = sprite_get_width(_node.spr); + var _sh = sprite_get_height(_node.spr); + var _ss = ui(32) / max(_sw, _sh); + + var _sox = sprite_get_xoffset(_node.spr); + var _soy = sprite_get_yoffset(_node.spr); + + var _sx = _boxx + grid_size / 2; + var _sy = yy + grid_size / 2; + _sx += _sw * _ss / 2 - _sox * _ss; + _sy += _sh * _ss / 2 - _soy * _ss; + + draw_sprite_ext(_node.spr, _si, _sx, _sy, _ss, _ss, 0, c_white, 1); + } + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, _boxx + grid_size - 16, yy + grid_size - 16, 1, COLORS.add_node_blend_action); + } + + var _name = _node.getName(); + var _showQuery = _query != "" && is_instanceof(_node, NodeObject) && _node.createNode[0] == 0; + + draw_set_font(_showQuery? f_p3 : f_p2); + var _nmh = string_height_ext(_name, -1, grid_width); + + if(_showQuery) { + _query = string_title(_query); + var _nmy = yy + grid_size + 4; + + draw_set_text(f_p3, fa_center, fa_top, COLORS._main_text_sub); + draw_text_ext_add(_boxx + grid_size / 2, _nmy, _name, -1, grid_width); + _nmy += _nmh - ui(2); + + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(_boxx + grid_size / 2, _nmy, _query, -1, grid_width); + _nmy += string_height_ext(_query, -1, grid_width); + + } else { + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text); + draw_text_ext_add(_boxx + grid_size / 2, yy + grid_size + 4, _name, -1, grid_width); + } + + name_height = max(name_height, _nmh + ui(8)); + + if(node_focusing == i) + search_pane.scroll_y_to = -max(0, hh - search_pane.h); + + if(++index >= col) { + index = 0; + var hght = grid_size + grid_space + name_height; + name_height = 0; + hh += hght; + yy += hght; + } + } + #endregion + } else if(PREFERENCES.dialog_add_node_view == 1) { #region list + + var list_width = search_pane.surface_w; + var list_height = ui(28); + var yy = _y + list_height / 2; + hh += list_height; + + for(var i = 0; i < amo; i++) { + var s_res = search_list[| i]; + var _node = noone; + var _param = {}; + var _query = ""; + + if(is_array(s_res)) { + _node = s_res[0]; + _param.query = s_res[1]; + _query = s_res[1]; + } else + _node = s_res; + + if(i % 2) { + BLEND_OVERRIDE; + draw_sprite_stretched_ext(THEME.node_bg, 0, ui(4), yy, list_width - ui(8), list_height, c_white, 0.2); + BLEND_NORMAL; + } + + if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, list_width, yy + list_height - 1)) { + if(struct_has(_node, "tooltip") && _node.getTooltip() != "") { + node_tooltip = _node; + node_tooltip_x = search_pane.x + 0; + node_tooltip_y = search_pane.y + yy + } + + node_selecting = i; + if(mouse_release(mb_left, sFOCUS)) + buildNode(_node, _param); + else if(struct_has(_node, "node") && mouse_release(mb_right, sFOCUS)) + rightClick(_node); + } + + if(node_selecting == i) { + draw_sprite_stretched_ext(THEME.node_active, 0, ui(4), yy, list_width - ui(8), list_height, COLORS._main_accent, 1); + if(keyboard_check_pressed(vk_enter)) + buildNode(_node, _param); + } + + if(is_instanceof(_node, NodeObject)) { + _node.drawList(0, yy, _m[0], _m[1], list_height, _param); + } else { + if(variable_struct_exists(_node, "getSpr")) _node.getSpr(); + if(sprite_exists(_node.spr)) { + var _si = current_time * PREFERENCES.collection_preview_speed / 3000; + var _sw = sprite_get_width(_node.spr); + var _sh = sprite_get_height(_node.spr); + var _ss = (list_height - ui(8)) / max(_sw, _sh); + + var _sox = sprite_get_xoffset(_node.spr); + var _soy = sprite_get_yoffset(_node.spr); + + var _sx = list_height / 2 + ui(32); + var _sy = yy + list_height / 2; + _sx += _sw * _ss / 2 - _sox * _ss; + _sy += _sh * _ss / 2 - _soy * _ss; + + draw_sprite_ext(_node.spr, _si, _sx, _sy, _ss, _ss, 0, c_white, 1); + + if(is_instanceof(_node, NodeAction)) + draw_sprite_ui_uniform(THEME.play_action, 0, _sx + list_height / 2 - 8, _sy + list_height / 2 - 8, 0.5, COLORS.add_node_blend_action); + } + + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text); + draw_text_add(list_height + ui(40), yy + list_height / 2, _node.getName()); + } + + if(node_focusing == i) search_pane.scroll_y_to = -max(0, hh - search_pane.h); + + hh += list_height; + yy += list_height; + } + #endregion + } + + node_focusing = -1; + + if(keyboard_check_pressed(vk_up)) { + node_selecting = safe_mod(node_selecting - 1 + amo, amo); + node_focusing = node_selecting; + } + + if(keyboard_check_pressed(vk_down)) { + node_selecting = safe_mod(node_selecting + 1, amo); + node_focusing = node_selecting; + } + + return hh; + }); +#endregion + +#event destroy +event_inherited(); + +WIDGET_CURRENT = noone; + +#event draw_gui init +if !ready exit; + +#region base UI + DIALOG_DRAW_BG + if(sFOCUS) DIALOG_DRAW_FOCUS +#endregion + +#region search + WIDGET_CURRENT = tb_search; + tb_search.setFocusHover(sFOCUS, sHOVER); + + if(search_string == "") { + catagory_pane.setFocusHover(sFOCUS, sHOVER); + catagory_pane.draw(dialog_x + ui(14), dialog_y + ui(52)); + + var _x = dialog_x + category_width - ui(12); + draw_sprite_stretched(THEME.ui_panel_bg, 1, _x, dialog_y + ui(52), dialog_w - category_width - ui(2), dialog_h - ui(66)); + content_pane.setFocusHover(sFOCUS, sHOVER); + content_pane.draw(_x, dialog_y + ui(52)); + + node_selecting = 0; + } else { + draw_sprite_stretched(THEME.ui_panel_bg, 1, dialog_x + ui(14), dialog_y + ui(52), dialog_w - ui(28), dialog_h - ui(66)); + search_pane.setFocusHover(sFOCUS, sHOVER); + search_pane.draw(dialog_x + ui(16), dialog_y + ui(52)); + } + + var tw = dialog_w - ui(96); + if(node_called != noone || junction_hovering != noone) + tw -= ui(32); + tb_search.draw(dialog_x + ui(14), dialog_y + ui(14), tw, ui(32), search_string, mouse_ui); + + var bx = dialog_x + dialog_w - ui(44); + var by = dialog_y + ui(16); + var b = buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, sFOCUS, sHOVER, + PREFERENCES.dialog_add_node_view? __txtx("view_list", "List view") : __txtx("view_grid", "Grid view"), + THEME.view_mode, PREFERENCES.dialog_add_node_view, COLORS._main_icon); + if(b == 2) + PREFERENCES.dialog_add_node_view = !PREFERENCES.dialog_add_node_view; + + bx -= ui(32); + var b = buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, sFOCUS, sHOVER, + PREFERENCES.dialog_add_node_grouping? __txtx("add_node_group_enabled", "Group enabled") : __txtx("add_node_group_disabled", "Group disabled"), + THEME.view_group, PREFERENCES.dialog_add_node_grouping, COLORS._main_icon); + if(b == 2) + PREFERENCES.dialog_add_node_grouping = !PREFERENCES.dialog_add_node_grouping; + + if(node_called != noone || junction_hovering != noone) { + var txt = node_show_connectable? __txtx("add_node_show_connect", "Showing connectable") : __txtx("add_node_show_all", "Showing all"); + var cc = node_show_connectable? COLORS._main_accent : COLORS._main_icon; + bx -= ui(32); + var b = buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, sFOCUS, sHOVER, txt, THEME.filter_type, node_show_connectable, cc); + if(b == 2) + node_show_connectable = !node_show_connectable; + } +#endregion + +#region tooltip + if(node_tooltip != noone) { + var ww = ui(300 + 8); + var hh = ui(16); + + var txt = node_tooltip.getTooltip(); + var spr = node_tooltip.tooltip_spr; + + draw_set_font(f_p1); + + if(spr) { + ww = ui(8) + sprite_get_width(spr); + hh = ui(8) + sprite_get_height(spr); + } else + hh = ui(16) + string_height_ext(txt, -1, ww - ui(16)); + + var x0 = min(node_tooltip_x, WIN_W - ww - ui(8)); + var x1 = node_tooltip_x + ww; + var y1 = node_tooltip_y - ui(8); + var y0 = y1 - hh; + + draw_sprite_stretched(THEME.textbox, 3, x0, y0, ww, hh); + draw_sprite_stretched(THEME.textbox, 0, x0, y0, ww, hh); + + if(spr) draw_sprite(spr, 0, x0 + ui(4), y0 + ui(4)); + + draw_set_text(f_p1, fa_left, fa_bottom, COLORS._main_text) + draw_text_line(x0 + ui(8), y1 - ui(8), txt, -1, ww - ui(16)); + } + + node_tooltip = noone; + ADD_NODE_SCROLL = content_pane.scroll_y_to; +#endregion \ No newline at end of file diff --git a/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup0 b/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup0 index 3d9d9401e..ec88ac085 100644 --- a/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup0 +++ b/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:48:07 +// 2024-04-16 10:48:46 function canvas_tool() constructor { node = noone; @@ -17,6 +17,12 @@ function canvas_tool() constructor { subtool = 0; + function disable() { + PANEL_PREVIEW.tool_current = noone; + } + + function getTool() { return self; } + function init() {} function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} diff --git a/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup1 b/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup1 index 2b3ce6828..1db81f4d4 100644 --- a/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup1 +++ b/#backups/scripts/__canvas_tool/__canvas_tool.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 10:20:09 +// 2024-04-16 10:48:44 function canvas_tool() constructor { node = noone; @@ -17,6 +17,12 @@ function canvas_tool() constructor { subtool = 0; + function disable() { + PANEL_PREVIEW.tool_current = noone; + } + + function getTool() { return self; } + function init() {} function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} diff --git a/#backups/scripts/buttonPalette/buttonPalette.gml.backup0 b/#backups/scripts/buttonPalette/buttonPalette.gml.backup0 new file mode 100644 index 000000000..57b9e7eef --- /dev/null +++ b/#backups/scripts/buttonPalette/buttonPalette.gml.backup0 @@ -0,0 +1,162 @@ +// 2024-04-16 09:39:26 +function buttonPalette(_onApply, dialog = noone) : widget() constructor { + onApply = _onApply; + parentDialog = dialog; + + current_palette = []; + side_button = noone; + + function apply(value) { #region + if(!interactable) return; + onApply(value); + } #endregion + + static trigger = function() { #region + var dialog = dialogCall(o_dialog_palette, WIN_W / 2, WIN_H / 2); + dialog.setDefault(current_palette); + dialog.onApply = apply; + dialog.interactable = interactable; + + if(parentDialog) + parentDialog.addChildren(dialog); + } #endregion + + static drawParam = function(params) { return draw(params.x, params.y, params.w, params.h, params.data, params.m); } + + static draw = function(_x, _y, _w, _h, _color, _m) { #region + x = _x; + y = _y; + w = _w; + h = _h; + + var _bs = min(_h, ui(32)); + hovering = hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + if(_w - _bs > ui(100) && side_button && instanceof(side_button) == "buttonClass") { + side_button.setFocusHover(active, hover); + side_button.draw(_x + _w -_bs, _y + _h / 2 - _bs / 2, _bs, _bs, _m, THEME.button_hide); + _w -= _bs + ui(8); + } + + var _pw = _w - ui(8); + var _ph = _h - ui(8); + + current_palette = _color; + + if(array_length(_color) > 0 && is_array(_color[0])) { + if(array_length(_color[0]) == 0) return 0; + + h = ui(12) + array_length(_color) * _ph; + current_palette = _color[0]; + } else { + h = _h; + } + + if(!is_array(current_palette) || array_empty(current_palette) || is_array(current_palette[0])) + return 0; + + var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + h); + if(ihover && hoverRect) { + draw_sprite_stretched(THEME.button_def, 1, _x, _y, _w, h); + if(mouse_press(mb_left, iactive)) + trigger(); + + if(mouse_click(mb_left, iactive)) { + draw_sprite_stretched(THEME.button_def, 2, _x, _y, _w, h); + draw_sprite_stretched_ext(THEME.button_def, 3, _x, _y, _w, h, COLORS._main_accent, 1); + } + } else { + draw_sprite_stretched(THEME.button_def, 0, _x, _y, _w, h); + if(mouse_press(mb_left)) deactivate(); + } + + if(!is_array(_color[0])) _color = [ _color ]; + + for( var i = 0, n = array_length(_color); i < n; i++ ) { + var _pal = _color[i]; + var _px = _x + ui(4); + var _py = _y + ui(4) + i * _ph; + + if(is_array(_pal)) + drawPalette(_pal, _px, _py, _pw, _ph); + } + + if(WIDGET_CURRENT == self) + draw_sprite_stretched_ext(THEME.widget_selecting, 0, _x - ui(3), _y - ui(3), _w + ui(6), h + ui(6), COLORS._main_accent, 1); + + if(DRAGGING && DRAGGING.type == "Palette" && hover && hoverRect) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, _y, _w, h, COLORS._main_value_positive, 1); + if(mouse_release(mb_left)) + onApply(DRAGGING.data); + } + + resetFocus(); + + return h; + } #endregion + + static clone = function() { #region + var cln = new buttonPalette(onApply, parentDialog); + return cln; + } #endregion +} + +function drawPalette(_pal, _x, _y, _w, _h, _a = 1) { #region + var aa = array_length(_pal); + + if(aa == 1) { + draw_sprite_stretched_ext(THEME.palette_mask, 1, _x, _y, _w, _h, _pal[0], _a); + return; + } + + var ww = _w / aa; + var _x0 = _x; + var _in; + + for(var i = 0; i < aa; i++) { + if(!is_numeric(_pal[i])) continue; + + if(i == 0) _in = 2; + else if(i == aa - 1) _in = 3; + else _in = 0; + + var _ca = _color_get_alpha(_pal[i]); + + if(_ca == 1) { + draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h, _pal[i], _a); + } else { + draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h - ui(8), _pal[i], _a); + + draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww), ui(6), c_black, _a); + draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww) * _ca, ui(6), c_white, _a); + } + + _x0 += ww; + } +} #endregion + + +function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { #region + var amo = array_length(_pal); + var col = floor(_w / _gs); + var row = ceil(amo / col); + var cx = -1, cy = -1; + var _pd = ui(5); + + for(var i = 0; i < array_length(_pal); i++) { + draw_set_color(_pal[i]); + var _x0 = _x + safe_mod(i, col) * _gs; + var _y0 = _y + floor(i / col) * _gs; + + draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false); + + if(c_color == _pal[i]) { + cx = _x0; + cy = _y0; + } + } + + if(cx == -1) return; + + draw_sprite_stretched_ext(THEME.palette_selecting, 0, cx - _pd, cy + 1 - _pd, _gs + _pd * 2, _gs + _pd * 2); +} #endregion \ No newline at end of file diff --git a/#backups/scripts/buttonPalette/buttonPalette.gml.backup1 b/#backups/scripts/buttonPalette/buttonPalette.gml.backup1 new file mode 100644 index 000000000..c7cd7868d --- /dev/null +++ b/#backups/scripts/buttonPalette/buttonPalette.gml.backup1 @@ -0,0 +1,162 @@ +// 2024-04-16 09:39:25 +function buttonPalette(_onApply, dialog = noone) : widget() constructor { + onApply = _onApply; + parentDialog = dialog; + + current_palette = []; + side_button = noone; + + function apply(value) { #region + if(!interactable) return; + onApply(value); + } #endregion + + static trigger = function() { #region + var dialog = dialogCall(o_dialog_palette, WIN_W / 2, WIN_H / 2); + dialog.setDefault(current_palette); + dialog.onApply = apply; + dialog.interactable = interactable; + + if(parentDialog) + parentDialog.addChildren(dialog); + } #endregion + + static drawParam = function(params) { return draw(params.x, params.y, params.w, params.h, params.data, params.m); } + + static draw = function(_x, _y, _w, _h, _color, _m) { #region + x = _x; + y = _y; + w = _w; + h = _h; + + var _bs = min(_h, ui(32)); + hovering = hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + if(_w - _bs > ui(100) && side_button && instanceof(side_button) == "buttonClass") { + side_button.setFocusHover(active, hover); + side_button.draw(_x + _w -_bs, _y + _h / 2 - _bs / 2, _bs, _bs, _m, THEME.button_hide); + _w -= _bs + ui(8); + } + + var _pw = _w - ui(8); + var _ph = _h - ui(8); + + current_palette = _color; + + if(array_length(_color) > 0 && is_array(_color[0])) { + if(array_length(_color[0]) == 0) return 0; + + h = ui(12) + array_length(_color) * _ph; + current_palette = _color[0]; + } else { + h = _h; + } + + if(!is_array(current_palette) || array_empty(current_palette) || is_array(current_palette[0])) + return 0; + + var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + h); + if(ihover && hoverRect) { + draw_sprite_stretched(THEME.button_def, 1, _x, _y, _w, h); + if(mouse_press(mb_left, iactive)) + trigger(); + + if(mouse_click(mb_left, iactive)) { + draw_sprite_stretched(THEME.button_def, 2, _x, _y, _w, h); + draw_sprite_stretched_ext(THEME.button_def, 3, _x, _y, _w, h, COLORS._main_accent, 1); + } + } else { + draw_sprite_stretched(THEME.button_def, 0, _x, _y, _w, h); + if(mouse_press(mb_left)) deactivate(); + } + + if(!is_array(_color[0])) _color = [ _color ]; + + for( var i = 0, n = array_length(_color); i < n; i++ ) { + var _pal = _color[i]; + var _px = _x + ui(4); + var _py = _y + ui(4) + i * _ph; + + if(is_array(_pal)) + drawPalette(_pal, _px, _py, _pw, _ph); + } + + if(WIDGET_CURRENT == self) + draw_sprite_stretched_ext(THEME.widget_selecting, 0, _x - ui(3), _y - ui(3), _w + ui(6), h + ui(6), COLORS._main_accent, 1); + + if(DRAGGING && DRAGGING.type == "Palette" && hover && hoverRect) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, _y, _w, h, COLORS._main_value_positive, 1); + if(mouse_release(mb_left)) + onApply(DRAGGING.data); + } + + resetFocus(); + + return h; + } #endregion + + static clone = function() { #region + var cln = new buttonPalette(onApply, parentDialog); + return cln; + } #endregion +} + +function drawPalette(_pal, _x, _y, _w, _h, _a = 1) { #region + var aa = array_length(_pal); + + if(aa == 1) { + draw_sprite_stretched_ext(THEME.palette_mask, 1, _x, _y, _w, _h, _pal[0], _a); + return; + } + + var ww = _w / aa; + var _x0 = _x; + var _in; + + for(var i = 0; i < aa; i++) { + if(!is_numeric(_pal[i])) continue; + + if(i == 0) _in = 2; + else if(i == aa - 1) _in = 3; + else _in = 0; + + var _ca = _color_get_alpha(_pal[i]); + + if(_ca == 1) { + draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h, _pal[i], _a); + } else { + draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h - ui(8), _pal[i], _a); + + draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww), ui(6), c_black, _a); + draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww) * _ca, ui(6), c_white, _a); + } + + _x0 += ww; + } +} #endregion + + +function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { #region + var amo = array_length(_pal); + var col = floor(_w / _gs); + var row = ceil(amo / col); + var cx = -1, cy = -1; + var _pd = ui(5); + + for(var i = 0; i < array_length(_pal); i++) { + draw_set_color(_pal[i]); + var _x0 = _x + safe_mod(i, col) * _gs; + var _y0 = _y + floor(i / col) * _gs; + + draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false); + + if(c_color == _pal[i]) { + cx = _x0; + cy = _y0; + } + } + + if(cx == -1) return; + + draw_sprite_stretched_ext(THEME.palette_selecting, 0, cx - _pd, cy + 1 - _pd, _gs + _pd * 2, _gs + _pd * 2); +} #endregion \ No newline at end of file diff --git a/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 new file mode 100644 index 000000000..7ff9b4316 --- /dev/null +++ b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 @@ -0,0 +1,191 @@ +// 2024-04-15 17:50:18 +function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region + if(brush.brush_surface == noone) { + + if(brush.brush_size <= 1) + draw_point(_x, _y); + + else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_point(_x + fx[i][0], _y + fx[i][1]); + + } else + draw_circle_prec(_x, _y, brush.brush_size / 2, 0); + + } else { + var _sw = surface_get_width_safe(brush.brush_surface); + var _sh = surface_get_height_safe(brush.brush_surface); + var _r = brush.brush_direction + angle_random_eval(brush.brush_rand_dir, brush.brush_seed); + var _p = point_rotate(-_sw / 2, -_sh / 2, 0, 0, _r); + + draw_surface_ext_safe(brush.brush_surface, _x + _p[0], _y + _p[1], 1, 1, _r, draw_get_color(), draw_get_alpha()); + + if(_draw) brush.brush_seed = irandom_range(100000, 999999); + } +} #endregion + +function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false, _cap = false) { #region + + if(brush.brush_surface == noone) { + + if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + if(_x1 > _x0) _x0--; + if(_y1 > _y0) _y0--; + if(_y1 < _y0) _y1--; + if(_x1 < _x0) _x1--; + } + + if(brush.brush_size == 1) { + draw_line(_x0, _y0, _x1, _y1); + + } else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_line(_x0 + fx[i][0], _y0 + fx[i][1], _x1 + fx[i][0], _y1 + fx[i][1]); + + } else { + draw_line_width(_x0, _y0, _x1, _y1, brush.brush_size); + if(_cap) { + canvas_draw_point_size(brush, _x0, _y0, true); + canvas_draw_point_size(brush, _x1, _y1, true); + } + } + + } else { + var diss = point_distance(_x0, _y0, _x1, _y1); + var dirr = point_direction(_x0, _y0, _x1, _y1); + var st_x = lengthdir_x(1, dirr); + var st_y = lengthdir_y(1, dirr); + + var _i = _draw? brush.brush_next_dist : 0; + var _dst = diss; + + if(_i < diss) { + while(_i < diss) { + var _px = _x0 + st_x * _i; + var _py = _y0 + st_y * _i; + + canvas_draw_point_size(brush, _px, _py, _draw); + + brush.brush_next_dist = random_range(brush.brush_dist_min, brush.brush_dist_max); + _i += brush.brush_next_dist; + _dst -= brush.brush_next_dist; + } + + brush.brush_next_dist -= _dst; + } else + brush.brush_next_dist -= diss; + + if(brush.brush_dist_min == brush.brush_dist_max && brush.brush_dist_min == 1) + canvas_draw_point_size(brush, _x1, _y1, _draw); + } +} #endregion + +function canvas_draw_rect_size(brush, _x0, _y0, _x1, _y1, _fill) { #region + if(_x0 == _x1 && _y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + return; + + } else if(_x0 == _x1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x0, _y1); + return; + + } else if(_y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x1, _y0); + return; + } + + var _min_x = min(_x0, _x1); + var _max_x = max(_x0, _x1); + var _min_y = min(_y0, _y1); + var _may_y = max(_y0, _y1); + + if(_fill) draw_rectangle(_min_x, _min_y, _max_x, _may_y, 0); + + if(brush.brush_size == 1 && brush.brush_surface == noone) + draw_rectangle(_min_x + 1, _min_y + 1, _max_x - 1, _may_y - 1, 1); + else { + canvas_draw_line_size(brush, _min_x, _min_y, _max_x, _min_y); + canvas_draw_line_size(brush, _min_x, _min_y, _min_x, _may_y); + canvas_draw_line_size(brush, _max_x, _may_y, _max_x, _min_y); + canvas_draw_line_size(brush, _max_x, _may_y, _min_x, _may_y); + } +} #endregion + +function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region + if(_x0 == _x1 && _y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + return; + + } else if(_x0 == _x1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x0, _y1); + return; + + } else if(_y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x1, _y0); + return; + } + + var _min_x = min(_x0, _x1) - 1; + var _max_x = max(_x0, _x1); + var _min_y = min(_y0, _y1) - 1; + var _max_y = max(_y0, _y1); + + if(_fill) { + draw_set_circle_precision(64); + draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + } + + var samp = 64; + var cx = (_min_x + _max_x) / 2; + var cy = (_min_y + _max_y) / 2; + var rx = abs(_x0 - _x1) / 2; + var ry = abs(_y0 - _y1) / 2; + + var ox, oy, nx, ny; + for( var i = 0; i <= samp; i++ ) { + nx = round(cx + lengthdir_x(rx, 360 / samp * i)); + ny = round(cy + lengthdir_y(ry, 360 / samp * i)); + + if(i) canvas_draw_line_size(brush, ox, oy, nx, ny); + + ox = nx; + oy = ny; + } +} #endregion + +function canvas_draw_curve_brush(brush, x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region + var ox, oy, nx, ny; + + var _st = 1 / prec; + + for (var i = 0; i <= prec; i++) { + var _t = _st * i; + var _t1 = 1 - _t; + + nx = _t1 * _t1 * _t1 * x0 + + 3 * (_t1 * _t1 * _t) * cx0 + + 3 * (_t1 * _t * _t) * cx1 + + _t * _t * _t * x1; + + ny = _t1 * _t1 * _t1 * y0 + + 3 * (_t1 * _t1 * _t) * cy0 + + 3 * (_t1 * _t * _t) * cy1 + + _t * _t * _t * y1; + + if(i) canvas_draw_line_size(brush, ox, oy, nx, ny, true, true); + + ox = nx; + oy = ny; + } +} #endregion \ No newline at end of file diff --git a/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 new file mode 100644 index 000000000..cf6c95a8f --- /dev/null +++ b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 @@ -0,0 +1,191 @@ +// 2024-04-15 17:50:17 +function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region + if(brush.brush_surface == noone) { + + if(brush.brush_size <= 1) + draw_point(_x, _y); + + else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_point(_x + fx[i][0], _y + fx[i][1]); + + } else + draw_circle_prec(_x, _y, brush.brush_size / 2, 0); + + } else { + var _sw = surface_get_width_safe(brush.brush_surface); + var _sh = surface_get_height_safe(brush.brush_surface); + var _r = brush.brush_direction + angle_random_eval(brush.brush_rand_dir, brush.brush_seed); + var _p = point_rotate(-_sw / 2, -_sh / 2, 0, 0, _r); + + draw_surface_ext_safe(brush.brush_surface, _x + _p[0], _y + _p[1], 1, 1, _r, draw_get_color(), draw_get_alpha()); + + if(_draw) brush.brush_seed = irandom_range(100000, 999999); + } +} #endregion + +function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false, _cap = false) { #region + + if(brush.brush_surface == noone) { + + if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + if(_x1 > _x0) _x0--; + if(_y1 > _y0) _y0--; + if(_y1 < _y0) _y1--; + if(_x1 < _x0) _x1--; + } + + if(brush.brush_size == 1) { + draw_line(_x0, _y0, _x1, _y1); + + } else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_line(_x0 + fx[i][0], _y0 + fx[i][1], _x1 + fx[i][0], _y1 + fx[i][1]); + + } else { + draw_line_width(_x0, _y0, _x1, _y1, brush.brush_size); + if(_cap) { + canvas_draw_point_size(brush, _x0, _y0, true); + canvas_draw_point_size(brush, _x1, _y1, true); + } + } + + } else { + var diss = point_distance(_x0, _y0, _x1, _y1); + var dirr = point_direction(_x0, _y0, _x1, _y1); + var st_x = lengthdir_x(1, dirr); + var st_y = lengthdir_y(1, dirr); + + var _i = _draw? brush.brush_next_dist : 0; + var _dst = diss; + + if(_i < diss) { + while(_i < diss) { + var _px = _x0 + st_x * _i; + var _py = _y0 + st_y * _i; + + canvas_draw_point_size(brush, _px, _py, _draw); + + brush.brush_next_dist = random_range(brush.brush_dist_min, brush.brush_dist_max); + _i += brush.brush_next_dist; + _dst -= brush.brush_next_dist; + } + + brush.brush_next_dist -= _dst; + } else + brush.brush_next_dist -= diss; + + if(brush.brush_dist_min == brush.brush_dist_max && brush.brush_dist_min == 1) + canvas_draw_point_size(brush, _x1, _y1, _draw); + } +} #endregion + +function canvas_draw_rect_size(brush, _x0, _y0, _x1, _y1, _fill) { #region + if(_x0 == _x1 && _y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + return; + + } else if(_x0 == _x1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x0, _y1); + return; + + } else if(_y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x1, _y0); + return; + } + + var _min_x = min(_x0, _x1); + var _max_x = max(_x0, _x1); + var _min_y = min(_y0, _y1); + var _may_y = max(_y0, _y1); + + if(_fill) draw_rectangle(_min_x, _min_y, _max_x, _may_y, 0); + + if(brush.brush_size == 1 && brush.brush_surface == noone) + draw_rectangle(_min_x + 1, _min_y + 1, _max_x - 1, _may_y - 1, 1); + else { + canvas_draw_line_size(brush, _min_x, _min_y, _max_x, _min_y); + canvas_draw_line_size(brush, _min_x, _min_y, _min_x, _may_y); + canvas_draw_line_size(brush, _max_x, _may_y, _max_x, _min_y); + canvas_draw_line_size(brush, _max_x, _may_y, _min_x, _may_y); + } +} #endregion + +function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region + if(_x0 == _x1 && _y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + return; + + } else if(_x0 == _x1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x0, _y1); + return; + + } else if(_y0 == _y1) { + canvas_draw_point_size(brush, _x0, _y0); + canvas_draw_point_size(brush, _x1, _y1); + canvas_draw_line_size(brush, _x0, _y0, _x1, _y0); + return; + } + + var _min_x = min(_x0, _x1) - 1; + var _max_x = max(_x0, _x1); + var _min_y = min(_y0, _y1) - 1; + var _max_y = max(_y0, _y1); + + if(_fill) { + draw_set_circle_precision(64); + draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + } + + var samp = 64; + var cx = (_min_x + _max_x) / 2; + var cy = (_min_y + _max_y) / 2; + var rx = abs(_x0 - _x1) / 2; + var ry = abs(_y0 - _y1) / 2; + + var ox, oy, nx, ny; + for( var i = 0; i <= samp; i++ ) { + nx = round(cx + lengthdir_x(rx, 360 / samp * i)); + ny = round(cy + lengthdir_y(ry, 360 / samp * i)); + + if(i) canvas_draw_line_size(brush, ox, oy, nx, ny); + + ox = nx; + oy = ny; + } +} #endregion + +function canvas_draw_curve_brush(brush, x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region + var ox, oy, nx, ny; + + var _st = 1 / prec; + + for (var i = 0; i <= prec; i++) { + var _t = _st * i; + var _t1 = 1 - _t; + + nx = _t1 * _t1 * _t1 * x0 + + 3 * (_t1 * _t1 * _t) * cx0 + + 3 * (_t1 * _t * _t) * cx1 + + _t * _t * _t * x1; + + ny = _t1 * _t1 * _t1 * y0 + + 3 * (_t1 * _t1 * _t) * cy0 + + 3 * (_t1 * _t * _t) * cy1 + + _t * _t * _t * y1; + + if(i) canvas_draw_line_size(brush, ox, oy, nx, ny, true, true); + + ox = nx; + oy = ny; + } +} #endregion \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup0 b/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup0 index 232f0a334..2132dd44b 100644 --- a/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup0 +++ b/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:50:50 +// 2024-04-14 18:56:07 function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { self.brush = brush; isEraser = eraser; @@ -28,7 +28,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { } if(mouse_press(mb_left, active)) { - brush_next_dist = 0; surface_set_shader(drawing_surface, noone); canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y, true); @@ -37,7 +36,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { mouse_holding = true; if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT)) { ///////////////// shift line surface_set_shader(drawing_surface, noone, true, BLEND.alpha); - brush_next_dist = 0; canvas_draw_line_size(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, true); surface_reset_shader(); mouse_holding = false; diff --git a/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup1 b/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup1 index eee79f1d7..3d2386700 100644 --- a/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup1 +++ b/#backups/scripts/canvas_tool_brush/canvas_tool_brush.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 10:04:07 +// 2024-04-14 14:45:30 function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { self.brush = brush; isEraser = eraser; diff --git a/#backups/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml.backup0 b/#backups/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml.backup0 new file mode 100644 index 000000000..97f43e96c --- /dev/null +++ b/#backups/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml.backup0 @@ -0,0 +1,75 @@ +// 2024-04-16 10:15:33 +enum CANVAS_TOOL_SHAPE { + rectangle, + ellipse +} + +function canvas_tool_shape(brush, shape) : canvas_tool() constructor { + self.brush = brush; + self.shape = shape; + + brush_resizable = true; + mouse_holding = false; + + mouse_cur_x = 0; + mouse_cur_y = 0; + mouse_pre_x = 0; + mouse_pre_y = 0; + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + mouse_cur_x = round((_mx - _x) / _s - 0.5); + mouse_cur_y = round((_my - _y) / _s - 0.5); + + if(mouse_holding && key_mod_press(SHIFT)) { + var ww = mouse_cur_x - mouse_pre_x; + var hh = mouse_cur_y - mouse_pre_y; + var ss = max(abs(ww), abs(hh)); + + mouse_cur_x = mouse_pre_x + ss * sign(ww); + mouse_cur_y = mouse_pre_y + ss * sign(hh); + } + + if(mouse_holding) { + + surface_set_shader(drawing_surface, noone); + + if(shape == CANVAS_TOOL_SHAPE.rectangle) + canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + + else if(shape == CANVAS_TOOL_SHAPE.ellipse) + canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + + surface_reset_shader(); + + if(mouse_release(mb_left)) { + apply_draw_surface(); + mouse_holding = false; + } + + } else if(mouse_press(mb_left, active)) { + mouse_pre_x = mouse_cur_x; + mouse_pre_y = mouse_cur_y; + + mouse_holding = true; + + node.tool_pick_color(mouse_cur_x, mouse_cur_y); + } + + } + + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + if(!mouse_holding) { + canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y); + return; + } + + if(shape == CANVAS_TOOL_SHAPE.rectangle) + canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + + if(shape == CANVAS_TOOL_SHAPE.ellipse) + canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + } + +} \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml.backup1 b/#backups/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml.backup1 new file mode 100644 index 000000000..97f43e96c --- /dev/null +++ b/#backups/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml.backup1 @@ -0,0 +1,75 @@ +// 2024-04-16 10:15:33 +enum CANVAS_TOOL_SHAPE { + rectangle, + ellipse +} + +function canvas_tool_shape(brush, shape) : canvas_tool() constructor { + self.brush = brush; + self.shape = shape; + + brush_resizable = true; + mouse_holding = false; + + mouse_cur_x = 0; + mouse_cur_y = 0; + mouse_pre_x = 0; + mouse_pre_y = 0; + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + mouse_cur_x = round((_mx - _x) / _s - 0.5); + mouse_cur_y = round((_my - _y) / _s - 0.5); + + if(mouse_holding && key_mod_press(SHIFT)) { + var ww = mouse_cur_x - mouse_pre_x; + var hh = mouse_cur_y - mouse_pre_y; + var ss = max(abs(ww), abs(hh)); + + mouse_cur_x = mouse_pre_x + ss * sign(ww); + mouse_cur_y = mouse_pre_y + ss * sign(hh); + } + + if(mouse_holding) { + + surface_set_shader(drawing_surface, noone); + + if(shape == CANVAS_TOOL_SHAPE.rectangle) + canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + + else if(shape == CANVAS_TOOL_SHAPE.ellipse) + canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + + surface_reset_shader(); + + if(mouse_release(mb_left)) { + apply_draw_surface(); + mouse_holding = false; + } + + } else if(mouse_press(mb_left, active)) { + mouse_pre_x = mouse_cur_x; + mouse_pre_y = mouse_cur_y; + + mouse_holding = true; + + node.tool_pick_color(mouse_cur_x, mouse_cur_y); + } + + } + + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + if(!mouse_holding) { + canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y); + return; + } + + if(shape == CANVAS_TOOL_SHAPE.rectangle) + canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + + if(shape == CANVAS_TOOL_SHAPE.ellipse) + canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); + } + +} \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup0 b/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup0 index aef9bf750..a404201c6 100644 --- a/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup0 +++ b/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup0 @@ -1,4 +1,185 @@ -// 2024-04-14 12:31:27 -function canvas_tool_curve() : canvas_tool() constructor { - +// 2024-04-16 11:00:41 +function canvas_tool_curve_bezier(brush) : canvas_tool() constructor { + self.brush = brush; + brush_resizable = true; + + anchors = []; + + mouse_cur_x = 0; + mouse_cur_y = 0; + editing = [ noone, 0 ]; + + mouse_edit_mx = 0; + mouse_edit_my = 0; + mouse_edit_sx = 0; + mouse_edit_sy = 0; + + mouse_hovering = [ noone, 0 ]; + draw_hovering = []; + + function init() { + anchors = []; + editing = [ noone, 0 ]; + } + + function apply() { + apply_draw_surface(); + + disable(); + } + + function cancel() { + surface_clear(drawing_surface); + disable(); + } + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + mouse_cur_x = (_mx - _x) / _s; + mouse_cur_y = (_my - _y) / _s; + + if(editing[0] != noone) { + var _a = anchors[editing[0]]; + var _dx = mouse_cur_x - mouse_edit_mx; + var _dy = mouse_cur_y - mouse_edit_my; + + if(editing[1] == 0) { + _a[2] += _dx; + _a[3] += _dy; + + } else if(editing[1] == -1) { + _a[0] += _dx; + _a[1] += _dy; + + _a[4] -= _dx; + _a[5] -= _dy; + + } else if(editing[1] == 1) { + _a[0] -= _dx; + _a[1] -= _dy; + + _a[4] += _dx; + _a[5] += _dy; + + } + + mouse_edit_mx = mouse_cur_x; + mouse_edit_my = mouse_cur_y; + + if(mouse_release(mb_left)) + editing[0] = noone; + } + + if(mouse_press(mb_left, active)) { + if(mouse_hovering[0] == noone) { + array_push(anchors, [ 0, 0, mouse_cur_x, mouse_cur_y, 0, 0 ]); + editing[0] = array_length(anchors) - 1; + editing[1] = 1; + + } else { + if(key_mod_press(SHIFT)) + array_delete(anchors, mouse_hovering[0], 1); + else { + editing[0] = mouse_hovering[0]; + editing[1] = mouse_hovering[1]; + } + } + + mouse_edit_mx = mouse_cur_x; + mouse_edit_my = mouse_cur_y; + mouse_edit_sx = mouse_cur_x; + mouse_edit_sy = mouse_cur_y; + } + + surface_set_shader(drawing_surface, noone); + var ox, oy, nx, ny; + var oax1, oay1, nax0, nay0; + + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = anchors[i][2]; + ny = anchors[i][3]; + + nax0 = nx + anchors[i][0]; + nay0 = ny + anchors[i][1]; + + if(i) canvas_draw_curve_brush(brush, ox, oy, oax1, oay1, nax0, nay0, nx, ny); + + oax1 = nx + anchors[i][4]; + oay1 = ny + anchors[i][5]; + + ox = nx; + oy = ny; + } + + surface_reset_shader(); + + node.tool_curve_apply.setInteract(!array_empty(anchors)); + node.tool_curve_cancel.setInteract(!array_empty(anchors)); + if(key_press(vk_enter)) apply(); + if(key_press(vk_escape)) disable(); + } + + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + draw_surface_ext_safe(drawing_surface, _x, _y, _s, _s); + } + + function drawMask(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + } + + function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var ox, oy, nx, ny, ax0, ay0, ax1, ay1; + var oax1, oay1, nax0, nay0; + + draw_set_color(c_white); + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = _x + anchors[i][2] * _s; + ny = _y + anchors[i][3] * _s; + + nax0 = nx + anchors[i][0] * _s; + nay0 = ny + anchors[i][1] * _s; + + if(i) draw_curve_bezier(ox, oy, oax1, oay1, nax0, nay0, nx, ny); + + oax1 = nx + anchors[i][4] * _s; + oay1 = ny + anchors[i][5] * _s; + + draw_line(nx, ny, nax0, nay0); + draw_line(nx, ny, oax1, oay1); + + ox = nx; + oy = ny; + } + + mouse_hovering = [ noone, 0 ]; + + draw_hovering = array_verify(draw_hovering, array_length(anchors) * 3); + + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = _x + anchors[i][2] * _s; + ny = _y + anchors[i][3] * _s; + + ax0 = nx + anchors[i][0] * _s; + ay0 = ny + anchors[i][1] * _s; + + ax1 = nx + anchors[i][4] * _s; + ay1 = ny + anchors[i][5] * _s; + + draw_anchor(0, nx, ny, lerp(10, 13, draw_hovering[i * 3 + 1])); + draw_anchor(0, ax0, ay0, lerp( 7, 10, draw_hovering[i * 3 + 0])); + draw_anchor(0, ax1, ay1, lerp( 7, 10, draw_hovering[i * 3 + 2])); + + if(point_in_circle(_mx, _my, nx, ny, 10)) mouse_hovering = [ i, 0 ]; + else if(point_in_circle(_mx, _my, ax0, ay0, 10)) mouse_hovering = [ i, -1 ]; + else if(point_in_circle(_mx, _my, ax1, ay1, 10)) mouse_hovering = [ i, 1 ]; + } + + if(mouse_hovering[0] != noone) { + var index = mouse_hovering[0] * 3 + mouse_hovering[1] + 1; + + for (var i = 0, n = array_length(draw_hovering); i < n; i++) + draw_hovering[i] = lerp_float(draw_hovering[i], i == index, 4); + } + } + } \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup1 b/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup1 index 04fafb6bd..01fad8ae2 100644 --- a/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup1 +++ b/#backups/scripts/canvas_tool_curve/canvas_tool_curve.gml.backup1 @@ -1,4 +1,185 @@ -// 2024-04-14 12:31:12 -function canvas_tool_curve() : canvas_tool() constructor { - +// 2024-04-16 11:00:38 +function canvas_tool_curve_bezier(brush) : canvas_tool() constructor { + self.brush = brush; + brush_resizable = true; + + anchors = []; + + mouse_cur_x = 0; + mouse_cur_y = 0; + editing = [ noone, 0 ]; + + mouse_edit_mx = 0; + mouse_edit_my = 0; + mouse_edit_sx = 0; + mouse_edit_sy = 0; + + mouse_hovering = [ noone, 0 ]; + draw_hovering = []; + + function init() { + anchors = []; + editing = [ noone, 0 ]; + } + + function apply() { + apply_draw_surface(); + + disable(); + } + + function cancel() { + surface_clear(drawing_surface); + disable(); + } + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + mouse_cur_x = (_mx - _x) / _s; + mouse_cur_y = (_my - _y) / _s; + + if(editing[0] != noone) { + var _a = anchors[editing[0]]; + var _dx = mouse_cur_x - mouse_edit_mx; + var _dy = mouse_cur_y - mouse_edit_my; + + if(editing[1] == 0) { + _a[2] += _dx; + _a[3] += _dy; + + } else if(editing[1] == -1) { + _a[0] += _dx; + _a[1] += _dy; + + _a[4] -= _dx; + _a[5] -= _dy; + + } else if(editing[1] == 1) { + _a[0] -= _dx; + _a[1] -= _dy; + + _a[4] += _dx; + _a[5] += _dy; + + } + + mouse_edit_mx = mouse_cur_x; + mouse_edit_my = mouse_cur_y; + + if(mouse_release(mb_left)) + editing[0] = noone; + } + + if(mouse_press(mb_left, active)) { + if(mouse_hovering[0] == noone) { + array_push(anchors, [ 0, 0, mouse_cur_x, mouse_cur_y, 0, 0 ]); + editing[0] = array_length(anchors) - 1; + editing[1] = 1; + + } else { + if(key_mod_press(SHIFT)) + array_delete(anchors, mouse_hovering[0], 1); + else { + editing[0] = mouse_hovering[0]; + editing[1] = mouse_hovering[1]; + } + } + + mouse_edit_mx = mouse_cur_x; + mouse_edit_my = mouse_cur_y; + mouse_edit_sx = mouse_cur_x; + mouse_edit_sy = mouse_cur_y; + } + + surface_set_shader(drawing_surface, noone); + var ox, oy, nx, ny; + var oax1, oay1, nax0, nay0; + + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = anchors[i][2]; + ny = anchors[i][3]; + + nax0 = nx + anchors[i][0]; + nay0 = ny + anchors[i][1]; + + if(i) canvas_draw_curve_brush(brush, ox, oy, oax1, oay1, nax0, nay0, nx, ny); + + oax1 = nx + anchors[i][4]; + oay1 = ny + anchors[i][5]; + + ox = nx; + oy = ny; + } + + surface_reset_shader(); + + node.tool_curve_apply.setInteract(!array_empty(anchors)); + node.tool_curve_cancel.setInteract(!array_empty(anchors)); + if(key_press(vk_enter)) apply(); + if(key_press(vk_escape)) disable(); + } + + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + draw_surface_ext_safe(drawing_surface, _x, _y, _s, _s); + } + + function drawMask(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + } + + function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var ox, oy, nx, ny, ax0, ay0, ax1, ay1; + var oax1, oay1, nax0, nay0; + + draw_set_color(c_white); + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = _x + anchors[i][2] * _s; + ny = _y + anchors[i][3] * _s; + + nax0 = nx + anchors[i][0] * _s; + nay0 = ny + anchors[i][1] * _s; + + if(i) draw_curve_bezier(ox, oy, oax1, oay1, nax0, nay0, nx, ny); + + oax1 = nx + anchors[i][4] * _s; + oay1 = ny + anchors[i][5] * _s; + + draw_line(nx, ny, nax0, nay0); + draw_line(nx, ny, oax1, oay1); + + ox = nx; + oy = ny; + } + + mouse_hovering = [ noone, 0 ]; + + draw_hovering = array_verify(draw_hovering, array_length(anchors) * 3); + + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = _x + anchors[i][2] * _s; + ny = _y + anchors[i][3] * _s; + + ax0 = nx + anchors[i][0] * _s; + ay0 = ny + anchors[i][1] * _s; + + ax1 = nx + anchors[i][4] * _s; + ay1 = ny + anchors[i][5] * _s; + + draw_anchor(0, nx, ny, lerp(10, 13, draw_hovering[i * 3 + 1])); + draw_anchor(0, ax0, ay0, lerp( 7, 10, draw_hovering[i * 3 + 0])); + draw_anchor(0, ax1, ay1, lerp( 7, 10, draw_hovering[i * 3 + 2])); + + if(point_in_circle(_mx, _my, nx, ny, 10)) mouse_hovering = [ i, 0 ]; + else if(point_in_circle(_mx, _my, ax0, ay0, 10)) mouse_hovering = [ i, -1 ]; + else if(point_in_circle(_mx, _my, ax1, ay1, 10)) mouse_hovering = [ i, 1 ]; + } + + if(mouse_hovering[0] != noone) { + var index = mouse_hovering[0] * 3 + mouse_hovering[1] + 1; + + for (var i = 0, n = array_length(draw_hovering); i < n; i++) + draw_hovering[i] = lerp_float(draw_hovering[i], i == index, 4); + } + } + } \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 index 6d4cb6595..eccb4747c 100644 --- a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 +++ b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:48:46 +// 2024-04-16 15:02:26 function canvas_tool_node(canvas, node) : canvas_tool() constructor { self.canvas = canvas; @@ -28,8 +28,15 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { if(applySelection) canvas.tool_selection.apply(); canvas.nodeTool = noone; - surface_free(targetSurface); - surface_free(maskedSurface); + surface_free_safe(maskedSurface); + + cleanUp(); + } + + static cleanUp = function() { + surface_free_safe(targetSurface); + surface_free_safe(maskedSurface); + nodeObject.destroy(); } nodeObject = node.build(0, 0); @@ -66,21 +73,41 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { //////////////////////////////////////////////////////////////////////////////////////////////////////// function apply() { + var _surf = surface_create(sw, sh); if(applySelection) { + + surface_set_shader(_surf, sh_blend_normal); + shader_set_surface("fore", maskedSurface); + shader_set_f("dimension", 1, 1); + shader_set_f("opacity", 1); + + draw_surface(canvas.tool_selection.selection_surface, 0, 0); + surface_reset_shader(); + surface_free(canvas.tool_selection.selection_surface); - canvas.tool_selection.selection_surface = maskedSurface; + canvas.tool_selection.selection_surface = _surf; canvas.tool_selection.apply(); } else { canvas.storeAction(); - canvas.setCanvasSurface(maskedSurface); + + surface_set_shader(_surf, sh_blend_normal); + shader_set_surface("fore", maskedSurface); + shader_set_f("dimension", 1, 1); + shader_set_f("opacity", 1); + + draw_surface(canvas.getCanvasSurface(), 0, 0); + surface_reset_shader(); + + canvas.setCanvasSurface(_surf); canvas.surface_store_buffer(); } PANEL_PREVIEW.tool_current = noone; canvas.nodeTool = noone; - surface_free_safe(targetSurface); + + cleanUp(); } function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { @@ -110,7 +137,10 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { else if(inputJunction.name == "Dimension") inputJunction.setValue([ sw, sh ]); } - nodeObject.update(); + if(is_instanceof(nodeObject, Node_Collection)) + RenderList(nodeObject.nodes); + else + nodeObject.update(); var _surf = outputJunction.getValue(); @@ -126,6 +156,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { } else maskedSurface = _surf; + draw_surface_ext_safe(destiSurface, _dx, _dy, _s, _s); draw_surface_ext_safe(maskedSurface, _dx, _dy, _s, _s); if(mouse_press(mb_left, active)) { apply(); MOUSE_BLOCK = true; } diff --git a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 index a28f04ae5..b03cbccf0 100644 --- a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 +++ b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:22:33 +// 2024-04-16 15:02:19 function canvas_tool_node(canvas, node) : canvas_tool() constructor { self.canvas = canvas; @@ -28,8 +28,15 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { if(applySelection) canvas.tool_selection.apply(); canvas.nodeTool = noone; - surface_free(targetSurface); - surface_free(maskedSurface); + surface_free_safe(maskedSurface); + + cleanUp(); + } + + static cleanUp = function() { + surface_free_safe(targetSurface); + surface_free_safe(maskedSurface); + nodeObject.destroy(); } nodeObject = node.build(0, 0); @@ -66,21 +73,41 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { //////////////////////////////////////////////////////////////////////////////////////////////////////// function apply() { + var _surf = surface_create(sw, sh); if(applySelection) { + + surface_set_shader(_surf, sh_blend_normal); + shader_set_surface("fore", maskedSurface); + shader_set_f("dimension", 1, 1); + shader_set_f("opacity", 1); + + draw_surface(canvas.tool_selection.selection_surface, 0, 0); + surface_reset_shader(); + surface_free(canvas.tool_selection.selection_surface); - canvas.tool_selection.selection_surface = maskedSurface; + canvas.tool_selection.selection_surface = _surf; canvas.tool_selection.apply(); } else { canvas.storeAction(); - canvas.setCanvasSurface(maskedSurface); + + surface_set_shader(_surf, sh_blend_normal); + shader_set_surface("fore", maskedSurface); + shader_set_f("dimension", 1, 1); + shader_set_f("opacity", 1); + + draw_surface(canvas.getCanvasSurface(), 0, 0); + surface_reset_shader(); + + canvas.setCanvasSurface(_surf); canvas.surface_store_buffer(); } PANEL_PREVIEW.tool_current = noone; canvas.nodeTool = noone; - surface_free_safe(targetSurface); + + cleanUp(); } function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { @@ -110,7 +137,10 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { else if(inputJunction.name == "Dimension") inputJunction.setValue([ sw, sh ]); } - nodeObject.update(); + if(is_instanceof(nodeObject, Node_Collection)) + RenderList(nodeObject.nodes); + else + nodeObject.update(); var _surf = outputJunction.getValue(); @@ -126,6 +156,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { } else maskedSurface = _surf; + draw_surface_ext_safe(destiSurface, _dx, _dy, _s, _s); draw_surface_ext_safe(maskedSurface, _dx, _dy, _s, _s); if(mouse_press(mb_left, active)) { apply(); MOUSE_BLOCK = true; } diff --git a/#backups/scripts/canvas_tool_outline_select/canvas_tool_outline_select.gml.backup0 b/#backups/scripts/canvas_tool_outline_select/canvas_tool_outline_select.gml.backup0 new file mode 100644 index 000000000..2e95177a4 --- /dev/null +++ b/#backups/scripts/canvas_tool_outline_select/canvas_tool_outline_select.gml.backup0 @@ -0,0 +1,9 @@ +// 2024-04-16 09:50:49 +function canvas_tool_outline_select() : canvas_tool() constructor { + override = true; + + function init(node) { + PANEL_PREVIEW.tool_current = node.tools[1]; + node.selection_tool_after = new canvas_tool_outline(); + } +} \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_outline_select/canvas_tool_outline_select.gml.backup1 b/#backups/scripts/canvas_tool_outline_select/canvas_tool_outline_select.gml.backup1 new file mode 100644 index 000000000..8648b5a64 --- /dev/null +++ b/#backups/scripts/canvas_tool_outline_select/canvas_tool_outline_select.gml.backup1 @@ -0,0 +1,9 @@ +// 2024-04-16 09:50:30 +function canvas_tool_outline_select() : canvas_tool() constructor { + override = true; + + function init(node) { + PANEL_PREVIEW.tool_current = node.tools[1]; + node.selection_tool_after = new canvas_tool_outline(); + } +} \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup0 b/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup0 index ad87c7285..a9e0f3e20 100644 --- a/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup0 +++ b/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:48:56 +// 2024-04-14 17:59:42 function canvas_tool_resize() : canvas_tool() constructor { override = true; diff --git a/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup1 b/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup1 index 1e79e17a8..ad87c7285 100644 --- a/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup1 +++ b/#backups/scripts/canvas_tool_resize/canvas_tool_resize.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:31:10 +// 2024-04-14 12:48:56 function canvas_tool_resize() : canvas_tool() constructor { override = true; diff --git a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 index 5a6e70da0..b843559b4 100644 --- a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 +++ b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:51:12 +// 2024-04-15 19:18:42 function canvas_tool_selection(selector = noone) : canvas_tool() constructor { self.selector = selector; @@ -23,9 +23,14 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { mouse_pre_y = 0; function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region + if(is_selected) apply(); - + else { + createNewSelection(_mask, sel_x0, sel_y0, sel_w, sel_h); + return; + } + if(key_mod_press(SHIFT)) modifySelection(_mask, sel_x0, sel_y0, sel_w, sel_h, true); diff --git a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 index ee32f0512..6245b0570 100644 --- a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 +++ b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:51:08 +// 2024-04-15 19:18:37 function canvas_tool_selection(selector = noone) : canvas_tool() constructor { self.selector = selector; @@ -23,9 +23,14 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { mouse_pre_y = 0; function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region + if(is_selected) apply(); - + else { + createNewSelection(_mask, sel_x0, sel_y0, sel_w, sel_h); + return; + } + if(key_mod_press(SHIFT)) modifySelection(_mask, sel_x0, sel_y0, sel_w, sel_h, true); diff --git a/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup0 b/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup0 index dd235abfe..7693d52e2 100644 --- a/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup0 +++ b/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:49:02 +// 2024-04-16 09:27:06 function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(selector) constructor { self.brush = brush; @@ -63,10 +63,10 @@ function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(se sel_x1 = max(sel_x1, mouse_cur_x + brush.brush_size); sel_y1 = max(sel_y1, mouse_cur_y + brush.brush_size); - if(mouse_release(mb_left)) { - var _sel_w = sel_x1 - sel_x0; - var _sel_h = sel_y1 - sel_y0; + var _sel_w = sel_x1 - sel_x0; + var _sel_h = sel_y1 - sel_y0; + if(mouse_release(mb_left)) { var _sel = surface_create(_sel_w, _sel_h); surface_set_shader(_sel); draw_surface(selection_mask, -sel_x0, -sel_y0); diff --git a/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup1 b/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup1 index 8b6b98230..34679bc57 100644 --- a/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup1 +++ b/#backups/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:16:19 +// 2024-04-16 07:47:35 function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(selector) constructor { self.brush = brush; @@ -63,10 +63,12 @@ function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(se sel_x1 = max(sel_x1, mouse_cur_x + brush.brush_size); sel_y1 = max(sel_y1, mouse_cur_y + brush.brush_size); - if(mouse_release(mb_left)) { - var _sel_w = sel_x1 - sel_x0; - var _sel_h = sel_y1 - sel_y0; + var _sel_w = sel_x1 - sel_x0; + var _sel_h = sel_y1 - sel_y0; + + PANEL_PREVIEW.mouse_pos_string = $"[{_sel_w}, {_sel_h}]"; + if(mouse_release(mb_left)) { var _sel = surface_create(_sel_w, _sel_h); surface_set_shader(_sel); draw_surface(selection_mask, -sel_x0, -sel_y0); diff --git a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 index e61bca41c..a99435b94 100644 --- a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 +++ b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:49:17 +// 2024-04-16 10:03:25 function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor { self.tool_attribute = toolAttr; @@ -54,6 +54,10 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h); surface_free_safe(selection_mask); + + if(node.selection_tool_after != noone) + node.selection_tool_after.toggle(); + node.selection_tool_after = noone; } } } diff --git a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 index 8e389e2da..91cb9ae24 100644 --- a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 +++ b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:16:16 +// 2024-04-16 10:03:18 function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor { self.tool_attribute = toolAttr; @@ -54,6 +54,10 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h); surface_free_safe(selection_mask); + + if(node.selection_tool_after != noone) + node.selection_tool_after.toggle(); + node.selection_tool_after = noone; } } } diff --git a/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup0 b/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup0 index 988168534..8852e7f70 100644 --- a/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup0 +++ b/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:49:25 +// 2024-04-16 09:29:46 function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(selector) constructor { self.shape = shape; @@ -36,7 +36,9 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se } surface_reset_target(); - + + PANEL_PREVIEW.mouse_pos_string = $"[{sel_w}, {sel_h}]"; + if(mouse_release(mb_left)) { is_selecting = false; selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h); diff --git a/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup1 b/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup1 index 5508bfa36..43a39c615 100644 --- a/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup1 +++ b/#backups/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:45:07 +// 2024-04-16 09:29:45 function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(selector) constructor { self.shape = shape; @@ -36,7 +36,9 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se } surface_reset_target(); - + + PANEL_PREVIEW.mouse_pos_string = $"[{sel_w}, {sel_h}]"; + if(mouse_release(mb_left)) { is_selecting = false; selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h); @@ -52,4 +54,7 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se } } + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y); + } } \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml.backup0 b/#backups/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml.backup0 new file mode 100644 index 000000000..d8008c7c7 --- /dev/null +++ b/#backups/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml.backup0 @@ -0,0 +1,10 @@ +// 2024-04-16 10:54:27 +function canvas_tool_with_selector(tool) : canvas_tool() constructor { + self.tool = tool; + + function init(node) { + node.selection_tool_after = tool; + } + + function getTool() { return node.tool_sel_magic; } +} \ No newline at end of file diff --git a/#backups/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml.backup1 b/#backups/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml.backup1 new file mode 100644 index 000000000..cac75fbbd --- /dev/null +++ b/#backups/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml.backup1 @@ -0,0 +1,10 @@ +// 2024-04-16 10:54:26 +function canvas_tool_with_selector(tool) : canvas_tool() constructor { + self.tool = tool; + + function init(node) { + node.selection_tool_after = tool; + } + + function getTool() { return node.tool_sel_magic; } +} \ No newline at end of file diff --git a/#backups/scripts/curve_bezier_function/curve_bezier_function.gml.backup0 b/#backups/scripts/curve_bezier_function/curve_bezier_function.gml.backup0 new file mode 100644 index 000000000..bb9bd4d38 --- /dev/null +++ b/#backups/scripts/curve_bezier_function/curve_bezier_function.gml.backup0 @@ -0,0 +1,223 @@ +// 2024-04-15 17:50:18 +//curve format [-cx0, -cy0, x0, y0, +cx0, +cy0, -cx1, -cy1, x1, y1, +cx1, +cy1] +//segment format [y0, +cx0, +cy0, -cx1, -cy1, y1] + +#macro CURVE_DEF_00 [0, 0, 0, 0, 1/3, 0, /**/ -1/3, 0, 1, 0, 0, 0] +#macro CURVE_DEF_01 [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0] +#macro CURVE_DEF_10 [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0] +#macro CURVE_DEF_11 [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0] + +function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { #region + var segments = array_length(_bz) / 6 - 1; + + for( var i = 0; i < segments; i++ ) { + var ind = i * 6; + var _x0 = _bz[ind + 2]; + var _y0 = _bz[ind + 3]; + //var bx0 = _x0 + _bz[ind + 0]; + //var by0 = _y0 + _bz[ind + 1]; + var ax0 = _x0 + _bz[ind + 4]; + var ay0 = _y0 + _bz[ind + 5]; + + var _x1 = _bz[ind + 6 + 2]; + var _y1 = _bz[ind + 6 + 3]; + var bx1 = _x1 + _bz[ind + 6 + 0]; + var by1 = _y1 + _bz[ind + 6 + 1]; + //var ax1 = _x1 + _bz[ind + 6 + 4]; + //var ay1 = _y1 + _bz[ind + 6 + 5]; + + var dx0 = x0 + _w * _x0; + var dx1 = x0 + _w * _x1; + var dw = dx1 - dx0; + var smp = ceil((_x1 - _x0) * 32); + + draw_curve_segment(dx0, y0, dw, _h, [_y0, ax0, ay0, bx1, by1, _y1], smp, miny, maxy); + } +} #endregion + +function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1) { #region + var _ox, _oy; + + for(var i = 0; i <= SAMPLE; i++) { + var t = i / SAMPLE; + var _r = eval_curve_segment_t_position(t, _bz); + var _rx = _r[0], _ry = _r[1]; + _ry = (_ry - miny) / (maxy - miny); + + var _nx = _rx * _w + x0; + var _ny = (_h? _ry : 1 - _ry) * abs(_h) + y0; + + if(i) + draw_line(_ox, _oy, _nx, _ny); + + _ox = _nx; + _oy = _ny; + } +} #endregion + +function eval_curve_segment_t_position(t, _bz) { #region + return [ + power(1 - t, 3) * 0 + + 3 * power(1 - t, 2) * t * _bz[1] + + 3 * (1 - t) * power(t, 2) * _bz[3] + + power(t, 3) * 1, + + power(1 - t, 3) * _bz[0] + + 3 * power(1 - t, 2) * t * _bz[2] + + 3 * (1 - t) * power(t, 2) * _bz[4] + + power(t, 3) * _bz[5] + ]; +} #endregion + +function eval_curve_segment_t(_bz, t) { #region + return power(1 - t, 3) * _bz[0] + + 3 * power(1 - t, 2) * t * _bz[2] + + 3 * (1 - t) * power(t, 2) * _bz[4] + + power(t, 3) * _bz[5]; +} #endregion + +function eval_curve_x(_bz, _x, _tolr = 0.00001) { #region + static _CURVE_DEF_01 = [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0]; + static _CURVE_DEF_10 = [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0]; + static _CURVE_DEF_11 = [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0]; + + if(array_equals(_bz, _CURVE_DEF_11)) return 1; + if(array_equals(_bz, _CURVE_DEF_01)) return _x; + if(array_equals(_bz, _CURVE_DEF_10)) return 1 - _x; + + var segments = array_length(_bz) / 6 - 1; + _x = clamp(_x, 0, 1); + + for( var i = 0; i < segments; i++ ) { + var ind = i * 6; + var _x0 = _bz[ind + 2]; + var _y0 = _bz[ind + 3]; + //var bx0 = _x0 + _bz[ind + 0]; + //var by0 = _y0 + _bz[ind + 1]; + var ax0 = _x0 + _bz[ind + 4]; + var ay0 = _y0 + _bz[ind + 5]; + + var _x1 = _bz[ind + 6 + 2]; + var _y1 = _bz[ind + 6 + 3]; + var bx1 = _x1 + _bz[ind + 6 + 0]; + var by1 = _y1 + _bz[ind + 6 + 1]; + //var ax1 = _x1 + _bz[ind + 6 + 4]; + //var ay1 = _y1 + _bz[ind + 6 + 5]; + + if(_x < _x0) continue; + if(_x > _x1) continue; + + return eval_curve_segment_x([_y0, ax0, ay0, bx1, by1, _y1], (_x - _x0) / (_x1 - _x0), _tolr); + } + + return array_safe_get_fast(_bz, array_length(_bz) - 3); +} #endregion + +function eval_curve_segment_x(_bz, _x, _tolr = 0.00001) { #region + var st = 0; + var ed = 1; + + var _xt = _x; + var _binRep = 8; + + if(_x <= 0) return _bz[0]; + if(_x >= 1) return _bz[5]; + if(_bz[0] == _bz[2] && _bz[0] == _bz[4] && _bz[0] == _bz[5]) return _bz[0]; + + repeat(_binRep) { + var _1xt = 1 - _xt; + + var _ftx = 3 * _1xt * _1xt * _xt * _bz[1] + + 3 * _1xt * _xt * _xt * _bz[3] + + _xt * _xt * _xt; + + if(abs(_ftx - _x) < _tolr) + return eval_curve_segment_t(_bz, _xt); + + if(_xt < _x) st = _xt; + else ed = _xt; + + _xt = (st + ed) / 2; + } + + var _newRep = 8; + + repeat(_newRep) { + var _bz1 = _bz[1]; + var _bz3 = _bz[3]; + + var slope = ( 9 * _bz1 - 9 * _bz3 + 3) * _xt * _xt + + (-12 * _bz1 + 6 * _bz3) * _xt + + 3 * _bz1; + + var _1xt = 1 - _xt; + + var _ftx = 3 * _1xt * _1xt * _xt * _bz1 + + 3 * _1xt * _xt * _xt * _bz3 + + _xt * _xt * _xt + - _x; + + _xt -= _ftx / slope; + + if(abs(_ftx) < _tolr) + break; + } + + _xt = clamp(_xt, 0, 1); + return eval_curve_segment_t(_bz, _xt); +} #endregion + +function bezier_range(bz) { return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ]; } + +function ease_cubic_in(rat) { return power(rat, 3); } +function ease_cubic_out(rat) { return 1 - power(1 - rat, 3); } +function ease_cubic_inout(rat) { return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2; } + +function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor { + bz = _bz; + prec = _prec; + size = 1 / _prec; + tolr = _tolr; + + map = array_create(_prec); + for( var i = 0; i < _prec; i++ ) + map[i] = eval_curve_x(bz, i * size, tolr); + + static get = function(i) { #region + INLINE + + var _ind = clamp(i, 0, 1) * (prec - 1); + var _indL = floor(_ind); + var _indH = ceil(_ind); + var _indF = frac(_ind); + + if(_indL == _indH) return map[_ind]; + return lerp(map[_indL], map[_indH], _indF); + } #endregion +} + +function draw_curve_bezier(x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region + var ox, oy, nx, ny; + + var _st = 1 / prec; + + for (var i = 0; i <= prec; i++) { + var _t = _st * i; + var _t1 = 1 - _t; + + nx = _t1 * _t1 * _t1 * x0 + + 3 * (_t1 * _t1 * _t) * cx0 + + 3 * (_t1 * _t * _t) * cx1 + + _t * _t * _t * x1; + + ny = _t1 * _t1 * _t1 * y0 + + 3 * (_t1 * _t1 * _t) * cy0 + + 3 * (_t1 * _t * _t) * cy1 + + _t * _t * _t * y1; + + if(i) draw_line(ox, oy, nx, ny); + + ox = nx; + oy = ny; + } +} #endregion \ No newline at end of file diff --git a/#backups/scripts/curve_bezier_function/curve_bezier_function.gml.backup1 b/#backups/scripts/curve_bezier_function/curve_bezier_function.gml.backup1 new file mode 100644 index 000000000..b5e0e9557 --- /dev/null +++ b/#backups/scripts/curve_bezier_function/curve_bezier_function.gml.backup1 @@ -0,0 +1,223 @@ +// 2024-04-15 17:50:17 +//curve format [-cx0, -cy0, x0, y0, +cx0, +cy0, -cx1, -cy1, x1, y1, +cx1, +cy1] +//segment format [y0, +cx0, +cy0, -cx1, -cy1, y1] + +#macro CURVE_DEF_00 [0, 0, 0, 0, 1/3, 0, /**/ -1/3, 0, 1, 0, 0, 0] +#macro CURVE_DEF_01 [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0] +#macro CURVE_DEF_10 [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0] +#macro CURVE_DEF_11 [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0] + +function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { #region + var segments = array_length(_bz) / 6 - 1; + + for( var i = 0; i < segments; i++ ) { + var ind = i * 6; + var _x0 = _bz[ind + 2]; + var _y0 = _bz[ind + 3]; + //var bx0 = _x0 + _bz[ind + 0]; + //var by0 = _y0 + _bz[ind + 1]; + var ax0 = _x0 + _bz[ind + 4]; + var ay0 = _y0 + _bz[ind + 5]; + + var _x1 = _bz[ind + 6 + 2]; + var _y1 = _bz[ind + 6 + 3]; + var bx1 = _x1 + _bz[ind + 6 + 0]; + var by1 = _y1 + _bz[ind + 6 + 1]; + //var ax1 = _x1 + _bz[ind + 6 + 4]; + //var ay1 = _y1 + _bz[ind + 6 + 5]; + + var dx0 = x0 + _w * _x0; + var dx1 = x0 + _w * _x1; + var dw = dx1 - dx0; + var smp = ceil((_x1 - _x0) * 32); + + draw_curve_segment(dx0, y0, dw, _h, [_y0, ax0, ay0, bx1, by1, _y1], smp, miny, maxy); + } +} #endregion + +function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1) { #region + var _ox, _oy; + + for(var i = 0; i <= SAMPLE; i++) { + var t = i / SAMPLE; + var _r = eval_curve_segment_t_position(t, _bz); + var _rx = _r[0], _ry = _r[1]; + _ry = (_ry - miny) / (maxy - miny); + + var _nx = _rx * _w + x0; + var _ny = (_h? _ry : 1 - _ry) * abs(_h) + y0; + + if(i) + draw_line(_ox, _oy, _nx, _ny); + + _ox = _nx; + _oy = _ny; + } +} #endregion + +function eval_curve_segment_t_position(t, _bz) { #region + return [ + power(1 - t, 3) * 0 + + 3 * power(1 - t, 2) * t * _bz[1] + + 3 * (1 - t) * power(t, 2) * _bz[3] + + power(t, 3) * 1, + + power(1 - t, 3) * _bz[0] + + 3 * power(1 - t, 2) * t * _bz[2] + + 3 * (1 - t) * power(t, 2) * _bz[4] + + power(t, 3) * _bz[5] + ]; +} #endregion + +function eval_curve_segment_t(_bz, t) { #region + return power(1 - t, 3) * _bz[0] + + 3 * power(1 - t, 2) * t * _bz[2] + + 3 * (1 - t) * power(t, 2) * _bz[4] + + power(t, 3) * _bz[5]; +} #endregion + +function eval_curve_x(_bz, _x, _tolr = 0.00001) { #region + static _CURVE_DEF_01 = [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0]; + static _CURVE_DEF_10 = [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0]; + static _CURVE_DEF_11 = [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0]; + + if(array_equals(_bz, _CURVE_DEF_11)) return 1; + if(array_equals(_bz, _CURVE_DEF_01)) return _x; + if(array_equals(_bz, _CURVE_DEF_10)) return 1 - _x; + + var segments = array_length(_bz) / 6 - 1; + _x = clamp(_x, 0, 1); + + for( var i = 0; i < segments; i++ ) { + var ind = i * 6; + var _x0 = _bz[ind + 2]; + var _y0 = _bz[ind + 3]; + //var bx0 = _x0 + _bz[ind + 0]; + //var by0 = _y0 + _bz[ind + 1]; + var ax0 = _x0 + _bz[ind + 4]; + var ay0 = _y0 + _bz[ind + 5]; + + var _x1 = _bz[ind + 6 + 2]; + var _y1 = _bz[ind + 6 + 3]; + var bx1 = _x1 + _bz[ind + 6 + 0]; + var by1 = _y1 + _bz[ind + 6 + 1]; + //var ax1 = _x1 + _bz[ind + 6 + 4]; + //var ay1 = _y1 + _bz[ind + 6 + 5]; + + if(_x < _x0) continue; + if(_x > _x1) continue; + + return eval_curve_segment_x([_y0, ax0, ay0, bx1, by1, _y1], (_x - _x0) / (_x1 - _x0), _tolr); + } + + return array_safe_get_fast(_bz, array_length(_bz) - 3); +} #endregion + +function eval_curve_segment_x(_bz, _x, _tolr = 0.00001) { #region + var st = 0; + var ed = 1; + + var _xt = _x; + var _binRep = 8; + + if(_x <= 0) return _bz[0]; + if(_x >= 1) return _bz[5]; + if(_bz[0] == _bz[2] && _bz[0] == _bz[4] && _bz[0] == _bz[5]) return _bz[0]; + + repeat(_binRep) { + var _1xt = 1 - _xt; + + var _ftx = 3 * _1xt * _1xt * _xt * _bz[1] + + 3 * _1xt * _xt * _xt * _bz[3] + + _xt * _xt * _xt; + + if(abs(_ftx - _x) < _tolr) + return eval_curve_segment_t(_bz, _xt); + + if(_xt < _x) st = _xt; + else ed = _xt; + + _xt = (st + ed) / 2; + } + + var _newRep = 8; + + repeat(_newRep) { + var _bz1 = _bz[1]; + var _bz3 = _bz[3]; + + var slope = ( 9 * _bz1 - 9 * _bz3 + 3) * _xt * _xt + + (-12 * _bz1 + 6 * _bz3) * _xt + + 3 * _bz1; + + var _1xt = 1 - _xt; + + var _ftx = 3 * _1xt * _1xt * _xt * _bz1 + + 3 * _1xt * _xt * _xt * _bz3 + + _xt * _xt * _xt + - _x; + + _xt -= _ftx / slope; + + if(abs(_ftx) < _tolr) + break; + } + + _xt = clamp(_xt, 0, 1); + return eval_curve_segment_t(_bz, _xt); +} #endregion + +function bezier_range(bz) { return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ]; } + +function ease_cubic_in(rat) { return power(rat, 3); } +function ease_cubic_out(rat) { return 1 - power(1 - rat, 3); } +function ease_cubic_inout(rat) { return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2; } + +function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor { + bz = _bz; + prec = _prec; + size = 1 / _prec; + tolr = _tolr; + + map = array_create(_prec); + for( var i = 0; i < _prec; i++ ) + map[i] = eval_curve_x(bz, i * size, tolr); + + static get = function(i) { #region + INLINE + + var _ind = clamp(i, 0, 1) * (prec - 1); + var _indL = floor(_ind); + var _indH = ceil(_ind); + var _indF = frac(_ind); + + if(_indL == _indH) return map[_ind]; + return lerp(map[_indL], map[_indH], _indF); + } #endregion +} + +function draw_curve_bezier(x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region + var ox, oy, nx, ny; + + var _st = 1 / prec; + + for (var i = 0; i <= prec; i++) { + var _t = _st * i; + var _t1 = 1 - _t; + + nx = _t1 * _t1 * _t1 * x0 + + 3 * (_t1 * _t1 * _t) * cx0 + + 3 * (_t1 * _t * _t) * cx1 + + _t * _t * _t * x1; + + ny = _t1 * _t1 * _t1 * y0 + + 3 * (_t1 * _t1 * _t) * cy0 + + 3 * (_t1 * _t * _t) * cy1 + + _t * _t * _t * y1; + + if(i) draw_line(ox, oy, nx, ny); + + ox = nx; + oy = ny; + } +} #endregion \ No newline at end of file diff --git a/#backups/scripts/draw_surface_blend/draw_surface_blend.gml.backup0 b/#backups/scripts/draw_surface_blend/draw_surface_blend.gml.backup0 new file mode 100644 index 000000000..f80b2006b --- /dev/null +++ b/#backups/scripts/draw_surface_blend/draw_surface_blend.gml.backup0 @@ -0,0 +1,60 @@ +// 2024-04-16 14:58:31 +globalvar BLEND_TYPES; +BLEND_TYPES = [ + "Normal", "Add", "Subtract", "Multiply", "Screen", + "Overlay", "Hue", "Saturation", "Luminosity", "Maximum", + "Minimum", "Replace", "Difference" +]; + +function draw_surface_blend(background, foreground, blend = 0, alpha = 1, _pre_alp = true, _mask = 0, tile = 0) { + if(!is_surface(background)) return; + + var sh = sh_blend_normal + switch(array_safe_get_fast(BLEND_TYPES, blend)) { + case "Normal" : sh = sh_blend_normal break; + case "Add" : sh = sh_blend_add; break; + case "Subtract" : sh = sh_blend_subtract; break; + case "Multiply" : sh = sh_blend_multiply; break; + case "Screen" : sh = sh_blend_screen; break; + + case "Overlay" : sh = sh_blend_overlay; break; + case "Hue" : sh = sh_blend_hue; break; + case "Saturation" : sh = sh_blend_sat; break; + case "Luminosity" : sh = sh_blend_luma; break; + case "Maximum" : sh = sh_blend_max; break; + + case "Minimum" : sh = sh_blend_min; break; + case "Replace" : sh = sh_blend_replace; break; + case "Difference" : sh = sh_blend_difference; break; + default: return; + } + + var surf = surface_get_target(); + var surf_w = surface_get_width_safe(surf); + var surf_h = surface_get_height_safe(surf); + + if(is_surface(foreground)) { + shader_set(sh); + shader_set_surface("fore", foreground); + shader_set_surface("mask", _mask); + shader_set_i("useMask", is_surface(_mask)); + shader_set_f("dimension", surface_get_width_safe(background) / surface_get_width_safe(foreground), surface_get_height_safe(background) / surface_get_height_safe(foreground)); + shader_set_f("opacity", alpha); + shader_set_i("preserveAlpha", _pre_alp); + shader_set_i("tile_type", tile); + } + + BLEND_OVERRIDE + draw_surface_stretched_safe(background, 0, 0, surf_w, surf_h); + BLEND_NORMAL + shader_reset(); +} + +function draw_surface_blend_ext(bg, fg, _x, _y, _sx = 1, _sy = 1, _rot = 0, _col = c_white, _alpha = 1, _blend = 0, _pre_alp = false) { + surface_set_shader(blend_temp_surface); + shader_set_interpolation(fg); + draw_surface_ext_safe(fg, _x, _y, _sx, _sy, _rot, _col, 1); + surface_reset_shader(); + + draw_surface_blend(bg, blend_temp_surface, _blend, _alpha, _pre_alp); +} \ No newline at end of file diff --git a/#backups/scripts/globals/globals.gml.backup0 b/#backups/scripts/globals/globals.gml.backup0 index f86f7c868..21ea44562 100644 --- a/#backups/scripts/globals/globals.gml.backup0 +++ b/#backups/scripts/globals/globals.gml.backup0 @@ -1,122 +1,56 @@ -// 2023-08-07 09:56:48 +// 2024-04-16 08:32:52 #region save - globalvar LOADING, APPENDING, CLONING, SAFE_MODE; - globalvar CONNECTION_CONFLICT, ALWAYS_FULL; + globalvar LOADING, CLONING, CLONING_GROUP; + globalvar CONNECTION_CONFLICT, LOADING_VERSION; + globalvar MESSAGE; - LOADING = false; - CLONING = false; - APPENDING = false; - SAFE_MODE = false; + globalvar APPENDING, APPEND_MAP, APPEND_LIST; + APPEND_MAP = ds_map_create(); + APPEND_LIST = ds_list_create(); + + LOADING = false; + LOADING_VERSION = 0; + CLONING_GROUP = noone; + CLONING = false; + APPENDING = false; + MESSAGE = noone; CONNECTION_CONFLICT = ds_queue_create(); randomize(); - ALWAYS_FULL = false; #endregion -#region project - function Project() constructor { - active = true; /// @is {bool} - - path = ""; /// @is {string} - version = SAVE_VERSION; /// @is {number} - seed = irandom_range(100000, 999999); /// @is {number} - - modified = false; /// @is {bool} - readonly = false; /// @is {bool} - - nodes = ds_list_create(); - nodeMap = ds_map_create(); - nodeNameMap = ds_map_create(); - - animator = new AnimationManager(); - - globalNode = new Node_Global(); - - previewGrid = { - show : false, - snap : false, - width : 16, - height : 16, - opacity : 0.5, - color : COLORS.panel_preview_grid, - } - - graphGrid = { - show : true, - snap : true, - size : 32, - opacity : 0.05, - color : c_white, - } - - addons = {}; - - onion_skin = { - enabled: false, - range: [ -1, 1 ], - step: 1, - color: [ c_red, c_blue ], - alpha: 0.5, - on_top: true, - }; - - attributes = { - surface_dimension: [ 32, 32 ], - palette: [ c_black, c_white ] - } - - attributeEditor = [ - [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; }) ], - [ "Palette", "palette", new buttonPalette(function(pal) { attributes.palette = pal; }) ], - ] - - static cleanup = function() { - if(!ds_map_empty(nodeMap)) - array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { nodeMap[? _key].active = false; }); - - ds_list_destroy(nodes); - ds_map_destroy(nodeMap); - ds_map_destroy(nodeNameMap); - } - } - - globalvar PROJECTS; /// @is {Project[]} - globalvar PROJECT; /// @is {Project} - - gml_pragma("global", "__init()"); - function __init() { - PROJECT = new Project(); - PROJECTS = [ PROJECT ]; - } -#endregion - -#region main +#region ======================================================================= MAIN ======================================================================= globalvar OS, DEBUG, THEME, COLOR_KEYS; - OS = os_type; - //OS = os_macosx; + globalvar CMD, CMDIN; + globalvar FPS_REAL; + + OS = os_type; + CMD = []; + CMDIN = []; + FPS_REAL = 0; DEBUG = false; THEME = new Theme(); COLOR_KEYS = []; - globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER; - - VERSION = 11484; - SAVE_VERSION = 11482; - VERSION_STRING = "1.15rc4"; - BUILD_NUMBER = 11484; - - globalvar APPEND_MAP; - APPEND_MAP = ds_map_create(); + globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION; + + LATEST_VERSION = 11600; + VERSION = 11700; + SAVE_VERSION = 11690; + VERSION_STRING = "1.17.rc1"; + BUILD_NUMBER = 11700; globalvar HOTKEYS, HOTKEY_CONTEXT; HOTKEYS = ds_map_create(); HOTKEY_CONTEXT = ds_list_create(); HOTKEY_CONTEXT[| 0] = ""; - globalvar CURSOR, TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER; - globalvar UPDATE, RENDER_QUEUE; + globalvar TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER; + global.KEYS = { + download_links: "", + }; #endregion #region inputs @@ -126,37 +60,48 @@ DOUBLE_CLICK_POS = [ 0, 0 ]; DOUBLE_CLICK = false; - FOCUS = noone; + + FOCUS = noone; FOCUS_STR = ""; - HOVER = noone; + + HOVER = noone; HOVERING_ELEMENT = noone; _HOVERING_ELEMENT = noone; + DIALOG_CLICK = true; - globalvar ADD_NODE_PAGE; - ADD_NODE_PAGE = 0; + globalvar ADD_NODE_PAGE, ADD_NODE_SCROLL; + + ADD_NODE_PAGE = 0; + ADD_NODE_SCROLL = 0; #endregion #region macro + #macro TEMPDIR filepath_resolve(PREFERENCES.temp_path) + + #macro NOT_LOAD !LOADING && !APPENDING + #macro WIN_W window_get_width() #macro WIN_H window_get_height() #macro WIN_SW window_get_width() #macro WIN_SH window_get_height() - #macro UI_SCALE PREF_MAP[? "display_scaling"] + #macro UI_SCALE PREFERENCES.display_scaling - #macro mouse_mx device_mouse_x_to_gui(0) - #macro mouse_my device_mouse_y_to_gui(0) + #macro mouse_mx (PEN_USE? PEN_X : device_mouse_x_to_gui(0)) + #macro mouse_my (PEN_USE? PEN_Y : device_mouse_y_to_gui(0)) #macro mouse_raw_x (device_mouse_raw_x(0) + window_get_x()) #macro mouse_raw_y (device_mouse_raw_y(0) + window_get_y()) #macro mouse_ui [device_mouse_x_to_gui(0), device_mouse_y_to_gui(0)] - #macro sFOCUS FOCUS == self.id - #macro sHOVER HOVER == self.id + #macro sFOCUS (FOCUS == self.id) + #macro sHOVER (!CURSOR_IS_LOCK && HOVER == self.id) #macro DELTA_TIME delta_time / 1_000_000 + #macro INLINE gml_pragma("forceinline"); + #macro CONF_TESTING false globalvar TESTING, TEST_ERROR; TESTING = CONF_TESTING; @@ -165,10 +110,6 @@ #macro DEMO false #macro ItchDemo:DEMO true #macro SteamDemo:DEMO true - #macro MacAlpha:DEMO true - - #macro ALPHA false - #macro MacAlpha:ALPHA true #region color #macro c_ui_blue_dkblack $251919 @@ -202,22 +143,20 @@ #macro PANEL_PAD THEME_VALUE.panel_padding function print(str) { - //show_debug_message(string(str)); + INLINE noti_status(string(str)); } function printIf(cond, log) { - if(!cond) return; - show_debug_message(log); + INLINE + if(cond) print(log); } #endregion #region presets function INIT_FOLDERS() { - if(!directory_exists(DIRECTORY + "Palettes")) - directory_create(DIRECTORY + "Palettes"); - if(!directory_exists(DIRECTORY + "Gradients")) - directory_create(DIRECTORY + "Gradients"); + directory_verify(DIRECTORY + "Palettes"); + directory_verify(DIRECTORY + "Gradients"); } #endregion @@ -237,10 +176,33 @@ DEF_SURFACE_RESET(); #endregion -#region PATCH - #macro PATCH_STATIC static _doUpdate = function() { doUpdate() }; +#region functions + function __fnInit_Global() { + __registerFunction("fullscreen", global_fullscreen); + __registerFunction("render_all", global_render_all); + __registerFunction("project_close", global_project_close); + + __registerFunction("theme_reload", global_theme_reload); + } + + function global_fullscreen() { CALL("fullscreen"); winMan_setFullscreen(!window_is_fullscreen); } + function global_render_all() { CALL("render_all"); RENDER_ALL_REORDER } + function global_project_close() { CALL("project_close"); PANEL_GRAPH.close(); } + + function global_theme_reload() { CALL("theme_reload"); loadGraphic(PREFERENCES.theme); resetPanel(); } + + function reset_global_getset() { + COLORS_GLOBAL_GET = noone; + COLORS_GLOBAL_SET = noone; + } #endregion #region debug global.FLAG = {}; + + global.FLAG.render = 0; + global.FLAG.renderTime = false; + global.FLAG.keyframe_override = true; + global.FLAG.wav_import = true; + global.FLAG.ase_import = false; #endregion \ No newline at end of file diff --git a/#backups/scripts/globals/globals.gml.backup1 b/#backups/scripts/globals/globals.gml.backup1 index 00dc65d8c..2b71aad65 100644 --- a/#backups/scripts/globals/globals.gml.backup1 +++ b/#backups/scripts/globals/globals.gml.backup1 @@ -1,122 +1,56 @@ -// 2023-08-07 09:55:37 +// 2024-04-15 17:50:18 #region save - globalvar LOADING, APPENDING, CLONING, SAFE_MODE; - globalvar CONNECTION_CONFLICT, ALWAYS_FULL; + globalvar LOADING, CLONING, CLONING_GROUP; + globalvar CONNECTION_CONFLICT, LOADING_VERSION; + globalvar MESSAGE; - LOADING = false; - CLONING = false; - APPENDING = false; - SAFE_MODE = false; + globalvar APPENDING, APPEND_MAP, APPEND_LIST; + APPEND_MAP = ds_map_create(); + APPEND_LIST = ds_list_create(); + + LOADING = false; + LOADING_VERSION = 0; + CLONING_GROUP = noone; + CLONING = false; + APPENDING = false; + MESSAGE = noone; CONNECTION_CONFLICT = ds_queue_create(); randomize(); - ALWAYS_FULL = false; #endregion -#region project - function Project() constructor { - active = true; /// @is {bool} - - path = ""; /// @is {string} - version = SAVE_VERSION; /// @is {number} - seed = irandom_range(100000, 999999); /// @is {number} - - modified = false; /// @is {bool} - readonly = false; /// @is {bool} - - nodes = ds_list_create(); - nodeMap = ds_map_create(); - nodeNameMap = ds_map_create(); - - animator = new AnimationManager(); - - globalNode = new Node_Global(); - - previewGrid = { - show : false, - snap : false, - width : 16, - height : 16, - opacity : 0.5, - color : COLORS.panel_preview_grid, - } - - graphGrid = { - show : true, - snap : true, - size : 32, - opacity : 0.05, - color : c_white, - } - - addons = {}; - - onion_skin = { - enabled: false, - range: [ -1, 1 ], - step: 1, - color: [ c_red, c_blue ], - alpha: 0.5, - on_top: true, - }; - - attributes = { - surface_dimension: [ 32, 32 ], - palette: [ c_black, c_white ] - } - - attributeEditor = [ - [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; }) ], - [ "Palette", "palette", new buttonPalette(function(pal) { attributes.palette = pal; }) ], - ] - - static cleanup = function() { - if(!ds_map_empty(nodeMap)) - array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { nodeMap[? _key].active = false; }); - - ds_list_destroy(nodes); - ds_map_destroy(nodeMap); - ds_map_destroy(nodeNameMap); - } - } - - globalvar PROJECTS; /// @is {Project[]} - globalvar PROJECT; /// @is {Project} - - gml_pragma("global", "__init()"); - function __init() { - PROJECT = new Project(); - PROJECTS = [ PROJECT ]; - } -#endregion - -#region main +#region ======================================================================= MAIN ======================================================================= globalvar OS, DEBUG, THEME, COLOR_KEYS; - OS = os_type; - //OS = os_macosx; + globalvar CMD, CMDIN; + globalvar FPS_REAL; + + OS = os_type; + CMD = []; + CMDIN = []; + FPS_REAL = 0; DEBUG = false; THEME = new Theme(); COLOR_KEYS = []; - globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER; - - VERSION = 11484; - SAVE_VERSION = 11482; - VERSION_STRING = "1.15rc4"; - BUILD_NUMBER = 11484; - - globalvar APPEND_MAP; - APPEND_MAP = ds_map_create(); + globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION; + + LATEST_VERSION = 11600; + VERSION = 11700; + SAVE_VERSION = 11690; + VERSION_STRING = "1.17.rc1"; + BUILD_NUMBER = 11700; globalvar HOTKEYS, HOTKEY_CONTEXT; HOTKEYS = ds_map_create(); HOTKEY_CONTEXT = ds_list_create(); HOTKEY_CONTEXT[| 0] = ""; - globalvar CURSOR, TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER; - globalvar UPDATE, RENDER_QUEUE; + globalvar TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER; + global.KEYS = { + download_links: "", + }; #endregion #region inputs @@ -126,37 +60,48 @@ DOUBLE_CLICK_POS = [ 0, 0 ]; DOUBLE_CLICK = false; - FOCUS = noone; + + FOCUS = noone; FOCUS_STR = ""; - HOVER = noone; + + HOVER = noone; HOVERING_ELEMENT = noone; _HOVERING_ELEMENT = noone; + DIALOG_CLICK = true; - globalvar ADD_NODE_PAGE; - ADD_NODE_PAGE = 0; + globalvar ADD_NODE_PAGE, ADD_NODE_SCROLL; + + ADD_NODE_PAGE = 0; + ADD_NODE_SCROLL = 0; #endregion #region macro + #macro TEMPDIR filepath_resolve(PREFERENCES.temp_path) + + #macro NOT_LOAD !LOADING && !APPENDING + #macro WIN_W window_get_width() #macro WIN_H window_get_height() #macro WIN_SW window_get_width() #macro WIN_SH window_get_height() - #macro UI_SCALE PREF_MAP[? "display_scaling"] + #macro UI_SCALE PREFERENCES.display_scaling - #macro mouse_mx device_mouse_x_to_gui(0) - #macro mouse_my device_mouse_y_to_gui(0) + #macro mouse_mx (PEN_USE? PEN_X : device_mouse_x_to_gui(0)) + #macro mouse_my (PEN_USE? PEN_Y : device_mouse_y_to_gui(0)) #macro mouse_raw_x (device_mouse_raw_x(0) + window_get_x()) #macro mouse_raw_y (device_mouse_raw_y(0) + window_get_y()) #macro mouse_ui [device_mouse_x_to_gui(0), device_mouse_y_to_gui(0)] - #macro sFOCUS FOCUS == self.id - #macro sHOVER HOVER == self.id + #macro sFOCUS (FOCUS == self.id) + #macro sHOVER (!CURSOR_IS_LOCK && HOVER == self.id) #macro DELTA_TIME delta_time / 1_000_000 + #macro INLINE gml_pragma("forceinline"); + #macro CONF_TESTING false globalvar TESTING, TEST_ERROR; TESTING = CONF_TESTING; @@ -165,10 +110,6 @@ #macro DEMO false #macro ItchDemo:DEMO true #macro SteamDemo:DEMO true - #macro MacAlpha:DEMO true - - #macro ALPHA false - #macro MacAlpha:ALPHA true #region color #macro c_ui_blue_dkblack $251919 @@ -202,22 +143,20 @@ #macro PANEL_PAD THEME_VALUE.panel_padding function print(str) { - //show_debug_message(string(str)); + INLINE noti_status(string(str)); } function printIf(cond, log) { - if(!cond) return; - show_debug_message(log); + INLINE + if(cond) print(log); } #endregion #region presets function INIT_FOLDERS() { - if(!directory_exists(DIRECTORY + "Palettes")) - directory_create(DIRECTORY + "Palettes"); - if(!directory_exists(DIRECTORY + "Gradients")) - directory_create(DIRECTORY + "Gradients"); + directory_verify(DIRECTORY + "Palettes"); + directory_verify(DIRECTORY + "Gradients"); } #endregion @@ -237,10 +176,33 @@ DEF_SURFACE_RESET(); #endregion -#region PATCH - #macro PATCH_STATIC static _doUpdate = function() { doUpdate() }; +#region functions + function __fnInit_Global() { + __registerFunction("fullscreen", global_fullscreen); + __registerFunction("render_all", global_render_all); + __registerFunction("project_close", global_project_close); + + __registerFunction("theme_reload", global_theme_reload); + } + + function global_fullscreen() { CALL("fullscreen"); winMan_setFullscreen(!window_is_fullscreen); } + function global_render_all() { CALL("render_all"); RENDER_ALL_REORDER } + function global_project_close() { CALL("project_close"); PANEL_GRAPH.close(); } + + function global_theme_reload() { CALL("theme_reload"); loadGraphic(PREFERENCES.theme); resetPanel(); } + + function reset_global_getset() { + COLORS_GLOBAL_GET = noone; + COLORS_GLOBAL_SET = noone; + } #endregion #region debug global.FLAG = {}; + + global.FLAG.render = 0; + global.FLAG.renderTime = false; + global.FLAG.keyframe_override = true; + global.FLAG.wav_import = true; + global.FLAG.ase_import = false; #endregion \ No newline at end of file diff --git a/#backups/scripts/node_canvas/node_canvas.gml.backup0 b/#backups/scripts/node_canvas/node_canvas.gml.backup0 index d5cc347c7..ec529ddd7 100644 --- a/#backups/scripts/node_canvas/node_canvas.gml.backup0 +++ b/#backups/scripts/node_canvas/node_canvas.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:59:25 +// 2024-04-16 14:17:00 function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Canvas"; color = COLORS.node_blend_canvas; @@ -54,7 +54,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor frame_renderer_x_max = 0; frame_renderer_content = surface_create(1, 1); - frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region + frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region frame_renderer var _h = 64; _y += 8; @@ -128,7 +128,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor _fr_x += _sw * _ss + 8; frame_renderer_x_max += _sw * _ss + 8; - } + } if(_del > noone) removeFrame(_del); surface_reset_shader(); @@ -183,7 +183,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor preview_draw_mask = surface_create_empty(1, 1); draw_stack = ds_list_create(); - brush = new canvas_brush(); + + #endregion + + #region ++++ tool object ++++ + brush = new canvas_brush(); + + tool_selection = new canvas_tool_selection(); + + tool_brush = new canvas_tool_brush(brush, false); + tool_eraser = new canvas_tool_brush(brush, true); + tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); + tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); + tool_fill = new canvas_tool_fill(tool_attribute); + tool_freeform = new canvas_tool_draw_freeform(brush); + tool_curve_bez = new canvas_tool_curve_bezier(brush); + + tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle); + tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse); + tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); + tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); + tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush); #endregion @@ -197,7 +217,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.pickColor = c_white; tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); - tool_attribute.mirror = [ false, false ]; + tool_attribute.mirror = [ false, false, false ]; tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }); tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ], @@ -223,48 +243,52 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_fil8_edit = new checkBox(function() { tool_attribute.fill8 = !tool_attribute.fill8; }); tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ]; - tools = [ - new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]), - - new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) + tool_attribute.button_apply = [ false, false ]; + tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0); + tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1); + + toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) .setSetting(tool_thrs) - .setSetting(tool_fil8), + .setSetting(tool_fil8) + .setToolObject(tool_sel_magic) + + tools = [ + new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]) + .setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]), + + toolObject_selection_magic, new NodeTool( "Pencil", THEME.canvas_tools_pencil) - .setSetting(tool_size), - + .setSetting(tool_size) + .setToolObject(tool_brush), + new NodeTool( "Eraser", THEME.canvas_tools_eraser) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_eraser), new NodeTool( "Rectangle", [ THEME.canvas_tools_rect, THEME.canvas_tools_rect_fill ]) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_rectangle), new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ]) - .setSetting(tool_size), - + .setSetting(tool_size) + .setToolObject(tool_ellipse), + + new NodeTool( "Curve", THEME.canvas_tool_curve_icon) + .setSetting(tool_size) + .setSetting([ "", tool_curve_apply, 0, tool_attribute ]) + .setSetting([ "", tool_curve_cancel, 0, tool_attribute ]) + .setToolObject(tool_curve_bez), + new NodeTool( "Freeform", THEME.canvas_tools_freeform) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_freeform), new NodeTool( "Fill", THEME.canvas_tools_bucket) .setSetting(tool_thrs) - .setSetting(tool_fil8), + .setSetting(tool_fil8) + .setToolObject(tool_fill), ]; - - tool_selection = new canvas_tool_selection(); - - tool_brush = new canvas_tool_brush(brush, false); - tool_eraser = new canvas_tool_brush(brush, true); - tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); - tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); - tool_fill = new canvas_tool_fill(tool_attribute); - tool_freeform = new canvas_tool_draw_freeform(brush); - - tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle); - tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse); - tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); - tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); - tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush); - #endregion #region ++++ right tools ++++ @@ -314,9 +338,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor new NodeTool( "Make/Reset Brush", THEME.canvas_tools_pencil ).setToolFn( __action_make_brush ), -1, new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ), - new NodeTool( [ "Extrude", "Inset" ], - [ THEME.canvas_tools_extrude, THEME.canvas_tools_inset ] ) - .setToolObject( [ new canvas_tool_extrude(), new canvas_tool_inset() ] ), + new NodeTool( "Extrude", THEME.canvas_tools_extrude ).setToolObject( new canvas_tool_extrude() ), + new NodeTool( "Inset", THEME.canvas_tools_inset ).setToolObject( new canvas_tool_inset() ), + ]; + + rightTools_not_selection = [ + -1, + new NodeTool( "Outline", THEME.canvas_tools_outline, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[3]) ), + new NodeTool( "Extrude", THEME.canvas_tools_extrude, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[4]) ), + new NodeTool( "Inset", THEME.canvas_tools_inset, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[5]) ), ]; rightTools_brush = [ @@ -330,6 +360,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_eraser.rightTools = rightTools_brush; tool_rectangle.rightTools = rightTools_brush; tool_ellipse.rightTools = rightTools_brush; + + selection_tool_after = noone; #endregion function setToolColor(color) { tool_attribute.color = color; } @@ -391,7 +423,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor return hh + ui(4); } #endregion - function removeFrame(index = 0) { #region + static removeFrame = function(index = 0) { #region if(attributes.frames <= 1) return; if(preview_index == attributes.frames) @@ -403,7 +435,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor update(); } #endregion - function refreshFrames() { #region + static refreshFrames = function() { #region var fr = attributes.frames; var _dim = attributes.dimension; @@ -429,7 +461,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor function setCanvasSurface(surface, index = preview_index) { INLINE canvas_surface[index] = surface; } - function storeAction() { #region + static storeAction = function() { #region var action = recordAction(ACTION_TYPE.custom, function(data) { is_selected = false; @@ -447,7 +479,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor action.clear_action = function(data) { surface_free_safe(data.surface); }; } #endregion - function apply_surfaces() { #region + static apply_surfaces = function() { #region for( var i = 0; i < attributes.frames; i++ ) apply_surface(i); } #endregion @@ -502,7 +534,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor apply_surface(index); } #endregion - function tool_pick_color(_x, _y) { #region + static tool_pick_color = function(_x, _y) { #region if(tool_selection.is_selected) tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]); else @@ -532,9 +564,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor BLEND_ALPHA - if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1); + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1); BLEND_NORMAL @@ -554,11 +586,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_surface(drawing_surface, 0, 0); BLEND_ALPHA - - if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1); - + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1); + } else { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, 1, -90); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, 0, -1, 1, 90); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], 1, 1, 180); + } BLEND_NORMAL surface_reset_target(); @@ -642,6 +678,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor array_append(rightTools, rightTools_general); if(tool_selection.is_selected) array_append(rightTools, rightTools_selection); + else array_append(rightTools, rightTools_not_selection); if(nodeTool != noone) _tool = nodeTool; @@ -649,37 +686,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor else if(_currTool != noone) { _tool = _currTool.getToolObject(); - switch(_currTool.getName()) { - case "Pencil" : _tool = tool_brush; break; - case "Eraser" : _tool = tool_eraser; break; - case "Fill" : _tool = tool_fill; break; - case "Freeform" : _tool = tool_freeform; break; - - case "Rectangle" : - _tool = tool_rectangle; - _tool.fill = _currTool.selecting == 1; - break; - - case "Ellipse" : - _tool = tool_ellipse; - _tool.fill = _currTool.selecting == 1; - break; - - case "Selection" : - switch(_currTool.selecting) { - case 0 : _tool = tool_sel_rectangle; break; - case 1 : _tool = tool_sel_ellipse; break; - case 2 : _tool = tool_sel_freeform; break; - case 3 : _tool = tool_sel_brush; break; - } - - break; - - case "Magic Selection" : _tool = tool_sel_magic; break; - - } - if(_tool) { + _tool.node = self; + _tool = _tool.getTool(); _tool.subtool = _currTool.selecting; array_append(rightTools, _tool.rightTools); } @@ -690,6 +699,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_selection.apply_draw_surface = apply_draw_surface; if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + + tool_mirror_edit.sprs = (!tool_selection.is_selected && tool_attribute.mirror[0])? THEME.canvas_mirror_diag : THEME.canvas_mirror; } if(_tool && _tool.override) { @@ -771,14 +782,20 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _spw = tool_selection.selection_size[0]; var _sph = tool_selection.selection_size[1]; - if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1); + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1); } else { - if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1); + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1); + } else { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, 1, -90); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, 0, -1, 1, 90); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], 1, 1, 180); + } } draw_set_color(tool_attribute.color); @@ -786,7 +803,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor canvas_draw_point_size(brush, brush.brush_sizing_dx, brush.brush_sizing_dy); else if(_tool) _tool.drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); - surface_reset_shader(); draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp); diff --git a/#backups/scripts/node_canvas/node_canvas.gml.backup1 b/#backups/scripts/node_canvas/node_canvas.gml.backup1 index c07b4e568..c75b03c06 100644 --- a/#backups/scripts/node_canvas/node_canvas.gml.backup1 +++ b/#backups/scripts/node_canvas/node_canvas.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 12:58:03 +// 2024-04-16 14:16:53 function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Canvas"; color = COLORS.node_blend_canvas; @@ -54,7 +54,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor frame_renderer_x_max = 0; frame_renderer_content = surface_create(1, 1); - frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region + frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region frame_renderer var _h = 64; _y += 8; @@ -128,7 +128,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor _fr_x += _sw * _ss + 8; frame_renderer_x_max += _sw * _ss + 8; - } + } if(_del > noone) removeFrame(_del); surface_reset_shader(); @@ -183,7 +183,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor preview_draw_mask = surface_create_empty(1, 1); draw_stack = ds_list_create(); - brush = new canvas_brush(); + + #endregion + + #region ++++ tool object ++++ + brush = new canvas_brush(); + + tool_selection = new canvas_tool_selection(); + + tool_brush = new canvas_tool_brush(brush, false); + tool_eraser = new canvas_tool_brush(brush, true); + tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); + tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); + tool_fill = new canvas_tool_fill(tool_attribute); + tool_freeform = new canvas_tool_draw_freeform(brush); + tool_curve_bez = new canvas_tool_curve_bezier(brush); + + tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle); + tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse); + tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); + tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); + tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush); #endregion @@ -197,7 +217,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.pickColor = c_white; tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); - tool_attribute.mirror = [ false, false ]; + tool_attribute.mirror = [ false, false, false ]; tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }); tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ], @@ -223,48 +243,52 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_fil8_edit = new checkBox(function() { tool_attribute.fill8 = !tool_attribute.fill8; }); tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ]; - tools = [ - new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]), - - new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) + tool_attribute.button_apply = [ false, false ]; + tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0); + tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1); + + toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) .setSetting(tool_thrs) - .setSetting(tool_fil8), + .setSetting(tool_fil8) + .setToolObject(tool_sel_magic) + + tools = [ + new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]) + .setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]), + + toolObject_selection_magic, new NodeTool( "Pencil", THEME.canvas_tools_pencil) - .setSetting(tool_size), - + .setSetting(tool_size) + .setToolObject(tool_brush), + new NodeTool( "Eraser", THEME.canvas_tools_eraser) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_eraser), new NodeTool( "Rectangle", [ THEME.canvas_tools_rect, THEME.canvas_tools_rect_fill ]) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_rectangle), new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ]) - .setSetting(tool_size), - + .setSetting(tool_size) + .setToolObject(tool_ellipse), + + new NodeTool( "Curve", THEME.canvas_tool_curve_icon) + .setSetting(tool_size) + .setSetting([ "", tool_curve_apply, 0, tool_attribute ]) + .setSetting([ "", tool_curve_cancel, 0, tool_attribute ]) + .setToolObject(tool_curve_bez), + new NodeTool( "Freeform", THEME.canvas_tools_freeform) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_freeform), new NodeTool( "Fill", THEME.canvas_tools_bucket) .setSetting(tool_thrs) - .setSetting(tool_fil8), + .setSetting(tool_fil8) + .setToolObject(tool_fill), ]; - - tool_selection = new canvas_tool_selection(); - - tool_brush = new canvas_tool_brush(brush, false); - tool_eraser = new canvas_tool_brush(brush, true); - tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); - tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); - tool_fill = new canvas_tool_fill(tool_attribute); - tool_freeform = new canvas_tool_draw_freeform(brush); - - tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle); - tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse); - tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); - tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); - tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush); - #endregion #region ++++ right tools ++++ @@ -314,9 +338,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor new NodeTool( "Make/Reset Brush", THEME.canvas_tools_pencil ).setToolFn( __action_make_brush ), -1, new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ), - new NodeTool( [ "Extrude", "Inset" ], - [ THEME.canvas_tools_extrude, THEME.canvas_tools_inset ] ) - .setToolObject( [ new canvas_tool_extrude(), new canvas_tool_inset() ] ), + new NodeTool( "Extrude", THEME.canvas_tools_extrude ).setToolObject( new canvas_tool_extrude() ), + new NodeTool( "Inset", THEME.canvas_tools_inset ).setToolObject( new canvas_tool_inset() ), + ]; + + rightTools_not_selection = [ + -1, + new NodeTool( "Outline", THEME.canvas_tools_outline, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[3]) ), + new NodeTool( "Extrude", THEME.canvas_tools_extrude, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[4]) ), + new NodeTool( "Inset", THEME.canvas_tools_inset, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[5]) ), ]; rightTools_brush = [ @@ -330,6 +360,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_eraser.rightTools = rightTools_brush; tool_rectangle.rightTools = rightTools_brush; tool_ellipse.rightTools = rightTools_brush; + + selection_tool_after = noone; #endregion function setToolColor(color) { tool_attribute.color = color; } @@ -391,7 +423,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor return hh + ui(4); } #endregion - function removeFrame(index = 0) { #region + static removeFrame = function(index = 0) { #region if(attributes.frames <= 1) return; if(preview_index == attributes.frames) @@ -403,7 +435,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor update(); } #endregion - function refreshFrames() { #region + static refreshFrames = function() { #region var fr = attributes.frames; var _dim = attributes.dimension; @@ -429,7 +461,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor function setCanvasSurface(surface, index = preview_index) { INLINE canvas_surface[index] = surface; } - function storeAction() { #region + static storeAction = function() { #region var action = recordAction(ACTION_TYPE.custom, function(data) { is_selected = false; @@ -447,7 +479,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor action.clear_action = function(data) { surface_free_safe(data.surface); }; } #endregion - function apply_surfaces() { #region + static apply_surfaces = function() { #region for( var i = 0; i < attributes.frames; i++ ) apply_surface(i); } #endregion @@ -502,7 +534,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor apply_surface(index); } #endregion - function tool_pick_color(_x, _y) { #region + static tool_pick_color = function(_x, _y) { #region if(tool_selection.is_selected) tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]); else @@ -532,9 +564,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor BLEND_ALPHA - if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1); + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1); BLEND_NORMAL @@ -554,11 +586,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_surface(drawing_surface, 0, 0); BLEND_ALPHA - - if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1); - + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1); + } else { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, 1, -90); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, 0, -1, 1, 90); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], 1, 1, 180); + } BLEND_NORMAL surface_reset_target(); @@ -642,6 +678,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor array_append(rightTools, rightTools_general); if(tool_selection.is_selected) array_append(rightTools, rightTools_selection); + else array_append(rightTools, rightTools_not_selection); if(nodeTool != noone) _tool = nodeTool; @@ -649,37 +686,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor else if(_currTool != noone) { _tool = _currTool.getToolObject(); - switch(_currTool.getName()) { - case "Pencil" : _tool = tool_brush; break; - case "Eraser" : _tool = tool_eraser; break; - case "Fill" : _tool = tool_fill; break; - case "Freeform" : _tool = tool_freeform; break; - - case "Rectangle" : - _tool = tool_rectangle; - _tool.fill = _currTool.selecting == 1; - break; - - case "Ellipse" : - _tool = tool_ellipse; - _tool.fill = _currTool.selecting == 1; - break; - - case "Selection" : - switch(_currTool.selecting) { - case 0 : _tool = tool_sel_rectangle; break; - case 1 : _tool = tool_sel_ellipse; break; - case 2 : _tool = tool_sel_freeform; break; - case 3 : _tool = tool_sel_brush; break; - } - - break; - - case "Magic Selection" : _tool = tool_sel_magic; break; - - } - if(_tool) { + _tool.node = self; + _tool = _tool.getTool(); _tool.subtool = _currTool.selecting; array_append(rightTools, _tool.rightTools); } @@ -690,6 +699,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_selection.apply_draw_surface = apply_draw_surface; if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + + tool_mirror_edit.sprs = (!tool_selection.is_selected && tool_attribute.mirror[0])? THEME.canvas_mirror_diag : THEME.canvas_mirror; } if(_tool && _tool.override) { @@ -771,14 +782,20 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _spw = tool_selection.selection_size[0]; var _sph = tool_selection.selection_size[1]; - if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1); + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1); } else { - if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1); + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1); + } else { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, 1, -90); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, 0, -1, 1, 90); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], 1, 1, 180); + } } draw_set_color(tool_attribute.color); @@ -786,7 +803,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor canvas_draw_point_size(brush, brush.brush_sizing_dx, brush.brush_sizing_dy); else if(_tool) _tool.drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); - surface_reset_shader(); draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp); diff --git a/#backups/scripts/node_collection/node_collection.gml.backup0 b/#backups/scripts/node_collection/node_collection.gml.backup0 new file mode 100644 index 000000000..2d4a229e0 --- /dev/null +++ b/#backups/scripts/node_collection/node_collection.gml.backup0 @@ -0,0 +1,717 @@ +// 2024-04-16 08:42:15 +enum COLLECTION_TAG { + group = 1, + loop = 2 +} + +function groupNodes(nodeArray, _group = noone, record = true, check_connect = true) { #region + #region check inline + var _ctx_nodes = []; + + for(var i = 0; i < array_length(nodeArray); i++) { + var node = nodeArray[i]; + var ctx = node.inline_context; + + if(ctx == noone) continue; + array_push_unique(_ctx_nodes, ctx); + + for( var k = 0, n = array_length(ctx.members); k < n; k++ ) { + if(array_exists(nodeArray, ctx.members[k])) continue; + noti_warning("Grouping incomplete inline group is not allowed."); + return; + } + } + #endregion + + UNDO_HOLDING = true; + + if(_group == noone) { + var cx = 0; + var cy = 0; + for(var i = 0; i < array_length(nodeArray); i++) { + var _node = nodeArray[i]; + cx += _node.x; + cy += _node.y; + } + + cx = value_snap(cx / array_length(nodeArray), 32); + cy = value_snap(cy / array_length(nodeArray), 32); + + _group = new Node_Group(cx, cy, PANEL_GRAPH.getCurrentContext()); + } + + var _content = []; + + for(var i = 0; i < array_length(nodeArray); i++) { + _group.add(nodeArray[i]); + _content[i] = nodeArray[i]; + } + + for( var i = 0, n = array_length(_ctx_nodes); i < n; i++ ) { + _group.add(_ctx_nodes[i]); + _content[i] = _ctx_nodes[i]; + } + + var _io = { inputs: {}, outputs: {}, map: {} }; + + if(check_connect) { #region IO creation + for(var i = 0; i < array_length(nodeArray); i++) + nodeArray[i].checkConnectGroup(_io); + + var _in = _io.inputs; + var _inKey = struct_get_names(_in); + var _x, _y, m; + + for( var i = 0, n = array_length(_inKey); i < n; i++ ) { + var _frm = _io.map[$ _inKey[i]]; + var _tos = _in[$ _inKey[i]]; + + _x = 0 + _y = 0; + m = array_length(_tos); + + for( var j = 0; j < m; j++ ) { + var _to = _tos[j]; + + _x = min(_x, _to.node.x); + _y += _to.node.y; + } + + _x = value_snap(_x - 64 - 128, 32); + _y = value_snap(_y / m, 32); + + var _n = new Node_Group_Input(_x, _y, _group); + _n.inputs[| 2].setValue(_frm.type); + _n.onValueUpdate(0); + _n.inParent.setFrom(_frm); + + for( var j = 0; j < m; j++ ) { + var _to = _tos[j]; + _to.setFrom(_n.outputs[| 0]); + } + } + + var _ot = _io.outputs; + var _otKey = struct_get_names(_ot); + + for( var i = 0, n = array_length(_otKey); i < n; i++ ) { + var _frm = _io.map[$ _otKey[i]]; + var _tos = _ot[$ _otKey[i]]; + + _x = value_snap(_frm.node.x + _frm.node.w + 64, 32); + _y = value_snap(_frm.node.y, 32); + m = array_length(_tos); + + var _n = new Node_Group_Output(_x, _y, _group); + _n.inputs[| 0].setFrom(_frm); + + for( var j = 0; j < m; j++ ) { + var _to = _tos[j]; + _to.setFrom(_n.outParent); + } + } + + } #endregion + + UNDO_HOLDING = false; + if(record) recordAction(ACTION_TYPE.group, _group, { content: _content }); + + return _group; +} #endregion + +function upgroupNode(collection, record = true) { #region + UNDO_HOLDING = true; + var _content = []; + var node_list = collection.getNodeList(); + + while(!ds_list_empty(node_list)) { + var remNode = node_list[| 0]; + if(!remNode.destroy_when_upgroup) + array_push(_content, remNode); + + collection.remove(remNode); + } + + collection.destroy(); + UNDO_HOLDING = false; + + if(record) recordAction(ACTION_TYPE.ungroup, collection, { content: _content }); +} #endregion + +function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + nodes = ds_list_create(); + node_length = ds_list_size(nodes); + + ungroupable = true; + auto_render_time = false; + combine_render_time = true; + previewable = true; + + reset_all_child = false; + isInstancer = false; + instanceBase = noone; + + input_display_list_def = []; + custom_input_index = 0; + custom_output_index = 0; + + metadata = new MetaDataManager(); + + attributes.input_display_list = []; + attributes.output_display_list = []; + + managedRenderOrder = false; + + input_dummy = nodeValue("Add to group", self, JUNCTION_CONNECT.input, VALUE_TYPE.any, 0); + draw_dummy = false; + + input_dummy.onSetFrom = function(juncFrom) { #region + array_remove(juncFrom.value_to, input_dummy); + input_dummy.value_from = noone; + + var input = nodeBuild("Node_Group_Input", 0, 0, self); + var _type = juncFrom.type; + var _tind = array_find(input.data_type_map, juncFrom.type); + + input.attributes.inherit_type = false; + if(_tind != -1) + input.inputs[| 2].setValue(_tind); + + input.inParent.setFrom(juncFrom); + + if(onNewInputFromGraph != noone) onNewInputFromGraph(juncFrom); + } #endregion + + onNewInputFromGraph = noone; + + tool_node = noone; + draw_input_overlay = true; + + array_push(attributeEditors, ["Edit Input Display", function() { return 0; }, + button(function() { dialogCall(o_dialog_group_input_order).setNode(self, JUNCTION_CONNECT.input); }) ]); + + array_push(attributeEditors, ["Edit Output Display", function() { return 0; }, + button(function() { dialogCall(o_dialog_group_input_order).setNode(self, JUNCTION_CONNECT.output); }) ]); + + hasInsp1 = false; + insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node contents"); + insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + + hasInsp2 = false; + insp2UpdateTooltip = "Clear cache"; + insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; + + static inspector1Update = function() { onInspector1Update(); } + static onInspector1Update = function() { RenderList(nodes); } + static hasInspector1Update = function() { INLINE return hasInsp1; } + + static inspector2Update = function() { onInspector2Update(); } + static onInspector2Update = function() { #region + var i = 0; + + repeat(ds_list_size(nodes)) { + if(nodes[| i].hasInspector2Update()) + nodes[| i].inspector2Update(); + i++; + } + } #endregion + static hasInspector2Update = function() { INLINE return hasInsp2; } + + will_refresh = false; + static refreshNodes = function() { #region + will_refresh = false; + + hasInsp1 = false; + hasInsp2 = false; + + node_length = ds_list_size(nodes); + + var i = 0; + repeat(node_length) { + hasInsp1 |= nodes[| i].hasInspector1Update(); + hasInsp2 |= nodes[| i].hasInspector2Update(); + + i++; + } + + } #endregion + + static getNodeBase = function() { #region + if(instanceBase == noone) return self; + return instanceBase.getNodeBase(); + } #endregion + + static getNodeList = function() { #region + INLINE + if(instanceBase == noone) return nodes; + return instanceBase.getNodeList(); + } #endregion + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + if(!draw_input_overlay) return; + + for(var i = custom_input_index; i < ds_list_size(inputs); i++) { + var _in = inputs[| i]; + var _show = _in.from.getInputData(6); + + if(!_show) continue; + var _hov = _in.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + if(_hov != undefined) active &= !_hov; + } + } #endregion + + static getOutputNodes = function() { #region + var _nodes = []; + for( var i = custom_output_index; i < ds_list_size(outputs); i++ ) { + var _junc = outputs[| i]; + + for( var j = 0; j < array_length(_junc.value_to); j++ ) { + var _to = _junc.value_to[j]; + if(_to.value_from != _junc) continue; + array_push_unique(_nodes, _to.node); + } + } + return _nodes; + } #endregion + + static getInput = function(junc = noone) { #region + return input_dummy; + } #endregion + + static getNextNodes = function() { return getNextNodesInternal(); } + + static getNextNodesInternal = function() { #region //get node inside the group + LOG_BLOCK_START(); + LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from group: {INAME}"); + + var _nodes = []; + if(isRenderActive()) { + var allReady = true; + for(var i = custom_input_index; i < ds_list_size(inputs); i++) { + var _in = inputs[| i].from; + if(!_in.isRenderActive()) continue; + + if(!_in.isRenderable()) { + LOG_IF(global.FLAG.render == 1, $"Node {_in.internalName} not ready, loop skip."); + LOG_BLOCK_END(); + return []; + } + } + + _nodes = __nodeLeafList(getNodeList()); + } + + LOG_BLOCK_END(); + return _nodes; + } #endregion + + static getNextNodesExternal = function() { #region //get node connected to the parent object + LOG_IF(global.FLAG.render == 1, $"Checking next node external for {INAME}"); + LOG_BLOCK_START(); + + var nextNodes = []; + for( var i = 0; i < ds_list_size(outputs); i++ ) { + var _ot = outputs[| i]; + if(!_ot.forward) continue; + if(_ot.type == VALUE_TYPE.node) continue; + + var _tos = _ot.getJunctionTo(); + for( var j = 0, n = array_length(_tos); j < n; j++ ) { + var _to = _tos[j]; + var _node = _to.node; + + LOG_IF(global.FLAG.render == 1, $"Checking node {_node.internalName} : {_node.isRenderable()}"); + if(!_node.isRenderable()) continue; + + array_push(nextNodes, _to.node); + } + } + LOG_BLOCK_END(); + + return nextNodes; + } #endregion + + static clearTopoSorted = function() { INLINE topoSorted = false; for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { nodes[| i].clearTopoSorted(); } } + + static setRenderStatus = function(result) { #region + LOG_BLOCK_START(); + LOG_IF(global.FLAG.render == 1, $"Set render status for {INAME} : {result}"); + rendered = result; + if(rendered == result) return; + + if(result) + for( var i = custom_output_index, n = ds_list_size(outputs); i < n; i++ ) { + var _o = outputs[| i]; + if(_o.from.rendered) continue; + + LOG_IF(global.FLAG.render == 1, $"Set fail because {_o.from.internalName} is not rendered."); + rendered = false; + break; + } + + if(rendered) exitGroup(); + + if(!result && group != noone) + group.setRenderStatus(result); + LOG_BLOCK_END(); + } #endregion + + static isActiveDynamic = function(frame = CURRENT_FRAME) { #region + if(update_on_frame) return true; + if(!rendered) return true; + + for( var i = custom_input_index, n = ds_list_size(inputs); i < n; i++ ) + if(inputs[| i].isActiveDynamic(frame) || !inputs[| i].from.rendered) return true; + + return false; + } #endregion + + static exitGroup = function() {} + + static add = function(_node) { #region + ds_list_add(getNodeList(), _node); + var list = _node.group == noone? PANEL_GRAPH.nodes_list : _node.group.getNodeList(); + ds_list_remove(list, _node); + + recordAction(ACTION_TYPE.group_added, self, _node); + _node.group = self; + + will_refresh = true; + node_length = ds_list_size(nodes); + } #endregion + + static remove = function(_node) { #region + var node_list = getNodeList(); + var _pos = ds_list_find_index(node_list, _node); + ds_list_delete(node_list, _pos); + var list = group == noone? PANEL_GRAPH.nodes_list : group.getNodeList(); + ds_list_add(list, _node); + + recordAction(ACTION_TYPE.group_removed, self, _node); + + if(struct_has(_node, "ungroup")) + _node.ungroup(); + + if(_node.destroy_when_upgroup) + _node.destroy(); + else + _node.group = group; + + will_refresh = true; + node_length = ds_list_size(nodes); + } #endregion + + static clearCache = function() { #region + var node_list = getNodeList(); + for(var i = 0; i < ds_list_size(node_list); i++) { + node_list[| i].clearCache(); + } + } #endregion + + static stepBegin = function() { #region + if(will_refresh) refreshNodes(); + doStepBegin(); + } #endregion + + static step = function() { #region + if(combine_render_time) { + render_time = 0; + var node_list = getNodeList(); + for(var i = 0; i < ds_list_size(node_list); i++) + render_time += node_list[| i].render_time; + } + + onStep(); + } #endregion + + static onStep = function() {} + + static onPreDraw = function(_x, _y, _s, _iny, _outy) { #region + var xx = x * _s + _x; + var yy = y * _s + _y; + + input_dummy.x = xx; + input_dummy.y = _iny; + } #endregion + + static preConnect = function() { #region + sortIO(); + deserialize(load_map, load_scale); + } #endregion + + static onDrawJunctions = function(_x, _y, _mx, _my, _s) { #region + input_dummy.visible = false; + + if(draw_dummy) { + input_dummy.visible = true; + input_dummy.drawJunction(_s, _mx, _my); + } + + draw_dummy = false; + } #endregion + + static sortIO = function() { #region + var _ilen = ds_list_size(inputs); + var _iarr = attributes.input_display_list; + + for( var i = 0; i < _ilen; i++ ) + array_push_unique(_iarr, i); + for( var i = array_length(_iarr) - 1; i >= 0; i-- ) { + if(is_array(_iarr[i])) continue; + if(_iarr[i] >= _ilen) array_delete(_iarr, i, 1); + } + + input_display_list = attributes.input_display_list; + + /////////////////////////////////////////////////////////////////// + + var _olen = ds_list_size(outputs); + var _oarr = attributes.output_display_list; + + for( var i = 0; i < _olen; i++ ) + array_push_unique(_oarr, i); + for( var i = array_length(_oarr) - 1; i >= 0; i-- ) { + if(is_array(_oarr[i])) continue; + if(_oarr[i] >= _olen) array_delete(_oarr, i, 1); + } + output_display_list = attributes.output_display_list; + + /////////////////////////////////////////////////////////////////// + + refreshNodeDisplay(); + } #endregion + + static getTool = function() { #region + for(var i = 0, n = ds_list_size(nodes); i < n; i++) { + var _node = nodes[| i]; + if(!_node.active) continue; + if(_node.isTool) return _node.getTool(); + } + + return self; + } #endregion + + static onClone = function(_newNode, target = PANEL_GRAPH.getCurrentContext()) { #region + if(instanceBase != noone) { + _newNode.instanceBase = instanceBase; + return; + } + + var dups = ds_list_create(); + + for(var i = 0, n = ds_list_size(nodes); i < n; i++) { + var _node = nodes[| i]; + var _cnode = _node.clone(target); + ds_list_add(dups, _cnode); + + APPEND_MAP[? _node.node_id] = _cnode.node_id; + } + + APPENDING = true; + for(var i = 0; i < ds_list_size(dups); i++) { + var _node = dups[| i]; + _node.connect(); + } + APPENDING = false; + + ds_list_destroy(dups); + } #endregion + + static enable = function() { #region + active = true; + var node_list = getNodeList(); + for( var i = 0; i < ds_list_size(node_list); i++ ) + node_list[| i].enable(); + } #endregion + + static disable = function() { #region + active = false; + var node_list = getNodeList(); + for( var i = 0; i < ds_list_size(node_list); i++ ) + node_list[| i].disable(); + } #endregion + + static resetRender = function(_clearCache = false) { #region + LOG_LINE_IF(global.FLAG.render == 1, $"Reset Render for group {INAME}"); + + setRenderStatus(false); + if(_clearCache) clearInputCache(); + + if(reset_all_child) + for(var i = 0, n = ds_list_size(nodes); i < n; i++) + nodes[| i].resetRender(_clearCache); + } #endregion + + static setInstance = function(node) { #region + instanceBase = node; + } #endregion + + static resetInstance = function() { #region + instanceBase = noone; + } #endregion + + static onDoubleClick = function(panel) { #region + if(PREFERENCES.panel_graph_group_require_shift && !key_mod_press(SHIFT)) return false; + + __temp_panel = panel; + + if(PREFERENCES.graph_open_group_in_tab) + run_in(1, function() { __temp_panel.openGroupTab(self) }); + else + panel.addContext(self); + + if(ononDoubleClick != noone) + ononDoubleClick(panel); + + return true; + } #endregion + + static ononDoubleClick = noone; + + static getGraphPreviewSurface = function() { #region + var _output_junc = outputs[| preview_channel]; + + for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { + if(!nodes[| i].active) continue; + if(is_instanceof(nodes[| i], Node_Group_Thumbnail)) + _output_junc = nodes[| i].inputs[| 0]; + } + + if(!is_instanceof(_output_junc, NodeValue)) return noone; + + switch(_output_junc.type) { + case VALUE_TYPE.surface : + case VALUE_TYPE.dynaSurface : + return _output_junc.getValue(); + } + + return noone; + } #endregion + + static enable = function() { #region + active = true; timeline_item.active = true; + for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) nodes[| i].enable(); + } #endregion + + static disable = function() { #region + active = false; timeline_item.active = false; + for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) nodes[| i].disable(); + } #endregion + + static attributeSerialize = function() { #region + sortIO(); + + var _attr = variable_clone(attributes); + + _attr.custom_input_list = []; + for( var i = custom_input_index, n = ds_list_size(inputs); i < n; i++ ) { + if(struct_has(inputs[| i], "from")) + array_push(_attr.custom_input_list, inputs[| i].from.node_id); + } + + _attr.custom_output_list = []; + for( var i = custom_output_index, n = ds_list_size(outputs); i < n; i++ ) { + if(struct_has(outputs[| i], "from")) + array_push(_attr.custom_output_list , outputs[| i].from.node_id); + } + + return _attr; + } #endregion + + static preApplyDeserialize = function() { #region + var attr = attributes; + + if(LOADING_VERSION < 11690) { #region + var pr = ds_priority_create(); + + for( var i = ds_list_size(inputs) - 1; i >= custom_input_index; i-- ) { + if(!struct_has(inputs[| i].attributes, "input_priority")) continue; + + var _pri = inputs[| i].attributes.input_priority; + ds_priority_add(pr, inputs[| i], _pri); + ds_list_delete(inputs, i); + } + + repeat(ds_priority_size(pr)) ds_list_add(inputs, ds_priority_delete_min(pr)); + + for( var i = ds_list_size(outputs) - 1; i >= custom_output_index; i-- ) { + if(!struct_has(outputs[| i].attributes, "output_priority")) continue; + + var _pri = outputs[| i].attributes.output_priority; + ds_priority_add(pr, outputs[| i], _pri); + ds_list_delete(outputs, i); + } + + repeat(ds_priority_size(pr)) ds_list_add(outputs, ds_priority_delete_min(pr)); + + ds_priority_destroy(pr); + return; + } #endregion + + if(struct_has(attr, "custom_input_list")) { + var _ilist = attr.custom_input_list; + var _inarr = {}; + var _dilst = []; + + if(APPENDING) + for( var i = 0, n = array_length(_ilist); i < n; i++ ) + _ilist[i] = ds_map_try_get(APPEND_MAP, _ilist[i], _ilist[i]); + + for( var i = ds_list_size(inputs) - 1; i >= custom_input_index; i-- ) { + if(!struct_has(inputs[| i], "from")) continue; + + var _frNode = inputs[| i].from.node_id; + if(array_exists(_ilist, _frNode)) { + _inarr[$ _frNode] = inputs[| i]; + ds_list_delete(inputs, i); + } + } + + for( var i = 0, n = array_length(_ilist); i < n; i++ ) { + if(!struct_has(_inarr, _ilist[i])) continue; + + ds_list_add(inputs, _inarr[$ _ilist[i]]); + } + + } + + if(struct_has(attr, "custom_output_list")) { + var _ilist = attr.custom_output_list; + var _inarr = {}; + + if(APPENDING) + for( var i = 0, n = array_length(_ilist); i < n; i++ ) + _ilist[i] = ds_map_try_get(APPEND_MAP, _ilist[i], _ilist[i]); + + for( var i = ds_list_size(outputs) - 1; i >= custom_output_index; i-- ) { + if(!struct_has(outputs[| i], "from")) continue; + + var _frNode = outputs[| i].from.node_id; + if(array_exists(_ilist, _frNode)) { + _inarr[$ _frNode] = outputs[| i]; + ds_list_delete(outputs, i); + } + } + + for( var i = 0, n = array_length(_ilist); i < n; i++ ) { + if(!struct_has(_inarr, _ilist[i])) continue; + + ds_list_add(outputs, _inarr[$ _ilist[i]]); + } + + } + + } #endregion + + static processSerialize = function(_map) { #region + _map.instance_base = instanceBase? instanceBase.node_id : noone; + } #endregion + + static preConnect = function() { #region + instanceBase = GetAppendID(struct_try_get(load_map, "instance_base", noone)); + + sortIO(); + applyDeserialize(); + } #endregion + +} \ No newline at end of file diff --git a/#backups/scripts/node_data/node_data.gml.backup0 b/#backups/scripts/node_data/node_data.gml.backup0 index 2ba8de8b1..ca3818bc5 100644 --- a/#backups/scripts/node_data/node_data.gml.backup0 +++ b/#backups/scripts/node_data/node_data.gml.backup0 @@ -1,147 +1,310 @@ -// 2023-08-08 14:42:15 +// 2024-04-16 12:09:31 global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ]; -function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x, _y) constructor { - active = true; - renderActive = true; +#macro INAME internalName == ""? name : internalName +#macro NODE_HAS_INSP1 (onInspector1Update != noone) +#macro NODE_HAS_INSP2 (onInspector2Update != noone) + +enum CACHE_USE { + none, + manual, + auto +} + +enum DYNA_INPUT_COND { + connection = 1 << 0, + zero = 1 << 1, +} + +function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { - node_id = UUID_generate(); + #region ---- main & active ---- + active = true; + renderActive = true; + + node_id = UUID_generate(); + group = _group; + manual_deletable = true; + manual_ungroupable = true; + destroy_when_upgroup = false; + + var l = _group == noone? PROJECT.nodes : _group.getNodeList(); + ds_list_add(l, self); + + active_index = -1; + active_range = [ 0, TOTAL_FRAMES - 1 ]; + + array_push(PROJECT.nodeArray, self); + + inline_context = noone; + inline_parent_object = ""; + #endregion - group = _group; - destroy_when_upgroup = false; - ds_list_add(PANEL_GRAPH.getNodeList(_group), self); - - active_index = -1; - active_range = [ 0, PROJECT.animator.frames_total - 1 ]; - - color = c_white; - icon = noone; - bg_spr = THEME.node_bg; - bg_sel_spr = THEME.node_active; - anim_priority = ds_map_size(PROJECT.nodeMap); - - static resetInternalName = function() { + static resetInternalName = function() { #region var str = string_replace_all(name, " ", "_"); str = string_replace_all(str, "/", ""); str = string_replace_all(str, "-", ""); - + + ds_map_delete(PROJECT.nodeNameMap, internalName); internalName = str + string(irandom_range(10000, 99999)); PROJECT.nodeNameMap[? internalName] = self; - } + } #endregion - if(!LOADING && !APPENDING) { + if(!LOADING && !APPENDING) { #region recordAction(ACTION_TYPE.node_added, self); PROJECT.nodeMap[? node_id] = self; PROJECT.modified = true; - //print($"Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]"); - run_in(1, function() { - if(display_name != "") return; resetInternalName(); - display_name = name; //__txt_node_name(instanceof(self), name); + + if(renamed) return; + display_name = __txt_node_name(instanceof(self), name); + if(!LOCALE_DEF || TESTING) renamed = true; }); - } + + RENDER_ALL_REORDER + } #endregion - name = ""; - display_name = ""; - internalName = ""; + #region ---- display ---- + color = c_white; + icon = noone; + icon_24 = noone; + bg_spr = THEME.node_bg; + bg_sel_spr = THEME.node_active; - tooltip = ""; - x = _x; - y = _y; + name = ""; + display_name = ""; + internalName = ""; + onSetDisplayName = noone; + renamed = false; + + tooltip = ""; + x = _x; + y = _y; - w = 128; - h = 128; - min_h = 0; - draw_padding = 8; - auto_height = true; + w = 128; + h = 128; + min_w = w; + min_h = h; + fix_h = h; + will_setHeight = false; + + selectable = true; + clonable = true; + draw_padding = 4; + auto_height = true; + + display_parameter = new connectionParameter(); + + draw_name = true; + draggable = true; + + draw_boundary = [ 0, 0, 0, 0 ]; + draw_graph_culled = false; + + badgePreview = 0; + badgeInspect = 0; + + active_draw_index = -1; + + draw_droppable = false; + + junction_draw_pad_y = 32; + junction_draw_hei_y = 24; + + branch_drawing = false; + #endregion - draw_name = true; - draggable = true; + #region ---- junctions ---- + inputs = ds_list_create(); + outputs = ds_list_create(); + inputMap = ds_map_create(); + outputMap = ds_map_create(); + input_value_map = {}; + + use_display_list = true; + input_display_list = -1; + output_display_list = -1; + inspector_display_list = -1; + is_dynamic_output = false; + + inspectInput1 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + inspectInput2 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + + inspectInput1.index = -1; + inspectInput2.index = -1; + + autoUpdatedTrigger = true; + updatedInTrigger = nodeValue("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, false).setVisible(true, true); + updatedOutTrigger = nodeValue("Updated", self, JUNCTION_CONNECT.output, VALUE_TYPE.trigger, false).setVisible(true, true); + + updatedInTrigger.index = -1; + updatedOutTrigger.index = -1; + + updatedInTrigger.tags = VALUE_TAG.updateInTrigger; + updatedOutTrigger.tags = VALUE_TAG.updateOutTrigger; + + insp1UpdateActive = true; + insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); + insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + + insp2UpdateActive = true; + insp2UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); + insp2UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + + is_dynamic_input = false; + auto_input = false; + input_display_len = 0; + input_fix_len = 0; + data_length = 1; + inputs_data = []; + input_hash = ""; + input_hash_raw = ""; + + inputs_amount = 0; + inputs_index = []; + in_cache_len = 0; + inputDisplayList = []; + + outputs_amount = 0; + outputs_index = []; + out_cache_len = 0; + + input_buttons = []; + input_button_length = 0; + + run_in(1, function() { + input_buttons = []; + + for( var i = 0; i < ds_list_size(inputs); i++ ) { + var _in = inputs[| i]; + if(!is_instanceof(_in, NodeValue)) continue; + if(_in.type != VALUE_TYPE.trigger) continue; + + if(_in.runInUI) array_push(input_buttons, _in); + } + + input_button_length = array_length(input_buttons); + }); + #endregion - inputs = ds_list_create(); - outputs = ds_list_create(); - inputMap = ds_map_create(); - outputMap = ds_map_create(); + #region --- attributes ---- + attributes.node_param_width = PREFERENCES.node_param_width; + attributes.node_width = 0; + attributes.node_height = 0; + + attributeEditors = [ + "Display", + ["Params Width", function() { return attributes.node_param_width; }, new textBox(TEXTBOX_INPUT.number, function(val) { attributes.node_param_width = val; refreshNodeDisplay(); }) ], + + "Node update", + ["Auto update", function() { return attributes.update_graph; }, new checkBox(function() { attributes.update_graph = !attributes.update_graph; }) ], + ["Update trigger", function() { return attributes.show_update_trigger; }, new checkBox(function() { attributes.show_update_trigger = !attributes.show_update_trigger; }) ], + ]; + + bufferStore = {}; + #endregion - input_display_list = -1; - output_display_list = -1; - inspector_display_list = -1; - is_dynamic_output = false; + #region ---- preview ---- + show_parameter = PREFERENCES.node_param_show; + + show_input_name = false; + show_output_name = false; - attributes = {}; - attributeEditors = []; + inspecting = false; + previewing = 0; + + preview_surface = noone; + preview_amount = 0; + previewable = true; + preview_draw = true; + preview_speed = 0; + preview_index = 0; + preview_channel = 0; + preview_alpha = 1; + preview_x = 0; + preview_y = 0; + + preview_mx = 0; + preview_my = 0; + + graph_preview_alpha = 1; + + getPreviewingNode = noone; + + preview_value = 0; + preview_array = ""; + #endregion - inspectInput1 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); - inspectInput2 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + #region ---- rendering ---- + rendered = false; + update_on_frame = false; + render_time = 0; + render_cached = false; + auto_render_time = true; + updated = false; + passiveDynamic = false; + topoSorted = false; + temp_surface = []; + force_requeue = false; + is_simulation = false; + + in_VFX = false; + + is_group_io = false; + #endregion - updateAction = nodeValue("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); + #region ---- timeline ---- + timeline_item = new timelineItemNode(self); + anim_priority = ds_map_size(PROJECT.nodeMap); + is_anim_timeline = false; + #endregion - show_input_name = false; - show_output_name = false; + #region ---- notification ---- + value_validation = array_create(3); - inspecting = false; - previewing = 0; + manual_updated = false; + #endregion - preview_surface = noone; - preview_amount = 0; - previewable = true; - preview_speed = 0; - preview_index = 0; - preview_channel = 0; - preview_alpha = 1; - preview_x = 0; - preview_y = 0; + #region ---- tools ---- + tools = -1; + rightTools = -1; + isTool = false; + tool_settings = []; + tool_attribute = {}; + #endregion - preview_surface_prev = noone; - preview_trans = 1; - preview_drop_x = 0; - preview_drop_y = 0; + #region ---- 3d ---- + is_3D = false; + #endregion - preview_mx = 0; - preview_my = 0; + #region ---- cache ---- + use_cache = CACHE_USE.none; + cached_manual = false; + cached_output = []; + cache_result = []; + cache_group = noone; + + clearCacheOnChange = true; + #endregion - rendered = false; - update_on_frame = false; - render_time = 0; - auto_render_time = true; - updated = false; + #region ---- log ---- + messages = []; + #endregion - use_cache = false; - clearCacheOnChange = true; - cached_output = []; - cache_result = []; - temp_surface = []; - - tools = -1; - - on_dragdrop_file = -1; - - anim_show = true; - dopesheet_color = COLORS.panel_animation_dope_blend_default; - dopesheet_y = 0; - - value_validation = array_create(3); - - error_noti_update = noone; - error_update_enabled = false; - manual_updated = false; - manual_deletable = true; - - isTool = false; - tool_settings = []; - tool_attribute = {}; - - is_dynamic_input = false; - input_display_len = 0; - input_fix_len = 0; - data_length = 1; + #region ---- serialization ---- + load_scale = false; + load_map = -1; + load_group = noone; + #endregion static createNewInput = noone; - static initTooltip = function() { - var type_self:string = instanceof(self); + static initTooltip = function() { #region + if(IS_CMD) return; + + var type_self = instanceof(self); if(!struct_has(global.NODE_GUIDE, type_self)) return; var _n = global.NODE_GUIDE[$ type_self]; @@ -159,10 +322,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x outputs[| i].name = _ots[i].name; outputs[| i].tooltip = _ots[i].tooltip; } - } + } #endregion run_in(1, initTooltip); - static resetDefault = function() { + static resetDefault = function() { #region var folder = instanceof(self); if(!ds_map_exists(global.PRESETS_MAP, folder)) return; @@ -176,59 +339,155 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x } doUpdate(); - } + } #endregion if(!APPENDING && !LOADING) run_in(1, method(self, resetDefault)); - static getInputJunctionIndex = function(index) { - if(input_display_list == -1) + static getInputJunctionIndex = function(index) { #region + INLINE + + if(input_display_list == -1 || !use_display_list) return index; var jun_list_arr = input_display_list[index]; - if(is_array(jun_list_arr)) return noone; + if(is_array(jun_list_arr)) return noone; if(is_struct(jun_list_arr)) return noone; + return jun_list_arr; - } + } #endregion - static getOutputJunctionIndex = function(index) { + static getOutputJunctionIndex = function(index) { #region if(output_display_list == -1) return index; return output_display_list[index]; - } + } #endregion - static setHeight = function() { - var _hi = ui(32); - var _ho = ui(32); + static updateIO = function() { #region + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) + inputs[| i].visible_in_list = false; - for( var i = 0; i < ds_list_size(inputs); i++ ) { - if(inputs[| i].isVisible()) _hi += 24; + inputs_amount = (input_display_list == -1 || !use_display_list)? ds_list_size(inputs) : array_length(input_display_list); + inputs_index = []; + + for( var i = 0; i < inputs_amount; i++ ) { + var _input = getInputJunctionIndex(i); + if(_input == noone) continue; + + var _inp = inputs[| _input]; + if(!is_struct(_inp) || !is_instanceof(_inp, NodeValue)) continue; + + array_push(inputs_index, _input); + _inp.visible_in_list = true; + } + inputs_amount = array_length(inputs_index); + + outputs_amount = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list); + outputs_index = array_create_ext(outputs_amount, function(index) { return getOutputJunctionIndex(index); }); + } #endregion + + static setDimension = function(_w = 128, _h = 128, _apply = true) { #region + INLINE + + min_w = _w; + min_h = _h; + + if(_apply) { + w = _w; + h = _h; + } + } #endregion + + static setHeight = function() { #region + w = show_parameter? attributes.node_param_width : min_w; + + if(!auto_height) return; + junction_draw_hei_y = show_parameter? 32 : 24; + junction_draw_pad_y = show_parameter? min_h : 32; + + var _hi = junction_draw_pad_y + show_parameter * 4; + var _ho = junction_draw_pad_y + show_parameter * 4; + + var _prev_surf = previewable && preview_draw && + ( is_surface(getGraphPreviewSurface()) || + (preview_channel >= 0 && preview_channel < ds_list_size(outputs) && outputs[| preview_channel].type == VALUE_TYPE.surface) + ); + + for( var i = 0; i < ds_list_size(inputs); i++ ) { + var _inp = inputs[| i]; + if(is_instanceof(_inp, NodeValue) && _inp.isVisible()) + _hi += junction_draw_hei_y; } - for( var i = 0; i < ds_list_size(outputs); i++ ) { - if(outputs[| i].isVisible()) _ho += 24; - } + for( var i = 0; i < ds_list_size(outputs); i++ ) + if(outputs[| i].isVisible()) _ho += junction_draw_hei_y; - h = max(min_h, (preview_surface && previewable)? 128 : 0, _hi, _ho); - } + h = max(min_h, _prev_surf * 128, _hi, _ho, attributes.node_height); + fix_h = h; + + } #endregion - onSetDisplayName = noone; - static setDisplayName = function(_name) { + static setDisplayName = function(_name) { #region + renamed = true; display_name = _name; internalName = string_replace_all(display_name, " ", "_"); refreshNodeMap(); if(onSetDisplayName != noone) onSetDisplayName(); - } + + return self; + } #endregion - static setIsDynamicInput = function(_data_length = 1) { - is_dynamic_input = true; + static setIsDynamicInput = function(_data_length = 1, _auto_input = true, _dynamic_input_cond = DYNA_INPUT_COND.connection) { #region + is_dynamic_input = true; + auto_input = _auto_input; input_display_len = input_display_list == -1? 0 : array_length(input_display_list); input_fix_len = ds_list_size(inputs); data_length = _data_length; - } + + dynamic_input_cond = _dynamic_input_cond; + } #endregion - static getOutput = function(junc = noone) { + static createNewInput = -1; + + static refreshDynamicInput = function() { #region + var _in = ds_list_create(); + + for( var i = 0; i < input_fix_len; i++ ) + ds_list_add(_in, inputs[| i]); + + array_resize(input_display_list, input_display_len); + + for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) { + var _active = false; + if(dynamic_input_cond & DYNA_INPUT_COND.connection) + _active |= inputs[| i].value_from != noone; + if(dynamic_input_cond & DYNA_INPUT_COND.zero) { + var _val = inputs[| i].getValue(); + _active |= _val != 0 || _val != ""; + } + + if(_active) { + for( var j = 0; j < data_length; j++ ) { + ds_list_add(_in, inputs[| i + j]); + array_push(input_display_list, i + j); + } + } else { + for( var j = 0; j < data_length; j++ ) + delete inputs[| i + j]; + } + } + + for( var i = 0; i < ds_list_size(_in); i++ ) + _in[| i].index = i; + + ds_list_destroy(inputs); + inputs = _in; + + createNewInput(); + } #endregion + + static getOutput = function(junc = noone) { #region for( var i = 0; i < ds_list_size(outputs); i++ ) { if(!outputs[| i].visible) continue; if(junc != noone && !junc.isConnectable(outputs[| i], true)) continue; @@ -236,10 +495,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x return outputs[| i]; } return noone; - } + } #endregion - static getInput = function(junc = noone) { - for( var i = 0; i < ds_list_size(inputs); i++ ) { + static getInput = function(junc = noone, shift = input_fix_len) { #region + for( var i = shift; i < ds_list_size(inputs); i++ ) { if(!inputs[| i].visible) continue; if(inputs[| i].value_from != noone) continue; if(junc != noone && !inputs[| i].isConnectable(junc, true)) continue; @@ -247,147 +506,181 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x return inputs[| i]; } return noone; - } + } #endregion - static getFullName = function() { - return display_name == ""? name : "[" + name + "] " + display_name; - } + static getFullName = function() { #region + INLINE + return renamed? "[" + name + "] " + display_name : name; + } #endregion - static addInput = function(junctionFrom) { - var targ = getInput(junctionFrom); + static getDisplayName = function() { #region + INLINE + return renamed? display_name : name; + } #endregion + + static addInput = function(junctionFrom, shift = input_fix_len) { #region + var targ = getInput(junctionFrom, shift); if(targ == noone) return; targ.setFrom(junctionFrom); - } + } #endregion - static isAnimated = function() { - for(var i = 0; i < ds_list_size(inputs); i++) { - if(inputs[| i].isAnimated()) - return true; - } + static isActiveDynamic = function(frame = CURRENT_FRAME) { #region + if(update_on_frame) return true; + if(!rendered) return true; + + force_requeue = false; + for(var i = 0; i < ds_list_size(inputs); i++) + if(inputs[| i].isActiveDynamic(frame)) return true; + return false; - } + } #endregion - static isInLoop = function() { + static isInLoop = function() { #region return array_exists(global.loop_nodes, instanceof(group)); - } + } #endregion - static move = function(_x, _y) { + static move = function(_x, _y, _s) { #region if(x == _x && y == _y) return; x = _x; y = _y; if(!LOADING) PROJECT.modified = true; - } + } #endregion - insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); - insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; + #region ++++ inspector update ++++ + static onInspector1Update = noone; + static inspector1Update = function() { INLINE onInspector1Update(); } + static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; } - static inspector1Update = function() { - if(error_update_enabled && error_noti_update != noone) - noti_remove(error_noti_update); - error_noti_update = noone; - - onInspector1Update(); - } - static onInspector1Update = noone; - static hasInspector1Update = function() { return onInspector1Update != noone; } + static onInspector2Update = noone; + static inspector2Update = function() { INLINE onInspector2Update(); } + static hasInspector2Update = function() { INLINE return NODE_HAS_INSP2; } + #endregion - insp2UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); - insp2UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; - - static inspector2Update = function() { onInspector2Update(); } - static onInspector2Update = noone; - static hasInspector2Update = function() { return onInspector2Update != noone; } - - static stepBegin = function() { + static stepBegin = function() { #region if(use_cache) cacheArrayCheck(); - var willUpdate = false; - - if(PROJECT.animator.frame_progress) { - if(update_on_frame) willUpdate = true; - if(isAnimated()) willUpdate = true; - - if(willUpdate) { - setRenderStatus(false); - UPDATE |= RENDER_TYPE.partial; - } - } - - if(auto_height) - setHeight(); doStepBegin(); - if(hasInspector1Update()) inspectInput1.name = insp1UpdateTooltip; - if(hasInspector2Update()) inspectInput2.name = insp2UpdateTooltip; - } + if(NODE_HAS_INSP1) inspectInput1.name = insp1UpdateTooltip; + if(NODE_HAS_INSP2) inspectInput2.name = insp2UpdateTooltip; + + if(attributes.show_update_trigger) { + if(updatedInTrigger.getValue()) { + getInputs(); + update(); + + updatedInTrigger.setValue(false); + } + updatedOutTrigger.setValue(false); + } + + if(will_setHeight) { + setHeight(); + will_setHeight = false; + } + + if(is_3D) USE_DEPTH = true; + if(is_simulation) PROJECT.animator.is_simulating = true; + } #endregion + static doStepBegin = function() {} - static triggerCheck = function() { - _triggerCheck(); - } - - static _triggerCheck = function() { - for( var i = 0; i < ds_list_size(inputs); i++ ) { - if(inputs[| i].type != VALUE_TYPE.trigger) continue; - if(!is_instanceof(inputs[| i].editWidget, buttonClass)) continue; + static triggerCheck = function() { #region + var i = 0; + + repeat( input_button_length ) { + var _in = input_buttons[i++]; - var trig = inputs[| i].getValue(); - if(trig) { - inputs[| i].editWidget.onClick(); - inputs[| i].setValue(false); + if(_in.getStaticValue()) { + _in.editWidget.onClick(); + _in.setValue(false); } } - if(hasInspector1Update()) { - var trig = inspectInput1.getValue(); - if(trig) { - inspectInput1.editWidget.onClick(); - inspectInput1.setValue(false); - } + if(NODE_HAS_INSP1 && inspectInput1.getStaticValue()) { + onInspector1Update(); + inspectInput1.setValue(false); } - if(hasInspector2Update()) { - var trig = inspectInput2.getValue(); - if(trig) { - inspectInput2.editWidget.onClick(); - inspectInput2.setValue(false); - } + if(NODE_HAS_INSP2 && inspectInput2.getStaticValue()) { + onInspector2Update(); + inspectInput2.setValue(false); } - } + } #endregion static step = function() {} static focusStep = function() {} static inspectorStep = function() {} - static doUpdate = function() { - if(SAFE_MODE) return; - if(NODE_EXTRACT) return; + static getInputData = function(index, def = 0) { #region + INLINE - var sBase = surface_get_target(); - LOG_BLOCK_START(); - LOG_IF(global.FLAG.render, $">>>>>>>>>> DoUpdate called from {internalName} <<<<<<<<<<"); + return array_safe_get_fast(inputs_data, index, def); + } #endregion + + static setInputData = function(index, value) { #region + INLINE - try { - var t = get_timer(); + inputs_data[index] = value; + var _inp = inputs[| index]; + if(is_struct(_inp)) input_value_map[$ _inp.internalName] = value; + } #endregion + + static getInputs = function(frame = CURRENT_FRAME) { #region + inputs_data = array_verify(inputs_data, ds_list_size(inputs)); + + for(var i = 0; i < ds_list_size(inputs); i++) { + if(!is_instanceof(inputs[| i], NodeValue)) continue; - if(!is_instanceof(self, Node_Collection)) - setRenderStatus(true); - - update(); ///UPDATE - - if(!is_instanceof(self, Node_Collection)) - render_time = get_timer() - t; - } catch(exception) { - var sCurr = surface_get_target(); - while(surface_get_target() != sBase) - surface_reset_target(); + var val = inputs[| i].getValue(frame); + setInputData(i, val); + } + } #endregion + + static forceUpdate = function() { #region + input_hash = ""; + doUpdate(); + } #endregion + + static postUpdate = function(frame = CURRENT_FRAME) {} + + static doUpdate = function(frame = CURRENT_FRAME) { #region + if(PROJECT.safeMode) return; + if(NODE_EXTRACT) return; + + var render_timer = get_timer(); + + if(cached_manual || (use_cache == CACHE_USE.auto && recoverCache())) { + render_cached = true; - log_warning("RENDER", exception_print(exception), self); + if(!is_instanceof(self, Node_Collection)) setRenderStatus(true); + } else { + render_cached = false; + getInputs(frame); + + LOG_BLOCK_START(); + LOG_IF(global.FLAG.render == 1, $">>>>>>>>>> DoUpdate called from {INAME} <<<<<<<<<<"); + + if(!is_instanceof(self, Node_Collection)) setRenderStatus(true); + var sBase = surface_get_target(); + + try { + update(frame); + } catch(exception) { + var sCurr = surface_get_target(); + while(surface_get_target() != sBase) + surface_reset_target(); + + log_warning("RENDER", exception_print(exception), self); + } } - if(!use_cache && PROJECT.onion_skin) { + postUpdate(frame); + cached_manual = false; + + if(!use_cache && PROJECT.onion_skin.enabled) { for( var i = 0; i < ds_list_size(outputs); i++ ) { if(outputs[| i].type != VALUE_TYPE.surface) continue; cacheCurrentFrame(outputs[| i].getValue()); @@ -395,39 +688,53 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x } } - if(hasInspector1Update()) { - var trigger = inspectInput1.getValue(); - if(trigger) onInspector1Update(); - } + if(NODE_HAS_INSP1 && inspectInput1.getValue()) onInspector1Update(); + if(NODE_HAS_INSP2 && inspectInput2.getValue()) onInspector2Update(); - if(hasInspector2Update()) { - var trigger = inspectInput2.getValue(); - if(trigger) onInspector2Update(); - } + updatedOutTrigger.setValue(true); + + if(!is_instanceof(self, Node_Collection)) + render_time = get_timer() - render_timer; + + refreshNodeDisplay(); LOG_BLOCK_END(); - } + } #endregion - static valueUpdate = function(index) { - if(error_update_enabled && error_noti_update == noone) - error_noti_update = noti_error(getFullName() + " node require manual execution.",, self); + static cacheCheck = function() { #region + INLINE + + if(cache_group) cache_group.enableNodeGroup(); + if(group != noone) group.cacheCheck(); + } #endregion + + static valueUpdate = function(index) { #region onValueUpdate(index); - } + + if(is_dynamic_input) will_setHeight = true; + cacheCheck(); + } #endregion + + static valueFromUpdate = function(index) { #region + onValueFromUpdate(index); + + if(is_dynamic_input) will_setHeight = true; + cacheCheck(); + } #endregion static onValueUpdate = function(index = 0) {} static onValueFromUpdate = function(index) {} - static triggerRender = function() { + static triggerRender = function() { #region LOG_BLOCK_START(); - LOG_IF(global.FLAG.render, $"Trigger render for {internalName}"); + LOG_IF(global.FLAG.render == 1, $"Trigger render for {self}"); - setRenderStatus(false); - UPDATE |= RENDER_TYPE.partial; + resetRender(false); + RENDER_PARTIAL - if(is_instanceof(group, Node_Collection) && group.reset_all_child) { - group.resetRender(); + if(is_instanceof(group, Node_Collection)) { + group.triggerRender(); } else { - resetRender(); var nodes = getNextNodesRaw(); for(var i = 0; i < array_length(nodes); i++) @@ -435,291 +742,582 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x } LOG_BLOCK_END(); - } + } #endregion - static resetRender = function() { setRenderStatus(false); } - static isRenderActive = function() { return renderActive || (PREF_MAP[? "render_all_export"] && PROJECT.animator.rendering); } + static clearTopoSorted = function() { INLINE topoSorted = false; } - static isRenderable = function(log = false) { //Check if every input is ready (updated) - if(!active) return false; - if(!isRenderActive()) return false; + static forwardPassiveDynamic = function() { #region + rendered = false; - //if(group && struct_has(group, "iterationStatus") && group.iterationStatus() == ITERATION_STATUS.complete) return false; - - for(var j = 0; j < ds_list_size(inputs); j++) { - var _in = inputs[| j]; - if( _in.type == VALUE_TYPE.node) continue; + for( var i = 0, n = ds_list_size(outputs); i < n; i++ ) { + var _outp = outputs[| i]; - var val_from = _in.value_from; - if( val_from == noone) continue; - if(!val_from.node.active) continue; - if(!val_from.node.isRenderActive()) continue; - if!(val_from.node.rendered || val_from.node.update_on_frame) { - LOG_LINE_IF(global.FLAG.render, $"Node {internalName} is not renderable because input {val_from.node.internalName} is not rendered ({val_from.node.rendered})"); - return false; + for(var j = 0; j < array_length(_outp.value_to); j++) { + var _to = _outp.value_to[j]; + if(!_to.node.active || _to.value_from != _outp) continue; + + //LOG_IF(global.FLAG.render == 1, $"|| Forwarding dynamic to {_to.node.name} ||"); + _to.node.passiveDynamic = true; + _to.node.rendered = false; } } + } #endregion + + static resetRender = function(_clearCache = false) { #region + setRenderStatus(false); + if(_clearCache) clearInputCache(); + } #endregion + + static isLeaf = function() { #region + INLINE + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _inp = inputs[| i]; + if(!_inp.isLeaf()) return false; + } return true; - } + } #endregion - static getNextNodesRaw = function() { return getNextNodes(); } + static isLeafList = function(list = noone) { #region + INLINE + + if(list == noone) return isLeaf(); + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _inp = inputs[| i]; + if(!_inp.isLeafList(list)) return false; + } + + return true; + } #endregion - static getNextNodes = function() { + static isRenderActive = function() { return renderActive || (PREFERENCES.render_all_export && IS_RENDERING); } + + static isRenderable = function(log = false) { #region //Check if every input is ready (updated) + if(!active) return false; + if(!isRenderActive()) return false; + + for(var j = 0; j < ds_list_size(inputs); j++) + if(!inputs[| j].isRendered()) return false; + + return true; + } #endregion + + static setRenderStatus = function(result) { #region + INLINE + + if(rendered == result) return; + LOG_LINE_IF(global.FLAG.render == 1, $"Set render status for {self} : {result}"); + + rendered = result; + } #endregion + + static getPreviousNodes = function() { #region + var prev = []; + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _in = inputs[| i]; + + if(_in.value_from != noone) { + if(in_VFX && !_in.value_from.node.in_VFX) { + array_push(in_VFX.prev_nodes, _in.value_from.node); + array_push(prev, in_VFX); + continue; + } + + array_push_unique(prev, _in.value_from.node); + } + + if(_in.value_from_loop != noone) + array_push_unique(prev, _in.value_from_loop); + } + + onGetPreviousNodes(prev); + return prev; + } #endregion + + static onGetPreviousNodes = function(arr) {} + + static getNextNodes = function() { #region var nodes = []; var nodeNames = []; LOG_BLOCK_START(); - LOG_IF(global.FLAG.render, $"→→→→→ Call get next node from: {internalName}"); + LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from: {INAME}"); LOG_BLOCK_START(); for(var i = 0; i < ds_list_size(outputs); i++) { var _ot = outputs[| i]; - if(!_ot.forward) continue; + if(!_ot.forward) continue; + for( var j = 0, n = array_length(_ot.value_to_loop); j < n; j++ ) { + var _to = _ot.value_to_loop[j]; + if(!_to.active) continue; + if(!_to.bypassNextNode()) continue; + + LOG_BLOCK_END(); + LOG_BLOCK_END(); + + return _to.getNextNodes(); + } + var _tos = _ot.getJunctionTo(); - for( var j = 0; j < array_length(_tos); j++ ) { var _to = _tos[j]; array_push(nodes, _to.node); array_push(nodeNames, _to.node.internalName); - //LOG_IF(global.FLAG.render, $"→→ Check output: {_ot.name} connect to node {_to.node.internalName}"); + //LOG_IF(global.FLAG.render == 1, $"→→ Check output: {_ot.name} connect to node {_to.node.internalName}"); } } - LOG_IF(global.FLAG.render, $"→→ Push {nodeNames} to stack."); + LOG_IF(global.FLAG.render == 1, $"→→ Push {nodeNames} to queue."); LOG_BLOCK_END(); LOG_BLOCK_END(); return nodes; - } + } #endregion - static isTerminal = function() { + static getNextNodesRaw = function() { #region + var nodes = []; + + for(var i = 0; i < ds_list_size(outputs); i++) { + var _ot = outputs[| i]; + if(!_ot.forward) continue; + if(_ot.type == VALUE_TYPE.node) continue; + + for( var j = 0, n = array_length(_ot.value_to_loop); j < n; j++ ) { + var _to = _ot.value_to_loop[j]; + if(!_to.active) continue; + if(!_to.bypassNextNode()) continue; + + return _to.getNextNodes(); + } + + var _tos = _ot.getJunctionTo(); + for( var j = 0; j < array_length(_tos); j++ ) + array_push(nodes, _tos[j].node); + } + + return nodes; + } #endregion + + static isTerminal = function() { #region for( var i = 0; i < ds_list_size(outputs); i++ ) { var _to = outputs[| i].getJunctionTo(); if(array_length(_to)) return false; } return true; - } + } #endregion static onInspect = function() {} - static setRenderStatus = function(result) { - LOG_LINE_IF(global.FLAG.render, $"Set render status for {internalName} : {result}"); - - rendered = result; - } - - static pointIn = function(_x, _y, _mx, _my, _s) { + static pointIn = function(_x, _y, _mx, _my, _s) { #region var xx = x * _s + _x; var yy = y * _s + _y; return point_in_rectangle(_mx, _my, xx, yy, xx + w * _s, yy + h * _s); - } + } #endregion - draw_graph_culled = false; - static cullCheck = function(_x, _y, _s, minx, miny, maxx, maxy) { + static cullCheck = function(_x, _y, _s, minx, miny, maxx, maxy) { #region var x0 = x * _s + _x; var y0 = y * _s + _y; var x1 = (x + w) * _s + _x; var y1 = (y + h) * _s + _y; + draw_boundary[0] = minx; + draw_boundary[1] = miny; + draw_boundary[2] = maxx; + draw_boundary[3] = maxy; + draw_graph_culled = !rectangle_in_rectangle(minx, miny, maxx, maxy, x0, y0, x1, y1); - } + } #endregion - static preDraw = function(_x, _y, _s) { + static refreshNodeDisplay = function() { #region + INLINE + + updateIO(); + setHeight(); + getJunctionList(); + } run_in(1, function() { refreshNodeDisplay(); }); #endregion + + static getJunctionList = function() { #region + var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); + inputDisplayList = []; + + for(var i = 0; i < amo; i++) { + var ind = getInputJunctionIndex(i); + if(ind == noone) continue; + + var jun = ds_list_get(inputs, ind, noone); + if(jun == noone || is_undefined(jun)) continue; + if(!jun.isVisible()) continue; + + array_push(inputDisplayList, jun); + } + }#endregion + + static preDraw = function(_x, _y, _s) { #region var xx = x * _s + _x; var yy = y * _s + _y; var jun; - var inspCount = hasInspector1Update() + hasInspector2Update(); + var inspCount = NODE_HAS_INSP1 + NODE_HAS_INSP2; var ind = 1; - if(hasInspector1Update()) { + if(NODE_HAS_INSP1) { inspectInput1.x = xx + w * _s * ind / (inspCount + 1); inspectInput1.y = yy; ind++; } - if(hasInspector2Update()) { + if(NODE_HAS_INSP2) { inspectInput2.x = xx + w * _s * ind / (inspCount + 1); inspectInput2.y = yy; ind++; } - var inamo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); - var _in = yy + ui(32) * _s; + updatedInTrigger.x = xx; + updatedInTrigger.y = yy + 10; - for(var i = 0; i < inamo; i++) { - var idx = getInputJunctionIndex(i); - if(idx == noone) continue; + updatedOutTrigger.x = xx + w * _s; + updatedOutTrigger.y = yy + 10; + + if(in_cache_len != array_length(inputDisplayList) || out_cache_len != ds_list_size(outputs)) { + refreshNodeDisplay(); - jun = ds_list_get(inputs, idx, noone); - if(jun == noone || is_undefined(jun)) continue; + in_cache_len = array_length(inputDisplayList); + out_cache_len = ds_list_size(outputs); + } + + var _iny = yy + (junction_draw_pad_y + junction_draw_hei_y * 0.5 * show_parameter) * _s; + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + jun = inputs[| i]; jun.x = xx; - jun.y = _in; - _in += 24 * _s * jun.isVisible(); + jun.y = _iny; } - var outamo = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list); + for(var i = 0; i < in_cache_len; i++) { + jun = inputDisplayList[i]; + + jun.x = xx; + jun.y = _iny; + _iny += junction_draw_hei_y * _s; + } - xx = xx + w * _s; - _in = yy + ui(32) * _s; - for(var i = 0; i < outamo; i++) { - var idx = getOutputJunctionIndex(i); + xx = xx + w * _s; + var _outy = yy + (junction_draw_pad_y + junction_draw_hei_y * 0.5 * show_parameter) * _s; + + for(var i = 0; i < outputs_amount; i++) { + var idx = outputs_index[i]; jun = outputs[| idx]; jun.x = xx; - jun.y = _in; - _in += 24 * _s * jun.isVisible(); + jun.y = _outy; + _outy += junction_draw_hei_y * _s * jun.isVisible(); } - } + + onPreDraw(_x, _y, _s, _iny, _outy); + } #endregion - static drawNodeBase = function(xx, yy, _s) { + static onPreDraw = function(_x, _y, _s, _iny, _outy) {} + + static isHighlightingInGraph = function() { #region + var high = display_parameter.highlight; + var _selc = active_draw_index == 0 || branch_drawing; + return !high || _selc; + } #endregion + + static getColor = function() { #region + INLINE + return attributes.color == -1? color : attributes.color; + } #endregion + + static drawNodeBase = function(xx, yy, _s) { #region if(draw_graph_culled) return; if(!active) return; + var aa = 0.25 + 0.5 * renderActive; - draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, color, aa); - } - - static drawGetBbox = function(xx, yy, _s) { - var x0 = xx + draw_padding * _s; - var x1 = xx + (w - draw_padding) * _s; - var y0 = yy + 20 * draw_name + draw_padding * _s; - var y1 = yy + (h - draw_padding) * _s; + if(!isHighlightingInGraph()) aa *= 0.25; + var cc = getColor(); - return BBOX().fromPoints(x0, y0, x1, y1); - } + draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, cc, aa); + } #endregion - static drawNodeName = function(xx, yy, _s) { - if(draw_graph_culled) return; - if(!active) return; + __draw_bbox = BBOX(); + static drawGetBbox = function(xx, yy, _s) { #region + var pad_label = draw_name && display_parameter.avoid_label; - draw_name = false; - var _name = display_name == ""? name : display_name; + var _w = w; + var _h = show_parameter? min_h : h; + + _w *= _s; + _h *= _s; + + _w -= draw_padding * 2; + _h -= draw_padding * 2 + 20 * pad_label; + + var _xc = xx + w * _s / 2; + var _yc = yy + _h / 2 + pad_label * 20 + draw_padding; + + _w *= display_parameter.preview_scale / 100; + _h *= display_parameter.preview_scale / 100; + + var x0 = _xc - _w / 2; + var x1 = _xc + _w / 2; + var y0 = _yc - _h / 2; + var y1 = _yc + _h / 2; + + return __draw_bbox.fromPoints(x0, y0, x1, y1); + } #endregion + + static drawNodeName = function(xx, yy, _s) { #region + + var _name = renamed? display_name : name; if(_name == "") return; - if(_s < 0.75) return; + draw_name = true; var aa = 0.25 + 0.5 * renderActive; - draw_sprite_stretched_ext(THEME.node_bg_name, 0, xx, yy, w * _s, ui(20), color, aa); + if(!isHighlightingInGraph()) aa *= 0.25; + var cc = getColor(); + + draw_sprite_stretched_ext(THEME.node_bg_name, 0, xx, yy, w * _s, ui(20), cc, aa); var cc = COLORS._main_text; - if(PREF_MAP[? "node_show_render_status"] && !rendered) + if(PREFERENCES.node_show_render_status && !rendered) cc = isRenderable()? COLORS._main_value_positive : COLORS._main_value_negative; draw_set_text(f_p1, fa_left, fa_center, cc); - if(hasInspector1Update()) icon = THEME.refresh_s; + if(NODE_HAS_INSP1) icon = THEME.refresh_16; var ts = clamp(power(_s, 0.5), 0.5, 1); var aa = 0.5 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; + draw_set_alpha(aa); if(icon && _s > 0.75) { draw_sprite_ui_uniform(icon, 0, xx + ui(12), yy + ui(10),,, aa); - draw_text_cut(xx + ui(24), yy + ui(10), _name, w * _s - ui(24), ts); + draw_text_cut(round(xx + ui(24)), round(yy + ui(10)), _name, w * _s - ui(24), ts); } else - draw_text_cut(xx + ui(8), yy + ui(10), _name, w * _s - ui(8), ts); + draw_text_cut(round(xx + ui(8)), round(yy + ui(10)), _name, w * _s - ui(8), ts); draw_set_alpha(1); - } + } #endregion - static drawJunctions = function(_x, _y, _mx, _my, _s) { + static drawJunctionWidget = function(_x, _y, _mx, _my, _s, _hover, _focus) { #region + + var hover = noone; + + var wh = junction_draw_hei_y * _s; + var ww = w * _s * 0.5; + var wt = w * _s * 0.25; + var wx = _x + w * _s - ww - 8; + var lx = _x + 12 * _s; + + var _m = [ _mx, _my ]; + var rx = PANEL_GRAPH.x; + var ry = PANEL_GRAPH.y; + + var jy = _y + junction_draw_pad_y * _s + wh / 2; + + var boundH = _x > draw_boundary[0] - w * _s && _x < draw_boundary[2]; + var boundV = 1;//_y > draw_boundary[1] - h * _s && _y < draw_boundary[3]; + var extY = 0; + var drawText = _s > 0.5; + + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + var wd = jun.graphWidget; + + jun.y = jy; + + if(drawText) { + draw_set_text(f_sdf, fa_left, fa_center, jun.color_display); + draw_text_add(lx, jun.y, jun.getName(), _s * 0.25); + + } else { + draw_set_color(jun.color_display); + draw_rectangle(lx, jun.y - 1 * _s, lx + wt, jun.y + 4 * _s, false); + } + + if(jun.value_from || wd == noone) { + jy += wh; + continue; + } + + var _param = jun.graphWidgetP; + + _param.w = ww; + _param.h = wh - 4 * _s; + _param.x = wx; + _param.y = jy - _param.h / 2; + + _param.data = jun.showValue(); + _param.m = _m; + _param.rx = rx; + _param.ry = ry; + _param.s = wh; + _param.font = f_p2; + + if(is_instanceof(jun, checkBox)) + _param.halign = fa_center; + + wd.setInteract(wh > line_get_height(f_p2)); + wd.setFocusHover(_focus, _hover); + var _h = wd.drawParam(_param); + jun.graphWidgetH = _h / _s; + + extY += max(0, (jun.graphWidgetH + 4) - junction_draw_hei_y); + + if(wd.isHovering()) draggable = false; + + jy += (jun.graphWidgetH + 4) * _s; + } + + h = fix_h + extY; + } #endregion + + static drawJunctions = function(_x, _y, _mx, _my, _s) { #region if(!active) return; var hover = noone; - var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); - var jun; - for(var i = 0; i < amo; i++) { - var ind = getInputJunctionIndex(i); - if(ind == noone) continue; - jun = ds_list_get(inputs, ind, noone); - if(jun == noone || is_undefined(jun)) continue; + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; if(jun.drawJunction(_s, _mx, _my)) hover = jun; } for(var i = 0; i < ds_list_size(outputs); i++) { - jun = outputs[| i]; + var jun = outputs[| i]; + if(!jun.isVisible()) continue; if(jun.drawJunction(_s, _mx, _my)) hover = jun; } - if(hasInspector1Update() && inspectInput1.drawJunction(_s, _mx, _my)) + if(NODE_HAS_INSP1 && inspectInput1.drawJunction(_s, _mx, _my)) hover = inspectInput1; - if(hasInspector2Update() && inspectInput2.drawJunction(_s, _mx, _my)) + if(NODE_HAS_INSP2 && inspectInput2.drawJunction(_s, _mx, _my)) hover = inspectInput2; + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawJunction(_s, _mx, _my)) hover = updatedInTrigger; + if(updatedOutTrigger.drawJunction(_s, _mx, _my)) hover = updatedOutTrigger; + } + + onDrawJunctions(_x, _y, _mx, _my, _s); + return hover; - } + } #endregion - static drawJunctionNames = function(_x, _y, _mx, _my, _s) { + static drawJunctions_fast = function(_x, _y, _mx, _my, _s) { #region + if(!active) return; + var hover = noone; + + _s = _s * 6; + + draw_set_circle_precision(4); + + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + + if(jun.drawJunction_fast(_s, _mx, _my)) + hover = jun; + } + + for(var i = 0; i < ds_list_size(outputs); i++) { + var jun = outputs[| i]; + + if(jun.drawJunction_fast(_s, _mx, _my)) + hover = jun; + } + + if(NODE_HAS_INSP1 && inspectInput1.drawJunction_fast(_s, _mx, _my)) + hover = inspectInput1; + + if(NODE_HAS_INSP2 && inspectInput2.drawJunction_fast(_s, _mx, _my)) + hover = inspectInput2; + + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawJunction_fast(_s, _mx, _my)) hover = updatedInTrigger; + if(updatedOutTrigger.drawJunction_fast(_s, _mx, _my)) hover = updatedOutTrigger; + } + + onDrawJunctions(_x, _y, _mx, _my, _s / 6); + + return hover; + } #endregion + + static onDrawJunctions = function(_x, _y, _mx, _my, _s) {} + + static drawJunctionNames = function(_x, _y, _mx, _my, _s) { #region if(draw_graph_culled) return; if(!active) return; + var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list); var jun; var xx = x * _s + _x; var yy = y * _s + _y; - show_input_name = PANEL_GRAPH.pHOVER && point_in_rectangle(_mx, _my, xx - 8 * _s, yy + 20 * _s, xx + 8 * _s, yy + h * _s); - show_output_name = PANEL_GRAPH.pHOVER && point_in_rectangle(_mx, _my, xx + (w - 8) * _s, yy + 20 * _s, xx + (w + 8) * _s, yy + h * _s); + var _hov = PANEL_GRAPH.pHOVER && (PANEL_GRAPH.node_hovering == noone || PANEL_GRAPH.node_hovering == self); + show_input_name = _hov && point_in_rectangle(_mx, _my, xx - 8 * _s, yy + 20 * _s, xx + 8 * _s, yy + h * _s); + show_output_name = _hov && point_in_rectangle(_mx, _my, xx + (w - 8) * _s, yy + 20 * _s, xx + (w + 8) * _s, yy + h * _s); if(show_input_name) { - for(var i = 0; i < amo; i++) { - var ind = getInputJunctionIndex(i); - if(ind == noone) continue; - if(!inputs[| ind]) continue; - - inputs[| ind].drawNameBG(_s); + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + jun.drawNameBG(_s); } - for(var i = 0; i < amo; i++) { - var ind = getInputJunctionIndex(i); - if(ind == noone) continue; - if(!inputs[| ind]) continue; - - inputs[| ind].drawName(_s, _mx, _my); + for(var i = 0, n = array_length(inputDisplayList); i < n; i++) { + var jun = inputDisplayList[i]; + jun.drawName(_s, _mx, _my); } } if(show_output_name) { for(var i = 0; i < ds_list_size(outputs); i++) - outputs[| i].drawNameBG(_s); + if(outputs[| i].visible) outputs[| i].drawNameBG(_s); for(var i = 0; i < ds_list_size(outputs); i++) - outputs[| i].drawName(_s, _mx, _my); + if(outputs[| i].visible) outputs[| i].drawName(_s, _mx, _my); } - if(hasInspector1Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) { + if(NODE_HAS_INSP1 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput1.x, inspectInput1.y, 10)) { inspectInput1.drawNameBG(_s); inspectInput1.drawName(_s, _mx, _my); } - if(hasInspector2Update() && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) { + if(NODE_HAS_INSP2 && PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, inspectInput2.x, inspectInput2.y, 10)) { inspectInput2.drawNameBG(_s); inspectInput2.drawName(_s, _mx, _my); } - } + } #endregion - static drawConnections = function(_x, _y, _s, mx, my, _active, aa = 1, minx = undefined, miny = undefined, maxx = undefined, maxy = undefined) { + static drawConnections = function(params = {}) { #region if(!active) return; var hovering = noone; var drawLineIndex = 1; + var high = params.highlight; // 0 + var bg = params.bg; // 0 + for(var i = 0; i < ds_list_size(outputs); i++) { var jun = outputs[| i]; var connected = false; - for( var j = 0; j < ds_list_size(jun.value_to); j++ ) { - if(jun.value_to[| j].value_from == jun) + for( var j = 0; j < array_length(jun.value_to); j++ ) { + if(jun.value_to[j].value_from == jun) connected = true; } @@ -727,13 +1325,24 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x jun.drawLineIndex = drawLineIndex; drawLineIndex += 0.5; } + + if(high) { + jun.draw_blend_color = bg; + jun.draw_blend = PREFERENCES.connection_line_highlight_fade; + } else { + jun.draw_blend_color = bg; + jun.draw_blend = -1; + } + } var st = 0; - if(hasInspector1Update()) st = -1; - if(hasInspector2Update()) st = -2; + if(NODE_HAS_INSP1) st = -1; + if(NODE_HAS_INSP2) st = -2; + + var _inputs = array_create(ds_list_size(inputs)); + var _len = 0; - var _inputs = []; var drawLineIndex = 1; for(var i = st; i < ds_list_size(inputs); i++) { var jun; @@ -741,39 +1350,64 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x else if(i == -2) jun = inspectInput2; else jun = inputs[| i]; - if(jun.value_from == noone) continue; + if(high) { + jun.draw_blend_color = bg; + jun.draw_blend = PREFERENCES.connection_line_highlight_fade; + } else { + jun.draw_blend_color = bg; + jun.draw_blend = -1; + } + + if(jun.isLeaf()) continue; if(!jun.value_from.node.active) continue; if(!jun.isVisible()) continue; - if(i >= 0) - array_push(_inputs, jun); + if(i >= 0) _inputs[_len++] = jun; } - var len = array_length(_inputs); - for( var i = 0; i < len; i++ ) - _inputs[i].drawLineIndex = 1 + (i > len / 2? (len - 1 - i) : i) * 0.5; - - for(var i = st; i < ds_list_size(inputs); i++) { - var jun; - if(i == -1) jun = inspectInput1; - else if(i == -2) jun = inspectInput2; - else jun = inputs[| i]; + for( var i = 0; i < _len; i++ ) { + var jun = _inputs[i]; - var hov = jun.drawConnections(_x, _y, _s, mx, my, _active, aa, minx, miny, maxx, maxy); + jun.drawLineIndex = 1 + (i > _len / 2? (_len - 1 - i) : i) * 0.5; + var hov = jun.drawConnections(params); if(hov) hovering = hov; } + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawConnections(params)) hovering = updatedInTrigger; + if(updatedOutTrigger.drawConnections(params)) hovering = updatedOutTrigger; + } + return hovering; - } + } #endregion - static drawPreview = function(xx, yy, _s) { - if(draw_graph_culled) return; - if(!active) return; - + static getGraphPreviewSurface = function() { #region var _node = outputs[| preview_channel]; - if(_node.type != VALUE_TYPE.surface) return; + if(!is_instanceof(_node, NodeValue)) return noone; + + switch(_node.type) { + case VALUE_TYPE.surface : + case VALUE_TYPE.dynaSurface : + var val = _node.showValue(); + return val; + } + + return noone; + } #endregion + + __preview_surf = false; + __preview_sw = noone; + __preview_sh = noone; + + static setPreview = function(_surf) { #region + preview_surface = _surf; + __preview_surf = is_surface(_surf); + } #endregion + + static drawPreview = function(xx, yy, _s) { #region + var surf = getGraphPreviewSurface(); + if(surf == noone) return; - var surf = _node.getValue(); preview_amount = 0; if(is_array(surf)) { if(array_length(surf) == 0) return; @@ -789,61 +1423,31 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x surf = surf[preview_index]; } - preview_surface = is_surface(surf)? surf : noone; - if(preview_surface == noone) return; + setPreview(surf); + if(!__preview_surf) return; - var pw = surface_get_width(preview_surface); - var ph = surface_get_height(preview_surface); - var ps = min((w * _s - 8) / pw, (h * _s - 8) / ph); - var px = xx + w * _s / 2 - pw * ps / 2; - var py = yy + h * _s / 2 - ph * ps / 2; - var aa = 0.5 + 0.5 * renderActive; + __preview_sw = surface_get_width_safe(preview_surface); + __preview_sh = surface_get_height_safe(preview_surface); - if(preview_trans == 1) { - draw_surface_ext_safe(preview_surface, px, py, ps, ps, 0, c_white, aa); - return; - } + var bbox = drawGetBbox(xx, yy, _s); + var aa = 0.5 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; - if(preview_trans < 1 && is_surface(preview_surface_prev)) { - preview_trans = lerp_float(preview_trans, 1, 8); - var _pw = surface_get_width(preview_surface_prev); - var _ph = surface_get_height(preview_surface_prev); - var _ps = min((w * _s - 8) / _pw, (h * _s - 8) / _ph); - var _px = xx + w * _s / 2 - _pw * _ps / 2; - var _py = yy + h * _s / 2 - _ph * _ps / 2; - - draw_surface_ext_safe(preview_surface_prev, _px, _py, _ps, _ps, 0, c_white, aa); - - shader_set(sh_trans_node_prev_drop); - shader_set_f("dimension", _pw, _ph); - shader_set_f("position", (preview_drop_x - px) / (_pw * _ps), (preview_drop_y - py) / (_ph * _ps)); - shader_set_f("prog", preview_trans); - draw_surface_ext_safe(preview_surface, px, py, ps, ps, 0, c_white, aa); - shader_reset(); - } else if(is_surface(preview_surface_prev)) - surface_free(preview_surface_prev); - } + var _sw = __preview_sw; + var _sh = __preview_sh; + var _ss = min(bbox.w / _sw, bbox.h / _sh); + draw_surface_ext_safe(preview_surface, bbox.xc - _sw * _ss / 2, bbox.yc - _sh * _ss / 2, _ss, _ss); + } #endregion - static previewDropAnimation = function() { - preview_surface_prev = surface_clone(preview_surface); - preview_trans = 0; - preview_drop_x = preview_mx; - preview_drop_y = preview_my; - } - - static getNodeDimension = function(showFormat = true) { - if(!is_surface(preview_surface)) { - if(ds_list_size(outputs)) - return "[" + array_shape(outputs[| 0].getValue()) + "]"; - return ""; - } + static getNodeDimension = function(showFormat = true) { #region + if(!__preview_surf) return preview_array; - var pw = surface_get_width(preview_surface); - var ph = surface_get_height(preview_surface); - var format = surface_get_format(preview_surface); + var pw = surface_get_width_safe(preview_surface); + var ph = surface_get_height_safe(preview_surface); + var format = surface_get_format_safe(preview_surface); - var txt = "[" + string(pw) + " x " + string(ph) + " "; - if(preview_amount) txt = string(preview_amount) + " x " + txt; + var txt = $"[{pw} x {ph} "; + if(preview_amount) txt = $"{preview_amount} x {txt}"; switch(format) { case surface_rgba4unorm : txt += showFormat? "4RGBA" : "4R"; break; @@ -858,9 +1462,9 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x txt += "]"; return txt; - } + } #endregion - static drawDimension = function(xx, yy, _s) { + static drawDimension = function(xx, yy, _s) { #region if(draw_graph_culled) return; if(!active) return; if(_s * w < 64) return; @@ -869,17 +1473,21 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var tx = xx + w * _s / 2; var ty = yy + (h + 4) * _s - 2; - if(PANEL_GRAPH.show_dimension) { + if(struct_get(display_parameter, "show_dimension")) { var txt = string(getNodeDimension(_s > 0.65)); draw_text(round(tx), round(ty), txt); - ty += string_height(txt) - 2; + ty += line_get_height(f_p2) - 2; } draw_set_font(f_p3); - if(PANEL_GRAPH.show_compute) { - var rt, unit; - if(render_time < 1000) { + if(struct_get(display_parameter, "show_compute")) { + var rt = 0, unit = ""; + + if(render_time == 0) { + draw_set_color(COLORS._main_text_sub); + unit = "us"; + } else if(render_time < 1000) { rt = round(render_time / 10) * 10; unit = "us"; draw_set_color(COLORS.speed[2]); @@ -892,45 +1500,68 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x unit = "s"; draw_set_color(COLORS.speed[0]); } + + if(render_cached) draw_set_color(COLORS._main_text_sub); + draw_text(round(tx), round(ty), string(rt) + " " + unit); } - } + } #endregion - static drawNode = function(_x, _y, _mx, _my, _s) { + static groupCheck = function(_x, _y, _s, _mx, _my) {} + + static drawNodeBG = function(_x, _y, _mx, _my, _s, display_parameter = noone) { return false; } + + static drawNode = function(_x, _y, _mx, _my, _s, display_parameter = noone) { #region if(draw_graph_culled) return; if(!active) return; + if(display_parameter != noone) + self.display_parameter = display_parameter; + var xx = x * _s + _x; var yy = y * _s + _y; preview_mx = _mx; preview_my = _my; - if(value_validation[VALIDATION.error] || error_noti_update != noone) - draw_sprite_stretched_ext(THEME.node_glow, 0, xx - 9, yy - 9, w * _s + 18, h * _s + 18, COLORS._main_value_negative, 1); + if(value_validation[VALIDATION.error]) + draw_sprite_stretched_ext(THEME.node_glow_border, 0, xx - 9, yy - 9, w * _s + 18, h * _s + 18, COLORS._main_value_negative, 1); drawNodeBase(xx, yy, _s); - if(previewable && ds_list_size(outputs) > 0) { - if(preview_channel >= ds_list_size(outputs)) - preview_channel = 0; - drawPreview(xx, yy, _s); - } drawDimension(xx, yy, _s); - onDrawNode(xx, yy, _mx, _my, _s, PANEL_GRAPH.node_hovering == self, PANEL_GRAPH.node_focus == self); - drawNodeName(xx, yy, _s); + draggable = true; + + if(previewable) { + if(preview_draw) drawPreview(xx, yy, _s); + + try { + var _hover = PANEL_GRAPH.node_hovering == self; + var _focus = PANEL_GRAPH.getFocusingNode() == self; + + onDrawNode(xx, yy, _mx, _my, _s, _hover, _focus); + } + catch(e) { log_warning("NODE onDrawNode", exception_print(e)); } + } + + if(show_parameter) + drawJunctionWidget(xx, yy, _mx, _my, _s, _hover, _focus); + + draw_name = false; + if(_s >= 0.75) drawNodeName(xx, yy, _s); if(active_draw_index > -1) { draw_sprite_stretched_ext(bg_sel_spr, 0, xx, yy, round(w * _s), round(h * _s), active_draw_index > 1? COLORS.node_border_file_drop : COLORS._main_accent, 1); active_draw_index = -1; } - if(draw_droppable) + if(draw_droppable) { draw_sprite_stretched_ext(THEME.ui_panel_active, 0, xx, yy, w * _s, h * _s, COLORS._main_value_positive, 1); - draw_droppable = false; + draw_droppable = false; + } - return drawJunctions(xx, yy, _mx, _my, _s); - } + return _s > 0.5? drawJunctions(xx, yy, _mx, _my, _s) : drawJunctions_fast(xx, yy, _mx, _my, _s); + } #endregion static onDrawNodeBehind = function(_x, _y, _mx, _my, _s) {} @@ -938,9 +1569,9 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x static onDrawHover = function(_x, _y, _mx, _my, _s) {} - badgePreview = 0; - badgeInspect = 0; - static drawBadge = function(_x, _y, _s) { + static drawPreviewBackground = function(_x, _y, _mx, _my, _s) { return false; } + + static drawBadge = function(_x, _y, _s) { #region if(!active) return; var xx = x * _s + _x + w * _s; var yy = y * _s + _y; @@ -949,7 +1580,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x badgeInspect = lerp_float(badgeInspect, inspecting, 2); if(badgePreview > 0) { - draw_sprite_ext(THEME.node_state, 0, xx, yy, badgePreview, badgePreview, 0, c_white, 1); + draw_sprite_ext(THEME.node_state, is_3D? 3 : 0, xx, yy, badgePreview, badgePreview, 0, c_white, 1); xx -= 28 * badgePreview; } @@ -965,37 +1596,57 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x inspecting = false; previewing = 0; - } + } #endregion - active_draw_index = -1; - static drawActive = function(_x, _y, _s, ind = 0) { - active_draw_index = ind; - } + static drawBranch = function(_depth = 0) { #region + if(branch_drawing) return; + branch_drawing = true; + + if(!PREFERENCES.connection_line_highlight_all && _depth == 1) return; + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + if(inputs[| i].isLeaf()) continue; + inputs[| i].value_from.node.drawBranch(_depth + 1); + } + } #endregion - static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {} + static drawActive = function(_x, _y, _s, ind = 0) { #region + active_draw_index = ind; + if(display_parameter.highlight) drawBranch(); + } #endregion + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} + + static drawPreviewToolOverlay = function(hover, active, _mx, _my, _panel) { return false; } static drawAnimationTimeline = function(_w, _h, _s) {} - static enable = function() { active = true; } - static disable = function() { active = false; } + static getAnimationCacheExist = function(frame) { return cacheExist(frame); } - static destroy = function(_merge = false) { + static enable = function() { INLINE active = true; timeline_item.active = true; } + static disable = function() { INLINE active = false; timeline_item.active = false; } + + static onDestroy = function() {} + + static destroy = function(_merge = false, record = true) { #region if(!active) return; disable(); - if(PANEL_GRAPH.node_hover == self) PANEL_GRAPH.node_hover = noone; - if(PANEL_GRAPH.node_focus == self) PANEL_GRAPH.node_focus = noone; - if(PANEL_INSPECTOR.inspecting == self) PANEL_INSPECTOR.inspecting = noone; + ds_list_remove(group == noone? PROJECT.nodes : group.getNodeList(), self); + + if(PANEL_GRAPH.node_hover == self) PANEL_GRAPH.node_hover = noone; + PANEL_GRAPH.nodes_selecting = []; + + if(PANEL_INSPECTOR.inspecting == self) PANEL_INSPECTOR.inspecting = noone; PANEL_PREVIEW.removeNodePreview(self); - PANEL_ANIMATION.updatePropertyList(); for(var i = 0; i < ds_list_size(outputs); i++) { var jun = outputs[| i]; - for(var j = 0; j < ds_list_size(jun.value_to); j++) { - var _vt = jun.value_to[| j]; - if(_vt.value_from == noone) break; + for(var j = 0; j < array_length(jun.value_to); j++) { + var _vt = jun.value_to[j]; + if(_vt.isLeaf()) break; if(_vt.value_from.node != self) break; _vt.removeFrom(false); @@ -1003,12 +1654,12 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(!_merge) continue; for( var k = 0; k < ds_list_size(inputs); k++ ) { - if(inputs[| k].value_from == noone) continue; + if(inputs[| k].isLeaf()) continue; if(_vt.setFrom(inputs[| k].value_from)) break; } } - ds_list_clear(jun.value_to); + jun.value_to = []; } for( var i = 0; i < ds_list_size(inputs); i++ ) @@ -1018,15 +1669,28 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x outputs[| i].destroy(); onDestroy(); - } + if(group) group.refreshNodes(); + + if(record) recordAction(ACTION_TYPE.node_delete, self); + + RENDER_ALL_REORDER + } #endregion - static restore = function() { + static onRestore = function() {} + + static restore = function() { #region if(active) return; enable(); + ds_list_add(group == noone? PROJECT.nodes : group.getNodeList(), self); - } + + onRestore(); + if(group) group.refreshNodes(); + + RENDER_ALL_REORDER + } #endregion - static onValidate = function() { + static onValidate = function() { #region value_validation[VALIDATION.pass] = 0; value_validation[VALIDATION.warning] = 0; value_validation[VALIDATION.error] = 0; @@ -1036,71 +1700,70 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(jun.value_validation) value_validation[jun.value_validation]++; } - } + } #endregion - static onDestroy = function() {} - - static clearInputCache = function() { + static clearInputCache = function() { #region for( var i = 0; i < ds_list_size(inputs); i++ ) inputs[| i].cache_value[0] = false; - } + } #endregion - static cacheArrayCheck = function() { - if(array_length(cached_output) != PROJECT.animator.frames_total) - array_resize(cached_output, PROJECT.animator.frames_total); - if(array_length(cache_result) != PROJECT.animator.frames_total) - array_resize(cache_result, PROJECT.animator.frames_total); - } + static cacheArrayCheck = function() { #region + cached_output = array_verify(cached_output, TOTAL_FRAMES); + cache_result = array_verify(cache_result, TOTAL_FRAMES); + } #endregion - static cacheCurrentFrame = function(_frame) { + static cacheCurrentFrame = function(_frame) { #region cacheArrayCheck(); - if(PROJECT.animator.current_frame < 0) return; - if(PROJECT.animator.current_frame >= array_length(cached_output)) return; + if(CURRENT_FRAME < 0) return; + if(CURRENT_FRAME >= array_length(cached_output)) return; - surface_array_free(cached_output[PROJECT.animator.current_frame]); - cached_output[PROJECT.animator.current_frame] = surface_array_clone(_frame); + surface_array_free(cached_output[CURRENT_FRAME]); + cached_output[CURRENT_FRAME] = surface_array_clone(_frame); - array_safe_set(cache_result, PROJECT.animator.current_frame, true); + array_safe_set(cache_result, CURRENT_FRAME, true); - return cached_output[PROJECT.animator.current_frame]; - } + return cached_output[CURRENT_FRAME]; + } #endregion - static cacheExist = function(frame = PROJECT.animator.current_frame) { + static cacheExist = function(frame = CURRENT_FRAME) { #region if(frame < 0) return false; if(frame >= array_length(cached_output)) return false; if(frame >= array_length(cache_result)) return false; - if(!array_safe_get(cache_result, frame, false)) return false; + if(!array_safe_get_fast(cache_result, frame, false)) return false; - var s = array_safe_get(cached_output, frame); + var s = array_safe_get_fast(cached_output, frame); return is_array(s) || surface_exists(s); - } + } #endregion - static getCacheFrame = function(frame = PROJECT.animator.current_frame) { + static getCacheFrame = function(frame = CURRENT_FRAME) { #region if(frame < 0) return false; if(!cacheExist(frame)) return noone; - var surf = array_safe_get(cached_output, frame); + var surf = array_safe_get_fast(cached_output, frame); return surf; - } + } #endregion - static recoverCache = function(frame = PROJECT.animator.current_frame) { + static recoverCache = function(frame = CURRENT_FRAME) { #region if(!cacheExist(frame)) return false; - var _s = cached_output[PROJECT.animator.current_frame]; + var _s = cached_output[CURRENT_FRAME]; outputs[| 0].setValue(_s); return true; - } - static clearCache = function() { + } #endregion + + static clearCache = function(_force = false) { #region clearInputCache(); - if(!clearCacheOnChange) return; - if(!use_cache) return; - if(!isRenderActive()) return; + if(!_force) { + if(!use_cache) return; + if(!clearCacheOnChange) return; + if(!isRenderActive()) return; + } - if(array_length(cached_output) != PROJECT.animator.frames_total) - array_resize(cached_output, PROJECT.animator.frames_total); + if(array_length(cached_output) != TOTAL_FRAMES) + array_resize(cached_output, TOTAL_FRAMES); for(var i = 0; i < array_length(cached_output); i++) { var _s = cached_output[i]; if(is_surface(_s)) @@ -1108,95 +1771,91 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x cached_output[i] = 0; cache_result[i] = false; } - } + } #endregion - static clearCacheForward = function() { - _clearCacheForward(); - } + static clearCacheForward = function() { #region + _clearCacheForward(); + } #endregion - static _clearCacheForward = function() { + static _clearCacheForward = function() { #region if(!isRenderActive()) return; clearCache(); var arr = getNextNodesRaw(); for( var i = 0, n = array_length(arr); i < n; i++ ) arr[i]._clearCacheForward(); + } #endregion + + static cachedPropagate = function(_group = group) { #region + if(group != _group) return; + setRenderStatus(true); - //for( var i = 0; i < ds_list_size(outputs); i++ ) - //for( var j = 0; j < ds_list_size(outputs[| i].value_to); j++ ) - // outputs[| i].value_to[| j].node._clearCacheForward(); - } + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + var _input = inputs[| i]; + if(_input.isLeaf()) continue; + + _input.value_from.node.cachedPropagate(_group); + } + } #endregion - static clearInputCache = function() { - for( var i = 0; i < ds_list_size(inputs); i++ ) + static clearInputCache = function() { #region + for( var i = 0; i < ds_list_size(inputs); i++ ) { + if(!is_instanceof(inputs[| i], NodeValue)) continue; inputs[| i].resetCache(); - } + } + } #endregion - static checkConnectGroup = function(_type = "group") { - var _y = y; - var nodes = []; - + static checkConnectGroup = function(_io) { #region + var _y = y; + var _n = noone; + for(var i = 0; i < ds_list_size(inputs); i++) { var _in = inputs[| i]; - if(_in.value_from == noone) continue; - if(_in.value_from.node.group == group) continue; - var input_node = noone; + if(_in.isLeaf()) continue; + if(_in.value_from.node.group == group) continue; - switch(_type) { - case "group" : input_node = new Node_Group_Input(x - w - 64, _y, group); break; - case "loop" : input_node = new Node_Iterator_Input(x - w - 64, _y, group); break; - case "feedback" : input_node = new Node_Feedback_Input(x - w - 64, _y, group); break; - } - - if(input_node == noone) continue; + var _ind = string(_in.value_from); + _io.map[$ _ind] = _in.value_from; - array_push(nodes, input_node); - input_node.inputs[| 2].setValue(_in.type); - input_node.inParent.setFrom(_in.value_from); - input_node.onValueUpdate(0); - _in.setFrom(input_node.outputs[| 0]); - - _y += 64; + if(struct_has(_io.inputs, _ind)) + array_push(_io.inputs[$ _ind ], _in); + else + _io.inputs[$ _ind ] = [ _in ]; } for(var i = 0; i < ds_list_size(outputs); i++) { var _ou = outputs[| i]; - for(var j = 0; j < ds_list_size(_ou.value_to); j++) { - var _to = _ou.value_to[| j]; - if(_to.value_from != _ou) continue; - if(!_to.node.active) continue; + + for(var j = 0; j < array_length(_ou.value_to); j++) { + var _to = _ou.value_to[j]; + if(_to.value_from != _ou) continue; + if(!_to.node.active) continue; if(_to.node.group == group) continue; - var output_node = noone; - switch(_type) { - case "group" : output_node = new Node_Group_Output(x + w + 64, y, group); break; - case "loop" : output_node = new Node_Iterator_Output(x + w + 64, y, group); break; - case "feedback" : output_node = new Node_Feedback_Output(x + w + 64, y, group); break; - } - - if(output_node == noone) continue; + var _ind = string(_ou); + _io.map[$ _ind] = _ou; - array_push(nodes, output_node); - _to.setFrom(output_node.outParent); - output_node.inputs[| 0].setFrom(_ou); + if(struct_has(_io.outputs, _ind)) + array_push(_io.outputs[$ _ind ], _to); + else + _io.outputs[$ _ind ] = [ _to ]; } } - - return nodes; - } + } #endregion - static isNotUsingTool = function() { - return PANEL_PREVIEW.tool_current == noone; - } + static isNotUsingTool = function() { return PANEL_PREVIEW.tool_current == noone; } - static isUsingTool = function(index, subtool = noone) { + static isUsingTool = function(index = undefined, subtool = noone) { #region if(tools == -1) return false; var _tool = PANEL_PREVIEW.tool_current; - if(_tool == noone) + if(_tool == noone) //not using any tool return false; + if(index == undefined) //using any tool + return true; + if(is_real(index) && _tool != tools[index]) return false; @@ -1207,15 +1866,15 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x return true; return _tool.selecting == subtool; - } + } #endregion - static clone = function(target = PANEL_GRAPH.getCurrentContext()) { + static clone = function(target = PANEL_GRAPH.getCurrentContext()) { #region CLONING = true; var _type = instanceof(self); var _node = nodeBuild(_type, x, y, target); CLONING = false; - PROJECT.version = SAVE_VERSION; + LOADING_VERSION = SAVE_VERSION; if(!_node) return; @@ -1228,58 +1887,67 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x PROJECT.nodeMap[? node_id] = self; PROJECT.nodeMap[? _nid] = _node; - PANEL_ANIMATION.updatePropertyList(); CLONING = false; + refreshTimeline(); onClone(_node, target); return _node; - } + } #endregion static onClone = function(_NewNode, target = PANEL_GRAPH.getCurrentContext()) {} - draw_droppable = false; - static droppable = function(dragObj) { + static droppable = function(dragObj) { #region for( var i = 0; i < ds_list_size(inputs); i++ ) { if(dragObj.type == inputs[| i].drop_key) return true; } return false; - } + } #endregion - static onDrop = function(dragObj) { + on_drop_file = noone; + static onDrop = function(dragObj) { #region + if(dragObj.type == "Asset" && is_callable(on_drop_file)) { + on_drop_file(dragObj.data.path); + return; + } + for( var i = 0; i < ds_list_size(inputs); i++ ) { if(dragObj.type == inputs[| i].drop_key) { inputs[| i].setValue(dragObj.data); - previewDropAnimation(); return; } } - } + } #endregion - static getPreviewValue = function() { - if(preview_channel > ds_list_size(outputs)) return noone; - return outputs[| preview_channel]; - } - - static getPreviewBoundingBox = function() { - var _node = getPreviewValue(); - if(_node == undefined) return noone; - if(_node.type != VALUE_TYPE.surface) return noone; + static getPreviewValues = function() { #region + if(preview_channel >= ds_list_size(outputs)) return noone; - var _surf = _node.getValue(); + switch(outputs[| preview_channel].type) { + case VALUE_TYPE.surface : + case VALUE_TYPE.dynaSurface : + break; + default : + return noone; + } + + return outputs[| preview_channel].getValue(); + } #endregion + + static getPreviewBoundingBox = function() { #region + var _surf = getPreviewValues(); if(is_array(_surf)) - _surf = array_safe_get(_surf, preview_index, noone); + _surf = array_safe_get_fast(_surf, preview_index, noone); if(!is_surface(_surf)) return noone; - return BBOX().fromWH(preview_x, preview_y, surface_get_width(_surf), surface_get_height(_surf)); - } + return BBOX().fromWH(preview_x, preview_y, surface_get_width_safe(_surf), surface_get_height_safe(_surf)); + } #endregion - static getTool = function() { - return self; - } + static getTool = function() { return self; } - static setTool = function(tool) { + static getToolSettings = function() { return tool_settings; } + + static setTool = function(tool) { #region if(!tool) { isTool = false; return; @@ -1289,10 +1957,13 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x group.nodes[| i].isTool = false; isTool = true; - } + } #endregion - #region[#88ffe916] === Save Load === - static serialize = function(scale = false, preset = false) { + static drawTools = function(_mx, _my, xx, yy, tool_size, hover, focus) { return 0; } + + static serialize = function(scale = false, preset = false) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SERIALIZE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + if(!active) return; + var _map = {}; //print(" > Serializing: " + name); @@ -1305,8 +1976,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x _map.y = y; _map.type = instanceof(self); _map.group = group == noone? group : group.node_id; - _map.preview = previewable; _map.tool = isTool; + + _map.previewable = previewable; + _map.show_parameter = show_parameter; } _map.attri = attributeSerialize(); @@ -1329,29 +2002,39 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var _trigger = []; array_push(_trigger, inspectInput1.serialize(scale, preset)); array_push(_trigger, inspectInput2.serialize(scale, preset)); + array_push(_trigger, updatedInTrigger.serialize(scale, preset)); + array_push(_trigger, updatedOutTrigger.serialize(scale, preset)); + _map.inspectInputs = _trigger; + _map.renamed = renamed; + + _map.buffer = {}; + var _bufferKey = struct_key(bufferStore); + for( var i = 0, n = array_length(_bufferKey); i < n; i++ ) { + var _key = _bufferKey[i]; + _map.buffer[$ _key] = buffer_serialize(bufferStore[$ _key]); + } doSerialize(_map); processSerialize(_map); return _map; - } + } #endregion static attributeSerialize = function() { return attributes; } static doSerialize = function(_map) {} static processSerialize = function(_map) {} - load_scale = false; - load_map = -1; - static deserialize = function(_map, scale = false, preset = false) { - load_map = _map; + static deserialize = function(_map, scale = false, preset = false) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESERIALIZE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + load_map = _map; load_scale = scale; + renamed = struct_try_get(load_map, "renamed", false); if(!preset) { if(APPENDING) APPEND_MAP[? load_map.id] = node_id; else node_id = load_map.id; PROJECT.nodeMap[? node_id] = self; - //print($"D Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]"); + //print($"Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]"); if(struct_has(load_map, "name")) setDisplayName(load_map.name); @@ -1360,19 +2043,30 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(internalName == "") resetInternalName(); - _group = struct_try_get(load_map, "group", noone); - if(_group == -1) _group = noone; + load_group = struct_try_get(load_map, "group", noone); + if(load_group == -1) load_group = noone; x = struct_try_get(load_map, "x"); y = struct_try_get(load_map, "y"); - renderActive = struct_try_get(load_map, "render", true); - previewable = struct_try_get(load_map, "preview", previewable); - isTool = struct_try_get(load_map, "tool"); + renderActive = struct_try_get(load_map, "render", true); + previewable = struct_try_get(load_map, "previewable", previewable); + isTool = struct_try_get(load_map, "tool"); + show_parameter = struct_try_get(load_map, "show_parameter"); } if(struct_has(load_map, "attri")) attributeDeserialize(load_map.attri); + if(struct_has(load_map, "buffer")) { + var _bufferKey = struct_key(bufferStore); + for( var i = 0, n = array_length(_bufferKey); i < n; i++ ) { + var _key = _bufferKey[i]; + if(!struct_has(bufferStore, _key)) continue; + + bufferStore[$ _key] = buffer_deserialize(load_map.buffer[$ _key]); + } + } + if(is_dynamic_input) { inputBalance(); inputGenerate(); @@ -1386,17 +2080,19 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x triggerRender(); } - } + } #endregion - static inputBalance = function() { //Cross version compatibility for dynamic input nodes + static inputBalance = function() { #region //Cross version compatibility for dynamic input nodes if(!struct_has(load_map, "data_length")) return; var _input_fix_len = load_map.input_fix_len; var _data_length = load_map.data_length; - print($"Balancing IO: {input_fix_len} => {load_map.input_fix_len} : {data_length} => {load_map.data_length}"); - print($"IO size before: {array_length(load_map.inputs)}"); + //print($"Balancing IO: {input_fix_len} => {load_map.input_fix_len} : {data_length} => {load_map.data_length}"); + //print($"IO size before: {array_length(load_map.inputs)}"); + //for( var i = 0, n = array_length(load_map.inputs); i < n; i++ ) + // print($"{i}: {load_map.inputs[i].name}"); var _dynamic_inputs = (array_length(load_map.inputs) - _input_fix_len) / _data_length; if(frac(_dynamic_inputs) != 0) { @@ -1409,20 +2105,24 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var _pad_dyna = data_length - _data_length; - for( var i = _dynamic_inputs - 1; i >= 0; i-- ) { + for( var i = _dynamic_inputs; i >= 1; i-- ) { var _ind = _input_fix_len + i * _data_length; - repeat(_pad_dyna) - array_insert(load_map.inputs, _ind, noone); + if(_pad_dyna > 0) + repeat(_pad_dyna) array_insert(load_map.inputs, _ind, noone); + else + array_delete(load_map.inputs, _ind + _pad_dyna, -_pad_dyna); } var _pad_fix = input_fix_len - _input_fix_len; repeat(_pad_fix) array_insert(load_map.inputs, _input_fix_len, noone); - print($"IO size after: {array_length(load_map.inputs)}"); - } + //print($"IO size after: {array_length(load_map.inputs)}"); + //for( var i = 0, n = array_length(load_map.inputs); i < n; i++ ) + // print($"{i}: {load_map.inputs[i] == noone? "noone" : load_map.inputs[i].name}"); + } #endregion - static inputGenerate = function() { //Generate input for dynamic input nodes + static inputGenerate = function() { #region //Generate input for dynamic input nodes if(createNewInput == noone) return; @@ -1430,22 +2130,30 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x //print($"Node {name} create {_dynamic_inputs} inputs for data length {data_length}"); repeat(_dynamic_inputs) createNewInput(); - } + } #endregion - static attributeDeserialize = function(attr) { - struct_override(attributes, attr); - } - - static postDeserialize = function() {} - static processDeserialize = function() {} + static attributeDeserialize = function(attr) { #region + if(struct_has(attributes, "use_project_dimension") && !struct_has(attr, "use_project_dimension")) + attributes.use_project_dimension = false; + + struct_append(attributes, attr); + } #endregion + + static processDeserialize = function() {} + static postDeserialize = function() {} + + static applyDeserialize = function(preset = false) { #region + preApplyDeserialize(); - static applyDeserialize = function(preset = false) { var _inputs = load_map.inputs; var amo = min(ds_list_size(inputs), array_length(_inputs)); + //print($"Applying deserialzie for {name}"); + for(var i = 0; i < amo; i++) { if(inputs[| i] == noone || _inputs[i] == noone) continue; - print($"Apply deserialize {_inputs[i].name} to {inputs[| i].name}"); + + //print($" Apply {i} : {inputs[| i].name}"); inputs[| i].applyDeserialize(_inputs[i], load_scale, preset); } @@ -1455,6 +2163,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x for(var i = 0; i < amo; i++) { if(outputs[| i] == noone) continue; + outputs[| i].applyDeserialize(_outputs[i], load_scale, preset); } } @@ -1463,56 +2172,66 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var insInp = load_map.inspectInputs; inspectInput1.applyDeserialize(insInp[0], load_scale, preset); inspectInput2.applyDeserialize(insInp[1], load_scale, preset); + + if(array_length(insInp) > 2) updatedInTrigger.applyDeserialize(insInp[2], load_scale, preset); + if(array_length(insInp) > 3) updatedOutTrigger.applyDeserialize(insInp[3], load_scale, preset); } + //print($"Applying deserialzie for {name} complete"); + doApplyDeserialize(); - } + } #endregion - static doApplyDeserialize = function() {} + static preApplyDeserialize = function() {} + static doApplyDeserialize = function() {} - static loadGroup = function(context = PANEL_GRAPH.getCurrentContext()) { - if(_group == noone) { - var c = context; - if(c != noone) c.add(self); + static loadGroup = function(context = noone) { #region + if(load_group == noone) { + if(context != noone) context.add(self); } else { - if(APPENDING) _group = GetAppendID(_group); + if(APPENDING) load_group = GetAppendID(load_group); - if(ds_map_exists(PROJECT.nodeMap, _group)) { - if(struct_has(PROJECT.nodeMap[? _group], "add")) - PROJECT.nodeMap[? _group].add(self); + if(ds_map_exists(PROJECT.nodeMap, load_group)) { + if(struct_has(PROJECT.nodeMap[? load_group], "add")) + PROJECT.nodeMap[? load_group].add(self); else { - var txt = $"Group load failed. Node ID {_group} is not a group."; + var txt = $"Group load failed. Node ID {load_group} is not a group."; throw(txt); } } else { - var txt = $"Group load failed. Can't find node ID {_group}"; + var txt = $"Group load failed. Can't find node ID {load_group}"; throw(txt); } } - } + + onLoadGroup(); + } #endregion - static connect = function(log = false) { + static onLoadGroup = function() {} + + static connect = function(log = false) { #region var connected = true; for(var i = 0; i < ds_list_size(inputs); i++) connected &= inputs[| i].connect(log); - if(struct_has(load_map, "inspectInputs")) { - inspectInput1.connect(log); - inspectInput2.connect(log); - } + inspectInput1.connect(log); + inspectInput2.connect(log); + updatedInTrigger.connect(log); if(!connected) ds_queue_enqueue(CONNECTION_CONFLICT, self); + refreshTimeline(); return connected; - } + } #endregion static preConnect = function() {} static postConnect = function() {} - #endregion + + static postLoad = function() {} static resetAnimation = function() {} - static cleanUp = function() { + static cleanUp = function() { #region for( var i = 0; i < ds_list_size(inputs); i++ ) inputs[| i].cleanUp(); for( var i = 0; i < ds_list_size(outputs); i++ ) @@ -1528,24 +2247,26 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x surface_free(temp_surface[i]); onCleanUp(); - } + } #endregion static onCleanUp = function() {} // helper function - static attrDepth = function() { + static attrDepth = function() { #region if(struct_has(attributes, "color_depth")) { var form = attributes.color_depth; if(inputs[| 0].type == VALUE_TYPE.surface) form--; if(form >= 0) - return array_safe_get(global.SURFACE_FORMAT, form, surface_rgba8unorm); + return array_safe_get_fast(global.SURFACE_FORMAT, form, surface_rgba8unorm); } - var _s = inputs[| 0].getValue(); + var _s = getInputData(0); while(is_array(_s) && array_length(_s)) _s = _s[0]; if(!is_surface(_s)) return surface_rgba8unorm; return surface_get_format(_s); - } + } #endregion + + static toString = function() { return $"Node [{internalName}]: {node_id}"; } } \ No newline at end of file diff --git a/#backups/scripts/node_data/node_data.gml.backup1 b/#backups/scripts/node_data/node_data.gml.backup1 index 54ae07ef6..2ba8de8b1 100644 --- a/#backups/scripts/node_data/node_data.gml.backup1 +++ b/#backups/scripts/node_data/node_data.gml.backup1 @@ -1,4 +1,4 @@ -// 2023-08-08 14:41:40 +// 2023-08-08 14:42:15 global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ]; function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x, _y) constructor { @@ -1445,7 +1445,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x for(var i = 0; i < amo; i++) { if(inputs[| i] == noone || _inputs[i] == noone) continue; - print($"Apply deserialize {_inputs[| i].name} to {inputs[| i].name}"); + print($"Apply deserialize {_inputs[i].name} to {inputs[| i].name}"); inputs[| i].applyDeserialize(_inputs[i], load_scale, preset); } diff --git a/#backups/scripts/node_tool/node_tool.gml.backup0 b/#backups/scripts/node_tool/node_tool.gml.backup0 index da21b8561..742cafb14 100644 --- a/#backups/scripts/node_tool/node_tool.gml.backup0 +++ b/#backups/scripts/node_tool/node_tool.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:51:01 +// 2024-04-16 10:52:40 function NodeTool(name, spr, context = instanceof(other)) constructor { ctx = context; self.name = name; @@ -79,7 +79,7 @@ function NodeTool(name, spr, context = instanceof(other)) constructor { onToggle(); var _obj = getToolObject(); - if(_obj) _obj.init(); + if(_obj) _obj.init(ctx); } static toggleKeyboard = function() { diff --git a/#backups/scripts/node_tool/node_tool.gml.backup1 b/#backups/scripts/node_tool/node_tool.gml.backup1 new file mode 100644 index 000000000..da21b8561 --- /dev/null +++ b/#backups/scripts/node_tool/node_tool.gml.backup1 @@ -0,0 +1,102 @@ +// 2024-04-14 12:51:01 +function NodeTool(name, spr, context = instanceof(other)) constructor { + ctx = context; + self.name = name; + self.spr = spr; + + subtools = is_array(spr)? array_length(spr) : 0; + selecting = 0; + settings = []; + attribute = {}; + + toolObject = noone; + toolFn = noone; + toolFnParam = {}; + + static checkHotkey = function() { + INLINE + + return getToolHotkey(ctx, name); + } + + static setToolObject = function(toolObject) { self.toolObject = toolObject; return self; } + static setToolFn = function(toolFn) { self.toolFn = toolFn; return self; } + + static getName = function(index = 0) { return is_array(name)? array_safe_get_fast(name, index, "") : name; } + + static getToolObject = function() { return is_array(toolObject)? toolObject[selecting] : toolObject; } + + static getDisplayName = function(index = 0) { + var _key = checkHotkey(); + + var _nme = getName(index); + if(_key != "") _nme += $" ({_key})"; + + return _nme; + } + + static setSetting = function(sets) { array_push(settings, sets); return self; } + + static addSetting = function(name, type, onEdit, keyAttr, val) { + var w; + + switch(type) { + case VALUE_TYPE.float : + w = new textBox(TEXTBOX_INPUT.number, onEdit); + w.font = f_p3; + break; + case VALUE_TYPE.boolean : + w = new checkBox(onEdit); + break; + } + + array_push(settings, [ name, w, keyAttr, attribute ]); + attribute[$ keyAttr] = val; + + return self; + } + + static toggle = function(index = 0) { + if(toolFn != noone) { + if(subtools == 0) toolFn(ctx); + else toolFn[index](ctx); + return; + } + + if(subtools == 0) { + PANEL_PREVIEW.tool_current = PANEL_PREVIEW.tool_current == self? noone : self; + } else { + if(PANEL_PREVIEW.tool_current == self && index == selecting) { + PANEL_PREVIEW.tool_current = noone; + selecting = 0; + } else { + PANEL_PREVIEW.tool_current = self; + selecting = index; + } + } + + if(PANEL_PREVIEW.tool_current == self) + onToggle(); + + var _obj = getToolObject(); + if(_obj) _obj.init(); + } + + static toggleKeyboard = function() { + if(subtools == 0) { + PANEL_PREVIEW.tool_current = PANEL_PREVIEW.tool_current == self? noone : self; + } else if(PANEL_PREVIEW.tool_current != self) { + PANEL_PREVIEW.tool_current = self; + selecting = 0; + } else if(selecting == subtools - 1) { + PANEL_PREVIEW.tool_current = noone; + selecting = 0; + } else + selecting++; + + if(PANEL_PREVIEW.tool_current == self) + onToggle(); + } + + static onToggle = function() {} +} \ No newline at end of file diff --git a/#backups/scripts/panel_color/panel_color.gml.backup0 b/#backups/scripts/panel_color/panel_color.gml.backup0 new file mode 100644 index 000000000..bd0b596af --- /dev/null +++ b/#backups/scripts/panel_color/panel_color.gml.backup0 @@ -0,0 +1,183 @@ +// 2024-04-16 09:31:58 +enum COLOR_SELECTOR_MODE { + hue, + value +} + +function Panel_Color() : PanelContent() constructor { + title = __txt("Color"); + padding = 8; + + w = ui(320); + h = ui(320); + + mode = COLOR_SELECTOR_MODE.hue; + + hue = 1; + sat = 1; + val = 1; + color = c_black; + + drag_con = false; + drag_sel = false; + + colors = []; + + static setColor = function(color) { + self.color = color; + hue = color_get_hue(color) / 255; + sat = color_get_saturation(color) / 255; + val = color_get_value(color) / 255; + + if(COLORS_GLOBAL_SET != noone) + COLORS_GLOBAL_SET(color); + } + + static setHSV = function(h = hue, s = sat, v = val) { + hue = h; + sat = s; + val = v; + + color = make_color_hsv(h * 255, s * 255, v * 255); + + if(COLORS_GLOBAL_SET != noone) + COLORS_GLOBAL_SET(color); + } + setHSV(); + + function drawContent(panel) { + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + var px = ui(padding); + var py = ui(padding); + var pw = w - ui(padding + padding); + var ph = h - ui(padding + padding); + + draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16)); + + if(COLORS_GLOBAL_GET != noone) { + var c = COLORS_GLOBAL_GET(); + if(c != color) setColor(c); + } + + var cont_x = ui(padding); + var cont_y = ui(padding); + var cont_w = w - ui(padding + padding + ui(16 + 8)); + var cont_h = h - ui(padding + padding + ui(24 + 8)); + + shader_set(sh_color_select_content); + shader_set_i("mode", mode); + shader_set_f("hue", hue); + shader_set_f("val", val); + draw_sprite_stretched(s_fx_pixel, 0, cont_x, cont_y, cont_w, cont_h); + + var sel_x = cont_x + cont_w + ui(8); + var sel_y = ui(padding); + var sel_w = ui(16); + var sel_h = cont_h; + + shader_set(sh_color_select_side); + shader_set_i("mode", mode); + shader_set_f("hue", hue); + draw_sprite_stretched(s_fx_pixel, 0, sel_x, sel_y, sel_w, sel_h); + shader_reset(); + + if(drag_con) { + if(mode == 0) { + sat = clamp((mx - cont_x) / cont_w, 0, 1); + val = 1 - clamp((my - cont_y) / cont_h, 0, 1); + } else if(mode == 1) { + hue = clamp((mx - cont_x) / cont_w, 0, 1); + sat = 1 - clamp((my - cont_y) / cont_h, 0, 1); + } + + setHSV(); + + if(mouse_release(mb_left)) + drag_con = false; + } + + if(drag_sel) { + if(mode == 0) + hue = clamp((my - sel_y) / sel_h, 0, 1); + else if(mode == 1) + val = 1 - clamp((my - sel_y) / sel_h, 0, 1); + + setHSV(); + + if(mouse_release(mb_left)) + drag_sel = false; + } + + if(mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(mx, my, cont_x, cont_y, cont_x + cont_w, cont_y + cont_h)) + drag_con = true; + + if(point_in_rectangle(mx, my, sel_x, sel_y, sel_x + sel_w, sel_y + sel_h)) + drag_sel = true; + } + + if(mode == 0) { + var hy = sel_y + hue * sel_h; + var cx = cont_x + sat * cont_w - ui(6); + var cy = cont_y + (1 - val) * cont_h - ui(6); + draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), hy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, 255), 1); + draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1); + + } else if(mode == 1) { + var vy = sel_y + (1 - val) * sel_h; + var cx = cont_x + hue * cont_w - ui(6); + var cy = cont_y + (1 - sat) * cont_h - ui(6); + draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), vy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, val * 255), 1); + draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1); + } + + var amo = min(array_length(colors) + 1, floor((w - ui(padding * 2)) / ui(24 + 4))); + + for( var i = 0; i < amo; i++ ) { + var cx = ui(padding) + ui(24 + 4) * i; + var cy = cont_y + cont_h + ui(8); + + if(i == 0) { + draw_sprite_stretched_ext(s_ui_base_white, 0, cx + ui(4), cy + ui(4), ui(16), ui(16), color, 1); + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 0.5); + + if(pHOVER && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 1); + if(mouse_press(mb_left, pFOCUS)) { + array_insert(colors, 0, color); + + if(COLORS_GLOBAL_SET != noone) { + COLORS_GLOBAL_SET(color); + + } else { + DRAGGING = { + type: "Color", + data: color + } + MESSAGE = DRAGGING; + } + } + } + continue; + } + + var c = colors[i - 1]; + draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(24), ui(24), c, 1); + + if(mouse_press(mb_left, pFOCUS) && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) { + DRAGGING = { + type: "Color", + data: c + } + MESSAGE = DRAGGING; + } + } + + if(DRAGGING && DRAGGING.type == "Color" && pHOVER) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, 2, 2, w - 4, h - 4, COLORS._main_value_positive, 1); + if(mouse_release(mb_left)) + setColor(DRAGGING.data); + } + } +} \ No newline at end of file diff --git a/#backups/scripts/panel_color/panel_color.gml.backup1 b/#backups/scripts/panel_color/panel_color.gml.backup1 new file mode 100644 index 000000000..d8b0ef7fc --- /dev/null +++ b/#backups/scripts/panel_color/panel_color.gml.backup1 @@ -0,0 +1,183 @@ +// 2024-04-16 09:31:56 +enum COLOR_SELECTOR_MODE { + hue, + value +} + +function Panel_Color() : PanelContent() constructor { + title = __txt("Color"); + padding = 8; + + w = ui(320); + h = ui(320); + + mode = COLOR_SELECTOR_MODE.hue; + + hue = 1; + sat = 1; + val = 1; + color = c_black; + + drag_con = false; + drag_sel = false; + + colors = []; + + static setColor = function(color) { + self.color = color; + hue = color_get_hue(color) / 255; + sat = color_get_saturation(color) / 255; + val = color_get_value(color) / 255; + + if(COLORS_GLOBAL_SET != noone) + COLORS_GLOBAL_SET(color); + } + + static setHSV = function(h = hue, s = sat, v = val) { + hue = h; + sat = s; + val = v; + + color = make_color_hsv(h * 255, s * 255, v * 255); + + if(COLORS_GLOBAL_SET != noone) + COLORS_GLOBAL_SET(color); + } + setHSV(); + + function drawContent(panel) { + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + var px = ui(padding); + var py = ui(padding); + var pw = w - ui(padding + padding); + var ph = h - ui(padding + padding); + + draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16)); + + if(COLORS_GLOBAL_GET != noone) { + var c = COLORS_GLOBAL_GET(); + if(c != color) setColor(c); + } + + var cont_x = ui(padding); + var cont_y = ui(padding); + var cont_w = w - ui(padding + padding + ui(16 + 8)); + var cont_h = h - ui(padding + padding + ui(24 + 8)); + + shader_set(sh_color_select_content); + shader_set_i("mode", mode); + shader_set_f("hue", hue); + shader_set_f("val", val); + draw_sprite_stretched(s_fx_pixel, 0, cont_x, cont_y, cont_w, cont_h); + + var sel_x = cont_x + cont_w + ui(8); + var sel_y = ui(padding); + var sel_w = ui(16); + var sel_h = cont_h; + + shader_set(sh_color_select_side); + shader_set_i("mode", mode); + shader_set_f("hue", hue); + draw_sprite_stretched(s_fx_pixel, 0, sel_x, sel_y, sel_w, sel_h); + shader_reset(); + + if(drag_con) { + if(mode == 0) { + sat = clamp((mx - cont_x) / cont_w, 0, 1); + val = 1 - clamp((my - cont_y) / cont_h, 0, 1); + } else if(mode == 1) { + hue = clamp((mx - cont_x) / cont_w, 0, 1); + sat = 1 - clamp((my - cont_y) / cont_h, 0, 1); + } + + setHSV(); + + if(mouse_release(mb_left)) + drag_con = false; + } + + if(drag_sel) { + if(mode == 0) + hue = clamp((my - sel_y) / sel_h, 0, 1); + else if(mode == 1) + val = 1 - clamp((my - sel_y) / sel_h, 0, 1); + + setHSV(); + + if(mouse_release(mb_left)) + drag_sel = false; + } + + if(mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(mx, my, cont_x, cont_y, cont_x + cont_w, cont_y + cont_h)) + drag_con = true; + + if(point_in_rectangle(mx, my, sel_x, sel_y, sel_x + sel_w, sel_y + sel_h)) + drag_sel = true; + } + + if(mode == 0) { + var hy = sel_y + hue * sel_h; + var cx = cont_x + sat * cont_w - ui(6); + var cy = cont_y + (1 - val) * cont_h - ui(6); + draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), hy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, 255), 1); + draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1); + + } else if(mode == 1) { + var vy = sel_y + (1 - val) * sel_h; + var cx = cont_x + hue * cont_w - ui(6); + var cy = cont_y + (1 - sat) * cont_h - ui(6); + draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), vy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, val * 255), 1); + draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1); + } + + var amo = min(array_length(colors) + 1, floor((w - ui(padding * 2)) / ui(24 + 4))); + + for( var i = 0; i < amo; i++ ) { + var cx = ui(padding) + ui(24 + 4) * i; + var cy = cont_y + cont_h + ui(8); + + if(i == 0) { + draw_sprite_stretched_ext(s_ui_base_white, 0, cx + ui(4), cy + ui(4), ui(16), ui(16), color, 1); + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 0.5); + + if(pHOVER && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 1); + if(mouse_press(mb_left, pFOCUS)) { + array_insert(colors, 0, color); + + if(COLORS_GLOBAL_SET != noone) { + COLORS_GLOBAL_SET(color); + + } else { + DRAGGING = { + type: "Color", + data: color + } + MESSAGE = DRAGGING; + } + } + } + continue; + } + + var c = colors[i - 1]; + draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(24), ui(24), c, 1); + + if(mouse_press(mb_left, pFOCUS) && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) { + DRAGGING = { + type: "Color", + data: c + } + MESSAGE = DRAGGING; + } + } + + if(DRAGGING && DRAGGING.type == "Color" && pHOVER) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, 2, 2, w - 4, h - 4, COLORS._main_value_positive, 1); + if(mouse_release(mb_left)) + setColor(DRAGGING.data); + } + } +} \ No newline at end of file diff --git a/#backups/scripts/panel_palette/panel_palette.gml.backup0 b/#backups/scripts/panel_palette/panel_palette.gml.backup0 new file mode 100644 index 000000000..637328f99 --- /dev/null +++ b/#backups/scripts/panel_palette/panel_palette.gml.backup0 @@ -0,0 +1,123 @@ +// 2024-04-16 09:33:06 +function Panel_Palette() : PanelContent() constructor { + title = __txt("Palettes"); + padding = 8; + + w = ui(320); + h = ui(480); + + view_mode = 0; + + color_dragging = noone; + + function onResize() { + sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding)); + } + + sp_palettes = new scrollPane(w - ui(padding + padding), h - ui(padding + padding), function(_y, _m) { + draw_clear_alpha(COLORS.panel_bg_clear, 0); + var ww = sp_palettes.surface_w; + var hh = ui(28); + var _gs = ui(24); + switch(view_mode) { + case 0 : _gs = ui(24); break; + case 1 : _gs = ui(32); break; + case 2 : _gs = ui(16); break; + } + var _height; + var yy = _y; + var cur = COLORS_GLOBAL_GET != noone? COLORS_GLOBAL_GET() : noone; + + for(var i = 0; i < array_length(PALETTES); i++) { + var preset = PALETTES[i]; + var pre_amo = array_length(preset.palette); + var col = floor((ww - ui(20)) / _gs); + var row = ceil(pre_amo / col); + + _height = ui(34) + row * _gs; + + var isHover = pHOVER && point_in_rectangle(_m[0], _m[1], 0, max(0, yy), ww, min(sp_palettes.h, yy + _height)); + + draw_sprite_stretched(THEME.ui_panel_bg, 3, 0, yy, ww, _height); + if(isHover) + draw_sprite_stretched_ext(THEME.node_active, 1, 0, yy, ww, _height, COLORS._main_accent, 1); + + draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub); + draw_text(ui(10), yy + ui(2), preset.name); + drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs, cur); + + if(isHover) { + if(mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(_m[0], _m[1], ui(10), yy + ui(24), ww - ui(10), yy + ui(24) + _height)) { + var m_ax = _m[0] - ui(10); + var m_ay = _m[1] - (yy + ui(24)); + + var m_gx = floor(m_ax / _gs); + var m_gy = floor(m_ay / _gs); + + var _index = m_gy * col + m_gx; + if(_index < pre_amo && _index >= 0) { + if(COLORS_GLOBAL_SET != noone) { + COLORS_GLOBAL_SET(array_safe_get_fast(preset.palette, _index)); + + } else { + DRAGGING = { + type: "Color", + data: array_safe_get_fast(preset.palette, _index) + } + MESSAGE = DRAGGING; + } + } + } else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) { + DRAGGING = { + type: "Palette", + data: preset.palette + } + MESSAGE = DRAGGING; + } + } + + if(mouse_press(mb_right, pFOCUS)) { + hovering = preset; + + menuCall("palette_window_preset_menu",,, [ + menuItem(__txt("Refresh"), function() { + __initPalette(); + }), + menuItem(__txtx("palette_change_preview_size", "Change preview size"), function() { + view_mode = (view_mode + 1) % 3; + }), + -1, + menuItem(__txtx("palette_editor_set_default", "Set as default"), function() { + DEF_PALETTE = array_clone(hovering.palette); + }), + menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { + file_delete(hovering.path); + __initPalette(); + }), + ]); + } + } + + yy += _height + ui(8); + hh += _height + ui(8); + } + + return hh; + }); + + function drawContent(panel) { + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + var px = ui(padding); + var py = ui(padding); + var pw = w - ui(padding + padding); + var ph = h - ui(padding + padding); + + draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16)); + + sp_palettes.setFocusHover(pFOCUS, pHOVER); + sp_palettes.draw(px, py, mx - px, my - py); + + } +} \ No newline at end of file diff --git a/#backups/scripts/panel_palette/panel_palette.gml.backup1 b/#backups/scripts/panel_palette/panel_palette.gml.backup1 new file mode 100644 index 000000000..01bebba08 --- /dev/null +++ b/#backups/scripts/panel_palette/panel_palette.gml.backup1 @@ -0,0 +1,123 @@ +// 2024-04-16 09:33:05 +function Panel_Palette() : PanelContent() constructor { + title = __txt("Palettes"); + padding = 8; + + w = ui(320); + h = ui(480); + + view_mode = 0; + + color_dragging = noone; + + function onResize() { + sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding)); + } + + sp_palettes = new scrollPane(w - ui(padding + padding), h - ui(padding + padding), function(_y, _m) { + draw_clear_alpha(COLORS.panel_bg_clear, 0); + var ww = sp_palettes.surface_w; + var hh = ui(28); + var _gs = ui(24); + switch(view_mode) { + case 0 : _gs = ui(24); break; + case 1 : _gs = ui(32); break; + case 2 : _gs = ui(16); break; + } + var _height; + var yy = _y; + var cur = COLORS_GLOBAL_GET != noone? COLORS_GLOBAL_GET() : noone; + + for(var i = 0; i < array_length(PALETTES); i++) { + var preset = PALETTES[i]; + var pre_amo = array_length(preset.palette); + var col = floor((ww - ui(20)) / _gs); + var row = ceil(pre_amo / col); + + _height = ui(34) + row * _gs; + + var isHover = pHOVER && point_in_rectangle(_m[0], _m[1], 0, max(0, yy), ww, min(sp_palettes.h, yy + _height)); + + draw_sprite_stretched(THEME.ui_panel_bg, 3, 0, yy, ww, _height); + if(isHover) + draw_sprite_stretched_ext(THEME.node_active, 1, 0, yy, ww, _height, COLORS._main_accent, 1); + + draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub); + draw_text(ui(10), yy + ui(2), preset.name); + drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs, cur); + + if(isHover) { + if(mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(_m[0], _m[1], ui(10), yy + ui(24), ww - ui(10), yy + ui(24) + _height)) { + var m_ax = _m[0] - ui(10); + var m_ay = _m[1] - (yy + ui(24)); + + var m_gx = floor(m_ax / _gs); + var m_gy = floor(m_ay / _gs); + + var _index = m_gy * col + m_gx; + if(_index < pre_amo && _index >= 0) { + if(COLORS_GLOBAL_SET != noone) { + COLORS_GLOBAL_SET(array_safe_get_fast(preset.palette, _index)); + + } else { + DRAGGING = { + type: "Color", + data: array_safe_get_fast(preset.palette, _index) + } + MESSAGE = DRAGGING; + } + } + } else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) { + DRAGGING = { + type: "Palette", + data: preset.palette + } + MESSAGE = DRAGGING; + } + } + + if(mouse_press(mb_right, pFOCUS)) { + hovering = preset; + + menuCall("palette_window_preset_menu",,, [ + menuItem(__txt("Refresh"), function() { + __initPalette(); + }), + menuItem(__txtx("palette_change_preview_size", "Change preview size"), function() { + view_mode = (view_mode + 1) % 3; + }), + -1, + menuItem(__txtx("palette_editor_set_default", "Set as default"), function() { + DEF_PALETTE = array_clone(hovering.palette); + }), + menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { + file_delete(hovering.path); + __initPalette(); + }), + ]); + } + } + + yy += _height + ui(8); + hh += _height + ui(8); + } + + return hh; + }); + + function drawContent(panel) { + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + var px = ui(padding); + var py = ui(padding); + var pw = w - ui(padding + padding); + var ph = h - ui(padding + padding); + + draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16)); + + sp_palettes.setFocusHover(pFOCUS, pHOVER); + sp_palettes.draw(px, py, mx - px, my - py); + + } +} \ No newline at end of file diff --git a/#backups/scripts/panel_preview/panel_preview.gml.backup0 b/#backups/scripts/panel_preview/panel_preview.gml.backup0 index f5a180b6f..89b1027b2 100644 --- a/#backups/scripts/panel_preview/panel_preview.gml.backup0 +++ b/#backups/scripts/panel_preview/panel_preview.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:50:29 +// 2024-04-16 09:29:34 #region funtion calls function __fnInit_Preview() { __registerFunction("preview_focus_content", panel_preview_focus_content); @@ -100,6 +100,8 @@ function Panel_Preview() : PanelContent() constructor { tileMode = 0; bg_color = COLORS.panel_bg_clear; + + mouse_pos_string = ""; #endregion #region ---- tool ---- @@ -1072,7 +1074,14 @@ function Panel_Preview() : PanelContent() constructor { var mpx = floor((mx - canvas_x) / canvas_s); var mpy = floor((my - canvas_y) / canvas_s); draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]"); + + if(mouse_pos_string != "") { + right_menu_y += string_height("l"); + draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}"); + } } + + mouse_pos_string = ""; if(_node == noone) return; @@ -1478,9 +1487,9 @@ function Panel_Preview() : PanelContent() constructor { var key = sett[2]; var atr = sett[3]; - if(i == 0 && nme != "") { - tolx += ui(8); - tol_max_w += ui(8); + if(nme != "") { + tolx += ui(8) + bool(i == 0) * ui(8); + tol_max_w += ui(8) + bool(i == 0) * ui(8); } draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub); @@ -1501,6 +1510,7 @@ function Panel_Preview() : PanelContent() constructor { case "checkBoxGroup" : tolw = tolh * wdg.size; break; case "checkBox" : tolw = tolh; break; case "scrollBox" : tolw = ui(96); break; + case "buttonClass" : tolw = wdg.text == ""? tolh : tolw; break; } var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) @@ -1509,11 +1519,6 @@ function Panel_Preview() : PanelContent() constructor { wdg.drawParam(params); - if(nme != "") { - tolx += ui(8); - tol_max_w += ui(8); - } - tolx += tolw + ui(8) + (nme != "") * ui(8); tol_max_w += tolw + ui(8) + (nme != "") * ui(8); } diff --git a/#backups/scripts/panel_preview/panel_preview.gml.backup1 b/#backups/scripts/panel_preview/panel_preview.gml.backup1 new file mode 100644 index 000000000..694d6583e --- /dev/null +++ b/#backups/scripts/panel_preview/panel_preview.gml.backup1 @@ -0,0 +1,1776 @@ +// 2024-04-16 09:29:29 +#region funtion calls + function __fnInit_Preview() { + __registerFunction("preview_focus_content", panel_preview_focus_content); + __registerFunction("preview_save_current_frame", panel_preview_save_current_frame); + __registerFunction("preview_save_all_current_frame", panel_preview_save_all_current_frame); + __registerFunction("preview_preview_window", panel_preview_preview_window); + __registerFunction("preview_toggle_grid", panel_preview_toggle_grid); + + __registerFunction("preview_pan", panel_preview_pan); + __registerFunction("preview_zoom", panel_preview_zoom); + } + + function panel_preview_focus_content() { CALL("preview_focus_content"); PANEL_PREVIEW.fullView(); } + function panel_preview_save_current_frame() { CALL("preview_save_current_frame"); PANEL_PREVIEW.saveCurrentFrame(); } + function panel_preview_save_all_current_frame() { CALL("preview_save_all_current_frame"); PANEL_PREVIEW.saveAllCurrentFrames(); } + function panel_preview_preview_window() { CALL("preview_preview_window"); PANEL_PREVIEW.create_preview_window(PANEL_PREVIEW.getNodePreview()); } + function panel_preview_toggle_grid() { CALL("preview_toggle_grid"); PROJECT.previewGrid.show = !PROJECT.previewGrid.show; } + + function panel_preview_pan() { CALL("preview_pan"); PANEL_PREVIEW.canvas_dragging_key = true; } + function panel_preview_zoom() { CALL("preview_zoom"); PANEL_PREVIEW.canvas_zooming_key = true; } +#endregion + +function Panel_Preview() : PanelContent() constructor { + title = __txt("Preview"); + context_str = "Preview"; + icon = THEME.panel_preview_icon; + + last_focus = noone; + + #region ---- canvas control & sample ---- + function initSize() { + canvas_x = w / 2; + canvas_y = h / 2; + } + run_in(1, function() { initSize() }); + + canvas_x = 0; + canvas_y = 0; + canvas_s = ui(1); + canvas_w = ui(128); + canvas_h = ui(128); + canvas_a = 0; + + canvas_bg = -1; + + do_fullView = false; + + canvas_hover = true; + canvas_dragging_key = false; + canvas_dragging = false; + canvas_drag_key = 0; + canvas_drag_mx = 0; + canvas_drag_my = 0; + canvas_drag_sx = 0; + canvas_drag_sy = 0; + + canvas_zooming_key = false; + canvas_zooming = false; + canvas_zoom_mx = 0; + canvas_zoom_my = 0; + canvas_zoom_m = 0; + canvas_zoom_s = 0; + + sample_color = noone; + sample_x = noone; + sample_y = noone; + + #endregion + + #region ---- preview ---- + locked = false; + preview_node = [ noone, noone ]; + preview_surfaces = [ 0, 0 ]; + preview_surface = [ 0, 0 ]; + tile_surface = surface_create(1, 1); + + preview_x = 0; + preview_x_to = 0; + preview_x_max = 0; + preview_sequence = [ 0, 0 ]; + _preview_sequence = preview_sequence; + preview_rate = 10; + + right_menu_x = 0; + right_menu_y = 8; + mouse_on_preview = 0; + _mouse_on_preview = 0; + + resetViewOnDoubleClick = true; + + splitView = 0; + splitPosition = 0.5; + splitSelection = 0; + + splitViewDragging = false; + splitViewStart = 0; + splitViewMouse = 0; + + tileMode = 0; + + bg_color = COLORS.panel_bg_clear; + + mouse_pos_string = ""; + mouse_pos_icon = ""; + #endregion + + #region ---- tool ---- + tool_x = 0; + tool_x_to = 0; + tool_x_max = 0; + + tool_y = 0; + tool_y_to = 0; + tool_y_max = 0; + + tool_ry = 0; + tool_ry_to = 0; + tool_ry_max = 0; + + tool_current = noone; + + toolbar_width = ui(40); + toolbar_height = ui(40); + + tool_hovering = false; + tool_side_drawing = false; + overlay_hovering = false; + + sbChannel = new scrollBox([], function(index) { #region + var node = getNodePreview(); + if(node == noone) return; + + node.preview_channel = array_safe_get_fast(sbChannelIndex, index); + }); #endregion + sbChannelIndex = []; + sbChannel.font = f_p1; + sbChannel.align = fa_left; + #endregion + + #region ---- 3d ---- + d3_active = false; + _d3_active = false; + d3_active_transition = 0; + + d3_surface = noone; + d3_surface_normal = noone; + d3_surface_depth = noone; + d3_surface_outline = noone; + d3_surface_bg = noone; + d3_preview_channel = 0; + + d3_deferData = noone; + + global.SKY_SPHERE = new __3dUVSphere(0.5, 16, 8, true); + + #region camera + d3_view_camera = new __3dCamera(); + d3_camW = 1; + d3_camH = 1; + + d3_view_camera.setFocusAngle(135, 45, 4); + d3_camLerp = false; + + d3_camTarget = new __vec3(); + + d3_camPanning = false; + d3_camPan_mx = 0; + d3_camPan_my = 0; + + d3_zoom_speed = 0.2; + d3_pan_speed = 2; + #endregion + + #region scene + d3_scene = new __3dScene(d3_view_camera, "Preview panel"); + d3_scene.lightAmbient = $404040; + d3_scene.cull_mode = cull_counterclockwise; + d3_scene_preview = d3_scene; + + d3_scene_light_enabled = true; + + d3_scene_light0 = new __3dLightDirectional(); + d3_scene_light0.transform.position.set(-1, -2, 3); + d3_scene_light0.color = $FFFFFF; + d3_scene_light0.shadow_active = false; + d3_scene_light0.shadow_map_scale = 4; + + d3_scene_light1 = new __3dLightDirectional(); + d3_scene_light1.transform.position.set(1, 2, -3); + d3_scene_light1.color = $505050; + #endregion + + #region tool + d3_tool_snap = false; + d3_tool_snap_position = 1; + d3_tool_snap_rotation = 15; + #endregion + + #region shadow map + + #endregion + + #region view channel + d3ChannelNames = [ "Rendered", "Normal", "Depth" ]; + d3Channel = new scrollBox(d3ChannelNames, function(index) { d3_preview_channel = index; }); + d3Channel.align = fa_left; + #endregion + #endregion + + tb_framerate = new textBox(TEXTBOX_INPUT.number, function(val) { preview_rate = real(val); }); + + #region ++++ hotkey ++++ + addHotkey("Preview", "Focus content", "F", MOD_KEY.none, panel_preview_focus_content); + addHotkey("Preview", "Save current frame", "S", MOD_KEY.shift, panel_preview_save_current_frame); + addHotkey("Preview", "Save all current frame", -1, MOD_KEY.none, panel_preview_save_all_current_frame); + addHotkey("Preview", "Preview window", "P", MOD_KEY.ctrl, panel_preview_preview_window); + addHotkey("Preview", "Toggle grid", "G", MOD_KEY.ctrl, panel_preview_toggle_grid); + + addHotkey("Preview", "Pan", "", MOD_KEY.ctrl, panel_preview_pan); + addHotkey("Preview", "Zoom", "", MOD_KEY.alt | MOD_KEY.ctrl, panel_preview_zoom); + #endregion + + #region ++++ toolbars & actions ++++ + topbar_height = ui(32); + toolbar_height = ui(40); + toolbars = [ + [ + THEME.icon_reset_when_preview, + function() { return resetViewOnDoubleClick; }, + function() { return resetViewOnDoubleClick? __txtx("panel_preview_center_canvas_on_preview", "Center canvas on preview") : + __txtx("panel_preview_keep_canvas_on_preview", "Keep canvas on preview"); }, + function() { resetViewOnDoubleClick = !resetViewOnDoubleClick; } + ], + [ + THEME.icon_split_view, + function() { return splitView; }, + function() { + switch(splitView) { + case 0 : return __txtx("panel_preview_split_view_off", "Split view off"); + case 1 : return __txtx("panel_preview_horizontal_split_view", "Horizontal split view"); + case 2 : return __txtx("panel_preview_vertical_split_view", "Vertical split view"); + } + return __txtx("panel_preview_split_view", "Split view"); + }, + function() { splitView = (splitView + 1) % 3; } + ], + [ + THEME.icon_tile_view, + function() { var t = [3, 0, 1, 2]; return array_safe_get_fast(t, tileMode); }, + function() { + switch(tileMode) { + case 0 : return __txtx("panel_preview_tile_off", "Tile off"); + case 1 : return __txtx("panel_preview_tile_horizontal", "Tile horizontal"); + case 2 : return __txtx("panel_preview_tile_vertical", "Tile vertical"); + case 3 : return __txtx("panel_preview_tile_both", "Tile both"); + } + return __txtx("panel_preview_tile_mode", "Tile mode"); + }, + function(data) { + menuCall("preview_tile_menu", data.x + ui(28), data.y + ui(28), [ + menuItem(__txtx("panel_preview_tile_off", "Tile off"), function() { tileMode = 0; }), + menuItem(__txtx("panel_preview_tile_horizontal", "Tile horizontal"), function() { tileMode = 1; }), + menuItem(__txtx("panel_preview_tile_vertical", "Tile vertical"), function() { tileMode = 2; }), + menuItem(__txtx("panel_preview_tile_both", "Tile both"), function() { tileMode = 3; }), + ]); + } + ], + [ + THEME.icon_grid_setting, + function() { return 0; }, + function() { return __txtx("grid_title", "Grid setting") }, + function(param) { + var dia = dialogPanelCall(new Panel_Preview_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); + } + ], + [ + THEME.onion_skin, + function() { return 0; }, + function() { return __txt("Onion Skin") }, + function(param) { + var dia = dialogPanelCall(new Panel_Preview_Onion_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); + } + ], + ]; + + toolbars_3d = [ + [ + THEME.d3d_preview_settings, + function() { return 0; }, + function() { return __txt("3D Preview Settings") }, + function(param) { + var dia = dialogPanelCall(new Panel_Preview_3D_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); + } + ], + [ + THEME.d3d_snap_settings, + function() { return 0; }, + function() { return __txt("3D Snap Settings") }, + function(param) { + var dia = dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); + } + ], + ]; + + tooltip_center = new tooltipHotkey(__txtx("panel_preview_center_canvas", "Center canvas"), "Preview", "Focus content"); + + actions = [ + [ + THEME.lock, + __txtx("panel_preview_lock_preview", "Lock previewing node"), + function() { locked = !locked; }, + function() { return !locked; }, + ], + [ + THEME.icon_preview_export, + __txtx("panel_preview_export_canvas", "Export canvas"), + function() { saveCurrentFrame(); }, + function() { return 0; }, + ], + [ + THEME.icon_center_canvas, + tooltip_center, + function() { fullView(); }, + function() { return 0; }, + ], + + ]; + #endregion + + function setNodePreview(node) { #region + if(locked) return; + + if(resetViewOnDoubleClick) + do_fullView = true; + + if(is_instanceof(node, Node) && node.getPreviewingNode != noone) + node = node.getPreviewingNode(); + + preview_node[splitView? splitSelection : 0] = node; + } #endregion + + function removeNodePreview(node) { #region + if(locked) return; + + if(preview_node[0] == node) preview_node[0] = noone; + if(preview_node[1] == node) preview_node[1] = noone; + } #endregion + + function resetNodePreview() { #region + preview_node = [ noone, noone ]; + locked = false; + } #endregion + + function getNodePreview() { return preview_node[splitView? splitSelection : 0]; } + function getNodePreviewSurface() { return preview_surfaces[splitView? splitSelection : 0]; } + function getNodePreviewSequence() { return preview_sequence[splitView? splitSelection : 0]; } + + function getPreviewData() { #region + preview_surfaces = [ noone, noone ]; + preview_sequence = [ noone, noone ]; + + for( var i = 0; i < 2; i++ ) { + var node = preview_node[i]; + + if(node == noone) continue; + if(!node.active) { + resetNodePreview(); + return; + } + + var value = node.getPreviewValues(); + + if(is_array(value)) { + preview_sequence[i] = value; + canvas_a = array_length(value); + } else { + preview_surfaces[i] = value; + canvas_a = 0; + } + + if(preview_sequence[i] != noone) { + if(array_length(preview_sequence[i]) == 0) return; + preview_surfaces[i] = preview_sequence[i][safe_mod(node.preview_index, array_length(preview_sequence[i]))]; + } + } + + var prevS = getNodePreviewSurface(); + + if(is_surface(prevS)) { + canvas_w = surface_get_width_safe(prevS); + canvas_h = surface_get_height_safe(prevS); + } + } #endregion + + function onFocusBegin() { PANEL_PREVIEW = self; } + + function dragCanvas() { #region + if(canvas_dragging) { + if(!MOUSE_WRAPPING) { + var dx = mx - canvas_drag_mx; + var dy = my - canvas_drag_my; + + canvas_x += dx; + canvas_y += dy; + } + + canvas_drag_mx = mx; + canvas_drag_my = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) + canvas_dragging = false; + } + + if(canvas_zooming) { + if(!MOUSE_WRAPPING) { + var dy = -(my - canvas_zoom_m) / 200; + + var _s = canvas_s; + canvas_s = clamp(canvas_s * (1 + dy), 0.10, 64); + + if(_s != canvas_s) { + var dx = (canvas_s - _s) * ((canvas_zoom_mx - canvas_x) / _s); + var dy = (canvas_s - _s) * ((canvas_zoom_my - canvas_y) / _s); + canvas_x -= dx; + canvas_y -= dy; + } + } + + canvas_zoom_m = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) + canvas_zooming = false; + } + + if(pHOVER && canvas_hover) { + var _doDragging = false; + var _doZooming = false; + + if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) { + _doDragging = true; + canvas_drag_key = PREFERENCES.pan_mouse_key; + } else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) { + _doDragging = true; + canvas_drag_key = mb_left; + } else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) { + _doZooming = true; + canvas_drag_key = mb_left; + } + + if(_doDragging) { + canvas_dragging = true; + canvas_drag_mx = mx; + canvas_drag_my = my; + canvas_drag_sx = canvas_x; + canvas_drag_sy = canvas_y; + } + + if(_doZooming) { + canvas_zooming = true; + canvas_zoom_mx = mx; + canvas_zoom_my = my; + canvas_zoom_m = my; + canvas_zoom_s = canvas_s; + } + + var _canvas_s = canvas_s; + var inc = 0.1; + if(canvas_s > 16) inc = 2; + else if(canvas_s > 8) inc = 1; + else if(canvas_s > 3) inc = 0.5; + else if(canvas_s > 1) inc = 0.25; + + if(mouse_wheel_down() && !key_mod_press_any()) canvas_s = max(round(canvas_s / inc) * inc - inc, 0.10); + if(mouse_wheel_up() && !key_mod_press_any()) canvas_s = min(round(canvas_s / inc) * inc + inc, 64); + + if(_canvas_s != canvas_s) { + var dx = (canvas_s - _canvas_s) * ((mx - canvas_x) / _canvas_s); + var dy = (canvas_s - _canvas_s) * ((my - canvas_y) / _canvas_s); + canvas_x -= dx; + canvas_y -= dy; + } + } + + canvas_dragging_key = false; + canvas_zooming_key = false; + canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height); + } #endregion + + function dragCanvas3D() { #region + if(d3_camPanning) { + if(!MOUSE_WRAPPING) { + var dx = mx - d3_camPan_mx; + var dy = my - d3_camPan_my; + + var px = d3_view_camera.focus_angle_x; + var py = d3_view_camera.focus_angle_y; + var ax = px + dx * 0.2 * d3_pan_speed; + var ay = py + dy * 0.1 * d3_pan_speed; + + //if(py < 90 && ay >= 90) ax -= 180; + //if(py > 90 && ay <= 90) ax += 180; + + //print($"{ax},\t{ay}"); + + d3_view_camera.focus_angle_x = ax; + d3_view_camera.focus_angle_y = ay; + } + + d3_camPan_mx = mx; + d3_camPan_my = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) + d3_camPanning = false; + } + + if(canvas_zooming) { + if(!MOUSE_WRAPPING) { + var dy = -(my - canvas_zoom_m) / 200; + d3_view_camera.focus_dist = clamp(d3_view_camera.focus_dist + dy, 1, 1000); + } + + canvas_zoom_m = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) + canvas_zooming = false; + } + + if(pHOVER && canvas_hover) { + var _doDragging = false; + var _doZooming = false; + + if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) { + _doDragging = true; + canvas_drag_key = PREFERENCES.pan_mouse_key; + } else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) { + _doDragging = true; + canvas_drag_key = mb_left; + } else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) { + _doZooming = true; + canvas_drag_key = mb_left; + } + + if(_doDragging) { + d3_camPanning = true; + d3_camPan_mx = mx; + d3_camPan_my = my; + } + + if(_doZooming) { + canvas_zooming = true; + canvas_zoom_m = my; + } + + if(mouse_wheel_up()) d3_view_camera.focus_dist = max( 1, d3_view_camera.focus_dist * (1 - d3_zoom_speed)); + if(mouse_wheel_down()) d3_view_camera.focus_dist = min(1000, d3_view_camera.focus_dist * (1 + d3_zoom_speed)); + } + + canvas_dragging_key = false; + canvas_zooming_key = false; + canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height); + } #endregion + + function fullView() { #region + var bbox = noone; + + var node = getNodePreview(); + if(node != noone) bbox = node.getPreviewBoundingBox(); + if(bbox == noone) bbox = BBOX().fromWH(0, 0, PROJECT.attributes.surface_dimension[0], PROJECT.attributes.surface_dimension[1]); + + var ss = min((w - 32 - tool_side_drawing * 40) / bbox.w, (h - 32 - toolbar_height * 2) / bbox.h); + canvas_s = ss; + canvas_x = w / 2 - bbox.w * canvas_s / 2 - bbox.x0 * canvas_s + (tool_side_drawing * 40 / 2); + canvas_y = h / 2 - bbox.h * canvas_s / 2 - bbox.y0 * canvas_s; + } #endregion + + function drawNodeChannel(_x, _y) { #region + var _node = getNodePreview(); + if(_node == noone) return; + if(ds_list_size(_node.outputs) < 2) return; + + var chName = []; + sbChannelIndex = []; + + var currName = _node.outputs[| _node.preview_channel].name; + draw_set_text(sbChannel.font, fa_center, fa_center); + var ww = 0; + var hh = TEXTBOX_HEIGHT - ui(2); + + for( var i = 0; i < ds_list_size(_node.outputs); i++ ) { + if(_node.outputs[| i].type != VALUE_TYPE.surface) continue; + + array_push(chName, _node.outputs[| i].name); + array_push(sbChannelIndex, i); + ww = max(ww, string_width(_node.outputs[| i].name) + ui(40)); + } + + sbChannel.data_list = chName; + sbChannel.setFocusHover(pFOCUS, pHOVER); + sbChannel.draw(_x - ww, _y - hh / 2, ww, hh, currName, [mx, my], x, y); + right_menu_y += ui(40); + } #endregion + + function drawNodeChannel3D(_x, _y) { #region + var _node = getNodePreview(); + if(_node == noone) return; + + var ww = ui(128); + var hh = toolbar_height - ui(12); + + d3Channel.setFocusHover(pFOCUS, pHOVER); + d3Channel.draw(_x - ww, _y - hh / 2, ww, hh, d3ChannelNames[d3_preview_channel], [mx, my], x, y); + right_menu_y += ui(40); + } #endregion + + function drawOnionSkin(node, psx, psy, ss) { #region + var _surf = preview_surfaces[0]; + var _rang = PROJECT.onion_skin.range; + + var _alph = PROJECT.onion_skin.alpha; + var _colr = PROJECT.onion_skin.color; + + var _step = PROJECT.onion_skin.step; + var _top = PROJECT.onion_skin.on_top; + + var fr = CURRENT_FRAME; + var st = min(_rang[0], _rang[1]); + var ed = max(_rang[0], _rang[1]); + + st = sign(st) * floor(abs(st) / _step) * _step; + ed = sign(ed) * floor(abs(ed) / _step) * _step; + + st += fr; + ed += fr; + + for( var i = st; i <= ed; i += _step ) { + var surf = node.getCacheFrame(i); + if(!is_surface(surf)) continue; + + var aa = power(_alph, abs((i - fr) / _step)); + var cc = c_white; + if(i < fr) cc = _colr[0]; + else if(i > fr) cc = _colr[1]; + + draw_surface_ext_safe(surf, psx, psy, ss, ss, 0, cc, aa); + } + + if(_top) draw_surface_ext_safe(_surf, psx, psy, ss, ss); + } #endregion + + function drawNodePreview() { #region + var ss = canvas_s; + var psx = 0, psy = 0; + var psw = 0, psh = 0; + var pswd = 0, pshd = 0; + var psx1 = 0, psy1 = 0; + + var ssx = 0, ssy = 0; + var ssw = 0, ssh = 0; + + if(is_surface(preview_surfaces[0])) { + psx = canvas_x + preview_node[0].preview_x * ss; + psy = canvas_y + preview_node[0].preview_y * ss; + + psw = surface_get_width_safe(preview_surfaces[0]); + psh = surface_get_height_safe(preview_surfaces[0]); + pswd = psw * ss; + pshd = psh * ss; + + psx1 = psx + pswd; + psy1 = psy + pshd; + } + + if(is_surface(preview_surfaces[1])) { + var ssx = canvas_x + preview_node[1].preview_x * ss; + var ssy = canvas_y + preview_node[1].preview_y * ss; + + var ssw = surface_get_width_safe(preview_surfaces[1]); + var ssh = surface_get_height_safe(preview_surfaces[1]); + } + + var _node = getNodePreview(); + if(_node) title = _node.renamed? _node.display_name : _node.name; + + #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Draw Surfaces <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + var _ps0 = is_surface(preview_surfaces[0]); + var _ps1 = is_surface(preview_surfaces[1]); + + if(_ps0) { + var _sw = surface_get_width_safe(preview_surfaces[0]); + var _sh = surface_get_height_safe(preview_surfaces[0]); + + preview_surface[0] = surface_verify(preview_surface[0], _sw, _sh); + + surface_set_shader(preview_surface[0], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample); + shader_set_f("palette", PROJECT.palettes); + shader_set_i("keys", array_length(PROJECT.attributes.palette)); + shader_set_i("alpha", 1); + + draw_surface_safe(preview_surfaces[0]); + surface_reset_shader(); + } + + if(_ps1) { + var _sw = surface_get_width_safe(preview_surfaces[1]); + var _sh = surface_get_height_safe(preview_surfaces[1]); + + preview_surface[1] = surface_verify(preview_surface[1], _sw, _sh); + + surface_set_shader(preview_surface[1], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample); + shader_set_f("palette", PROJECT.palettes); + shader_set_i("keys", array_length(PROJECT.attributes.palette)); + shader_set_i("alpha", 1); + + draw_surface_safe(preview_surfaces[1]); + surface_reset_shader(); + } + + switch(splitView) { + case 0 : + if(_ps0) { + preview_node[0].previewing = 1; + + switch(tileMode) { + case 0 : + if(PROJECT.onion_skin.enabled) drawOnionSkin(node, psx, psy, ss); + else draw_surface_ext(preview_surface[0], psx, psy, ss, ss, 0, c_white, preview_node[0].preview_alpha); + break; + + case 1 : + tile_surface = surface_verify(tile_surface, w, surface_get_height_safe(preview_surface[0]) * ss); + surface_set_target(tile_surface); + DRAW_CLEAR + draw_surface_tiled_ext_safe(preview_surface[0], psx, 0, ss, ss, 0, c_white, 1); + surface_reset_target(); + draw_surface_safe(tile_surface, 0, psy); + break; + + case 2 : + tile_surface = surface_verify(tile_surface, surface_get_width_safe(preview_surface[0]) * ss, h); + surface_set_target(tile_surface); + DRAW_CLEAR + draw_surface_tiled_ext_safe(preview_surface[0], 0, psy, ss, ss, 0, c_white, 1); + surface_reset_target(); + draw_surface_safe(tile_surface, psx, 0); + break; + + case 3 : + draw_surface_tiled_ext_safe(preview_surface[0], psx, psy, ss, ss, 0, c_white, 1); break; + } + } + break; + case 1 : + var sp = splitPosition * w; + + if(_ps0) { + preview_node[0].previewing = 2; + var maxX = min(sp, psx1); + var sW = min(psw, (maxX - psx) / ss); + + if(sW > 0) + draw_surface_part_ext_safe(preview_surface[0], 0, 0, sW, psh, psx, psy, ss, ss, 0, c_white, 1); + } + + if(_ps1) { + preview_node[1].previewing = 3; + var minX = max(ssx, sp); + var sX = (minX - ssx) / ss; + var spx = max(sp, ssx); + + if(sX >= 0 && sX < ssw) + draw_surface_part_ext_safe(preview_surface[1], sX, 0, ssw - sX, ssh, spx, ssy, ss, ss, 0, c_white, 1); + } + break; + case 2 : + var sp = splitPosition * h; + + if(_ps0) { + preview_node[0].previewing = 4; + var maxY = min(sp, psy1); + var sH = min(psh, (maxY - psy) / ss); + + if(sH > 0) + draw_surface_part_ext_safe(preview_surface[0], 0, 0, psw, sH, psx, psy, ss, ss, 0, c_white, 1); + } + + if(_ps1) { + preview_node[1].previewing = 5; + var minY = max(ssy, sp); + var sY = (minY - ssy) / ss; + var spy = max(sp, ssy); + + if(sY >= 0 && sY < ssh) + draw_surface_part_ext_safe(preview_surface[1], 0, sY, ssw, ssh - sY, ssx, spy, ss, ss, 0, c_white, 1); + } + break; + } + #endregion + + if(!instance_exists(o_dialog_menubox)) { #region color sample + sample_color = noone; + sample_x = noone; + sample_y = noone; + + if(mouse_on_preview && (mouse_press(mb_right) || key_mod_press(CTRL))) { + var _sx = sample_x; + var _sy = sample_y; + + sample_x = floor((mx - canvas_x) / canvas_s); + sample_y = floor((my - canvas_y) / canvas_s); + var surf = getNodePreviewSurface(); + sample_color = surface_get_pixel_ext(surf, sample_x, sample_y); + + //print($"{dec_to_hex(sample_color)}: {color_get_alpha(int64(sample_color))}"); + } + } #endregion + + if(is_surface(preview_surfaces[0])) { #region outline + if(PROJECT.previewGrid.show) { + var _gw = PROJECT.previewGrid.size[0] * canvas_s; + var _gh = PROJECT.previewGrid.size[1] * canvas_s; + + var gw = pswd / _gw; + var gh = pshd / _gh; + + var cx = canvas_x; + var cy = canvas_y; + + draw_set_color(PROJECT.previewGrid.color); + draw_set_alpha(PROJECT.previewGrid.opacity); + + for( var i = 1; i < gw; i++ ) { + var _xx = cx + i * _gw; + draw_line(_xx, cy, _xx, cy + pshd); + } + + for( var i = 1; i < gh; i++ ) { + var _yy = cy + i * _gh; + draw_line(cx, _yy, cx + pswd, _yy); + } + + draw_set_alpha(1); + } + + draw_set_color(COLORS.panel_preview_surface_outline); + draw_rectangle(psx, psy, psx + pswd - 1, psy + pshd - 1, true); + } #endregion + } #endregion + + function draw3D() { #region + var _prev_node = getNodePreview(); + if(_prev_node == noone) return; + if(!_prev_node.is_3D) return; + + _prev_node.previewing = 1; + + d3_scene_preview = struct_has(_prev_node, "scene")? _prev_node.scene : d3_scene; + d3_scene_preview.camera = d3_view_camera; + + #region view + var _pos, targ, _blend = 1; + + targ = d3_camTarget; + _pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist); + + if(d3_active_transition == 1) { + var _up = new __vec3(0, 0, -1); + + d3_view_camera.position._lerp_float(_pos, 5, 0.1); + d3_view_camera.focus._lerp_float( targ, 5, 0.1); + d3_view_camera.up._lerp_float( _up, 5, 0.1); + + if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) + d3_active_transition = 0; + } else if(d3_active_transition == -1) { + var _pos = new __vec3(0, 0, 8); + var targ = new __vec3(0, 0, 0); + var _up = new __vec3(0, 1, 0); + + d3_view_camera.position._lerp_float(_pos, 5, 0.1); + d3_view_camera.focus._lerp_float( targ, 5, 0.1); + d3_view_camera.up._lerp_float( _up, 5, 0.1); + + _blend = d3_view_camera.position.distance(_pos) / 2; + _blend = clamp(_blend, 0, 1); + + if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) + d3_active_transition = 0; + } else { + d3_view_camera.position.set(_pos); + d3_view_camera.focus.set(targ); + } + + d3_view_camera.setViewSize(w, h); + d3_view_camera.setMatrix(); + #endregion + + #region background + surface_free_safe(d3_surface_bg); + + if(d3_scene_preview != d3_scene) + d3_surface_bg = d3_scene_preview.renderBackground(w, h); + #endregion + + #region shadow + if(d3_scene_preview == d3_scene) { + d3_scene_light0.shadow_map_scale = d3_view_camera.focus_dist * 2; + + var _prev_obj = _prev_node.getPreviewObject(); + if(_prev_obj != noone) { + d3_scene_light0.submitShadow(d3_scene_preview, _prev_obj); + _prev_obj.submitShadow(d3_scene_preview, _prev_obj); + } + } + #endregion + + d3_surface = surface_verify(d3_surface, w, h); + d3_surface_normal = surface_verify(d3_surface_normal, w, h); + d3_surface_depth = surface_verify(d3_surface_depth, w, h); + d3_surface_outline = surface_verify(d3_surface_outline, w, h); + + #region defer + var _prev_obj = _prev_node.getPreviewObject(); + d3_deferData = d3_scene_preview.deferPass(_prev_obj, w, h, d3_deferData); + #endregion + + #region grid + surface_set_target_ext(0, d3_surface); + surface_set_target_ext(1, d3_surface_normal); + surface_set_target_ext(2, d3_surface_depth); + + draw_clear_alpha(bg_color, 0); + + d3_view_camera.applyCamera(); + + gpu_set_ztestenable(true); + gpu_set_zwriteenable(false); + + if(OS != os_macosx) { + gpu_set_cullmode(cull_noculling); + + shader_set(sh_d3d_grid_view); + var _dist = round(d3_view_camera.focus.distance(d3_view_camera.position)); + var _tx = round(d3_view_camera.focus.x); + var _ty = round(d3_view_camera.focus.y); + + var _scale = _dist * 2; + while(_scale > 32) _scale /= 2; + + shader_set_f("axisBlend", _blend); + shader_set_f("scale", _scale); + shader_set_f("shift", _tx / _dist / 2, _ty / _dist / 2); + draw_sprite_stretched(s_fx_pixel, 0, _tx - _dist, _ty - _dist, _dist * 2, _dist * 2); + shader_reset(); + } + + gpu_set_zwriteenable(true); + #endregion + + #region draw + d3_scene_preview.reset(); + gpu_set_cullmode(cull_counterclockwise); + + var _prev_obj = _prev_node.getPreviewObjects(); + + if(d3_scene_preview == d3_scene) { + if(d3_scene_light_enabled) { + d3_scene_preview.addLightDirectional(d3_scene_light0); + d3_scene_preview.addLightDirectional(d3_scene_light1); + } + } + + for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { + var _prev = _prev_obj[i]; + if(_prev == noone) continue; + + _prev.submitShader(d3_scene_preview); + } + + d3_scene_preview.apply(d3_deferData); + + //print("========= Submit begin ========="); + for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { + var _prev = _prev_obj[i]; + if(_prev == noone) continue; + _prev.submitUI(d3_scene_preview); //////////////// SUBMIT //////////////// + } + //print("========= Submit end ========="); + + gpu_set_cullmode(cull_noculling); + surface_reset_target(); + + draw_clear(bg_color); + + switch(d3_preview_channel) { + case 0 : + if(d3_scene_preview.draw_background) + draw_surface_safe(d3_surface_bg); + + draw_surface_safe(d3_surface); + + BLEND_MULTIPLY + draw_surface_safe(d3_deferData.ssao); + BLEND_NORMAL + break; + case 1 : draw_surface_safe(d3_surface_normal); break; + case 2 : draw_surface_safe(d3_surface_depth); break; + } + #endregion + + #region outline + var inspect_node = PANEL_INSPECTOR.getInspecting(); + + if(inspect_node && inspect_node.is_3D) { + var _inspect_obj = inspect_node.getPreviewObjectOutline(); + + surface_set_target(d3_surface_outline); + draw_clear(c_black); + + d3_scene_preview.camera.applyCamera(); + + gpu_set_ztestenable(false); + for( var i = 0, n = array_length(_inspect_obj); i < n; i++ ) { + if(_inspect_obj[i] == noone) continue; + _inspect_obj[i].submitSel(d3_scene_preview); + } + surface_reset_target(); + + shader_set(sh_d3d_outline); + shader_set_dim("dimension", d3_surface_outline); + shader_set_color("outlineColor", COLORS._main_accent); + draw_surface(d3_surface_outline, 0, 0); + shader_reset(); + } + #endregion + + d3_scene_preview.camera.resetCamera(); + } #endregion + + function drawPreviewOverlay() { #region + right_menu_y = toolbar_height - ui(4); + toolbar_draw = false; + + var _node = getNodePreview(); + + #region status texts (top right) + if(right_menu_x == 0) right_menu_x = w - ui(8); + + if(PANEL_PREVIEW == self) { + draw_set_text(f_p0, fa_right, fa_top, COLORS._main_text_accent); + draw_text(right_menu_x, right_menu_y, __txt("Active")); + right_menu_y += string_height("l"); + } + + var txt = $"{__txt("fps")} {fps}"; + if(PREFERENCES.panel_preview_show_real_fps) + txt += $" / {FPS_REAL}"; + + draw_set_text(f_p0, fa_right, fa_top, fps >= PROJECT.animator.framerate? COLORS._main_text_sub : COLORS._main_value_negative); + draw_text(right_menu_x, right_menu_y, txt); + right_menu_y += string_height("l"); + + draw_set_text(f_p0, fa_right, fa_top, COLORS._main_text_sub); + draw_text(right_menu_x, right_menu_y, $"{__txt("Frame")} {CURRENT_FRAME + 1}/{TOTAL_FRAMES}"); + + right_menu_y += string_height("l"); + draw_text(right_menu_x, right_menu_y, $"x{canvas_s}"); + + if(pHOVER) { + right_menu_y += string_height("l"); + var mpx = floor((mx - canvas_x) / canvas_s); + var mpy = floor((my - canvas_y) / canvas_s); + draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]"); + + if(mouse_pos_string != "") { + right_menu_y += string_height("l"); + draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}"); + } + } + + mouse_pos_string = ""; + + if(_node == noone) return; + + right_menu_y += string_height("l"); + var txt = $"{canvas_w} x {canvas_h}px"; + if(canvas_a) txt = $"{canvas_a} x {txt}"; + draw_text(right_menu_x, right_menu_y, txt); + + right_menu_y += string_height("l"); + right_menu_x = w - ui(8); + #endregion + + var pseq = getNodePreviewSequence(); + if(pseq == noone) return; + + if(!array_equals(pseq, _preview_sequence)) { + _preview_sequence = pseq; + preview_x = 0; + preview_x_to = 0; + } + + var prev_size = ui(48); + preview_x = lerp_float(preview_x, preview_x_to, 4); + + if(pHOVER && my > h - toolbar_height - prev_size - ui(16) && my > toolbar_height) { + canvas_hover = false; + + if(mouse_wheel_down() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to - prev_size * SCROLL_SPEED, - preview_x_max, 0); + if(mouse_wheel_up() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to + prev_size * SCROLL_SPEED, - preview_x_max, 0); + } + + #region surface array + preview_x_max = 0; + + if(array_length(pseq) > 1) { + var _xx = tool_side_drawing * ui(40); + var xx = _xx + preview_x + ui(8); + var yy = h - toolbar_height - prev_size - ui(8); + + if(my > yy - 8) mouse_on_preview = 0; + var hoverable = pHOVER && point_in_rectangle(mx, my, _xx, ui(32), w, h - toolbar_height); + + for(var i = 0; i < array_length(pseq); i++) { + var prev = pseq[i]; + if(is_instanceof(prev, __d3dMaterial)) + prev = prev.surface; + if(!is_surface(prev)) continue; + + var prev_w = surface_get_width_safe(prev); + var prev_h = surface_get_height_safe(prev); + var ss = prev_size / max(prev_w, prev_h); + var prev_sw = prev_w * ss; + + draw_set_color(COLORS.panel_preview_surface_outline); + draw_rectangle(xx, yy, xx + prev_w * ss, yy + prev_h * ss, true); + + if(hoverable && point_in_rectangle(mx, my, xx, yy, xx + prev_sw, yy + prev_h * ss)) { + if(mouse_press(mb_left, pFOCUS)) { + _node.preview_index = i; + _node.onValueUpdate(0); + if(resetViewOnDoubleClick) + do_fullView = true; + } + draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 1); + } else { + draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 0.5); + } + + if(i == _node.preview_index) { + draw_set_color(COLORS._main_accent); + draw_rectangle(xx, yy, xx + prev_sw, yy + prev_h * ss, true); + } + + xx += prev_sw + ui(8); + preview_x_max += prev_sw + ui(8); + } + } + #endregion + + preview_x_max = max(preview_x_max - ui(100), 0); + + #region ++++ sequence control ++++ + //var by = h - toolbar_height - prev_size - ui(56); + //var bx = ui(10); + + //var b = buttonInstant(THEME.button_hide, bx, by, ui(40), ui(40), [mx, my], pFOCUS, pHOVER); + + //if(_node.preview_speed == 0) { + // if(b) { + // draw_sprite_ui_uniform(THEME.sequence_control, 1, bx + ui(20), by + ui(20), 1, COLORS._main_icon, 1); + // if(b == 2) _node.preview_speed = preview_rate / game_get_speed(gamespeed_fps); + // } + // draw_sprite_ui_uniform(THEME.sequence_control, 1, bx + ui(20), by + ui(20), 1, COLORS._main_icon, 0.5); + //} else { + // if(b) { + // draw_sprite_ui_uniform(THEME.sequence_control, 0, bx + ui(20), by + ui(20), 1, COLORS._main_accent, 1); + // if(b == 2) _node.preview_speed = 0; + // } + // draw_sprite_ui_uniform(THEME.sequence_control, 0, bx + ui(20), by + ui(20), 1, COLORS._main_accent, .75); + //} + #endregion + } #endregion + + function drawNodeTools(active, _node) { #region + var _mx = mx; + var _my = my; + var isHover = pHOVER && mouse_on_preview == 1; + var tool_size = ui(32); + + var cx = canvas_x + _node.preview_x * canvas_s; + var cy = canvas_y + _node.preview_y * canvas_s; + var _snx = 0, _sny = 0; + + tool_side_drawing = _node.tools != -1; + + if(_node.tools != -1 && point_in_rectangle(_mx, _my, 0, 0, toolbar_width, h)) { + isHover = false; + mouse_on_preview = 0; + } + + var overlayHover = tool_hovering == noone && !overlay_hovering; + overlayHover &= active && isHover; + overlayHover &= point_in_rectangle(mx, my, (_node.tools != -1) * toolbar_width, toolbar_height, w, h - toolbar_height); + overlayHover &= !key_mod_press(CTRL); + var params = { w, h, toolbar_height }; + + reset_global_getset(); + + if(_node.is_3D) { + if(key_mod_press(CTRL) || d3_tool_snap) { + _snx = d3_tool_snap_position; + _sny = d3_tool_snap_rotation; + } + + _node.drawOverlay3D(overlayHover, d3_scene, _mx, _my, _snx, _sny, params); + } else { + if(key_mod_press(CTRL)) { + _snx = PROJECT.previewGrid.show? PROJECT.previewGrid.size[0] : 1; + _sny = PROJECT.previewGrid.show? PROJECT.previewGrid.size[1] : 1; + } else if(PROJECT.previewGrid.snap) { + _snx = PROJECT.previewGrid.size[0]; + _sny = PROJECT.previewGrid.size[1]; + } + + _node.drawOverlay(isHover, overlayHover, cx, cy, canvas_s, _mx, _my, _snx, _sny, params); + } + + #region node overlay + overlay_hovering = false; + + if(_node.drawPreviewToolOverlay(pHOVER, pFOCUS, _mx, _my, { x, y, w, h, toolbar_height, + x0: _node.tools == -1? 0 : ui(40), + x1: w, + y0: toolbar_height - ui(8), + y1: h - toolbar_height + })) { + canvas_hover = false; + overlay_hovering = true; + } + #endregion + + var _tool = tool_hovering; + tool_hovering = noone; + + if(_node.tools == -1) { + tool_current = noone; + return; + } + + var aa = d3_active? 0.8 : 1; + draw_sprite_stretched_ext(THEME.tool_side, 1, 0, ui(32), toolbar_width, h - toolbar_height - ui(32), c_white, aa); + + tool_y_max = 0; + tool_y = lerp_float(tool_y, tool_y_to, 5); + var xx = ui(1) + toolbar_width / 2; + var yy = ui(34) + tool_size / 2 + tool_y; + var pd = 2; + var thov = pHOVER && point_in_rectangle(mx, my, 0, toolbar_height, toolbar_width, h - toolbar_height); + if(thov) canvas_hover = false; + + for(var i = 0; i < array_length(_node.tools); i++) { #region left tools + var tool = _node.tools[i]; + var _x0 = xx - tool_size / 2; + var _y0 = yy - tool_size / 2; + var _x1 = xx + tool_size / 2; + var _y1 = yy + tool_size / 2; + + if(tool == -1) { + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); + + yy += ui(8); + tool_y_max += ui(8); + continue; + } + + if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) + tool_hovering = tool; + + if(tool.subtools > 0 && _tool == tool) { #region subtools + var s_ww = tool_size * tool.subtools; + var s_hh = tool_size; + draw_sprite_stretched(THEME.menu_bg, 0, _x0 - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); + + var stool = tool.spr; + + for( var j = 0; j < array_length(stool); j++ ) { + var _sxx = xx + j * tool_size; + var _syy = yy; + + var _sx0 = _sxx - tool_size / 2; + var _sy0 = _syy - tool_size / 2; + var _sx1 = _sxx + tool_size / 2; + var _sy1 = _syy + tool_size / 2; + + if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { + TOOLTIP = tool.getDisplayName(j); + draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(j); + } + + if(tool_current == tool && tool.selecting == j) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + + draw_sprite_colored(stool[j], 0, _sxx, _syy); + } + + if(point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x0 + s_ww, _y1 - 1)) + tool_hovering = tool; + #endregion + } else { #region single tools + if(tool_hovering == tool) { + draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2); + TOOLTIP = tool.getDisplayName(); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(); + } + + if(pFOCUS && WIDGET_CURRENT == noone) { + var _key = tool.checkHotkey(); + + if(keyboard_check_pressed(ord(string(i + 1))) || (_key != "" && keyboard_check_pressed(ord(_key)))) + tool.toggleKeyboard(); + } + + if(tool_current == tool) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + + if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); + else draw_sprite_colored(tool.spr, 0, xx, yy); + #endregion + } + + yy += tool_size; + tool_y_max += tool_size; + } #endregion + + var _h = _node.drawTools(_mx, _my, xx, yy - tool_size / 2, tool_size, thov, pFOCUS); + yy += _h; + tool_y_max += _h; + + tool_y_max = max(0, tool_y_max - h + toolbar_height * 2); + if(thov && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_y_to = clamp(tool_y_to + ui(64) * SCROLL_SPEED, -tool_y_max, 0); + if(mouse_wheel_down()) tool_y_to = clamp(tool_y_to - ui(64) * SCROLL_SPEED, -tool_y_max, 0); + } + + if(_node.rightTools != -1) { + right_menu_x = w - toolbar_width - ui(8); + tool_ry_max = 0; + tool_ry = lerp_float(tool_ry, tool_ry_to, 5); + + var _tbx = w - toolbar_width; + var xx = _tbx + toolbar_width / 2; + var yy = ui(34) + tool_size / 2 + tool_ry; + + var _sw = -toolbar_width / sprite_get_width(THEME.tool_side); + var _sh = h - toolbar_height - ui(32) / sprite_get_height(THEME.tool_side); + + draw_sprite_ext(THEME.tool_side, 1, w + 1, ui(32), _sw, _sh, 0, c_white, aa); + + var thov = pHOVER && point_in_rectangle(mx, my, _tbx, toolbar_height, w, h - toolbar_height); + if(thov) canvas_hover = false; + + for(var i = 0; i < array_length(_node.rightTools); i++) { #region right tools + var tool = _node.rightTools[i]; + var _x0 = xx - tool_size / 2; + var _y0 = yy - tool_size / 2; + var _x1 = xx + tool_size / 2; + var _y1 = yy + tool_size / 2; + + if(tool == -1) { + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); + + yy += ui(8); + tool_ry_max += ui(8); + continue; + } + + if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) + tool_hovering = tool; + + if(tool.subtools > 0 && _tool == tool) { #region subtools + + var stool = tool.spr; + var s_ww = tool_size * tool.subtools; + var s_hh = tool_size; + var tx = _x0 - s_ww + tool_size; + draw_sprite_stretched(THEME.menu_bg, 0, tx - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); + + var _am = array_length(stool); + + for( var j = 0; j < _am; j++ ) { + var _sind = _am - 1 - j; + var _sxx = tx + j * tool_size + tool_size / 2; + var _syy = yy; + + var _sx0 = _sxx - tool_size / 2; + var _sy0 = _syy - tool_size / 2; + var _sx1 = _sxx + tool_size / 2; + var _sy1 = _syy + tool_size / 2; + + draw_sprite_colored(stool[_sind], 0, _sxx, _syy); + + if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { + TOOLTIP = tool.getDisplayName(_sind); + draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(_sind); + } + + if(tool_current == tool && tool.selecting == _sind) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + } + + if(point_in_rectangle(_mx, _my, tx, _y0 + 1, tx + s_ww, _y1 - 1)) + tool_hovering = tool; + #endregion + } else { #region single tools + if(tool_hovering == tool) { + draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2); + TOOLTIP = tool.getDisplayName(); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(); + } + + if(tool_current == tool) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + + if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); + else draw_sprite_colored(tool.spr, 0, xx, yy); + #endregion + } + + yy += tool_size; + tool_ry_max += tool_size; + } #endregion + + tool_ry_max = max(0, tool_ry_max - h + toolbar_height * 2); + if(thov && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_ry_to = clamp(tool_ry_to + ui(64) * SCROLL_SPEED, -tool_ry_max, 0); + if(mouse_wheel_down()) tool_ry_to = clamp(tool_ry_to - ui(64) * SCROLL_SPEED, -tool_ry_max, 0); + } + } + } #endregion + + function drawToolBar(_tool) { #region + var ty = h - toolbar_height; + //draw_sprite_stretched_ext(THEME.toolbar_shadow, 0, 0, ty - 12 + 4, w, 12, c_white, 0.5); + + var aa = d3_active? 0.8 : 1; + draw_sprite_stretched_ext(THEME.toolbar, 1, 0, 0, w, topbar_height, c_white, aa); + draw_sprite_stretched_ext(THEME.toolbar, 0, 0, ty, w, toolbar_height, c_white, aa); + + if(_tool && tool_current != noone) { #region tool settings + var settings = array_merge(_tool.getToolSettings(), tool_current.settings); + + tool_x = lerp_float(tool_x, tool_x_to, 5); + var tolx = tool_x + ui(8); + var toly = ui(8); + var tolw = ui(48); + var tolh = toolbar_height - ui(20); + var tol_max_w = ui(16); + + for( var i = 0, n = array_length(settings); i < n; i++ ) { + var sett = settings[i]; + var nme = sett[0]; + var wdg = sett[1]; + var key = sett[2]; + var atr = sett[3]; + + if(nme != "") { + tolx += ui(8) + bool(i == 0) * ui(8); + tol_max_w += ui(8) + bool(i == 0) * ui(8); + } + + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub); + if(nme != "") { + draw_text(tolx, toolbar_height / 2 - ui(2), nme); + tolx += string_width(nme) + ui(8); + tol_max_w += string_width(nme) + ui(8); + } + + wdg.setFocusHover(pFOCUS, pHOVER); + + switch(instanceof(wdg)) { + case "textBox" : + tolw = ui(40); + if(wdg.side_button != noone) tolw += tolh + ui(8); + break; + + case "checkBoxGroup" : tolw = tolh * wdg.size; break; + case "checkBox" : tolw = tolh; break; + case "scrollBox" : tolw = ui(96); break; + case "buttonClass" : tolw = wdg.text == ""? tolh : tolw; break; + } + + var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) + params.s = tolh; + params.font = f_p3; + + wdg.drawParam(params); + + tolx += tolw + ui(8) + (nme != "") * ui(8); + tol_max_w += tolw + ui(8) + (nme != "") * ui(8); + } + + tol_max_w = max(0, tol_max_w - w); + if(point_in_rectangle(mx, my, 0, 0, w, toolbar_height) && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_x_to = clamp(tool_x_to + ui(64) * SCROLL_SPEED, -tol_max_w, 0); + if(mouse_wheel_down()) tool_x_to = clamp(tool_x_to - ui(64) * SCROLL_SPEED, -tol_max_w, 0); + } + #endregion + } else { #region color sampler + var cx = ui(8); + var cy = ui(8); + var cw = ui(32); + var ch = topbar_height - ui(16); + + if(sample_color != noone) { + draw_set_color(sample_color); + draw_rectangle(cx, cy, cx + cw, cy + ch, false); + draw_set_alpha(1); + } + + draw_set_color(COLORS.panel_toolbar_outline); + draw_rectangle(cx, cy, cx + cw, cy + ch, true); + + if(sample_color != noone) { + var tx = cx + cw + ui(16); + var hx = color_get_hex(sample_color); + draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + draw_text(tx, cy + ch / 2, hx); + + tx += string_width(hx) + ui(8); + draw_set_color(COLORS._main_text_sub); + draw_text(tx, cy + ch / 2, $"({color_get_alpha(sample_color)})"); + } + #endregion + } + + var tbx = toolbar_height / 2; + var tby = ty + toolbar_height / 2; + + var _toolbars = d3_active? toolbars_3d : toolbars; + + for( var i = 0, n = array_length(_toolbars); i < n; i++ ) { + var tb = _toolbars[i]; + var tbSpr = tb[0]; + var tbInd = tb[1](); + var tbTooltip = tb[2](); + var tbActive = tb[3]; + + var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbInd); + if(b == 2) tbActive( { x: x + tbx - ui(14), y: y + tby - ui(14) } ); + + tbx += ui(32); + } + + tbx = w - toolbar_height / 2; + for( var i = 0, n = array_length(actions); i < n; i++ ) { + var tb = actions[i]; + var tbSpr = tb[0]; + var tbTooltip = tb[1]; + var tbIndex = tb[3](); + + var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbIndex); + if(b == 2) tb[2](); + + tbx -= ui(32); + } + + draw_set_color(COLORS.panel_toolbar_separator); + draw_line_width(tbx + ui(12), tby - toolbar_height / 2 + ui(8), tbx + ui(12), tby + toolbar_height / 2 - ui(8), 2); + + if(d3_active) drawNodeChannel3D(tbx, tby); + else drawNodeChannel(tbx, tby); + } #endregion + + function drawSplitView() { #region + if(splitView == 0) return; + + draw_set_color(COLORS.panel_preview_split_line); + + if(splitViewDragging) { + if(splitView == 1) { + var cx = splitViewStart + (mx - splitViewMouse); + splitPosition = clamp(cx / w, .1, .9); + } else if(splitView == 2) { + var cy = splitViewStart + (my - splitViewMouse); + splitPosition = clamp(cy / h, .1, .9); + } + + if(mouse_release(mb_left)) + splitViewDragging = false; + } + + if(splitView == 1) { + var sx = w * splitPosition; + + if(mouse_on_preview && point_in_rectangle(mx, my, sx - ui(4), 0, sx + ui(4), h)) { + draw_line_width(sx, 0, sx, h, 2); + if(mouse_press(mb_left, pFOCUS)) { + splitViewDragging = true; + splitViewStart = sx; + splitViewMouse = mx; + } + } else + draw_line_width(sx, 0, sx, h, 1); + + draw_sprite_ui_uniform(THEME.icon_active_split, 0, splitSelection? sx + ui(16) : sx - ui(16), toolbar_height + ui(16),, COLORS._main_accent); + + if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(mx, my, 0, 0, sx, h)) + splitSelection = 0; + else if(point_in_rectangle(mx, my, sx, 0, w, h)) + splitSelection = 1; + } + } else { + var sy = h * splitPosition; + + if(mouse_on_preview && point_in_rectangle(mx, my, 0, sy - ui(4), w, sy + ui(4))) { + draw_line_width(0, sy, w, sy, 2); + if(mouse_press(mb_left, pFOCUS)) { + splitViewDragging = true; + splitViewStart = sy; + splitViewMouse = my; + } + } else + draw_line_width(0, sy, w, sy, 1); + draw_sprite_ui_uniform(THEME.icon_active_split, 0, ui(16), splitSelection? sy + ui(16) : sy - ui(16),, COLORS._main_accent); + + if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(mx, my, 0, 0, w, sy)) + splitSelection = 0; + else if(point_in_rectangle(mx, my, 0, sy, w, h)) + splitSelection = 1; + } + } + } #endregion + + function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<< + mouse_on_preview = pHOVER && point_in_rectangle(mx, my, 0, topbar_height, w, h - toolbar_height); + + var _prev_node = getNodePreview(); + + d3_active = _prev_node != noone && _prev_node.is_3D; + + draw_clear(bg_color); + if(canvas_bg == -1 && canvas_s >= 0.1) + draw_sprite_tiled_ext(s_transparent, 0, canvas_x, canvas_y, canvas_s, canvas_s, COLORS.panel_preview_transparent, 1); + else + draw_clear(canvas_bg); + draw_set_color(COLORS._main_icon_dark); + draw_line_width(canvas_x, 0, canvas_x, h, 1); + draw_line_width(0, canvas_y, w, canvas_y, 1); + + bg_color = lerp_color(bg_color, d3_active? COLORS.panel_3d_bg : COLORS.panel_bg_clear, 0.3); + title = __txt("Preview"); + + getPreviewData(); + + if(_prev_node) { + if(d3_active) { + dragCanvas3D(); + draw3D(); + } else { + dragCanvas(); + drawNodePreview(); + } + } else dragCanvas(); + + drawPreviewOverlay(); + + var inspect_node = PANEL_INSPECTOR.getInspecting(); + + var tool = noone; + if(inspect_node) { + tool = inspect_node.getTool(); + if(tool) drawNodeTools(pFOCUS, tool); + } else + tool_current = noone; + + if(do_fullView) { + do_fullView = false; + fullView(); + } + + if(mouse_on_preview && mouse_press(mb_right, pFOCUS) && !key_mod_press(SHIFT)) { + menuCall("preview_context_menu",,, [ + menuItem(__txtx("panel_graph_preview_window", "Send to preview window"), function() { create_preview_window(getNodePreview()); }, noone, ["Preview", "Preview window"]), + -1, + menuItem(__txtx("panel_preview_save", "Save current preview as") + "...", function() { saveCurrentFrame(); }), + menuItem(__txtx("panel_preview_save_all", "Save all current previews as") + "...", function() { saveAllCurrentFrames(); }), + -1, + menuItem(__txtx("panel_preview_copy_image", "Copy image"), function() { copyCurrentFrame(); }, THEME.copy), + menuItem(__txtx("panel_preview_copy_color", "Copy color") + " [" + string(sample_color) + "]", function() { clipboard_set_text(sample_color); }), + menuItem(__txtx("panel_preview_copy_hex", "Copy hex") + " [" + string(color_get_hex(sample_color)) + "]", function() { clipboard_set_text(color_get_hex(sample_color)); }), + ],, getNodePreview()); + } + + if(!d3_active) drawSplitView(); + drawToolBar(tool); + } #endregion + + static onFullScreen = function() { run_in(1, fullView); } + + function copyCurrentFrame() { #region + var prevS = getNodePreviewSurface(); + if(!is_surface(prevS)) return; + + var buff = buffer_create(surface_get_width_safe(prevS) * surface_get_height_safe(prevS) * 4, buffer_fixed, 1); + var s = surface_create(surface_get_width_safe(prevS), surface_get_height_safe(prevS)); + + surface_set_target(s); + shader_set(sh_BGR); + draw_surface(prevS, 0, 0); + shader_reset(); + surface_reset_target(); + + buffer_get_surface(buff, s, 0); + surface_free(s); + + clipboard_set_bitmap(buffer_get_address(buff), surface_get_width_safe(prevS), surface_get_height_safe(prevS)); + } #endregion + + function saveCurrentFrame() { #region + var prevS = getNodePreviewSurface(); + if(!is_surface(prevS)) return; + + var path = get_save_filename("image|*.png;*.jpg", "export"); + key_release(); + if(path == "") return; + if(filename_ext(path) != ".png") path += ".png"; + + surface_save_safe(prevS, path); + } #endregion + + function saveAllCurrentFrames() { #region + var path = get_save_filename("image|*.png;*.jpg", "export"); + key_release(); + if(path == "") return; + + var ext = ".png"; + var name = string_replace_all(path, ext, ""); + var ind = 0; + + var pseq = getNodePreviewSequence(); + for(var i = 0; i < array_length(pseq); i++) { + var prev = pseq[i]; + if(!is_surface(prev)) continue; + var _name = name + string(ind) + ext; + surface_save_safe(prev, _name); + ind++; + } + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/preferences/preferences.gml.backup0 b/#backups/scripts/preferences/preferences.gml.backup0 new file mode 100644 index 000000000..ab10f08f0 --- /dev/null +++ b/#backups/scripts/preferences/preferences.gml.backup0 @@ -0,0 +1,298 @@ +// 2024-04-15 17:50:18 +#region preference + globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA; + PREFERENCES = {}; + HOTKEYS_DATA = {}; + + #region ////////////////////////////////////////////////////////////////////// GENERAL UI ////////////////////////////////////////////////////////////////////// + + PREFERENCES.display_scaling = 1; + PREFERENCES.window_width = 1600; + PREFERENCES.window_height = 800; + PREFERENCES.window_maximize = false; + + PREFERENCES.theme = "default"; + PREFERENCES.local = "en"; + PREFERENCES.font_overwrite = ""; + + PREFERENCES.ui_framerate = 120; + PREFERENCES.path_resolution = 32; + PREFERENCES.move_directory = false; + + PREFERENCES.notification_time = 180; + PREFERENCES.notify_load_version = true; + PREFERENCES.show_crash_dialog = false; + + PREFERENCES.test_mode = false; + PREFERENCES.auto_save_time = 300; + PREFERENCES.use_legacy_exception = false; + + PREFERENCES.caret_blink = 0.75; + + PREFERENCES.textbox_shake = 0; + PREFERENCES.textbox_particle = 0; + + #endregion + + #region ////////////////////////////////////////////////////////////////////////// IO ////////////////////////////////////////////////////////////////////////// + + PREFERENCES.double_click_delay = 0.25; + PREFERENCES.mouse_wheel_speed = 1.00; + + PREFERENCES.keyboard_repeat_start = 0.50; + PREFERENCES.keyboard_repeat_speed = 0.10; + + #endregion + + #region ///////////////////////////////////////////////////////////////////////// DIALOG //////////////////////////////////////////////////////////////////////// + + PREFERENCES.node_recents_amount = 20; + + PREFERENCES.show_splash = true; + PREFERENCES.splash_expand_recent = false; + + PREFERENCES.dialog_add_node_grouping = true; + PREFERENCES.dialog_add_node_view = 0; + + PREFERENCES.dialog_add_node_w = 532; + PREFERENCES.dialog_add_node_h = 400; + + PREFERENCES.add_node_remember = true; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// PANEL ///////////////////////////////////////////////////////////////////////// + + PREFERENCES.panel_layout_file = "Vertical"; + + PREFERENCES.panel_graph_dragging = MOD_KEY.alt; + PREFERENCES.panel_graph_group_require_shift = true; + + PREFERENCES.panel_preview_dragging = MOD_KEY.alt; + PREFERENCES.panel_preview_show_real_fps = false; + + PREFERENCES.panel_menu_resource_monitor = false; + PREFERENCES.panel_menu_right_control = os_type == os_windows; + + PREFERENCES.inspector_focus_on_double_click = true; + PREFERENCES.inspector_view_default = 1; + + PREFERENCES.node_show_render_status = false; + PREFERENCES.node_show_time = true; + + PREFERENCES.expand_hover = false; + + PREFERENCES.graph_zoom_smoooth = 4; + PREFERENCES.graph_open_group_in_tab = false; + + PREFERENCES.connection_line_width = 2; + PREFERENCES.connection_line_sample = 1; + PREFERENCES.connection_line_corner = 8; + PREFERENCES.connection_line_aa = 2; + PREFERENCES.connection_line_transition = true; + PREFERENCES.connection_line_highlight = 0; + PREFERENCES.connection_line_highlight_fade = 0.75; + PREFERENCES.connection_line_highlight_all = false; + PREFERENCES.curve_connection_line = 1; + + PREFERENCES.collection_animated = true; + PREFERENCES.collection_preview_speed = 60; + PREFERENCES.collection_scale = 1; + + PREFERENCES.pan_mouse_key = mb_middle; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// WIDGET //////////////////////////////////////////////////////////////////////// + + PREFERENCES.widget_autocomplete_delay = 500; + PREFERENCES.alt_picker = true; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// NODES ///////////////////////////////////////////////////////////////////////// + + PREFERENCES.node_param_show = false; + PREFERENCES.node_param_width = 192; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// MISC ////////////////////////////////////////////////////////////////////////// + + PREFERENCES.save_file_minify = true; + PREFERENCES.render_all_export = true; + PREFERENCES.clear_temp_on_close = true; + + PREFERENCES.show_supporter_icon = true; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// PATHS ///////////////////////////////////////////////////////////////////////// + + PREFERENCES.temp_path = "%DIR%/temp/"; + PREFERENCES.ImageMagick_path = "%APP%/imagemagick/"; + PREFERENCES.webp_path = "%APP%/webp/"; + PREFERENCES.gifski_path = "%APP%/gifski/"; + PREFERENCES.ffmpeg_path = "%APP%/ffmpeg/"; + + PREFERENCES.versions = {}; + + #endregion + + PREFERENCES_DEF = variable_clone(PREFERENCES); +#endregion + +#region recent files + globalvar RECENT_FILES, RECENT_FILE_DATA; + RECENT_FILES = ds_list_create(); + RECENT_FILE_DATA = ds_list_create(); + + function RECENT_SAVE() { + var map = ds_map_create(); + var l = ds_list_create(); + ds_list_copy(l, RECENT_FILES); + ds_map_add_list(map, "Recents", l); + + var path = DIRECTORY + "recent.json"; + var file = file_text_open_write(path); + file_text_write_string(file, json_encode_minify(map)); + file_text_close(file); + ds_map_destroy(map); + } + + function RECENT_LOAD() { + var path = DIRECTORY + "recent.json"; + if(!file_exists_empty(path)) return; + + var file = file_text_open_read(path); + var load_str = ""; + while(!file_text_eof(file)) { + load_str += file_text_readln(file); + } + file_text_close(file); + var map = json_decode(load_str); + + if(ds_map_exists(map, "Recents")) { + var l = map[? "Recents"]; + ds_list_clear(RECENT_FILES); + + for(var i = 0; i < ds_list_size(l); i++) { + if(!file_exists_empty(l[| i])) continue; + ds_list_add(RECENT_FILES, l[| i]); + } + } + + RECENT_REFRESH(); + } + + function RECENT_REFRESH() { + for( var i = 0; i < ds_list_size(RECENT_FILE_DATA); i++ ) { + var d = RECENT_FILE_DATA[| i]; + if(sprite_exists(d.spr)) sprite_delete(d.spr); + if(surface_exists(d.thumbnail)) surface_free(d.thumbnail); + } + + ds_list_clear(RECENT_FILE_DATA); + + for( var i = 0; i < ds_list_size(RECENT_FILES); i++ ) { + var p = RECENT_FILES[| i]; + RECENT_FILE_DATA[| i] = new FileObject(filename_name_only(p), p); + } + } +#endregion + +#region save load + function PREF_SAVE() { #region + if(IS_CMD) return; + var map = {}; + + var save_l = []; + for(var j = 0; j < ds_list_size(HOTKEY_CONTEXT); j++) { + var ll = HOTKEYS[? HOTKEY_CONTEXT[| j]]; + + for(var i = 0; i < ds_list_size(ll); i++) + array_push(save_l, ll[| i].serialize()); + } + + map.key = save_l; + + PREFERENCES.window_maximize = window_is_maximized; + PREFERENCES.window_width = max(960, window_minimize_size[0]); + PREFERENCES.window_height = max(600, window_minimize_size[1]); + + map.preferences = PREFERENCES; + + json_save_struct(DIRECTORY + "keys.json", map); + json_save_struct(DIRECTORY + "Nodes/fav.json", global.FAV_NODES); + json_save_struct(DIRECTORY + "Nodes/recent.json", global.RECENT_NODES); + json_save_struct(DIRECTORY + "key_nodes.json", HOTKEYS_CUSTOM); + } #endregion + + function PREF_LOAD() { #region + var path = DIRECTORY + "keys.json"; + if(!file_exists_empty(path)) return; + + var map = json_load_struct(path); + if(array_empty(variable_struct_get_names(map))) return; + + HOTKEYS_DATA = {}; + + for(var i = 0; i < array_length(map.key); i++) { + var key_list = map.key[i]; + var _context = is_struct(key_list)? key_list.context : key_list[0]; + var name = is_struct(key_list)? key_list.name : key_list[1]; + + HOTKEYS_DATA[$ $"{_context}_{name}"] = key_list; + } + + struct_override(PREFERENCES, map.preferences); + + if(!directory_exists($"{DIRECTORY}Themes/{PREFERENCES.theme}")) + PREFERENCES.theme = "default"; + + var f = json_load_struct(DIRECTORY + "key_nodes.json"); + struct_override_nested(HOTKEYS_CUSTOM, f); + + LOCALE_DEF = PREFERENCES.local == "en"; + THEME_DEF = PREFERENCES.theme == "default"; + FONT_DEF = PREFERENCES.theme == "default" && PREFERENCES.local == "en" && PREFERENCES.display_scaling == 1; + + directory_verify(filepath_resolve(PREFERENCES.temp_path)); + + if(PREFERENCES.move_directory) directory_set_current_working(DIRECTORY); + } #endregion + + function PREF_APPLY() { #region + if(PREFERENCES.double_click_delay > 1) + PREFERENCES.double_click_delay /= 60; + + TESTING = struct_try_get(PREFERENCES, "test_mode", false); + if(TESTING) { + log_message("PREFERENCE", "Test mode enabled"); + instance_create_depth(0, 0, 0, addon_key_displayer); + } + + if(PREFERENCES.use_legacy_exception) resetException(); + else setException(); + + if(OS != os_macosx && !LOADING) { + if(PREFERENCES.window_maximize) { + winMan_Maximize(); + } else { + var ww = PREFERENCES.window_width; + var hh = PREFERENCES.window_height; + window_minimize_size = [ ww, hh ]; + + window_set_position(display_get_width() / 2 - ww / 2, display_get_height() / 2 - hh / 2); + window_set_size(ww, hh); + gameframe_set_shadow(true); + } + } + + window_refresh(); + game_set_speed(PREFERENCES.ui_framerate, gamespeed_fps); + + var grav = struct_try_get(PREFERENCES, "physics_gravity", [ 0, 10 ]); + physics_world_gravity(array_safe_get_fast(grav, 0, 0), array_safe_get_fast(grav, 1, 10)); + } #endregion +#endregion \ No newline at end of file diff --git a/#backups/scripts/preferences/preferences.gml.backup1 b/#backups/scripts/preferences/preferences.gml.backup1 new file mode 100644 index 000000000..ab7c66f84 --- /dev/null +++ b/#backups/scripts/preferences/preferences.gml.backup1 @@ -0,0 +1,298 @@ +// 2024-04-15 17:50:17 +#region preference + globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA; + PREFERENCES = {}; + HOTKEYS_DATA = {}; + + #region ////////////////////////////////////////////////////////////////////// GENERAL UI ////////////////////////////////////////////////////////////////////// + + PREFERENCES.display_scaling = 1; + PREFERENCES.window_width = 1600; + PREFERENCES.window_height = 800; + PREFERENCES.window_maximize = false; + + PREFERENCES.theme = "default"; + PREFERENCES.local = "en"; + PREFERENCES.font_overwrite = ""; + + PREFERENCES.ui_framerate = 120; + PREFERENCES.path_resolution = 32; + PREFERENCES.move_directory = false; + + PREFERENCES.notification_time = 180; + PREFERENCES.notify_load_version = true; + PREFERENCES.show_crash_dialog = false; + + PREFERENCES.test_mode = false; + PREFERENCES.auto_save_time = 300; + PREFERENCES.use_legacy_exception = false; + + PREFERENCES.caret_blink = 0.75; + + PREFERENCES.textbox_shake = 0; + PREFERENCES.textbox_particle = 0; + + #endregion + + #region ////////////////////////////////////////////////////////////////////////// IO ////////////////////////////////////////////////////////////////////////// + + PREFERENCES.double_click_delay = 0.25; + PREFERENCES.mouse_wheel_speed = 1.00; + + PREFERENCES.keyboard_repeat_start = 0.50; + PREFERENCES.keyboard_repeat_speed = 0.10; + + #endregion + + #region ///////////////////////////////////////////////////////////////////////// DIALOG //////////////////////////////////////////////////////////////////////// + + PREFERENCES.node_recents_amount = 20; + + PREFERENCES.show_splash = true; + PREFERENCES.splash_expand_recent = false; + + PREFERENCES.dialog_add_node_grouping = true; + PREFERENCES.dialog_add_node_view = 0; + + PREFERENCES.dialog_add_node_w = 532; + PREFERENCES.dialog_add_node_h = 400; + + PREFERENCES.add_node_remember = true; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// PANEL ///////////////////////////////////////////////////////////////////////// + + PREFERENCES.panel_layout_file = "Vertical"; + + PREFERENCES.panel_graph_dragging = MOD_KEY.alt; + PREFERENCES.panel_graph_group_require_shift = true; + + PREFERENCES.panel_preview_dragging = MOD_KEY.alt; + PREFERENCES.panel_preview_show_real_fps = false; + + PREFERENCES.panel_menu_resource_monitor = false; + PREFERENCES.panel_menu_right_control = os_type == os_windows; + + PREFERENCES.inspector_focus_on_double_click = true; + PREFERENCES.inspector_view_default = 1; + + PREFERENCES.node_show_render_status = false; + PREFERENCES.node_show_time = true; + + PREFERENCES.expand_hover = false; + + PREFERENCES.graph_zoom_smoooth = 4; + PREFERENCES.graph_open_group_in_tab = false; + + PREFERENCES.connection_line_width = 2; + PREFERENCES.connection_line_sample = 1; + PREFERENCES.connection_line_corner = 8; + PREFERENCES.connection_line_aa = 2; + PREFERENCES.connection_line_transition = true; + PREFERENCES.connection_line_highlight = 0; + PREFERENCES.connection_line_highlight_fade = 0.75; + PREFERENCES.connection_line_highlight_all = false; + PREFERENCES.curve_connection_line = 1; + + PREFERENCES.collection_animated = true; + PREFERENCES.collection_preview_speed = 60; + PREFERENCES.collection_scale = 1; + + PREFERENCES.pan_mouse_key = mb_middle; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// WIDGET //////////////////////////////////////////////////////////////////////// + + PREFERENCES.widget_autocomplete_delay = 500; + PREFERENCES.alt_picker = true; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// NODES ///////////////////////////////////////////////////////////////////////// + + PREFERENCES.node_param_show = false; + PREFERENCES.node_param_width = 192; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// MISC ////////////////////////////////////////////////////////////////////////// + + PREFERENCES.save_file_minify = true; + PREFERENCES.render_all_export = true; + PREFERENCES.clear_temp_on_close = true; + + PREFERENCES.show_supporter_icon = true; + + #endregion + + #region //////////////////////////////////////////////////////////////////////// PATHS ///////////////////////////////////////////////////////////////////////// + + PREFERENCES.temp_path = "%DIR%/temp/"; + PREFERENCES.ImageMagick_path = "%APP%/imagemagick/"; + PREFERENCES.webp_path = "%APP%/webp/"; + PREFERENCES.gifski_path = "%APP%/gifski/"; + PREFERENCES.ffmpeg_path = "%APP%/ffmpeg/"; + + PREFERENCES.versions = {}; + + #endregion + + PREFERENCES_DEF = variable_clone(PREFERENCES); +#endregion + +#region recent files + globalvar RECENT_FILES, RECENT_FILE_DATA; + RECENT_FILES = ds_list_create(); + RECENT_FILE_DATA = ds_list_create(); + + function RECENT_SAVE() { + var map = ds_map_create(); + var l = ds_list_create(); + ds_list_copy(l, RECENT_FILES); + ds_map_add_list(map, "Recents", l); + + var path = DIRECTORY + "recent.json"; + var file = file_text_open_write(path); + file_text_write_string(file, json_encode_minify(map)); + file_text_close(file); + ds_map_destroy(map); + } + + function RECENT_LOAD() { + var path = DIRECTORY + "recent.json"; + if(!file_exists_empty(path)) return; + + var file = file_text_open_read(path); + var load_str = ""; + while(!file_text_eof(file)) { + load_str += file_text_readln(file); + } + file_text_close(file); + var map = json_decode(load_str); + + if(ds_map_exists(map, "Recents")) { + var l = map[? "Recents"]; + ds_list_clear(RECENT_FILES); + + for(var i = 0; i < ds_list_size(l); i++) { + if(!file_exists_empty(l[| i])) continue; + ds_list_add(RECENT_FILES, l[| i]); + } + } + + RECENT_REFRESH(); + } + + function RECENT_REFRESH() { + for( var i = 0; i < ds_list_size(RECENT_FILE_DATA); i++ ) { + var d = RECENT_FILE_DATA[| i]; + if(sprite_exists(d.spr)) sprite_delete(d.spr); + if(surface_exists(d.thumbnail)) surface_free(d.thumbnail); + } + + ds_list_clear(RECENT_FILE_DATA); + + for( var i = 0; i < ds_list_size(RECENT_FILES); i++ ) { + var p = RECENT_FILES[| i]; + RECENT_FILE_DATA[| i] = new FileObject(filename_name_only(p), p); + } + } +#endregion + +#region save load + function PREF_SAVE() { #region + if(IS_CMD) return; + var map = {}; + + var save_l = []; + for(var j = 0; j < ds_list_size(HOTKEY_CONTEXT); j++) { + var ll = HOTKEYS[? HOTKEY_CONTEXT[| j]]; + + for(var i = 0; i < ds_list_size(ll); i++) + array_push(save_l, ll[| i].serialize()); + } + + map.key = save_l; + + PREFERENCES.window_maximize = window_is_maximized; + PREFERENCES.window_width = max(960, window_minimize_size[0]); + PREFERENCES.window_height = max(600, window_minimize_size[1]); + + map.preferences = PREFERENCES; + + json_save_struct(DIRECTORY + "keys.json", map); + json_save_struct(DIRECTORY + "Nodes/fav.json", global.FAV_NODES); + json_save_struct(DIRECTORY + "Nodes/recent.json", global.RECENT_NODES); + json_save_struct(DIRECTORY + "key_nodes.json", HOTKEYS_CUSTOM); + } #endregion + + function PREF_LOAD() { #region + var path = DIRECTORY + "keys.json"; + if(!file_exists_empty(path)) return; + + var map = json_load_struct(path); + if(array_empty(variable_struct_get_names(map))) return; + + HOTKEYS_DATA = {}; + + for(var i = 0; i < array_length(map.key); i++) { + var key_list = map.key[i]; + var _context = is_struct(key_list)? key_list.context : key_list[0]; + var name = is_struct(key_list)? key_list.name : key_list[1]; + + HOTKEYS_DATA[$ $"{_context}_{name}"] = key_list; + } + + struct_override(PREFERENCES, map.preferences); + + if(!directory_exists($"{DIRECTORY}Themes/{PREFERENCES.theme}")) + PREFERENCES.theme = "default"; + + var f = json_load_struct(DIRECTORY + "key_nodes.json"); + struct_override_nested(HOTKEYS_CUSTOM, f); + + LOCALE_DEF = PREFERENCES.local == "en"; + THEME_DEF = PREFERENCES.theme == "default"; + FONT_DEF = PREFERENCES.theme == "default" && PREFERENCES.local == "en" && PREFERENCES.display_scaling == 1; + + directory_verify(filepath_resolve(PREFERENCES.temp_path)); + + if(PREFERENCES.move_directory) directory_set_current_working(DIRECTORY); + } #endregion + + function PREF_APPLY() { #region + if(PREFERENCES.double_click_delay > 1) + PREFERENCES.double_click_delay /= 60; + + TESTING = struct_try_get(PREFERENCES, "test_mode", false); + if(TESTING) { + log_message("PREFERENCE", "Test mode enabled"); + instance_create_depth(0, 0, 0, addon_key_displayer); + } + + if(PREFERENCES.use_legacy_exception) resetException(); + else setException(); + + if(OS != os_macosx && !LOADING) { + if(PREFERENCES.window_maximize) { + winMan_Maximize(); + } else { + var ww = PREFERENCES.window_width; + var hh = PREFERENCES.window_height; + window_minimize_size = [ ww, hh ]; + + window_set_position(display_get_width() / 2 - ww / 2, display_get_height() / 2 - hh / 2); + window_set_size(ww, hh); + gameframe_set_shadow(true); + } + } + + window_refresh(); + game_set_speed(PREFERENCES.ui_framerate, gamespeed_fps); + + var grav = struct_try_get(PREFERENCES, "physics_gravity", [ 0, 10 ]); + physics_world_gravity(array_safe_get_fast(grav, 0, 0), array_safe_get_fast(grav, 1, 10)); + } #endregion +#endregion \ No newline at end of file diff --git a/#backups/scripts/string_functions/string_functions.gml.backup0 b/#backups/scripts/string_functions/string_functions.gml.backup0 new file mode 100644 index 000000000..c920cbe93 --- /dev/null +++ b/#backups/scripts/string_functions/string_functions.gml.backup0 @@ -0,0 +1,77 @@ +// 2024-04-16 08:41:19 +function string_to_array(str) { #region + var amo = string_length(str); + var arr = array_create(amo); + for( var i = 0; i < amo; i++ ) + arr[i] = string_char_at(str, i + 1); + return arr; +} #endregion + +function string_partial_match(str, key) { #region + var amo = string_length(str); + var run = 1; + var consec = 0; + var conMax = 0; + var misMatch = 0; + var kchr = string_char_at(key, run); + + for( var i = 1; i <= amo; i++ ) { + var ch = string_char_at(str, i); + if(ch == kchr) { + consec++; + conMax = max(conMax, consec); + run++; + if(run > string_length(key)) return conMax - (misMatch + (amo - i)); + kchr = string_char_at(key, run); + } else { + consec = 0; + misMatch += amo - i; + } + } + + return -9999; +} #endregion + +function string_real(val, digMax = 999, decMin = 5) { #region + if(is_string(val)) return val; + if(is_struct(val)) return string(val); + + if(is_array(val)) { + var s = "["; + var i = 0, n = array_length(val); + repeat( n ) { s += (i? ", " : "") + string_real(val[i]); i++; } + return s + "]"; + } + + if(val == 0 || !is_numeric(val)) return "0"; + + var pres, p = 1; + var presMax = min(decMin, digMax - ceil(log10(ceil(abs(val))))); + for( pres = 0; pres < presMax; pres++ ) { + if(frac(val * p) == 0) + break; + p *= 10; + } + + return string_format(val, -1, pres); +} #endregion + +function string_char_last(str, shift = 0) { #region + INLINE + return string_char_at(str, string_length(str) - shift); +} #endregion + +function filename_name_only(name) { #region + name = filename_name(name); + return string_replace(name, filename_ext(name), "") +} #endregion + +function string_to_var(str) { #region + INLINE + return string_replace_all(string_lower(str), " ", "_"); +} #endregion + +function string_quote(str) { #region + INLINE + return $"\"{str}\""; +} #endregion \ No newline at end of file diff --git a/#backups/scripts/string_functions/string_functions.gml.backup1 b/#backups/scripts/string_functions/string_functions.gml.backup1 new file mode 100644 index 000000000..4cf455ec9 --- /dev/null +++ b/#backups/scripts/string_functions/string_functions.gml.backup1 @@ -0,0 +1,77 @@ +// 2024-04-16 08:29:49 +function string_to_array(str) { #region + var amo = string_length(str); + var arr = array_create(amo); + for( var i = 0; i < amo; i++ ) + arr[i] = string_char_at(str, i + 1); + return arr; +} #endregion + +function string_partial_match(str, key) { #region + var amo = string_length(str); + var run = 1; + var consec = 0; + var conMax = 0; + var misMatch = 0; + var kchr = string_char_at(key, run); + + for( var i = 1; i <= amo; i++ ) { + var ch = string_char_at(str, i); + if(ch == kchr) { + consec++; + conMax = max(conMax, consec); + run++; + if(run > string_length(key)) return conMax - (misMatch + (amo - i)); + kchr = string_char_at(key, run); + } else { + consec = 0; + misMatch += amo - i; + } + } + + return -9999; +} #endregion + +function string_real(val, digMax = 999, decMin = 5) { #region + if(is_string(val)) return val; + if(is_struct(val)) return string(val); + + if(is_array(val)) { + var s = "["; + var i = 0, n = array_length(val); + repeat( n ) { s += (i? ", " : "") + string_real(val[i]); i++; } + return s + "]"; + } + + if(val == 0 || !is_numeric(val)) return "0"; + + var pres, p = 1; + var presMax = min(decMin, digMax - ceil(log10(ceil(abs(val))))); + for( pres = 0; pres < presMax; pres++ ) { + if(frac(val * p) == 0) + break; + p *= 10; + } + + return string_format(val, -1, pres); +} #endregion + +function string_char_last(str, shift = 0) { #region + INLINE + return string_char_at(str, string_length(str) - shift); +} #endregion + +function filename_name_only(name) { #region + name = filename_name(name); + return string_replace(name, filename_ext(name), "") +} #endregion + +function string_to_var(str) { #region + INLINE + return string_replace_all(string_lower(str), " ", "_"); +} #endregion + +function string_quote(str) { #region + INLINE + return $"\"{str}\""; +} #endregion \ No newline at end of file diff --git a/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup0 b/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup0 index 3cf007f9d..48444bb76 100644 --- a/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup0 +++ b/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup0 @@ -1,4 +1,4 @@ -// 2023-08-07 09:34:22 +// 2024-04-16 14:58:44 // // Simple passthrough fragment shader // @@ -21,20 +21,19 @@ float sampleMask() { } void main() { - vec4 _col1 = texture2D( gm_BaseTexture, v_vTexcoord ); + vec4 _cBg = texture2D( gm_BaseTexture, v_vTexcoord ); vec2 fore_tex = v_vTexcoord; - if(tile_type == 0) { + if(tile_type == 0) fore_tex = v_vTexcoord; - } else if(tile_type == 1) { + else if(tile_type == 1) fore_tex = fract(v_vTexcoord * dimension); - } - vec4 _col0 = texture2D( fore, fore_tex ); - _col0.a *= opacity * sampleMask(); + vec4 _cFg = texture2D( fore, fore_tex ); + _cFg.a *= opacity * sampleMask(); - float al = _col0.a + _col1.a * (1. - _col0.a); - vec4 res = ((_col0 * _col0.a) + (_col1 * _col1.a * (1. - _col0.a))) / al; + float al = _cFg.a + _cBg.a * (1. - _cFg.a); + vec4 res = ((_cFg * _cFg.a) + (_cBg * _cBg.a * (1. - _cFg.a))) / al; res.a = al; gl_FragColor = res; diff --git a/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup1 b/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup1 new file mode 100644 index 000000000..3cf007f9d --- /dev/null +++ b/#backups/shaders/sh_blend_normal/sh_blend_normal.fsh.backup1 @@ -0,0 +1,41 @@ +// 2023-08-07 09:34:22 +// +// Simple passthrough fragment shader +// +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform int tile_type; + +uniform int useMask; +uniform int preserveAlpha; +uniform sampler2D mask; +uniform sampler2D fore; +uniform float opacity; + +float sampleMask() { + if(useMask == 0) return 1.; + vec4 m = texture2D( mask, v_vTexcoord ); + return (m.r + m.g + m.b) / 3. * m.a; +} + +void main() { + vec4 _col1 = texture2D( gm_BaseTexture, v_vTexcoord ); + + vec2 fore_tex = v_vTexcoord; + if(tile_type == 0) { + fore_tex = v_vTexcoord; + } else if(tile_type == 1) { + fore_tex = fract(v_vTexcoord * dimension); + } + + vec4 _col0 = texture2D( fore, fore_tex ); + _col0.a *= opacity * sampleMask(); + + float al = _col0.a + _col1.a * (1. - _col0.a); + vec4 res = ((_col0 * _col0.a) + (_col1 * _col1.a * (1. - _col0.a))) / al; + res.a = al; + + gl_FragColor = res; +} diff --git a/#config/properties.json b/#config/properties.json new file mode 100644 index 000000000..96986e2e3 --- /dev/null +++ b/#config/properties.json @@ -0,0 +1,8 @@ +{ + "builderSettings": { + "runtimeVersion": "runtime-2024.2.0.163" + }, + "linterPrefs": { + + } +} \ No newline at end of file diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index a9e855ba8..5d7c53614 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -353,6 +353,7 @@ {"name":"canvas_freeform","order":3,"path":"scripts/canvas_freeform/canvas_freeform.yy",}, {"name":"canvas_magic_selection_functions","order":4,"path":"scripts/canvas_magic_selection_functions/canvas_magic_selection_functions.yy",}, {"name":"canvas_tool_brush_shape","order":3,"path":"scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.yy",}, + {"name":"canvas_tool_curve","order":14,"path":"scripts/canvas_tool_curve/canvas_tool_curve.yy",}, {"name":"canvas_tool_draw_freeform","order":5,"path":"scripts/canvas_tool_draw_freeform/canvas_tool_draw_freeform.yy",}, {"name":"canvas_tool_extrude","order":1,"path":"scripts/canvas_tool_extrude/canvas_tool_extrude.yy",}, {"name":"canvas_tool_fill","order":4,"path":"scripts/canvas_tool_fill/canvas_tool_fill.yy",}, @@ -360,6 +361,7 @@ {"name":"canvas_tool_node","order":12,"path":"scripts/canvas_tool_node/canvas_tool_node.yy",}, {"name":"canvas_tool_outline","order":3,"path":"scripts/canvas_tool_outline/canvas_tool_outline.yy",}, {"name":"canvas_tool_resize","order":11,"path":"scripts/canvas_tool_resize/canvas_tool_resize.yy",}, + {"name":"canvas_tool_selection_brush","order":13,"path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",}, {"name":"canvas_tool_selection_freeform","order":8,"path":"scripts/canvas_tool_selection_freeform/canvas_tool_selection_freeform.yy",}, {"name":"canvas_tool_selection_magic","order":9,"path":"scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.yy",}, {"name":"canvas_tool_selection_shape","order":6,"path":"scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.yy",}, @@ -1127,7 +1129,7 @@ {"name":"safe_operation","order":6,"path":"scripts/safe_operation/safe_operation.yy",}, {"name":"sample_projects","order":6,"path":"scripts/sample_projects/sample_projects.yy",}, {"name":"save_function","order":1,"path":"scripts/save_function/save_function.yy",}, - {"name":"canvas_tool_selection_brush","order":13,"path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",}, + {"name":"canvas_tool_with_selector","order":5,"path":"scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy",}, {"name":"scrollBox","order":2,"path":"scripts/scrollBox/scrollBox.yy",}, {"name":"scrollPane","order":3,"path":"scripts/scrollPane/scrollPane.yy",}, {"name":"shell_functions","order":20,"path":"scripts/shell_functions/shell_functions.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index bf1d7cd4f..535c744c3 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -714,6 +714,7 @@ {"id":{"name":"canvas_magic_selection_functions","path":"scripts/canvas_magic_selection_functions/canvas_magic_selection_functions.yy",},}, {"id":{"name":"canvas_tool_brush_shape","path":"scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.yy",},}, {"id":{"name":"canvas_tool_brush","path":"scripts/canvas_tool_brush/canvas_tool_brush.yy",},}, + {"id":{"name":"canvas_tool_curve","path":"scripts/canvas_tool_curve/canvas_tool_curve.yy",},}, {"id":{"name":"canvas_tool_draw_freeform","path":"scripts/canvas_tool_draw_freeform/canvas_tool_draw_freeform.yy",},}, {"id":{"name":"canvas_tool_extrude","path":"scripts/canvas_tool_extrude/canvas_tool_extrude.yy",},}, {"id":{"name":"canvas_tool_fill","path":"scripts/canvas_tool_fill/canvas_tool_fill.yy",},}, @@ -721,6 +722,7 @@ {"id":{"name":"canvas_tool_node","path":"scripts/canvas_tool_node/canvas_tool_node.yy",},}, {"id":{"name":"canvas_tool_outline","path":"scripts/canvas_tool_outline/canvas_tool_outline.yy",},}, {"id":{"name":"canvas_tool_resize","path":"scripts/canvas_tool_resize/canvas_tool_resize.yy",},}, + {"id":{"name":"canvas_tool_selection_brush","path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",},}, {"id":{"name":"canvas_tool_selection_freeform","path":"scripts/canvas_tool_selection_freeform/canvas_tool_selection_freeform.yy",},}, {"id":{"name":"canvas_tool_selection_magic","path":"scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.yy",},}, {"id":{"name":"canvas_tool_selection_shape","path":"scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.yy",},}, @@ -1608,7 +1610,7 @@ {"id":{"name":"safe_operation","path":"scripts/safe_operation/safe_operation.yy",},}, {"id":{"name":"sample_projects","path":"scripts/sample_projects/sample_projects.yy",},}, {"id":{"name":"save_function","path":"scripts/save_function/save_function.yy",},}, - {"id":{"name":"canvas_tool_selection_brush","path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",},}, + {"id":{"name":"canvas_tool_with_selector","path":"scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy",},}, {"id":{"name":"scrollBox","path":"scripts/scrollBox/scrollBox.yy",},}, {"id":{"name":"scrollPane","path":"scripts/scrollPane/scrollPane.yy",},}, {"id":{"name":"shader_functions","path":"scripts/shader_functions/shader_functions.yy",},}, diff --git a/PixelComposer.yyp.css b/PixelComposer.yyp.css new file mode 100644 index 000000000..e69de29bb diff --git a/datafiles/data/Theme.zip b/datafiles/data/Theme.zip index e97e21a59..155808b81 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/objects/o_dialog_add_node/Create_0.gml b/objects/o_dialog_add_node/Create_0.gml index d6110839e..505e52e11 100644 --- a/objects/o_dialog_add_node/Create_0.gml +++ b/objects/o_dialog_add_node/Create_0.gml @@ -248,7 +248,7 @@ event_inherited(); } } #endregion - catagory_pane = new scrollPane(category_width, dialog_h - ui(66), function(_y, _m) { #region + catagory_pane = new scrollPane(category_width, dialog_h - ui(66), function(_y, _m) { #region catagory_pane draw_clear_alpha(COLORS._main_text, 0); var ww = category_width - ui(32); @@ -339,7 +339,7 @@ event_inherited(); return hh; }); #endregion - content_pane = new scrollPane(dialog_w - category_width - ui(8), dialog_h - ui(66), function(_y, _m) { #region + content_pane = new scrollPane(dialog_w - category_width - ui(8), dialog_h - ui(66), function(_y, _m) { #region content_pane draw_clear_alpha(c_white, 0); var _hover = sHOVER && content_pane.hover; var _list = node_list; diff --git a/scripts/__canvas_tool/__canvas_tool.gml b/scripts/__canvas_tool/__canvas_tool.gml index 2ff77664c..9c1791638 100644 --- a/scripts/__canvas_tool/__canvas_tool.gml +++ b/scripts/__canvas_tool/__canvas_tool.gml @@ -16,6 +16,12 @@ function canvas_tool() constructor { subtool = 0; + function disable() { + PANEL_PREVIEW.tool_current = noone; + } + + function getTool() { return self; } + function init() {} function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} diff --git a/scripts/buttonPalette/buttonPalette.gml b/scripts/buttonPalette/buttonPalette.gml index 5615b8347..065984cbf 100644 --- a/scripts/buttonPalette/buttonPalette.gml +++ b/scripts/buttonPalette/buttonPalette.gml @@ -139,23 +139,23 @@ function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { #region var amo = array_length(_pal); var col = floor(_w / _gs); var row = ceil(amo / col); + var cx = -1, cy = -1; + var _pd = ui(5); for(var i = 0; i < array_length(_pal); i++) { draw_set_color(_pal[i]); var _x0 = _x + safe_mod(i, col) * _gs; var _y0 = _y + floor(i / col) * _gs; + draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false); + + if(c_color == _pal[i]) { + cx = _x0; + cy = _y0; + } } - if(c_color == -1) return; + if(cx == -1) return; - for(var i = 0; i < array_length(_pal); i++) { - if(c_color != _pal[i]) continue; - - var _x0 = _x + safe_mod(i, col) * _gs; - var _y0 = _y + floor(i / col) * _gs; - - draw_set_color(c_white); - draw_rectangle_border(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, 2); - } + draw_sprite_stretched_ext(THEME.palette_selecting, 0, cx - _pd, cy + 1 - _pd, _gs + _pd * 2, _gs + _pd * 2); } #endregion \ No newline at end of file diff --git a/scripts/canvas_draw_functions/canvas_draw_functions.gml b/scripts/canvas_draw_functions/canvas_draw_functions.gml index 7f56e2201..db3528ac6 100644 --- a/scripts/canvas_draw_functions/canvas_draw_functions.gml +++ b/scripts/canvas_draw_functions/canvas_draw_functions.gml @@ -24,7 +24,7 @@ function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region } } #endregion -function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false) { #region +function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false, _cap = false) { #region if(brush.brush_surface == noone) { @@ -44,8 +44,13 @@ function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false) { #regi for( var i = 0, n = array_length(fx); i < n; i++ ) draw_line(_x0 + fx[i][0], _y0 + fx[i][1], _x1 + fx[i][0], _y1 + fx[i][1]); - } else + } else { draw_line_width(_x0, _y0, _x1, _y1, brush.brush_size); + if(_cap) { + canvas_draw_point_size(brush, _x0, _y0, true); + canvas_draw_point_size(brush, _x1, _y1, true); + } + } } else { var diss = point_distance(_x0, _y0, _x1, _y1); @@ -157,3 +162,29 @@ function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region oy = ny; } } #endregion + +function canvas_draw_curve_brush(brush, x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region + var ox, oy, nx, ny; + + var _st = 1 / prec; + + for (var i = 0; i <= prec; i++) { + var _t = _st * i; + var _t1 = 1 - _t; + + nx = _t1 * _t1 * _t1 * x0 + + 3 * (_t1 * _t1 * _t) * cx0 + + 3 * (_t1 * _t * _t) * cx1 + + _t * _t * _t * x1; + + ny = _t1 * _t1 * _t1 * y0 + + 3 * (_t1 * _t1 * _t) * cy0 + + 3 * (_t1 * _t * _t) * cy1 + + _t * _t * _t * y1; + + if(i) canvas_draw_line_size(brush, ox, oy, nx, ny, true, true); + + ox = nx; + oy = ny; + } +} #endregion \ No newline at end of file diff --git a/scripts/canvas_tool_brush/canvas_tool_brush.gml b/scripts/canvas_tool_brush/canvas_tool_brush.gml index e81a4771b..bb02baf1e 100644 --- a/scripts/canvas_tool_brush/canvas_tool_brush.gml +++ b/scripts/canvas_tool_brush/canvas_tool_brush.gml @@ -27,7 +27,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { } if(mouse_press(mb_left, active)) { - brush_next_dist = 0; surface_set_shader(drawing_surface, noone); canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y, true); @@ -36,7 +35,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { mouse_holding = true; if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT)) { ///////////////// shift line surface_set_shader(drawing_surface, noone, true, BLEND.alpha); - brush_next_dist = 0; canvas_draw_line_size(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, true); surface_reset_shader(); mouse_holding = false; diff --git a/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml b/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml index a661f940d..7e56c1851 100644 --- a/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml +++ b/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml @@ -6,7 +6,6 @@ enum CANVAS_TOOL_SHAPE { function canvas_tool_shape(brush, shape) : canvas_tool() constructor { self.brush = brush; self.shape = shape; - self.fill = false; brush_resizable = true; mouse_holding = false; @@ -35,10 +34,10 @@ function canvas_tool_shape(brush, shape) : canvas_tool() constructor { surface_set_shader(drawing_surface, noone); if(shape == CANVAS_TOOL_SHAPE.rectangle) - canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill); + canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); else if(shape == CANVAS_TOOL_SHAPE.ellipse) - canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill); + canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); surface_reset_shader(); @@ -66,10 +65,10 @@ function canvas_tool_shape(brush, shape) : canvas_tool() constructor { } if(shape == CANVAS_TOOL_SHAPE.rectangle) - canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill); + canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); if(shape == CANVAS_TOOL_SHAPE.ellipse) - canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill); + canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool); } } \ No newline at end of file diff --git a/scripts/canvas_tool_curve/canvas_tool_curve.gml b/scripts/canvas_tool_curve/canvas_tool_curve.gml new file mode 100644 index 000000000..099dd6eb2 --- /dev/null +++ b/scripts/canvas_tool_curve/canvas_tool_curve.gml @@ -0,0 +1,184 @@ +function canvas_tool_curve_bezier(brush) : canvas_tool() constructor { + self.brush = brush; + brush_resizable = true; + + anchors = []; + + mouse_cur_x = 0; + mouse_cur_y = 0; + editing = [ noone, 0 ]; + + mouse_edit_mx = 0; + mouse_edit_my = 0; + mouse_edit_sx = 0; + mouse_edit_sy = 0; + + mouse_hovering = [ noone, 0 ]; + draw_hovering = []; + + function init() { + anchors = []; + editing = [ noone, 0 ]; + } + + function apply() { + apply_draw_surface(); + + disable(); + } + + function cancel() { + surface_clear(drawing_surface); + disable(); + } + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + mouse_cur_x = (_mx - _x) / _s; + mouse_cur_y = (_my - _y) / _s; + + if(editing[0] != noone) { + var _a = anchors[editing[0]]; + var _dx = mouse_cur_x - mouse_edit_mx; + var _dy = mouse_cur_y - mouse_edit_my; + + if(editing[1] == 0) { + _a[2] += _dx; + _a[3] += _dy; + + } else if(editing[1] == -1) { + _a[0] += _dx; + _a[1] += _dy; + + _a[4] -= _dx; + _a[5] -= _dy; + + } else if(editing[1] == 1) { + _a[0] -= _dx; + _a[1] -= _dy; + + _a[4] += _dx; + _a[5] += _dy; + + } + + mouse_edit_mx = mouse_cur_x; + mouse_edit_my = mouse_cur_y; + + if(mouse_release(mb_left)) + editing[0] = noone; + } + + if(mouse_press(mb_left, active)) { + if(mouse_hovering[0] == noone) { + array_push(anchors, [ 0, 0, mouse_cur_x, mouse_cur_y, 0, 0 ]); + editing[0] = array_length(anchors) - 1; + editing[1] = 1; + + } else { + if(key_mod_press(SHIFT)) + array_delete(anchors, mouse_hovering[0], 1); + else { + editing[0] = mouse_hovering[0]; + editing[1] = mouse_hovering[1]; + } + } + + mouse_edit_mx = mouse_cur_x; + mouse_edit_my = mouse_cur_y; + mouse_edit_sx = mouse_cur_x; + mouse_edit_sy = mouse_cur_y; + } + + surface_set_shader(drawing_surface, noone); + var ox, oy, nx, ny; + var oax1, oay1, nax0, nay0; + + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = anchors[i][2]; + ny = anchors[i][3]; + + nax0 = nx + anchors[i][0]; + nay0 = ny + anchors[i][1]; + + if(i) canvas_draw_curve_brush(brush, ox, oy, oax1, oay1, nax0, nay0, nx, ny); + + oax1 = nx + anchors[i][4]; + oay1 = ny + anchors[i][5]; + + ox = nx; + oy = ny; + } + + surface_reset_shader(); + + node.tool_curve_apply.setInteract(!array_empty(anchors)); + node.tool_curve_cancel.setInteract(!array_empty(anchors)); + if(key_press(vk_enter)) apply(); + if(key_press(vk_escape)) disable(); + } + + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + draw_surface_ext_safe(drawing_surface, _x, _y, _s, _s); + } + + function drawMask(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + } + + function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var ox, oy, nx, ny, ax0, ay0, ax1, ay1; + var oax1, oay1, nax0, nay0; + + draw_set_color(c_white); + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = _x + anchors[i][2] * _s; + ny = _y + anchors[i][3] * _s; + + nax0 = nx + anchors[i][0] * _s; + nay0 = ny + anchors[i][1] * _s; + + if(i) draw_curve_bezier(ox, oy, oax1, oay1, nax0, nay0, nx, ny); + + oax1 = nx + anchors[i][4] * _s; + oay1 = ny + anchors[i][5] * _s; + + draw_line(nx, ny, nax0, nay0); + draw_line(nx, ny, oax1, oay1); + + ox = nx; + oy = ny; + } + + mouse_hovering = [ noone, 0 ]; + + draw_hovering = array_verify(draw_hovering, array_length(anchors) * 3); + + for (var i = 0, n = array_length(anchors); i < n; i++) { + nx = _x + anchors[i][2] * _s; + ny = _y + anchors[i][3] * _s; + + ax0 = nx + anchors[i][0] * _s; + ay0 = ny + anchors[i][1] * _s; + + ax1 = nx + anchors[i][4] * _s; + ay1 = ny + anchors[i][5] * _s; + + draw_anchor(0, nx, ny, lerp(10, 13, draw_hovering[i * 3 + 1])); + draw_anchor(0, ax0, ay0, lerp( 7, 10, draw_hovering[i * 3 + 0])); + draw_anchor(0, ax1, ay1, lerp( 7, 10, draw_hovering[i * 3 + 2])); + + if(point_in_circle(_mx, _my, nx, ny, 10)) mouse_hovering = [ i, 0 ]; + else if(point_in_circle(_mx, _my, ax0, ay0, 10)) mouse_hovering = [ i, -1 ]; + else if(point_in_circle(_mx, _my, ax1, ay1, 10)) mouse_hovering = [ i, 1 ]; + } + + if(mouse_hovering[0] != noone) { + var index = mouse_hovering[0] * 3 + mouse_hovering[1] + 1; + + for (var i = 0, n = array_length(draw_hovering); i < n; i++) + draw_hovering[i] = lerp_float(draw_hovering[i], i == index, 4); + } + } + +} \ No newline at end of file diff --git a/scripts/canvas_tool_curve/canvas_tool_curve.yy b/scripts/canvas_tool_curve/canvas_tool_curve.yy new file mode 100644 index 000000000..baf378b74 --- /dev/null +++ b/scripts/canvas_tool_curve/canvas_tool_curve.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_tool_curve", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_tool_curve", + "parent":{ + "name":"tools", + "path":"folders/nodes/data/canvas/tools.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_tool_node/canvas_tool_node.gml b/scripts/canvas_tool_node/canvas_tool_node.gml index 96b988bb8..270906245 100644 --- a/scripts/canvas_tool_node/canvas_tool_node.gml +++ b/scripts/canvas_tool_node/canvas_tool_node.gml @@ -27,8 +27,15 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { if(applySelection) canvas.tool_selection.apply(); canvas.nodeTool = noone; - surface_free(targetSurface); - surface_free(maskedSurface); + surface_free_safe(maskedSurface); + + cleanUp(); + } + + static cleanUp = function() { + surface_free_safe(targetSurface); + surface_free_safe(maskedSurface); + nodeObject.destroy(); } nodeObject = node.build(0, 0); @@ -65,21 +72,41 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { //////////////////////////////////////////////////////////////////////////////////////////////////////// function apply() { + var _surf = surface_create(sw, sh); if(applySelection) { + + surface_set_shader(_surf, sh_blend_normal); + shader_set_surface("fore", maskedSurface); + shader_set_f("dimension", 1, 1); + shader_set_f("opacity", 1); + + draw_surface(canvas.tool_selection.selection_surface, 0, 0); + surface_reset_shader(); + surface_free(canvas.tool_selection.selection_surface); - canvas.tool_selection.selection_surface = maskedSurface; + canvas.tool_selection.selection_surface = _surf; canvas.tool_selection.apply(); } else { canvas.storeAction(); - canvas.setCanvasSurface(maskedSurface); + + surface_set_shader(_surf, sh_blend_normal); + shader_set_surface("fore", maskedSurface); + shader_set_f("dimension", 1, 1); + shader_set_f("opacity", 1); + + draw_surface(canvas.getCanvasSurface(), 0, 0); + surface_reset_shader(); + + canvas.setCanvasSurface(_surf); canvas.surface_store_buffer(); } PANEL_PREVIEW.tool_current = noone; canvas.nodeTool = noone; - surface_free_safe(targetSurface); + + cleanUp(); } function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { @@ -109,7 +136,10 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { else if(inputJunction.name == "Dimension") inputJunction.setValue([ sw, sh ]); } - nodeObject.update(); + if(is_instanceof(nodeObject, Node_Collection)) + RenderList(nodeObject.nodes); + else + nodeObject.update(); var _surf = outputJunction.getValue(); @@ -125,6 +155,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { } else maskedSurface = _surf; + draw_surface_ext_safe(destiSurface, _dx, _dy, _s, _s); draw_surface_ext_safe(maskedSurface, _dx, _dy, _s, _s); if(mouse_press(mb_left, active)) { apply(); MOUSE_BLOCK = true; } diff --git a/scripts/canvas_tool_selection/canvas_tool_selection.gml b/scripts/canvas_tool_selection/canvas_tool_selection.gml index 5949e4b44..156718ed2 100644 --- a/scripts/canvas_tool_selection/canvas_tool_selection.gml +++ b/scripts/canvas_tool_selection/canvas_tool_selection.gml @@ -22,9 +22,14 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { mouse_pre_y = 0; function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region + if(is_selected) apply(); - + else { + createNewSelection(_mask, sel_x0, sel_y0, sel_w, sel_h); + return; + } + if(key_mod_press(SHIFT)) modifySelection(_mask, sel_x0, sel_y0, sel_w, sel_h, true); diff --git a/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml b/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml index ecc40f521..8bcf3134e 100644 --- a/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml +++ b/scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.gml @@ -62,10 +62,10 @@ function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(se sel_x1 = max(sel_x1, mouse_cur_x + brush.brush_size); sel_y1 = max(sel_y1, mouse_cur_y + brush.brush_size); - if(mouse_release(mb_left)) { - var _sel_w = sel_x1 - sel_x0; - var _sel_h = sel_y1 - sel_y0; + var _sel_w = sel_x1 - sel_x0; + var _sel_h = sel_y1 - sel_y0; + if(mouse_release(mb_left)) { var _sel = surface_create(_sel_w, _sel_h); surface_set_shader(_sel); draw_surface(selection_mask, -sel_x0, -sel_y0); diff --git a/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml b/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml index 2b0dd9ee8..bbf3fd4b3 100644 --- a/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml +++ b/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml @@ -53,6 +53,10 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h); surface_free_safe(selection_mask); + + if(node.selection_tool_after != noone) + node.selection_tool_after.toggle(); + node.selection_tool_after = noone; } } } diff --git a/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml b/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml index 58cb9813f..5a50315b1 100644 --- a/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml +++ b/scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.gml @@ -35,7 +35,9 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se } surface_reset_target(); - + + PANEL_PREVIEW.mouse_pos_string = $"[{sel_w}, {sel_h}]"; + if(mouse_release(mb_left)) { is_selecting = false; selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h); diff --git a/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml b/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml new file mode 100644 index 000000000..8a66daa43 --- /dev/null +++ b/scripts/canvas_tool_with_selector/canvas_tool_with_selector.gml @@ -0,0 +1,9 @@ +function canvas_tool_with_selector(tool) : canvas_tool() constructor { + self.tool = tool; + + function init(node) { + node.selection_tool_after = tool; + } + + function getTool() { return node.tool_sel_magic; } +} \ No newline at end of file diff --git a/scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy b/scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy new file mode 100644 index 000000000..2e07e5740 --- /dev/null +++ b/scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_tool_with_selector", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_tool_with_selector", + "parent":{ + "name":"actions", + "path":"folders/nodes/data/canvas/actions.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/curve_bezier_function/curve_bezier_function.gml b/scripts/curve_bezier_function/curve_bezier_function.gml index a6e7e7827..63d2c83e3 100644 --- a/scripts/curve_bezier_function/curve_bezier_function.gml +++ b/scripts/curve_bezier_function/curve_bezier_function.gml @@ -193,4 +193,30 @@ function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor { if(_indL == _indH) return map[_ind]; return lerp(map[_indL], map[_indH], _indF); } #endregion -} \ No newline at end of file +} + +function draw_curve_bezier(x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region + var ox, oy, nx, ny; + + var _st = 1 / prec; + + for (var i = 0; i <= prec; i++) { + var _t = _st * i; + var _t1 = 1 - _t; + + nx = _t1 * _t1 * _t1 * x0 + + 3 * (_t1 * _t1 * _t) * cx0 + + 3 * (_t1 * _t * _t) * cx1 + + _t * _t * _t * x1; + + ny = _t1 * _t1 * _t1 * y0 + + 3 * (_t1 * _t1 * _t) * cy0 + + 3 * (_t1 * _t * _t) * cy1 + + _t * _t * _t * y1; + + if(i) draw_line(ox, oy, nx, ny); + + ox = nx; + oy = ny; + } +} #endregion \ No newline at end of file diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index 7817d54d0..c8878ca67 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -53,7 +53,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor frame_renderer_x_max = 0; frame_renderer_content = surface_create(1, 1); - frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region + frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region frame_renderer var _h = 64; _y += 8; @@ -127,7 +127,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor _fr_x += _sw * _ss + 8; frame_renderer_x_max += _sw * _ss + 8; - } + } if(_del > noone) removeFrame(_del); surface_reset_shader(); @@ -182,7 +182,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor preview_draw_mask = surface_create_empty(1, 1); draw_stack = ds_list_create(); - brush = new canvas_brush(); + + #endregion + + #region ++++ tool object ++++ + brush = new canvas_brush(); + + tool_selection = new canvas_tool_selection(); + + tool_brush = new canvas_tool_brush(brush, false); + tool_eraser = new canvas_tool_brush(brush, true); + tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); + tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); + tool_fill = new canvas_tool_fill(tool_attribute); + tool_freeform = new canvas_tool_draw_freeform(brush); + tool_curve_bez = new canvas_tool_curve_bezier(brush); + + tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle); + tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse); + tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); + tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); + tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush); #endregion @@ -196,7 +216,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.pickColor = c_white; tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); - tool_attribute.mirror = [ false, false ]; + tool_attribute.mirror = [ false, false, false ]; tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }); tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ], @@ -222,48 +242,52 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_fil8_edit = new checkBox(function() { tool_attribute.fill8 = !tool_attribute.fill8; }); tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ]; - tools = [ - new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]), - - new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) + tool_attribute.button_apply = [ false, false ]; + tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0); + tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1); + + toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection ) .setSetting(tool_thrs) - .setSetting(tool_fil8), + .setSetting(tool_fil8) + .setToolObject(tool_sel_magic) + + tools = [ + new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]) + .setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]), + + toolObject_selection_magic, new NodeTool( "Pencil", THEME.canvas_tools_pencil) - .setSetting(tool_size), - + .setSetting(tool_size) + .setToolObject(tool_brush), + new NodeTool( "Eraser", THEME.canvas_tools_eraser) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_eraser), new NodeTool( "Rectangle", [ THEME.canvas_tools_rect, THEME.canvas_tools_rect_fill ]) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_rectangle), new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ]) - .setSetting(tool_size), - + .setSetting(tool_size) + .setToolObject(tool_ellipse), + + new NodeTool( "Curve", THEME.canvas_tool_curve_icon) + .setSetting(tool_size) + .setSetting([ "", tool_curve_apply, 0, tool_attribute ]) + .setSetting([ "", tool_curve_cancel, 0, tool_attribute ]) + .setToolObject(tool_curve_bez), + new NodeTool( "Freeform", THEME.canvas_tools_freeform) - .setSetting(tool_size), + .setSetting(tool_size) + .setToolObject(tool_freeform), new NodeTool( "Fill", THEME.canvas_tools_bucket) .setSetting(tool_thrs) - .setSetting(tool_fil8), + .setSetting(tool_fil8) + .setToolObject(tool_fill), ]; - - tool_selection = new canvas_tool_selection(); - - tool_brush = new canvas_tool_brush(brush, false); - tool_eraser = new canvas_tool_brush(brush, true); - tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle); - tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse); - tool_fill = new canvas_tool_fill(tool_attribute); - tool_freeform = new canvas_tool_draw_freeform(brush); - - tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle); - tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse); - tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); - tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); - tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush); - #endregion #region ++++ right tools ++++ @@ -313,9 +337,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor new NodeTool( "Make/Reset Brush", THEME.canvas_tools_pencil ).setToolFn( __action_make_brush ), -1, new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ), - new NodeTool( [ "Extrude", "Inset" ], - [ THEME.canvas_tools_extrude, THEME.canvas_tools_inset ] ) - .setToolObject( [ new canvas_tool_extrude(), new canvas_tool_inset() ] ), + new NodeTool( "Extrude", THEME.canvas_tools_extrude ).setToolObject( new canvas_tool_extrude() ), + new NodeTool( "Inset", THEME.canvas_tools_inset ).setToolObject( new canvas_tool_inset() ), + ]; + + rightTools_not_selection = [ + -1, + new NodeTool( "Outline", THEME.canvas_tools_outline, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[3]) ), + new NodeTool( "Extrude", THEME.canvas_tools_extrude, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[4]) ), + new NodeTool( "Inset", THEME.canvas_tools_inset, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[5]) ), ]; rightTools_brush = [ @@ -329,6 +359,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_eraser.rightTools = rightTools_brush; tool_rectangle.rightTools = rightTools_brush; tool_ellipse.rightTools = rightTools_brush; + + selection_tool_after = noone; #endregion function setToolColor(color) { tool_attribute.color = color; } @@ -390,7 +422,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor return hh + ui(4); } #endregion - function removeFrame(index = 0) { #region + static removeFrame = function(index = 0) { #region if(attributes.frames <= 1) return; if(preview_index == attributes.frames) @@ -402,7 +434,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor update(); } #endregion - function refreshFrames() { #region + static refreshFrames = function() { #region var fr = attributes.frames; var _dim = attributes.dimension; @@ -428,7 +460,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor function setCanvasSurface(surface, index = preview_index) { INLINE canvas_surface[index] = surface; } - function storeAction() { #region + static storeAction = function() { #region var action = recordAction(ACTION_TYPE.custom, function(data) { is_selected = false; @@ -446,7 +478,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor action.clear_action = function(data) { surface_free_safe(data.surface); }; } #endregion - function apply_surfaces() { #region + static apply_surfaces = function() { #region for( var i = 0; i < attributes.frames; i++ ) apply_surface(i); } #endregion @@ -501,7 +533,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor apply_surface(index); } #endregion - function tool_pick_color(_x, _y) { #region + static tool_pick_color = function(_x, _y) { #region if(tool_selection.is_selected) tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]); else @@ -531,9 +563,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor BLEND_ALPHA - if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1); + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1); BLEND_NORMAL @@ -553,11 +585,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_surface(drawing_surface, 0, 0); BLEND_ALPHA - - if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1); - + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1); + } else { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, 1, -90); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, 0, -1, 1, 90); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], 1, 1, 180); + } BLEND_NORMAL surface_reset_target(); @@ -641,6 +677,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor array_append(rightTools, rightTools_general); if(tool_selection.is_selected) array_append(rightTools, rightTools_selection); + else array_append(rightTools, rightTools_not_selection); if(nodeTool != noone) _tool = nodeTool; @@ -648,37 +685,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor else if(_currTool != noone) { _tool = _currTool.getToolObject(); - switch(_currTool.getName()) { - case "Pencil" : _tool = tool_brush; break; - case "Eraser" : _tool = tool_eraser; break; - case "Fill" : _tool = tool_fill; break; - case "Freeform" : _tool = tool_freeform; break; - - case "Rectangle" : - _tool = tool_rectangle; - _tool.fill = _currTool.selecting == 1; - break; - - case "Ellipse" : - _tool = tool_ellipse; - _tool.fill = _currTool.selecting == 1; - break; - - case "Selection" : - switch(_currTool.selecting) { - case 0 : _tool = tool_sel_rectangle; break; - case 1 : _tool = tool_sel_ellipse; break; - case 2 : _tool = tool_sel_freeform; break; - case 3 : _tool = tool_sel_brush; break; - } - - break; - - case "Magic Selection" : _tool = tool_sel_magic; break; - - } - if(_tool) { + _tool.node = self; + _tool = _tool.getTool(); _tool.subtool = _currTool.selecting; array_append(rightTools, _tool.rightTools); } @@ -689,6 +698,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_selection.apply_draw_surface = apply_draw_surface; if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + + tool_mirror_edit.sprs = (!tool_selection.is_selected && tool_attribute.mirror[0])? THEME.canvas_mirror_diag : THEME.canvas_mirror; } if(_tool && _tool.override) { @@ -770,14 +781,20 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _spw = tool_selection.selection_size[0]; var _sph = tool_selection.selection_size[1]; - if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1); + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1); } else { - if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1); - if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1); - if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1); + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1); + } else { + if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, 1, -90); + if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, 0, -1, 1, 90); + if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], 1, 1, 180); + } } draw_set_color(tool_attribute.color); @@ -785,7 +802,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor canvas_draw_point_size(brush, brush.brush_sizing_dx, brush.brush_sizing_dy); else if(_tool) _tool.drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); - surface_reset_shader(); draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp); diff --git a/scripts/node_collection/node_collection.gml b/scripts/node_collection/node_collection.gml index 99f630ed8..76e48414d 100644 --- a/scripts/node_collection/node_collection.gml +++ b/scripts/node_collection/node_collection.gml @@ -201,7 +201,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; static inspector1Update = function() { onInspector1Update(); } - static onInspector1Update = function() { RenderList(nodes, true); } + static onInspector1Update = function() { RenderList(nodes); } static hasInspector1Update = function() { INLINE return hasInsp1; } static inspector2Update = function() { onInspector2Update(); } diff --git a/scripts/node_tool/node_tool.gml b/scripts/node_tool/node_tool.gml index 2884379b9..c08f3e489 100644 --- a/scripts/node_tool/node_tool.gml +++ b/scripts/node_tool/node_tool.gml @@ -78,7 +78,7 @@ function NodeTool(name, spr, context = instanceof(other)) constructor { onToggle(); var _obj = getToolObject(); - if(_obj) _obj.init(); + if(_obj) _obj.init(ctx); } static toggleKeyboard = function() { diff --git a/scripts/panel_palette/panel_palette.gml b/scripts/panel_palette/panel_palette.gml index 879e18ea2..3b3278e0e 100644 --- a/scripts/panel_palette/panel_palette.gml +++ b/scripts/panel_palette/panel_palette.gml @@ -10,8 +10,6 @@ function Panel_Palette() : PanelContent() constructor { color_dragging = noone; function onResize() { - PANEL_PADDING - sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding)); } @@ -25,8 +23,9 @@ function Panel_Palette() : PanelContent() constructor { case 1 : _gs = ui(32); break; case 2 : _gs = ui(16); break; } - var yy = _y; var _height; + var yy = _y; + var cur = COLORS_GLOBAL_GET != noone? COLORS_GLOBAL_GET() : noone; for(var i = 0; i < array_length(PALETTES); i++) { var preset = PALETTES[i]; @@ -44,7 +43,7 @@ function Panel_Palette() : PanelContent() constructor { draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub); draw_text(ui(10), yy + ui(2), preset.name); - drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs); + drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs, cur); if(isHover) { if(mouse_press(mb_left, pFOCUS)) { diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index b29750f50..78513f005 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -99,6 +99,8 @@ function Panel_Preview() : PanelContent() constructor { tileMode = 0; bg_color = COLORS.panel_bg_clear; + + mouse_pos_string = ""; #endregion #region ---- tool ---- @@ -1071,7 +1073,14 @@ function Panel_Preview() : PanelContent() constructor { var mpx = floor((mx - canvas_x) / canvas_s); var mpy = floor((my - canvas_y) / canvas_s); draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]"); + + if(mouse_pos_string != "") { + right_menu_y += string_height("l"); + draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}"); + } } + + mouse_pos_string = ""; if(_node == noone) return; @@ -1477,9 +1486,9 @@ function Panel_Preview() : PanelContent() constructor { var key = sett[2]; var atr = sett[3]; - if(i == 0 && nme != "") { - tolx += ui(8); - tol_max_w += ui(8); + if(nme != "") { + tolx += ui(8) + bool(i == 0) * ui(8); + tol_max_w += ui(8) + bool(i == 0) * ui(8); } draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub); @@ -1500,6 +1509,7 @@ function Panel_Preview() : PanelContent() constructor { case "checkBoxGroup" : tolw = tolh * wdg.size; break; case "checkBox" : tolw = tolh; break; case "scrollBox" : tolw = ui(96); break; + case "buttonClass" : tolw = wdg.text == ""? tolh : tolw; break; } var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) @@ -1508,11 +1518,6 @@ function Panel_Preview() : PanelContent() constructor { wdg.drawParam(params); - if(nme != "") { - tolx += ui(8); - tol_max_w += ui(8); - } - tolx += tolw + ui(8) + (nme != "") * ui(8); tol_max_w += tolw + ui(8) + (nme != "") * ui(8); } diff --git a/scripts/string_functions/string_functions.gml b/scripts/string_functions/string_functions.gml index 835eae08e..ef15a4b33 100644 --- a/scripts/string_functions/string_functions.gml +++ b/scripts/string_functions/string_functions.gml @@ -37,12 +37,12 @@ function string_real(val, digMax = 999, decMin = 5) { #region if(is_array(val)) { var s = "["; - for( var i = 0, n = array_length(val); i < n; i++ ) - s += (i? ", " : "") + string_real(val[i]); + var i = 0, n = array_length(val); + repeat( n ) { s += (i? ", " : "") + string_real(val[i]); i++; } return s + "]"; } - if(val == 0 || !is_real(val)) return "0"; + if(val == 0 || !is_numeric(val)) return "0"; var pres, p = 1; var presMax = min(decMin, digMax - ceil(log10(ceil(abs(val)))));