diff --git a/#backups/scripts/node_cache/node_cache.gml.backup0 b/#backups/scripts/node_cache/node_cache.gml.backup0 new file mode 100644 index 000000000..2c2d22ec1 --- /dev/null +++ b/#backups/scripts/node_cache/node_cache.gml.backup0 @@ -0,0 +1,71 @@ +// 2024-04-30 11:30:04 +function Node_Cache(_x, _y, _group = noone) : __Node_Cache(_x, _y, _group) constructor { + name = "Cache"; + use_cache = CACHE_USE.auto; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + outputs[| 0] = nodeValue("Cache surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ + ["Surfaces", true], 0, + ]; + + cache_loading = false; + cache_content = ""; + cache_loading_progress = 0; + + insp2UpdateTooltip = "Clear cache"; + insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; + + static onInspector2Update = function() { + clearCache(true); + enableNodeGroup(); + } + + static step = function() { #region + if(cache_loading) { + cached_output[cache_loading_progress] = __surface_array_deserialize(cache_content[cache_loading_progress]); + cache_result[cache_loading_progress] = true; + cache_loading_progress++; + + if(cache_loading_progress == TOTAL_FRAMES) { + cache_loading = false; + update(); + } + } + } #endregion + + static update = function() { #region + if(recoverCache() || cache_loading) return; + + if(!inputs[| 0].value_from) return; + if(!inputs[| 0].value_from.node.renderActive) { + enableNodeGroup(); + return; + } + + var _surf = getInputData(0); + cacheCurrentFrame(_surf); + + disableNodeGroup(); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region + if(cache_loading) + draw_sprite_ui(THEME.loading, 0, xx + w * _s / 2, yy + h * _s / 2, _s, _s, current_time / 2, COLORS._main_icon, 1); + } #endregion + + static doSerialize = function(_map) { #region + _map.cache = surface_array_serialize(cached_output); + } #endregion + + static postDeserialize = function() { #region + refreshCacheGroup(); + + if(!struct_has(load_map, "cache")) return; + cache_content = json_try_parse(load_map.cache); + cache_loading_progress = 0; + cache_loading = true; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_cache/node_cache.gml.backup1 b/#backups/scripts/node_cache/node_cache.gml.backup1 new file mode 100644 index 000000000..a4c4d66b4 --- /dev/null +++ b/#backups/scripts/node_cache/node_cache.gml.backup1 @@ -0,0 +1,71 @@ +// 2024-04-30 11:29:54 +function Node_Cache(_x, _y, _group = noone) : __Node_Cache(_x, _y, _group) constructor { + name = "Cache"; + use_cache = CACHE_USE.auto; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + outputs[| 0] = nodeValue("Cache surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ + ["Surfaces", true], 0, + ]; + + cache_loading = false; + cache_content = ""; + cache_loading_progress = 0; + + insp2UpdateTooltip = "Clear cache"; + insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; + + static onInspector2Update = function() { + clearCache(true); + enableNodeGroup(); + } + + static step = function() { #region + if(cache_loading) { + cached_output[cache_loading_progress] = __surface_array_deserialize(cache_content[cache_loading_progress]); + cache_result[cache_loading_progress] = true; + cache_loading_progress++; + + if(cache_loading_progress == TOTAL_FRAMES) { + cache_loading = false; + update(); + } + } + } #endregion + + static update = function() { #region + if(recoverCache() || cache_loading) return; + + if(!inputs[| 0].value_from) return; + if(!inputs[| 0].value_from.node.renderActive) { + enableNodeGroup(); + return; + } + + var _surf = getInputData(0); + cacheCurrentFrame(_surf); + + disableNodeGroup(); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region + if(cache_loading) + draw_sprite_ui(THEME.loading, 0, xx + w * _s / 2, yy + h * _s / 2, _s, _s, current_time / 2, COLORS._main_icon, 1); + } #endregion + + static doSerialize = function(_map) { #region + _map.cache = surface_array_serialize(cached_output); + } #endregion + + static postDeserialize = function() { #region + refreshCacheGroup(); + + if(!struct_has(load_map, "cache")) return; + cache_content = json_try_parse(load_map.cache); + cache_loading_progress = 0; + cache_loading = true; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_cache_array/node_cache_array.gml.backup0 b/#backups/scripts/node_cache_array/node_cache_array.gml.backup0 new file mode 100644 index 000000000..d7da3ca30 --- /dev/null +++ b/#backups/scripts/node_cache_array/node_cache_array.gml.backup0 @@ -0,0 +1,99 @@ +// 2024-04-30 11:32:57 +function Node_Cache_Array(_x, _y, _group = noone) : __Node_Cache(_x, _y, _group) constructor { + name = "Cache Array"; + use_cache = CACHE_USE.manual; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Start frame", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, -1, "Frame index to start caching, set to -1 to start at the first frame."); + + inputs[| 2] = nodeValue("Stop frame", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, -1, "Frame index to stop caching (inclusive), set to -1 to stop at the last frame."); + + inputs[| 3] = nodeValue("Step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1, "Cache every N frames, set to 1 to cache every frame."); + + outputs[| 0] = nodeValue("Cache array", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); + + input_display_list = [ + ["Surfaces", true], 0, + ["Range", false], 1, 2, 3, + ]; + + cache_loading = false; + cache_content = ""; + cache_loading_progress = 0; + + insp2UpdateTooltip = "Clear cache"; + insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; + + static onInspector2Update = function() { + clearCache(); + enableNodeGroup(); + } + + static step = function() { #region + if(!cache_loading) return; + + var _content = cache_content[cache_loading_progress]; + + cached_output[cache_loading_progress] = __surface_array_deserialize(_content); + cache_result[cache_loading_progress] = true; + cache_loading_progress++; + + if(cache_loading_progress == array_length(cache_content)) { + cache_loading = false; + update(); + } + } #endregion + + static update = function() { #region + if(cache_loading) return; + + if(!inputs[| 0].value_from) return; + if(!inputs[| 0].value_from.node.renderActive) { + if(!cacheExist(CURRENT_FRAME)) + enableNodeGroup(); + return; + } + + var ss = []; + var str = getInputData(1); + var lst = getInputData(2); + var stp = getInputData(3); + + if(str < 0) str = 1; + if(lst < 0) lst = TOTAL_FRAMES; + + str -= 1; + lst -= 1; + + if(CURRENT_FRAME < str) return; + if(CURRENT_FRAME > lst) return; + + cacheCurrentFrame(getInputData(0)); + + if(lst > str && stp > 0) + for( var i = str; i <= lst; i += stp ) + if(cacheExist(i)) array_push(ss, cached_output[i]); + + outputs[| 0].setValue(ss); + + disableNodeGroup(); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region + if(cache_loading) draw_sprite_ui(THEME.loading, 0, xx + w * _s / 2, yy + h * _s / 2, _s, _s, current_time / 2, COLORS._main_icon, 1); + } #endregion + + static doSerialize = function(_map) { #region + _map.cache = surface_array_serialize(cached_output); + } #endregion + + static postDeserialize = function() { #region + refreshCacheGroup(); + + if(!struct_has(load_map, "cache")) return; + cache_content = json_try_parse(load_map.cache); + cache_loading_progress = 0; + cache_loading = true; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_cache_array/node_cache_array.gml.backup1 b/#backups/scripts/node_cache_array/node_cache_array.gml.backup1 new file mode 100644 index 000000000..6894934f1 --- /dev/null +++ b/#backups/scripts/node_cache_array/node_cache_array.gml.backup1 @@ -0,0 +1,99 @@ +// 2024-04-30 11:31:48 +function Node_Cache_Array(_x, _y, _group = noone) : __Node_Cache(_x, _y, _group) constructor { + name = "Cache Array"; + use_cache = CACHE_USE.manual; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Start frame", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, -1, "Frame index to start caching, set to -1 to start at the first frame."); + + inputs[| 2] = nodeValue("Stop frame", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, -1, "Frame index to stop caching (inclusive), set to -1 to stop at the last frame."); + + inputs[| 3] = nodeValue("Step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1, "Cache every N frames, set to 1 to cache every frame."); + + outputs[| 0] = nodeValue("Cache array", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); + + input_display_list = [ + ["Surfaces", true], 0, + ["Range", false], 1, 2, 3, + ]; + + cache_loading = false; + cache_content = ""; + cache_loading_progress = 0; + + insp2UpdateTooltip = "Clear cache"; + insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ]; + + static onInspector2Update = function() { + clearCache(); + enableNodeGroup(); + } + + static step = function() { #region + if(!cache_loading) return; + + var _content = cache_content[cache_loading_progress]; + + cached_output[cache_loading_progress] = __surface_array_deserialize(_content); + cache_result[cache_loading_progress] = true; + cache_loading_progress++; + + if(cache_loading_progress == array_length(cache_content)) { + cache_loading = false; + update(); + } + } #endregion + + static update = function() { #region + if(cache_loading) return; + + if(!inputs[| 0].value_from) return; + if(!inputs[| 0].value_from.node.renderActive) { + if(!cacheExist(CURRENT_FRAME)) + enableNodeGroup(); + return; + } + + var ss = []; + var str = getInputData(1); + var lst = getInputData(2); + var stp = getInputData(3); + + if(str < 0) str = 1; + if(lst < 0) lst = TOTAL_FRAMES; + + str -= 1; + lst -= 1; + + if(CURRENT_FRAME < str) return; + if(CURRENT_FRAME > lst) return; + + cacheCurrentFrame(getInputData(0)); + + if(lst > str && stp > 0) + for( var i = str; i <= lst; i += stp ) + if(cacheExist(i)) array_push(ss, cached_output[i]); + + outputs[| 0].setValue(ss); + + disableNodeGroup(); + } #endregion + + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region + if(cache_loading) draw_sprite_ui(THEME.loading, 0, xx + w * _s / 2, yy + h * _s / 2, _s, _s, current_time / 2, COLORS._main_icon, 1); + } #endregion + + static doSerialize = function(_map) { #region + _map.cache = surface_array_serialize(cached_output); + } #endregion + + static postDeserialize = function() { #region + refreshCacheGroup(); + + if(!struct_has(load_map, "cache")) return; + cache_content = json_try_parse(load_map.cache); + cache_loading_progress = 0; + cache_loading = true; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_cache_base/node_cache_base.gml.backup0 b/#backups/scripts/node_cache_base/node_cache_base.gml.backup0 new file mode 100644 index 000000000..917b795db --- /dev/null +++ b/#backups/scripts/node_cache_base/node_cache_base.gml.backup0 @@ -0,0 +1,252 @@ +// 2024-04-30 11:27:59 +function __Node_Cache(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Cache"; + clearCacheOnChange = false; + update_on_frame = true; + + attributes.cache_group = []; + cache_group_members = []; + group_vertex = []; + group_dragging = false; + group_adding = false; + group_alpha = 0; + vertex_hash = ""; + + insp1UpdateTooltip = "Generate cache group"; + insp1UpdateIcon = [ THEME.cache_group, 0, COLORS._main_icon ]; + + if(NOT_LOAD) run_in(1, function() { onInspector1Update(); }); + + static removeNode = function(node) { #region + if(node.cache_group != self) return; + + array_remove(attributes.cache_group, node.node_id); + array_remove(cache_group_members, node); + + node.cache_group = noone; + } #endregion + + static addNode = function(node) { #region + if(node.cache_group == self) return; + if(node.cache_group != noone) + node.cache_group.removeNode(node); + + array_push(attributes.cache_group, node.node_id); + array_push(cache_group_members, node); + + node.cache_group = self; + } #endregion + + static enableNodeGroup = function() { #region + if(LOADING || APPENDING) return; + print("Enacle"); + + for( var i = 0, n = array_length(cache_group_members); i < n; i++ ) + cache_group_members[i].renderActive = true; + clearCache(true); + } #endregion + + static disableNodeGroup = function() { #region + if(LOADING || APPENDING) return; + print("Disable"); + + if(IS_PLAYING && IS_LAST_FRAME) + for( var i = 0, n = array_length(cache_group_members); i < n; i++ ) + cache_group_members[i].renderActive = false; + } #endregion + + static refreshCacheGroup = function() { #region + cache_group_members = []; + + for( var i = 0, n = array_length(attributes.cache_group); i < n; i++ ) { + if(!ds_map_exists(PROJECT.nodeMap, attributes.cache_group[i])) { + print($"Node not found {attributes.cache_group[i]}"); + continue; + } + + var _node = PROJECT.nodeMap[? attributes.cache_group[i]]; + array_push(cache_group_members, _node); + _node.cache_group = self; + } + } #endregion + + static getCacheGroup = function(node) { #region + if(node != self) addNode(node); + + for( var i = 0, n = ds_list_size(node.inputs); i < n; i++ ) { + var _from = node.inputs[| i].value_from; + + if(_from == noone) continue; + if(_from.node == self) continue; + if(array_exists(attributes.cache_group, _from.node.node_id)) continue; + getCacheGroup(_from.node); + } + } #endregion + + static onInspector1Update = function() { #region + attributes.cache_group = []; + cache_group_members = []; + + getCacheGroup(self); + refreshCacheGroup(); + } #endregion + + static ccw = function(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); } + + static getNodeBorder = function(_i, _vertex, _node) { #region + var _rad = 4; + var _stp = 15; + + var _nx0 = _node.x - 32 + _rad; + var _ny0 = _node.y - 32 + _rad; + var _nx1 = _node.x + (_node == self? _node.w / 2 : _node.w + 32 - _rad); + var _ny1 = _node.y + _node.h + 32 - _rad; + + var _ind = 0; + for( var i = 0; i <= 90; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx1 + lengthdir_x(_rad, i), _ny0 + lengthdir_y(_rad, i) ]; + for( var i = 90; i <= 180; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx0 + lengthdir_x(_rad, i), _ny0 + lengthdir_y(_rad, i) ]; + for( var i = 180; i <= 270; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx0 + lengthdir_x(_rad, i), _ny1 + lengthdir_y(_rad, i) ]; + for( var i = 270; i <= 360; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx1 + lengthdir_x(_rad, i), _ny1 + lengthdir_y(_rad, i) ]; + } #endregion + + static refreshGroupBG = function() { #region + var _hash = ""; + for( var i = -1, n = array_length(cache_group_members); i < n; i++ ) { + var _node = i == -1? self : cache_group_members[i]; + _hash += $"{_node.x},{_node.y},{_node.w},{_node.h}|"; + } + _hash = md5_string_utf8(_hash); + + if(vertex_hash == _hash) return; + vertex_hash = _hash; + + group_vertex = []; + + if(array_empty(cache_group_members)) return; + var _vtrx = array_create((array_length(cache_group_members) + 1) * 4 * 7); + + for( var i = -1, n = array_length(cache_group_members); i < n; i++ ) { + var _node = i == -1? self : cache_group_members[i]; + getNodeBorder(i + 1, _vtrx, _node); + } + + __temp_minP = [ x, y ]; + __temp_minI = 0; + + for( var i = 0, n = array_length(_vtrx); i < n; i++ ) { + var _v = _vtrx[i]; + + if(_v[1] > __temp_minP[1] || (_v[1] == __temp_minP[1] && _v[0] < __temp_minP[0])) { + __temp_minP = _v; + __temp_minI = i; + } + } + + _vtrx = array_map( _vtrx, function(a, i) { return [ a[0], a[1], i == __temp_minI? -999 : point_direction(__temp_minP[0], __temp_minP[1], a[0], a[1]) + 360 ] }); + array_sort(_vtrx, function(a0, a1) { return a0[2] == a1[2]? sign(a0[0] - a1[0]) : sign(a0[2] - a1[2]); }); + + var _linS = 0; + for( var i = 1, n = array_length(_vtrx); i < n; i++ ) { + if(_vtrx[i][1] != _vtrx[0][1]) break; + _linS = i; + } + + array_delete(_vtrx, 1, _linS - 1); + + group_vertex = [ _vtrx[0], _vtrx[1] ]; + + for( var i = 2, n = array_length(_vtrx); i < n; i++ ) { + var _v = _vtrx[i]; + + while( array_length(group_vertex) >= 2 && ccw( group_vertex[array_length(group_vertex) - 2], group_vertex[array_length(group_vertex) - 1], _v ) >= 0 ) + array_pop(group_vertex); + array_push(group_vertex, _v); + } + } #endregion + + static groupCheck = function(_x, _y, _s, _mx, _my) { #region + if(array_length(group_vertex) < 3) return; + var _inGroup = true; + var _m = [ _mx / _s - _x, _my / _s - _y ]; + + group_adding = false; + + if(PANEL_GRAPH.node_dragging && key_mod_press(SHIFT)) { + var side = undefined; + for( var i = 1, n = array_length(group_vertex); i < n; i++ ) { + var a = group_vertex[i - 1]; + var b = group_vertex[i - 0]; + + var _side = sign(ccw(a, b, _m)); + if(side == undefined) side = _side; + else if(side != _side) _inGroup = false; + } + + var _list = PANEL_GRAPH.nodes_selecting; + + if(_inGroup) { + group_adding = true; + for( var i = 0, n = array_length(_list); i < n; i++ ) + array_push_unique(attributes.cache_group, _list[i].node_id); + } else { + for( var i = 0, n = array_length(_list); i < n; i++ ) + array_remove(attributes.cache_group, _list[i].node_id); + } + + if(!group_dragging) { + for( var i = 0, n = array_length(_list); i < n; i++ ) + array_remove(attributes.cache_group, _list[i].node_id); + refreshCacheGroup(); + refreshGroupBG(); + } + group_dragging = true; + } + + if(group_dragging && mouse_release(mb_left)) { + refreshCacheGroup(); + refreshGroupBG(); + + group_dragging = false; + } + } #endregion + + static drawNodeBG = function(_x, _y, _mx, _my, _s) { #region + refreshGroupBG(); + if(array_length(group_vertex) < 3) return; + + var _color = getColor(); + draw_set_color(_color); + group_alpha = lerp_float(group_alpha, group_adding, 4); + draw_set_alpha(0.025 + 0.025 * group_alpha); + draw_primitive_begin(pr_trianglelist); + var a = group_vertex[0]; + var b = group_vertex[1]; + var c; + + for( var i = 2, n = array_length(group_vertex); i < n; i++ ) { + c = group_vertex[i]; + + draw_vertex(_x + a[0] * _s, _y + a[1] * _s); + draw_vertex(_x + b[0] * _s, _y + b[1] * _s); + draw_vertex(_x + c[0] * _s, _y + c[1] * _s); + + b = group_vertex[i]; + } + draw_primitive_end(); + + draw_set_alpha(0.3); + draw_primitive_begin(pr_linestrip); + for( var i = 0, n = array_length(group_vertex); i < n; i++ ) { + var a = group_vertex[i]; + draw_vertex(_x + a[0] * _s, _y + a[1] * _s); + } + + a = group_vertex[0]; + draw_vertex(_x + a[0] * _s, _y + a[1] * _s); + draw_primitive_end(); + + draw_set_alpha(1); + } #endregion + + static onDestroy = function() { enableNodeGroup(); } +} \ No newline at end of file diff --git a/#backups/scripts/node_cache_base/node_cache_base.gml.backup1 b/#backups/scripts/node_cache_base/node_cache_base.gml.backup1 new file mode 100644 index 000000000..9cc79dcfb --- /dev/null +++ b/#backups/scripts/node_cache_base/node_cache_base.gml.backup1 @@ -0,0 +1,252 @@ +// 2024-04-30 11:27:55 +function __Node_Cache(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Cache"; + clearCacheOnChange = false; + update_on_frame = true; + + attributes.cache_group = []; + cache_group_members = []; + group_vertex = []; + group_dragging = false; + group_adding = false; + group_alpha = 0; + vertex_hash = ""; + + insp1UpdateTooltip = "Generate cache group"; + insp1UpdateIcon = [ THEME.cache_group, 0, COLORS._main_icon ]; + + if(NOT_LOAD) run_in(1, function() { onInspector1Update(); }); + + static removeNode = function(node) { #region + if(node.cache_group != self) return; + + array_remove(attributes.cache_group, node.node_id); + array_remove(cache_group_members, node); + + node.cache_group = noone; + } #endregion + + static addNode = function(node) { #region + if(node.cache_group == self) return; + if(node.cache_group != noone) + node.cache_group.removeNode(node); + + array_push(attributes.cache_group, node.node_id); + array_push(cache_group_members, node); + + node.cache_group = self; + } #endregion + + static enableNodeGroup = function() { #region + if(LOADING || APPENDING) return; + print("Enacle"); + + for( var i = 0, n = array_length(cache_group_members); i < n; i++ ) + cache_group_members[i].renderActive = true; + clearCache(true); + } #endregion + + static disableNodeGroup = function() { #region + if(LOADING || APPENDING) return; + print("Disable"); + + if(IS_PLAYING && IS_LAST_FRAME) + for( var i = 0, n = array_length(cache_group_members); i < n; i++ ) + cache_group_members[i].renderActive = false; + } #endregion + + static refreshCacheGroup = function() { #region + cache_group_members = []; + + for( var i = 0, n = array_length(attributes.cache_group); i < n; i++ ) { + if(!ds_map_exists(PROJECT.nodeMap, attributes.cache_group[i])) { + print($"Node not found {attributes.cache_group[i]}"); + continue; + } + + var _node = PROJECT.nodeMap[? attributes.cache_group[i]]; + array_push(cache_group_members, _node); + _node.cache_group = self; + } + } #endregion + + static getCacheGroup = function(node) { #region + if(node != self) addNode(node); + + for( var i = 0, n = ds_list_size(node.inputs); i < n; i++ ) { + var _from = node.inputs[| i].value_from; + + if(_from == noone) continue; + if(_from.node == self) continue; + if(array_exists(attributes.cache_group, _from.node.node_id)) continue; + getCacheGroup(_from.node); + } + } #endregion + + static onInspector1Update = function() { #region + attributes.cache_group = []; + cache_group_members = []; + + getCacheGroup(self); + refreshCacheGroup(); + } #endregion + + static ccw = function(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]); } + + static getNodeBorder = function(_i, _vertex, _node) { #region + var _rad = 4; + var _stp = 15; + + var _nx0 = _node.x - 32 + _rad; + var _ny0 = _node.y - 32 + _rad; + var _nx1 = _node.x + (_node == self? _node.w / 2 : _node.w + 32 - _rad); + var _ny1 = _node.y + _node.h + 32 - _rad; + + var _ind = 0; + for( var i = 0; i <= 90; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx1 + lengthdir_x(_rad, i), _ny0 + lengthdir_y(_rad, i) ]; + for( var i = 90; i <= 180; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx0 + lengthdir_x(_rad, i), _ny0 + lengthdir_y(_rad, i) ]; + for( var i = 180; i <= 270; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx0 + lengthdir_x(_rad, i), _ny1 + lengthdir_y(_rad, i) ]; + for( var i = 270; i <= 360; i += _stp ) _vertex[_i * 7 * 4 + _ind++] = [ _nx1 + lengthdir_x(_rad, i), _ny1 + lengthdir_y(_rad, i) ]; + } #endregion + + static refreshGroupBG = function() { #region + var _hash = ""; + for( var i = -1, n = array_length(cache_group_members); i < n; i++ ) { + var _node = i == -1? self : cache_group_members[i]; + _hash += $"{_node.x},{_node.y},{_node.w},{_node.h}|"; + } + _hash = md5_string_utf8(_hash); + + if(vertex_hash == _hash) return; + vertex_hash = _hash; + + group_vertex = []; + + if(array_empty(cache_group_members)) return; + var _vtrx = array_create((array_length(cache_group_members) + 1) * 4 * 7); + + for( var i = -1, n = array_length(cache_group_members); i < n; i++ ) { + var _node = i == -1? self : cache_group_members[i]; + getNodeBorder(i + 1, _vtrx, _node); + } + + __temp_minP = [ x, y ]; + __temp_minI = 0; + + for( var i = 0, n = array_length(_vtrx); i < n; i++ ) { + var _v = _vtrx[i]; + + if(_v[1] > __temp_minP[1] || (_v[1] == __temp_minP[1] && _v[0] < __temp_minP[0])) { + __temp_minP = _v; + __temp_minI = i; + } + } + + _vtrx = array_map( _vtrx, function(a, i) { return [ a[0], a[1], i == __temp_minI? -999 : point_direction(__temp_minP[0], __temp_minP[1], a[0], a[1]) + 360 ] }); + array_sort(_vtrx, function(a0, a1) { return a0[2] == a1[2]? sign(a0[0] - a1[0]) : sign(a0[2] - a1[2]); }); + + var _linS = 0; + for( var i = 1, n = array_length(_vtrx); i < n; i++ ) { + if(_vtrx[i][1] != _vtrx[0][1]) break; + _linS = i; + } + + array_delete(_vtrx, 1, _linS - 1); + + group_vertex = [ _vtrx[0], _vtrx[1] ]; + + for( var i = 2, n = array_length(_vtrx); i < n; i++ ) { + var _v = _vtrx[i]; + + while( array_length(group_vertex) >= 2 && ccw( group_vertex[array_length(group_vertex) - 2], group_vertex[array_length(group_vertex) - 1], _v ) >= 0 ) + array_pop(group_vertex); + array_push(group_vertex, _v); + } + } #endregion + + static groupCheck = function(_x, _y, _s, _mx, _my) { #region + if(array_length(group_vertex) < 3) return; + var _inGroup = true; + var _m = [ _mx / _s - _x, _my / _s - _y ]; + + group_adding = false; + + if(PANEL_GRAPH.node_dragging && key_mod_press(SHIFT)) { + var side = undefined; + for( var i = 1, n = array_length(group_vertex); i < n; i++ ) { + var a = group_vertex[i - 1]; + var b = group_vertex[i - 0]; + + var _side = sign(ccw(a, b, _m)); + if(side == undefined) side = _side; + else if(side != _side) _inGroup = false; + } + + var _list = PANEL_GRAPH.nodes_selecting; + + if(_inGroup) { + group_adding = true; + for( var i = 0, n = array_length(_list); i < n; i++ ) + array_push_unique(attributes.cache_group, _list[i].node_id); + } else { + for( var i = 0, n = array_length(_list); i < n; i++ ) + array_remove(attributes.cache_group, _list[i].node_id); + } + + if(!group_dragging) { + for( var i = 0, n = array_length(_list); i < n; i++ ) + array_remove(attributes.cache_group, _list[i].node_id); + refreshCacheGroup(); + refreshGroupBG(); + } + group_dragging = true; + } + + if(group_dragging && mouse_release(mb_left)) { + refreshCacheGroup(); + refreshGroupBG(); + + group_dragging = false; + } + } #endregion + + static drawNodeBG = function(_x, _y, _mx, _my, _s) { #region + refreshGroupBG(); + if(array_length(group_vertex) < 3) return; + + var _color = getColor(); + draw_set_color(_color); + group_alpha = lerp_float(group_alpha, group_adding, 4); + draw_set_alpha(0.025 + 0.025 * group_alpha); + draw_primitive_begin(pr_trianglelist); + var a = group_vertex[0]; + var b = group_vertex[1]; + var c; + + for( var i = 2, n = array_length(group_vertex); i < n; i++ ) { + c = group_vertex[i]; + + draw_vertex(_x + a[0] * _s, _y + a[1] * _s); + draw_vertex(_x + b[0] * _s, _y + b[1] * _s); + draw_vertex(_x + c[0] * _s, _y + c[1] * _s); + + b = group_vertex[i]; + } + draw_primitive_end(); + + draw_set_alpha(0.3); + draw_primitive_begin(pr_linestrip); + for( var i = 0, n = array_length(group_vertex); i < n; i++ ) { + var a = group_vertex[i]; + draw_vertex(_x + a[0] * _s, _y + a[1] * _s); + } + + a = group_vertex[0]; + draw_vertex(_x + a[0] * _s, _y + a[1] * _s); + draw_primitive_end(); + + draw_set_alpha(1); + } #endregion + + static onDestroy = function() { enableNodeGroup(); } +} \ No newline at end of file diff --git a/#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup0 b/#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup0 new file mode 100644 index 000000000..930c35ac9 --- /dev/null +++ b/#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup0 @@ -0,0 +1,124 @@ +// 2024-04-30 15:22:54 +function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Pack Sprites"; + + inputs[| 0] = nodeValue("Sprites", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Algorithm", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, { data: [ "Skyline", "Shelf", "Top left", "Best fit" ], update_hover: false }); + + inputs[| 2] = nodeValue("Max width", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 128); + + inputs[| 3] = nodeValue("Max height", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 128); + + inputs[| 4] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); + + outputs[| 0] = nodeValue("Packed image", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); + + input_display_list = [ 0, 4, 1, 2, 3 ]; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var rect = outputs[| 1].getValue(); + var spac = getInputData(4); + + draw_set_color(COLORS._main_accent); + + for( var i = 0, n = array_length(rect); i < n; i++ ) { + var r = rect[i]; + + var _surf = r.getSurface(); + var _sx = r.x; + var _sy = r.y; + + if(!is_surface(_surf)) continue; + + var _sw = surface_get_width_safe(_surf); + var _sh = surface_get_height_safe(_surf); + + draw_rectangle( + _x + _s * (_sx), + _y + _s * (_sy), + _x + _s * (_sx + _sw), + _y + _s * (_sy + _sh), true); + } + } #endregion + + static step = function() { #region + var algo = getInputData(1); + + inputs[| 2].setVisible(algo == 1 || algo == 0); + inputs[| 3].setVisible(algo == 2 || algo == 0); + } #endregion + + static update = function() { #region + var _inpt = getInputData(0); + var _algo = getInputData(1); + var _spac = getInputData(4); + + if(!is_array(_inpt) || array_length(_inpt) == 0) return; + + var _rects = []; + + for( var i = 0, n = array_length(_inpt); i < n; i++ ) { + var s = _inpt[i]; + if(!is_surface(s)) continue; + + _rects[i] = new SurfaceAtlas(s); + _rects[i].w = surface_get_width_safe(s) + _spac * 2; + _rects[i].h = surface_get_height_safe(s) + _spac * 2; + } + + var pack; + + switch(_algo) { + case 0 : + var _wid = getInputData(2); + var _hei = getInputData(3); + pack = sprite_pack_skyline(_rects, _wid, _hei); + break; + + case 1 : + var _wid = getInputData(2); + pack = sprite_pack_shelf(_rects, _wid); + break; + + case 2 : + var _hei = getInputData(3); + pack = sprite_pack_bottom_left(_rects, _hei); + break; + + case 3 : + pack = sprite_pack_best_fit(_rects); + break; + } + + var area = pack[0]; + var rect = pack[1]; + var atlas = []; + + if(array_length(rect) < array_length(_rects)) + noti_warning($"Not enought space, packed {array_length(rect)} out of {array_length(_rects)} images."); + + var _surf = outputs[| 0].getValue(); + _surf = surface_verify(_surf, area.w, area.h, surface_get_format(_inpt[0])); + outputs[| 0].setValue(_surf); + + surface_set_target(_surf); + DRAW_CLEAR + BLEND_OVERRIDE + + for( var i = 0, n = array_length(rect); i < n; i++ ) { + var r = rect[i]; + + array_push(atlas, new SurfaceAtlas(r.surface.surface, r.x + _spac, r.y + _spac)); + draw_surface_safe(r.surface.surface, r.x + _spac, r.y + _spac); + } + + BLEND_NORMAL + surface_reset_target(); + + outputs[| 1].setValue(atlas); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup1 b/#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup1 new file mode 100644 index 000000000..ad390ed3b --- /dev/null +++ b/#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup1 @@ -0,0 +1,124 @@ +// 2024-04-30 15:21:24 +function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Pack Sprites"; + + inputs[| 0] = nodeValue("Sprites", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Algorithm", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, { data: [ "Skyline", "Shelf", "Top left", "Best fit" ], update_hover: false }); + + inputs[| 2] = nodeValue("Max width", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 128); + + inputs[| 3] = nodeValue("Max height", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 128); + + inputs[| 4] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); + + outputs[| 0] = nodeValue("Packed image", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); + + input_display_list = [ 0, 4, 1, 2, 3 ]; + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var rect = outputs[| 1].getValue(); + var spac = getInputData(4); + + draw_set_color(COLORS._main_accent); + + for( var i = 0, n = array_length(rect); i < n; i++ ) { + var r = rect[i]; + + var _surf = r.getSurface(); + var _sx = r.x; + var _sy = r.y; + + if(!is_surface(_surf)) continue; + + var _sw = surface_get_width_safe(_surf); + var _sh = surface_get_height_safe(_surf); + + draw_rectangle( + _x + _s * (_sx), + _y + _s * (_sy), + _x + _s * (_sx + _sw), + _y + _s * (_sy + _sh), true); + } + } #endregion + + static step = function() { #region + var algo = getInputData(1); + + inputs[| 2].setVisible(algo == 1 || algo == 0); + inputs[| 3].setVisible(algo == 2 || algo == 0); + } #endregion + + static update = function() { #region + var _inpt = getInputData(0); + var _algo = getInputData(1); + var _spac = getInputData(4); + + if(!is_array(_inpt) || array_length(_inpt) == 0) return; + + var _rects = []; + + for( var i = 0, n = array_length(_inpt); i < n; i++ ) { + var s = _inpt[i]; + if(!is_surface(s)) continue; + + _rects[i] = new SurfaceAtlas(s); + _rects[i].w = surface_get_width_safe(s) + _spac * 2; + _rects[i].h = surface_get_height_safe(s) + _spac * 2; + } + + var pack; + + switch(_algo) { + case 0 : + var _wid = getInputData(2); + var _hei = getInputData(3); + pack = sprite_pack_skyline(_rects, _wid, _hei); + break; + + case 1 : + var _wid = getInputData(2); + pack = sprite_pack_shelf(_rects, _wid); + break; + + case 2 : + var _hei = getInputData(3); + pack = sprite_pack_bottom_left(_rects, _hei); + break; + + case 3 : + pack = sprite_pack_best_fit(_rects); + break; + } + + var area = pack[0]; + var rect = pack[1]; + var atlas = []; + + if(array_length(rect) < array_length(_rects)) + noti_warning($"Not enought space, packed {array_length(rect)} out of {array_length(_rects)} images."); + + var _surf = outputs[| 0].getValue(); + _surf = surface_verify(_surf, area.w, area.h, surface_get_format(_inpt[0])); + outputs[| 0].setValue(_surf); + + surface_set_target(_surf); + DRAW_CLEAR + BLEND_OVERRIDE + + for( var i = 0, n = array_length(rect); i < n; i++ ) { + var r = rect[i]; + + array_push(atlas, new SurfaceAtlas(r.surface.surface, r.x + _spac, r.y + _spac)); + draw_surface_safe(r.surface.surface, r.x + _spac, r.y + _spac); + } + + BLEND_NORMAL + surface_reset_target(); + + outputs[| 1].setValue(atlas); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml.backup0 b/#backups/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml.backup0 new file mode 100644 index 000000000..f2701412f --- /dev/null +++ b/#backups/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml.backup0 @@ -0,0 +1,535 @@ +// 2024-04-30 13:20:26 +enum SPRITE_STACK { + horizontal, + vertical, + grid +} + +enum SPRITE_ANIM_GROUP { + animation, + all_sprites +} + +function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + static log = false; + + name = "Render Spritesheet"; + anim_drawn = array_create(TOTAL_FRAMES + 1, false); + + inputs[| 0] = nodeValue("Sprites", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Sprite set", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Animation", "Sprite array" ]) + .rejectArray(); + + inputs[| 2] = nodeValue("Frame step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1, "Number of frames until next sprite. Can be seen as (Step - 1) frame skip.") + .rejectArray(); + + inputs[| 3] = nodeValue("Packing type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ new scrollItem("Horizontal", s_node_alignment, 0), + new scrollItem("Vertical", s_node_alignment, 1), + new scrollItem("Grid", s_node_alignment, 2), ]) + .rejectArray(); + + inputs[| 4] = nodeValue("Grid column", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 4) + .rejectArray(); + + inputs[| 5] = nodeValue("Alignment", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ "First", "Middle", "Last" ]) + .rejectArray(); + + inputs[| 6] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); + + inputs[| 7] = nodeValue("Padding", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0, 0, 0 ]) + .setDisplay(VALUE_DISPLAY.padding) + + inputs[| 8] = nodeValue("Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0 ], "Starting/ending frames, set end to 0 to default to last frame.") + .setDisplay(VALUE_DISPLAY.slider_range) + + inputs[| 9] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0 ]) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 10] = nodeValue("Overlappable", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 11] = nodeValue("Custom Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) + .setArrayDepth(1); + + input_display_list = [ + ["Surfaces", false], 0, 1, 2, + ["Sprite", false], 3, + ["Packing", false], 4, 5, 6, 9, 7, + //["Rendering", false], 10, + ["Custom Range", true, 11], 8, + ] + + attribute_surface_depth(); + + static onInspector1Update = function(updateAll = true) { initSurface(true); PROJECT.animator.render(); } + + static step = function() { #region + var inpt = getInputData(0); + var grup = getInputData(1); + var pack = getInputData(3); + var user = getInputData(11); + + if(pack == 0) inputs[| 5].editWidget.data = [ "Top", "Center", "Bottom" ]; + else inputs[| 5].editWidget.data = [ "Left", "Center", "Right" ]; + + inputs[| 2].setVisible(grup == SPRITE_ANIM_GROUP.animation); + inputs[| 4].setVisible(pack == SPRITE_STACK.grid); + inputs[| 5].setVisible(pack != SPRITE_STACK.grid); + inputs[| 6].setVisible(pack != SPRITE_STACK.grid); + inputs[| 9].setVisible(pack == SPRITE_STACK.grid); + + if(grup == SPRITE_ANIM_GROUP.animation) { + inputs[| 8].editWidget.minn = FIRST_FRAME + 1; + inputs[| 8].editWidget.maxx = LAST_FRAME + 1; + if(!user) inputs[| 8].setValueDirect([ FIRST_FRAME + 1, LAST_FRAME + 1], noone, false, 0, false); + } else { + inputs[| 8].editWidget.minn = 0; + inputs[| 8].editWidget.maxx = array_length(inpt) - 1; + if(!user) inputs[| 8].setValueDirect([ 0, array_length(inpt) - 1], noone, false, 0, false); + } + + update_on_frame = grup == 0; + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region + if(IS_FIRST_FRAME) initSurface(); + + var grup = getInputData(1); + + if(grup == SPRITE_ANIM_GROUP.animation) animationRender(); + else arrayRender(); + } #endregion + + static initSurface = function(clear = false) { #region + for(var i = 0; i < TOTAL_FRAMES; i++) anim_drawn[i] = false; + + var grup = getInputData(1); + + if(grup == SPRITE_ANIM_GROUP.animation) animationInit(clear); + else arrayRender(); + } #endregion + + static arrayRender = function() { #region + var inpt = getInputData(0); + var grup = getInputData(1); + var pack = getInputData(3); + var alig = getInputData(5); + var spac = getInputData(6); + var padd = getInputData(7); + var rang = getInputData(8); + var spc2 = getInputData(9); + //var ovlp = getInputData(10); + + var cDep = attrDepth(); + + if(!is_array(inpt)) { + outputs[| 0].setValue(surface_clone(inpt)); + outputs[| 1].setValue([]); + return; + } + + #region frame + var _st, _ed; + var _ln = array_length(inpt); + + if(rang[0] < 0) _st = _ln + rang[0]; + else _st = rang[0]; + + if(rang[1] == 0) _ed = _ln; + else if(rang[1] < 0) _ed = _ln + rang[1]; + else _ed = rang[1]; + + _st = clamp(_st, 0, _ln); + _ed = clamp(_ed, 0, _ln); + + if(_ed < _st) return; + var amo = _ed - _st + 1; + #endregion + + var ww = 0; + var hh = 0; + var _atl = []; + + #region surface generate + + switch(pack) { + case SPRITE_STACK.horizontal : + for(var i = _st; i <= _ed; i++) { + ww += surface_get_width_safe(inpt[i]); + if(i > _st) ww += spac; + hh = max(hh, surface_get_height_safe(inpt[i])); + } + break; + case SPRITE_STACK.vertical : + for(var i = _st; i <= _ed; i++) { + ww = max(ww, surface_get_width_safe(inpt[i])); + hh += surface_get_height_safe(inpt[i]); + if(i > _st) hh += spac; + } + break; + case SPRITE_STACK.grid : + var col = getInputData(4); + var row = ceil(amo / col); + + for(var i = 0; i < row; i++) { + var row_w = 0; + var row_h = 0; + + for(var j = 0; j < col; j++) { + var index = _st + i * col + j; + if(index > _ed) break; + + row_w += surface_get_width_safe(inpt[index]); + if(j) row_w += spc2[0]; + row_h = max(row_h, surface_get_height_safe(inpt[index])); + } + + ww = max(ww, row_w); + hh += row_h + if(i) hh += spc2[1]; + } + break; + } + + ww += padd[0] + padd[2]; + hh += padd[1] + padd[3]; + var _surf = surface_create_valid(ww, hh, cDep); + #endregion + + #region draw + surface_set_shader(_surf, noone); + + var curr_w = -1; + var curr_h = -1; + + switch(pack) { + case SPRITE_STACK.horizontal : + var px = padd[2]; + var py = padd[1]; + for(var i = _st; i <= _ed; i++) { + var _w = surface_get_width_safe(inpt[i]); + var _h = surface_get_height_safe(inpt[i]); + var _sx = px; + var _sy = py; + + curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + switch(alig) { + case 1 : _sy = py + (hh - _h) / 2; break; + case 2 : _sy = py + (hh - _h); break; + } + + array_push(_atl, new SurfaceAtlas(inpt[i], _sx, _sy)); + draw_surface_safe(inpt[i], _sx, _sy); + + px += _w + spac; + } + break; + case SPRITE_STACK.vertical : + var px = padd[2]; + var py = padd[1]; + for(var i = _st; i <= _ed; i++) { + var _w = surface_get_width_safe(inpt[i]); + var _h = surface_get_height_safe(inpt[i]); + var _sx = px; + var _sy = py; + + curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + switch(alig) { + case 1 : _sx = px + (ww - _w) / 2; break; + case 2 : _sx = px + (ww - _w); break; + } + + array_push(_atl, new SurfaceAtlas(inpt[i], _sx, _sy)); + draw_surface_safe(inpt[i], _sx, _sy); + + py += _h + spac; + } + break; + case SPRITE_STACK.grid : + var amo = array_length(inpt); + var col = getInputData(4); + var row = ceil(amo / col); + + var row_w = 0; + var row_h = 0; + var px = padd[2]; + var py = padd[1]; + + for(var i = 0; i < row; i++) { + row_w = 0; + row_h = 0; + px = padd[2]; + + for(var j = 0; j < col; j++) { + var index = _st + i * col + j; + if(index > _ed) break; + + var _w = surface_get_width_safe(inpt[index]); + var _h = surface_get_height_safe(inpt[index]); + + curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + array_push(_atl, new SurfaceAtlas(inpt[index], px, py)); + draw_surface_safe(inpt[index], px, py); + + px += _w + spc2[0]; + row_h = max(row_h, _h); + } + py += row_h + spc2[1]; + } + break; + } + + surface_reset_shader(); + #endregion + + outputs[| 0].setValue(_surf); + outputs[| 1].setValue(_atl); + } #endregion + + anim_curr_w = -1; + anim_curr_h = -1; + + static animationInit = function(clear = false) { #region + var inpt = getInputData(0); + var skip = getInputData(2); + var pack = getInputData(3); + var grid = getInputData(4); + var alig = getInputData(5); + var spac = getInputData(6); + var padd = getInputData(7); + var rang = getInputData(8); + var spc2 = getInputData(9); + //var ovlp = getInputData(10); + var user = getInputData(11); + + var _out = outputs[| 0].getValue(); + var _atl = outputs[| 1].getValue(); + var cDep = attrDepth(); + + printIf(log, $"Init animation"); + + var arr = is_array(inpt); + if(arr && array_length(inpt) == 0) return; + if(!arr) inpt = [ inpt ]; + + if(!is_array(_out)) _out = [ _out ]; + + #region frame + var _st = FIRST_FRAME; + var _ed = LAST_FRAME + 1; + + if(user) { + if(rang[0] < 0) _st = LAST_FRAME + rang[0] - 1; + else _st = rang[0] - 1; + + if(rang[1] < 0) _ed = LAST_FRAME + rang[1]; + else _ed = rang[1]; + } + + if(_ed <= _st) return; + var amo = floor((_ed - _st) / skip); + #endregion + + var skip = getInputData(2); + + var ww = 1, hh = 1; + + for(var i = 0; i < array_length(inpt); i++) { + var _surfi = inpt[i]; + if(!is_surface(_surfi)) continue; + + _atl[i] = []; + + var sw = surface_get_width_safe(_surfi); + var sh = surface_get_height_safe(_surfi); + ww = sw; + hh = sh; + + anim_curr_w = sw; + anim_curr_h = sh; + + switch(pack) { + case SPRITE_STACK.horizontal : + ww = sw * amo + spac * (amo - 1); + break; + case SPRITE_STACK.vertical : + hh = sh * amo + spac * (amo - 1); + break; + case SPRITE_STACK.grid : + var row = ceil(amo / grid); + + ww = sw * grid + spc2[0] * (grid - 1); + hh = sh * row + spc2[1] * (row - 1); + break; + } + + ww += padd[0] + padd[2]; + hh += padd[1] + padd[3]; + + _out[i] = surface_verify(array_safe_get_fast(_out, i), surface_valid_size(ww), surface_valid_size(hh), cDep); + + if(clear) surface_clear(_out[i]); + } + + if(!arr) _out = array_safe_get_fast(_out, 0); + outputs[| 0].setValue(_out); + outputs[| 1].setValue(_atl); + + printIf(log, $"Surface generated [{ww}, {hh}]"); + } #endregion + + static animationRender = function() { #region + var inpt = getInputData(0); + var skip = getInputData(2); + var pack = getInputData(3); + var grid = getInputData(4); + var alig = getInputData(5); + var spac = getInputData(6); + var padd = getInputData(7); + var rang = getInputData(8); + var spc2 = getInputData(9); + //var ovlp = getInputData(10); + var user = getInputData(11); + + var _atl = outputs[| 1].getValue(); + var cDep = attrDepth(); + + printIf(log, $"Rendering animation {name}/{CURRENT_FRAME}"); + + var arr = is_array(inpt); + if(arr && array_length(inpt) == 0) return; + if(!arr) inpt = [ inpt ]; + + #region frame + var _st = FIRST_FRAME; + var _ed = LAST_FRAME + 1; + + if(user) { + if(rang[0] < 0) _st = LAST_FRAME + rang[0] - 1; + else _st = rang[0] - 1; + + if(rang[1] < 0) _ed = LAST_FRAME + rang[1] + 1; + else _ed = rang[1] + 1; + } + + if(_ed <= _st) return; + var amo = floor((_ed - _st) / skip); + #endregion + + if(safe_mod(CURRENT_FRAME - _st, skip) != 0) { + printIf(log, $" > Skip frame"); + return; + } + + #region check overlap + if(array_length(anim_drawn) != TOTAL_FRAMES) + array_resize(anim_drawn, TOTAL_FRAMES); + + if(CURRENT_FRAME >= 0 && CURRENT_FRAME < TOTAL_FRAMES && anim_drawn[CURRENT_FRAME]) { + printIf(log, $" > Skip drawn"); + return; + } + #endregion + + var oupt = outputs[| 0].getValue(); + var _frame = floor((CURRENT_FRAME - _st) / skip); + var drawn = false; + var px = padd[2]; + var py = padd[1]; + + for(var i = 0; i < array_length(inpt); i++) { #region + var _surfi = inpt[i]; + + if(!is_surface(_surfi)) { + printIf(log, $" > Skip input not surface"); + _atl[i] = noone; + break; + } + + if(!is_array(array_safe_get_fast(_atl, i))) + _atl[i] = []; + var _atli = _atl[i]; + + var oo = noone; + if(!is_array(oupt)) oo = oupt; + else oo = oupt[i]; + + if(!is_surface(oo)) { + printIf(log, $" > Skip output not surface"); + break; + } + + var ww = surface_get_width_safe(oo); + var hh = surface_get_height_safe(oo); + + var _w = surface_get_width_safe(_surfi); + var _h = surface_get_height_safe(_surfi); + + if(anim_curr_w != _w || anim_curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + var px; + var _sx = 0; + var _sy = 0; + + switch(pack) { + case SPRITE_STACK.horizontal : + px = padd[2] + _frame * _w + max(0, _frame) * spac; + _sx = px; + _sy = py; + + switch(alig) { + case 1 : _sy = py + (hh - _h) / 2; break; + case 2 : _sy = py + (hh - _h); break; + } + + break; + case SPRITE_STACK.vertical : + py = padd[1] + _frame * _h + max(0, _frame) * spac; + _sx = px; + _sy = py; + + switch(alig) { + case 1 : _sx = px + (ww - _w) / 2; break; + case 2 : _sx = px + (ww - _w); break; + } + + break; + case SPRITE_STACK.grid : + var col = getInputData(4); + var _row = floor(_frame / col); + var _col = safe_mod(_frame, col); + + _sx = px + _col * _w + max(0, _col) * spc2[0]; + _sy = py + _row * _h + max(0, _row) * spc2[1]; + break; + } + + surface_set_shader(oo, noone, false, BLEND.over); + + printIf(log, $" > Drawing frame ({CURRENT_FRAME}) {_surfi} at {_sx}, {_sy}"); + + _atli[i] = new SurfaceAtlas(_surfi, _sx, _sy); + draw_surface(_surfi, _sx, _sy); + + surface_reset_shader(); + + drawn = true; + } #endregion + + if(drawn) array_safe_set(anim_drawn, CURRENT_FRAME, true); + outputs[| 1].setValue(_atl); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml.backup1 b/#backups/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml.backup1 new file mode 100644 index 000000000..225367546 --- /dev/null +++ b/#backups/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml.backup1 @@ -0,0 +1,535 @@ +// 2024-04-30 13:20:21 +enum SPRITE_STACK { + horizontal, + vertical, + grid +} + +enum SPRITE_ANIM_GROUP { + animation, + all_sprites +} + +function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + static log = false; + + name = "Render Spritesheet"; + anim_drawn = array_create(TOTAL_FRAMES + 1, false); + + inputs[| 0] = nodeValue("Sprites", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Sprite set", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Animation", "Sprite array" ]) + .rejectArray(); + + inputs[| 2] = nodeValue("Frame step", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1, "Number of frames until next sprite. Can be seen as (Step - 1) frame skip.") + .rejectArray(); + + inputs[| 3] = nodeValue("Packing type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ new scrollItem("Horizontal", s_node_alignment, 0), + new scrollItem("Vertical", s_node_alignment, 1), + new scrollItem("Grid", s_node_alignment, 2), ]) + .rejectArray(); + + inputs[| 4] = nodeValue("Grid column", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 4) + .rejectArray(); + + inputs[| 5] = nodeValue("Alignment", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_button, [ "First", "Middle", "Last" ]) + .rejectArray(); + + inputs[| 6] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); + + inputs[| 7] = nodeValue("Padding", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0, 0, 0 ]) + .setDisplay(VALUE_DISPLAY.padding) + + inputs[| 8] = nodeValue("Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0 ], "Starting/ending frames, set end to 0 to default to last frame.") + .setDisplay(VALUE_DISPLAY.slider_range) + + inputs[| 9] = nodeValue("Spacing", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0 ]) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 10] = nodeValue("Overlappable", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 11] = nodeValue("Custom Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) + .setArrayDepth(1); + + input_display_list = [ + ["Surfaces", false], 0, 1, 2, + ["Sprite", false], 3, + ["Packing", false], 4, 5, 6, 9, 7, + //["Rendering", false], 10, + ["Custom Range", true, 11], 8, + ] + + attribute_surface_depth(); + + static onInspector1Update = function(updateAll = true) { initSurface(true); PROJECT.animator.render(); } + + static step = function() { #region + var inpt = getInputData(0); + var grup = getInputData(1); + var pack = getInputData(3); + var user = getInputData(11); + + if(pack == 0) inputs[| 5].editWidget.data = [ "Top", "Center", "Bottom" ]; + else inputs[| 5].editWidget.data = [ "Left", "Center", "Right" ]; + + inputs[| 2].setVisible(grup == SPRITE_ANIM_GROUP.animation); + inputs[| 4].setVisible(pack == SPRITE_STACK.grid); + inputs[| 5].setVisible(pack != SPRITE_STACK.grid); + inputs[| 6].setVisible(pack != SPRITE_STACK.grid); + inputs[| 9].setVisible(pack == SPRITE_STACK.grid); + + if(grup == SPRITE_ANIM_GROUP.animation) { + inputs[| 8].editWidget.minn = FIRST_FRAME + 1; + inputs[| 8].editWidget.maxx = LAST_FRAME + 1; + if(!user) inputs[| 8].setValueDirect([ FIRST_FRAME + 1, LAST_FRAME + 1], noone, false, 0, false); + } else { + inputs[| 8].editWidget.minn = 0; + inputs[| 8].editWidget.maxx = array_length(inpt) - 1; + if(!user) inputs[| 8].setValueDirect([ 0, array_length(inpt) - 1], noone, false, 0, false); + } + + update_on_frame = grup == 0; + } #endregion + + static update = function(frame = CURRENT_FRAME) { #region + if(IS_FIRST_FRAME) initSurface(); + + var grup = getInputData(1); + + if(grup == SPRITE_ANIM_GROUP.animation) animationRender(); + else arrayRender(); + } #endregion + + static initSurface = function(clear = false) { #region + for(var i = 0; i < TOTAL_FRAMES; i++) anim_drawn[i] = false; + + var grup = getInputData(1); + + if(grup == SPRITE_ANIM_GROUP.animation) animationInit(clear); + else arrayRender(); + } #endregion + + static arrayRender = function() { #region + var inpt = getInputData(0); + var grup = getInputData(1); + var pack = getInputData(3); + var alig = getInputData(5); + var spac = getInputData(6); + var padd = getInputData(7); + var rang = getInputData(8); + var spc2 = getInputData(9); + //var ovlp = getInputData(10); + + var cDep = attrDepth(); + + if(!is_array(inpt)) { + outputs[| 0].setValue(surface_clone(inpt)); + outputs[| 1].setValue([]); + return; + } + + #region frame + var _st, _ed; + var _ln = array_length(inpt); + + if(rang[0] < 0) _st = _ln + rang[0]; + else _st = rang[0]; + + if(rang[1] == 0) _ed = _ln; + else if(rang[1] < 0) _ed = _ln + rang[1]; + else _ed = rang[1]; + + _st = clamp(_st, 0, _ln); + _ed = clamp(_ed, 0, _ln); + + if(_ed < _st) return; + var amo = _ed - _st + 1; + #endregion + + var ww = 0; + var hh = 0; + var _atl = []; + + #region surface generate + + switch(pack) { + case SPRITE_STACK.horizontal : + for(var i = _st; i <= _ed; i++) { + ww += surface_get_width_safe(inpt[i]); + if(i > _st) ww += spac; + hh = max(hh, surface_get_height_safe(inpt[i])); + } + break; + case SPRITE_STACK.vertical : + for(var i = _st; i <= _ed; i++) { + ww = max(ww, surface_get_width_safe(inpt[i])); + hh += surface_get_height_safe(inpt[i]); + if(i > _st) hh += spac; + } + break; + case SPRITE_STACK.grid : + var col = getInputData(4); + var row = ceil(amo / col); + + for(var i = 0; i < row; i++) { + var row_w = 0; + var row_h = 0; + + for(var j = 0; j < col; j++) { + var index = _st + i * col + j; + if(index > _ed) break; + + row_w += surface_get_width_safe(inpt[index]); + if(j) row_w += spc2[0]; + row_h = max(row_h, surface_get_height_safe(inpt[index])); + } + + ww = max(ww, row_w); + hh += row_h + if(i) hh += spc2[1]; + } + break; + } + + ww += padd[0] + padd[2]; + hh += padd[1] + padd[3]; + var _surf = surface_create_valid(ww, hh, cDep); + #endregion + + #region draw + surface_set_shader(_surf, noone); + + var curr_w = -1; + var curr_h = -1; + + switch(pack) { + case SPRITE_STACK.horizontal : + var px = padd[2]; + var py = padd[1]; + for(var i = _st; i <= _ed; i++) { + var _w = surface_get_width_safe(inpt[i]); + var _h = surface_get_height_safe(inpt[i]); + var _sx = px; + var _sy = py; + + curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + switch(alig) { + case 1 : _sy = py + (hh - _h) / 2; break; + case 2 : _sy = py + (hh - _h); break; + } + + array_push(_atl, new SurfaceAtlas(inpt[i], _sx, _sy)); + draw_surface_safe(inpt[i], _sx, _sy); + + px += _w + spac; + } + break; + case SPRITE_STACK.vertical : + var px = padd[2]; + var py = padd[1]; + for(var i = _st; i <= _ed; i++) { + var _w = surface_get_width_safe(inpt[i]); + var _h = surface_get_height_safe(inpt[i]); + var _sx = px; + var _sy = py; + + curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + switch(alig) { + case 1 : _sx = px + (ww - _w) / 2; break; + case 2 : _sx = px + (ww - _w); break; + } + + array_push(_atl, new SurfaceAtlas(inpt[i], _sx, _sy)); + draw_surface_safe(inpt[i], _sx, _sy); + + py += _h + spac; + } + break; + case SPRITE_STACK.grid : + var amo = array_length(inpt); + var col = getInputData(4); + var row = ceil(amo / col); + + var row_w = 0; + var row_h = 0; + var px = padd[2]; + var py = padd[1]; + + for(var i = 0; i < row; i++) { + row_w = 0; + row_h = 0; + px = padd[2]; + + for(var j = 0; j < col; j++) { + var index = _st + i * col + j; + if(index > _ed) break; + + var _w = surface_get_width_safe(inpt[index]); + var _h = surface_get_height_safe(inpt[index]); + + curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + array_push(_atl, new SurfaceAtlas(inpt[index], px, py)); + draw_surface_safe(inpt[index], px, py); + + px += _w + spc2[0]; + row_h = max(row_h, _h); + } + py += row_h + spc2[1]; + } + break; + } + + surface_reset_shader(); + #endregion + + outputs[| 0].setValue(_surf); + outputs[| 1].setValue(_atl); + } #endregion + + anim_curr_w = -1; + anim_curr_h = -1; + + static animationInit = function(clear = false) { #region + var inpt = getInputData(0); + var skip = getInputData(2); + var pack = getInputData(3); + var grid = getInputData(4); + var alig = getInputData(5); + var spac = getInputData(6); + var padd = getInputData(7); + var rang = getInputData(8); + var spc2 = getInputData(9); + //var ovlp = getInputData(10); + var user = getInputData(11); + + var _out = outputs[| 0].getValue(); + var _atl = outputs[| 1].getValue(); + var cDep = attrDepth(); + + printIf(log, $"Init animation"); + + var arr = is_array(inpt); + if(arr && array_length(inpt) == 0) return; + if(!arr) inpt = [ inpt ]; + + if(!is_array(_out)) _out = [ _out ]; + + #region frame + var _st = FIRST_FRAME; + var _ed = LAST_FRAME + 1; + + if(user) { + if(rang[0] < 0) _st = LAST_FRAME + rang[0] - 1; + else _st = rang[0] - 1; + + if(rang[1] < 0) _ed = LAST_FRAME + rang[1]; + else _ed = rang[1]; + } + + if(_ed <= _st) return; + var amo = floor((_ed - _st) / skip); + #endregion + + var skip = getInputData(2); + + var ww = 1, hh = 1; + + for(var i = 0; i < array_length(inpt); i++) { + var _surfi = inpt[i]; + if(!is_surface(_surfi)) continue; + + _atl[i] = []; + + var sw = surface_get_width_safe(_surfi); + var sh = surface_get_height_safe(_surfi); + ww = sw; + hh = sh; + + anim_curr_w = sw; + anim_curr_h = sh; + + switch(pack) { + case SPRITE_STACK.horizontal : + ww = sw * amo + spac * (amo - 1); + break; + case SPRITE_STACK.vertical : + hh = sh * amo + spac * (amo - 1); + break; + case SPRITE_STACK.grid : + var row = ceil(amo / grid); + + ww = sw * grid + spc2[0] * (grid - 1); + hh = sh * row + spc2[1] * (row - 1); + break; + } + + ww += padd[0] + padd[2]; + hh += padd[1] + padd[3]; + + _out[i] = surface_verify(array_safe_get_fast(_out, i), surface_valid_size(ww), surface_valid_size(hh), cDep); + + if(clear) surface_clear(_out[i]); + } + + if(!arr) _out = array_safe_get_fast(_out, 0); + outputs[| 0].setValue(_out); + outputs[| 1].setValue(_atl); + + printIf(log, $"Surface generated [{ww}, {hh}]"); + } #endregion + + static animationRender = function() { #region + var inpt = getInputData(0); + var skip = getInputData(2); + var pack = getInputData(3); + var grid = getInputData(4); + var alig = getInputData(5); + var spac = getInputData(6); + var padd = getInputData(7); + var rang = getInputData(8); + var spc2 = getInputData(9); + //var ovlp = getInputData(10); + var user = getInputData(11); + + var _atl = outputs[| 1].getValue(); + var cDep = attrDepth(); + + printIf(log, $"Rendering animation {name}/{CURRENT_FRAME}"); + + var arr = is_array(inpt); + if(arr && array_length(inpt) == 0) return; + if(!arr) inpt = [ inpt ]; + + #region frame + var _st = FIRST_FRAME; + var _ed = LAST_FRAME + 1; + + if(user) { + if(rang[0] < 0) _st = LAST_FRAME + rang[0] - 1; + else _st = rang[0] - 1; + + if(rang[1] < 0) _ed = LAST_FRAME + rang[1] + 1; + else _ed = rang[1] + 1; + } + + if(_ed <= _st) return; + var amo = floor((_ed - _st) / skip); + #endregion + + if(safe_mod(CURRENT_FRAME - _st, skip) != 0) { + printIf(log, $" > Skip frame"); + return; + } + + #region check overlap + if(array_length(anim_drawn) != TOTAL_FRAMES) + array_resize(anim_drawn, TOTAL_FRAMES); + + if(CURRENT_FRAME >= 0 && CURRENT_FRAME < TOTAL_FRAMES && anim_drawn[CURRENT_FRAME]) { + printIf(log, $" > Skip drawn"); + return; + } + #endregion + + var oupt = outputs[| 0].getValue(); + var _frame = floor((CURRENT_FRAME - _st) / skip); + var drawn = false; + var px = padd[2]; + var py = padd[1]; + + for(var i = 0; i < array_length(inpt); i++) { #region + var _surfi = inpt[i]; + + if(!is_surface(_surfi)) { + printIf(log, $" > Skip input not surface"); + _atl[i] = noone; + break; + } + + if(!is_array(array_safe_get_fast(_atl, i))) + _atl[i] = []; + var _atli = _atl[i]; + + var oo = noone; + if(!is_array(oupt)) oo = oupt; + else oo = oupt[i]; + + if(!is_surface(oo)) { + printIf(log, $" > Skip output not surface"); + break; + } + + var ww = surface_get_width_safe(oo); + var hh = surface_get_height_safe(oo); + + var _w = surface_get_width_safe(_surfi); + var _h = surface_get_height_safe(_surfi); + + if(anim_curr_w != _w || anim_curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + + var px; + var _sx = 0; + var _sy = 0; + + switch(pack) { + case SPRITE_STACK.horizontal : + px = padd[2] + _frame * _w + max(0, _frame) * spac; + _sx = px; + _sy = py; + + switch(alig) { + case 1 : _sy = py + (hh - _h) / 2; break; + case 2 : _sy = py + (hh - _h); break; + } + + break; + case SPRITE_STACK.vertical : + py = padd[1] + _frame * _h + max(0, _frame) * spac; + _sx = px; + _sy = py; + + switch(alig) { + case 1 : _sx = px + (ww - _w) / 2; break; + case 2 : _sx = px + (ww - _w); break; + } + + break; + case SPRITE_STACK.grid : + var col = getInputData(4); + var _row = floor(_frame / col); + var _col = safe_mod(_frame, col); + + _sx = px + _col * _w + max(0, _col) * spc2[0]; + _sy = py + _row * _h + max(0, _row) * spc2[1]; + break; + } + + surface_set_shader(oo, noone, false, BLEND.over); + + printIf(log, $" > Drawing frame ({CURRENT_FRAME}) {_surfi} at {_sx}, {_sy}"); + + _atli[i] = new SurfaceAtlas(_surfi, _sx, _sy); + draw_surface(_surfi, _sx, _sy); + + surface_reset_shader(); + + drawn = true; + } #endregion + + if(drawn) array_safe_set(anim_drawn, CURRENT_FRAME, true); + outputs[| 1].setValue(_atl); + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_seperate_shape/node_seperate_shape.gml.backup0 b/#backups/scripts/node_seperate_shape/node_seperate_shape.gml.backup0 new file mode 100644 index 000000000..c64f2f539 --- /dev/null +++ b/#backups/scripts/node_seperate_shape/node_seperate_shape.gml.backup0 @@ -0,0 +1,156 @@ +// 2024-04-30 15:26:36 +function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Separate Shape"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) + .rejectArray(); + + inputs[| 1] = nodeValue("Tolerance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.2) + .setDisplay(VALUE_DISPLAY.slider, { range: [ 0, 1, 0.01 ], update_stat: SLIDER_UPDATE.release }) + .rejectArray(); + + inputs[| 2] = nodeValue("Override color", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) + .rejectArray(); + + inputs[| 3] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white) + .rejectArray(); + + inputs[| 4] = nodeValue("Ignore blank", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true, "Skip empty and black shape.") + .rejectArray(); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Atlas", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); + + input_display_list = [ + ["Shape", false], 0, 1, 4, + ["Override Color", true, 2], 3, + ] + + temp_surface = [ noone, noone ]; + surface_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2); + surface_w = 1; + surface_h = 1; + + _prev_type = -1; + + static onInspector1Update = function() { separateShape(); } + + static update = function() { + separateShape(); + } + + static separateShape = function() { + var _inSurf = getInputData(0); + var _thres = getInputData(1); + var _ovr = getInputData(2); + var _ovrclr = getInputData(3); + var _ignore = getInputData(4); + var t = current_time; + + if(!is_surface(_inSurf)) return; + + var ww = surface_get_width_safe(_inSurf); + var hh = surface_get_height_safe(_inSurf); + + for(var i = 0; i < 2; i++) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, surface_rgba32float); + + #region region indexing + surface_set_shader(temp_surface[1], sh_seperate_shape_index); + shader_set_i("ignore", _ignore); + shader_set_f("dimension", ww, hh); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, ww, hh); + surface_reset_shader(); + + shader_set(sh_seperate_shape_ite); + shader_set_i("ignore", _ignore); + shader_set_f("dimension", ww, hh); + shader_set_f("threshold", _thres); + shader_set_surface("map", _inSurf); + shader_reset(); + + var res_index = 0, iteration = ww + hh; + for(var i = 0; i <= iteration; i++) { + var bg = i % 2; + var fg = !bg; + + surface_set_shader(temp_surface[bg], sh_seperate_shape_ite,, BLEND.over); + draw_surface_safe(temp_surface[fg]); + surface_reset_shader(); + + res_index = bg; + } + #endregion + + #region count and match color + var i = 0, pxc = ww * hh; + var reg = ds_map_create(); + + var b = buffer_create(pxc * 16, buffer_fixed, 1); + buffer_get_surface(b, temp_surface[res_index], 0); + buffer_seek(b, buffer_seek_start, 0); + + repeat(pxc) { + var _r = buffer_read(b, buffer_f32); + var _g = buffer_read(b, buffer_f32); + var _b = buffer_read(b, buffer_f32); + var _a = buffer_read(b, buffer_f32); + + if(_r == 0 && _g == 0 && _b == 0 && _a == 0) continue; + + reg[? _g * ww + _r] = [ _r, _g, _b, _a ]; + } + + var px = ds_map_size(reg); + if(px == 0) return; + #endregion + + #region extract region + var _outSurf, _val; + _val = array_create(px); + + var _atlas = array_create(px); + var _reg = ds_map_keys_to_array(reg); + var _ind = 0; + + for(var i = 0; i < px; i++) { + var _k = _reg[i]; + var ccx = reg[? _k]; + + var min_x = round(ccx[0]); + var min_y = round(ccx[1]); + var max_x = round(ccx[2]); + var max_y = round(ccx[3]); + + var _sw = max_x - min_x + 1; + var _sh = max_y - min_y + 1; + + if(_sw <= 1 || _sh <= 1) continue; + + _outSurf = surface_create_valid(_sw, _sh); + _val[_ind] = _outSurf; + + surface_set_shader(_outSurf, sh_seperate_shape_sep); + shader_set_surface("original", _inSurf); + shader_set_f("color", ccx); + shader_set_i("override", _ovr); + shader_set_color("overColor", _ovrclr); + + draw_surface_safe(temp_surface[res_index], -min_x, -min_y); + surface_reset_shader(); + + _atlas[_ind] = new SurfaceAtlas(_outSurf, min_x, min_y).setOrginalSurface(_inSurf); + _ind++; + } + + array_resize(_val, _ind); + array_resize(_atlas, _ind); + + ds_map_destroy(reg); + + outputs[| 0].setValue(_val); + outputs[| 1].setValue(_atlas); + #endregion + } +} \ No newline at end of file diff --git a/#backups/scripts/node_seperate_shape/node_seperate_shape.gml.backup1 b/#backups/scripts/node_seperate_shape/node_seperate_shape.gml.backup1 new file mode 100644 index 000000000..4b6e29f44 --- /dev/null +++ b/#backups/scripts/node_seperate_shape/node_seperate_shape.gml.backup1 @@ -0,0 +1,156 @@ +// 2024-04-30 15:03:23 +function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Separate Shape"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) + .rejectArray(); + + inputs[| 1] = nodeValue("Tolerance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.2) + .setDisplay(VALUE_DISPLAY.slider, { range: [ 0, 1, 0.01 ], update_stat: SLIDER_UPDATE.release }) + .rejectArray(); + + inputs[| 2] = nodeValue("Override color", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) + .rejectArray(); + + inputs[| 3] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white) + .rejectArray(); + + inputs[| 4] = nodeValue("Ignore blank", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true, "Skip empty and black shape.") + .rejectArray(); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Atlas", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); + + input_display_list = [ + ["Shape", false], 0, 1, 4, + ["Override Color", true, 2], 3, + ] + + temp_surface = [ noone, noone ]; + surface_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2); + surface_w = 1; + surface_h = 1; + + _prev_type = -1; + + static onInspector1Update = function() { separateShape(); } + + static update = function() { + separateShape(); + } + + static separateShape = function() { + var _inSurf = getInputData(0); + var _thres = getInputData(1); + var _ovr = getInputData(2); + var _ovrclr = getInputData(3); + var _ignore = getInputData(4); + var t = current_time; + + if(!is_surface(_inSurf)) return; + + var ww = surface_get_width_safe(_inSurf); + var hh = surface_get_height_safe(_inSurf); + + for(var i = 0; i < 2; i++) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, surface_rgba32float); + + #region region indexing + surface_set_shader(temp_surface[1], sh_seperate_shape_index); + shader_set_i("ignore", _ignore); + shader_set_f("dimension", ww, hh); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, ww, hh); + surface_reset_shader(); + + shader_set(sh_seperate_shape_ite); + shader_set_i("ignore", _ignore); + shader_set_f("dimension", ww, hh); + shader_set_f("threshold", _thres); + shader_set_surface("map", _inSurf); + shader_reset(); + + var res_index = 0, iteration = ww + hh; + for(var i = 0; i <= iteration; i++) { + var bg = i % 2; + var fg = !bg; + + surface_set_shader(temp_surface[bg], sh_seperate_shape_ite,, BLEND.over); + draw_surface_safe(temp_surface[fg]); + surface_reset_shader(); + + res_index = bg; + } + #endregion + + #region count and match color + var i = 0, pxc = ww * hh; + var reg = ds_map_create(); + + var b = buffer_create(pxc * 16, buffer_fixed, 1); + buffer_get_surface(b, temp_surface[res_index], 0); + buffer_seek(b, buffer_seek_start, 0); + + repeat(pxc) { + var _r = buffer_read(b, buffer_f32); + var _g = buffer_read(b, buffer_f32); + var _b = buffer_read(b, buffer_f32); + var _a = buffer_read(b, buffer_f32); + + if(_r == 0 && _g == 0 && _b == 0 && _a == 0) continue; + + reg[? _g * ww + _r] = [ _r, _g, _b, _a ]; + } + + var px = ds_map_size(reg); + if(px == 0) return; + #endregion + + #region extract region + var _outSurf, _val; + _val = array_create(px); + + var _atlas = array_create(px); + var _reg = ds_map_keys_to_array(reg); + var _ind = 0; + + for(var i = 0; i < px; i++) { + var _k = _reg[i]; + var ccx = reg[? _k]; + + var min_x = round(ccx[0]); + var min_y = round(ccx[1]); + var max_x = round(ccx[2]); + var max_y = round(ccx[3]); + + var _sw = max_x - min_x + 1; + var _sh = max_y - min_y + 1; + + if(_sw <= 1 || _sh <= 1) continue; + + _outSurf = surface_create_valid(_sw, _sh); + _val[_ind] = _outSurf; + + surface_set_shader(_outSurf, sh_seperate_shape_sep); + shader_set_surface("original", _inSurf); + shader_set_f("color", ccx); + shader_set_i("override", _ovr); + shader_set_color("overColor", _ovrclr); + + draw_surface_safe(temp_surface[res_index], -min_x, -min_y); + surface_reset_shader(); + + _atlas[_ind] = new SurfaceAtlas(_outSurf, min_x, min_y).setOrginalSurface(_inSurf); + _ind++; + } + + array_resize(_val, _ind); + array_resize(_atlas, _ind); + + ds_map_destroy(reg); + + outputs[| 0].setValue(_val); + outputs[| 1].setValue(_atlas); + #endregion + } +} \ No newline at end of file diff --git a/#backups/scripts/pack_best_fit/pack_best_fit.gml.backup0 b/#backups/scripts/pack_best_fit/pack_best_fit.gml.backup0 new file mode 100644 index 000000000..dfd4f11ec --- /dev/null +++ b/#backups/scripts/pack_best_fit/pack_best_fit.gml.backup0 @@ -0,0 +1,60 @@ +// 2024-04-30 15:18:09 +function sprite_pack_best_fit(rectangles) { + + var area = new Rectangle(0, 0, 0, 0); + if(array_length(rectangles) <= 1) return [ area, rectangles ]; + + array_sort(rectangles, function(rect1, rect2) { return rect2.w * rect2.h - rect1.w * rect1.h; }); + + var grW = rectangles[0].w; + var grH = rectangles[0].h; + var _or, _nr; + + for (var i = 1; i < array_length(rectangles); i++) { + _nr = rectangles[i]; + + grW = gcd(_nr.w, grW); + grH = gcd(_nr.h, grH); + } + + for (var i = 0; i < array_length(rectangles); i++) { + var rect = rectangles[i]; + + var bestSpace = noone; + var bestArea = new Rectangle(0, 0, 0, 0); + + for (var xx = area.x; xx <= area.x + area.w; xx += grW) + for (var yy = area.y; yy <= area.y + area.h; yy += grH) { + var space = new Rectangle(xx, yy, rect.w, rect.h); + if (space.x + space.w > area.x + area.w || space.y + space.h > area.y + area.h) + continue; + + var overlaps = false; + for (var j = 0; j < i; j++) { + var otherRect = rectangles[j]; + if (rectangleOverlap(space, otherRect)) { + overlaps = true; + break; + } + } + + if (!overlaps && (bestSpace == noone || space.w * space.h < bestSpace.w * bestSpace.h)) { + bestSpace = space; + bestArea = new Rectangle(area.x, area.y, area.w, area.h); + } + } + + if (bestSpace == noone) { + area.w = max(area.w, rect.w); + area.h += rect.h; + rectangles[i].x = area.x; + rectangles[i].y = area.y + area.h - rect.h; + } else { + rectangles[i].x = bestSpace.x; + rectangles[i].y = bestSpace.y; + area = bestArea; + } + } + + return [ area, rectangles ]; +} diff --git a/#backups/scripts/pack_best_fit/pack_best_fit.gml.backup1 b/#backups/scripts/pack_best_fit/pack_best_fit.gml.backup1 new file mode 100644 index 000000000..8c5130235 --- /dev/null +++ b/#backups/scripts/pack_best_fit/pack_best_fit.gml.backup1 @@ -0,0 +1,60 @@ +// 2024-04-30 15:18:08 +function sprite_pack_best_fit(rectangles) { + + var area = new Rectangle(0, 0, 0, 0); + if(array_length(rectangles) <= 1) return [ area, rectangles ]; + + array_sort(rectangles, function(rect1, rect2) { return rect2.w * rect2.h - rect1.w * rect1.h; }); + + var grW = rectangles[0].w; + var grH = rectangles[0].h; + var _or, _nr; + + for (var i = 1; i < array_length(rectangles); i++) { + _nr = rectangles[i]; + + grW = gcd(_nr.w, grW); + grH = gcd(_nr.h, grH); + } + + for (var i = 0; i < array_length(rectangles); i++) { + var rect = rectangles[i]; + + var bestSpace = noone; + var bestArea = new Rectangle(0, 0, 0, 0); + + for (var xx = area.x; xx <= area.x + area.w; xx += grW) + for (var yy = area.y; yy <= area.y + area.h; yy += grH) { + var space = new Rectangle(xx, yy, rect.w, rect.h); + if (space.x + space.w > area.x + area.w || space.y + space.h > area.y + area.h) + continue; + + var overlaps = false; + for (var j = 0; j < i; j++) { + var otherRect = rectangles[j]; + if (rectangleOverlap(space, otherRect)) { + overlaps = true; + break; + } + } + + if (!overlaps && (bestSpace == noone || space.w * space.h < bestSpace.w * bestSpace.h)) { + bestSpace = space; + bestArea = new Rectangle(area.x, area.y, area.w, area.h); + } + } + + if (bestSpace == noone) { + area.w = max(area.w, rect.w); + area.h += rect.h; + rectangles[i].x = area.x; + rectangles[i].y = area.y + area.h - rect.h; + } else { + rectangles[i].x = bestSpace.x; + rectangles[i].y = bestSpace.y; + area = bestArea; + } + } + + return [ area, rectangles ]; +} diff --git a/#backups/scripts/panel_data/panel_data.gml.backup0 b/#backups/scripts/panel_data/panel_data.gml.backup0 new file mode 100644 index 000000000..110920e3e --- /dev/null +++ b/#backups/scripts/panel_data/panel_data.gml.backup0 @@ -0,0 +1,969 @@ +// 2024-04-30 12:45:18 +enum ANCHOR { + none = 0, + top = 1, + bottom = 2, + left = 4, + right = 8 +} + +function Panel(_parent, _x, _y, _w, _h) constructor { #region + parent = _parent; + if(parent) ds_list_add(parent.childs, self); + + padding = THEME_VALUE.panel_margin; + content = []; + content_index = 0; + childs = ds_list_create(); + anchor = ANCHOR.none; + + x = _x; + y = _y; + w = _w; + h = _h; + tx = x; + ty = y; + tw = w; + th = h; + split = ""; + + tab_width = 0; + tab_height = ui(24); + tab_x = 0; + tab_x_to = 0; + tab_surface = noone; + + min_w = ui(40); + min_h = ui(40); + + dragging = -1; + drag_sval = 0; + drag_sm = 0; + mouse_active = true; + + content_surface = surface_create_valid(w, h); + mask_surface = surface_create_valid(w, h); + + tab_holding = noone; + tab_hold_state = 0; + tab_holding_mx = 0; + tab_holding_my = 0; + tab_holding_sx = 0; + tab_holding_sy = 0; + tab_cover = noone; + + border_rb_close = menuItem(__txt("Close"), function() { #region + var con = getContent(); + if(con == noone) return; + con.close(); + }, THEME.cross); #endregion + + border_rb_menu = [ #region + menuItem(__txt("Move"), function() { + extract(); + panel_mouse = 1; + }), + menuItem(__txtx("panel_pop_out", "Pop out"), function() { popWindow(); }, THEME.node_goto), + border_rb_close + ]; #endregion + + static getContent = function() { return array_safe_get_fast(content, content_index, noone); } + static hasContent = function() { return bool(array_length(content)); } + + function resetMask() { #region + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + + content_surface = surface_verify(content_surface, tw, th); + mask_surface = surface_verify(mask_surface, tw, th); + surface_set_target(mask_surface); + draw_clear(c_black); + gpu_set_blendmode(bm_subtract); + draw_sprite_stretched(THEME.ui_panel_bg, 0, padding, padding, tw - padding * 2, th - padding * 2); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + } resetMask(); #endregion + + function setPadding(padding) { #region + self.padding = padding; + refresh(); + } #endregion + + function refresh() { #region + resetMask(); + + for( var i = 0, n = array_length(content); i < n; i++ ) + content[i].refresh(); + + for( var i = 0; i < ds_list_size(childs); i++ ) + childs[| i].refresh(); + } #endregion + + function move(dx, dy) { #region + x += dx; + y += dy; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + _panel.move(dx, dy); + } + + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].x = x; + content[i].y = y; + } + } #endregion + + function resizable(dw, dh, oppose = ANCHOR.left) { #region + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + + var hori = oppose == ANCHOR.left || oppose == ANCHOR.right; + + if(hasContent()) { + var res = true; + for( var i = 0, n = array_length(content); i < n; i++ ) + res &= hori? tw + dw > content[i].min_w : th + dh > content[i].min_h; + return res; + } + + var _c0 = ds_list_get(childs, 0, noone); + var _c1 = ds_list_get(childs, 1, noone); + + if(_c0 == noone || _c1 == noone) return false; + + var ind = hori? _c1.w > _c0.w : _c1.h > _c0.h; + return childs[| ind].resizable(dw, dh, oppose); + } #endregion + + function refreshSize(recur = true) { #region //refresh content surface after resize + //__debug_counter("refresh size"); + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].w = max(tw, content[i].min_w); + content[i].h = max(th, content[i].min_h); + content[i].onResize(); + } + + if(ds_list_size(childs) == 2) { + //print("=== Refreshing (" + string(w) + ", " + string(h) + ") " + string(split) + " ==="); + + var _tw = childs[| 0].w + childs[| 1].w; + var _th = childs[| 0].h + childs[| 1].h; + + var fixChild = split == "h"? childs[| 1].x < childs[| 0].x : childs[| 1].y < childs[| 0].y; + + childs[| fixChild].x = x; + childs[| fixChild].y = y; + + if(split == "h") { + childs[| fixChild].w = round(childs[| fixChild].w / _tw * w); + childs[| fixChild].h = round(h); + + childs[| !fixChild].x = x + childs[| fixChild].w; + childs[| !fixChild].y = y; + + childs[| !fixChild].w = round(w - childs[| fixChild].w); + childs[| !fixChild].h = round(h); + + childs[| fixChild].anchor = ANCHOR.left; + childs[| !fixChild].anchor = ANCHOR.right; + } else if(split == "v") { + childs[| fixChild].w = round(w); + childs[| fixChild].h = round(childs[| fixChild].h / _th * h); + + childs[| !fixChild].x = x; + childs[| !fixChild].y = y + childs[| fixChild].h; + + childs[| !fixChild].w = round(w); + childs[| !fixChild].h = round(h - childs[| fixChild].h); + + childs[| fixChild].anchor = ANCHOR.top; + childs[| !fixChild].anchor = ANCHOR.bottom; + } + + if(recur) + for(var i = 0; i < ds_list_size(childs); i++) + childs[| i].refreshSize(); + } + + refresh(); + } #endregion + + function resize(dw, dh, oppose = ANCHOR.left) { #region + if(dw == 0 && dh == 0) return; + + if(ds_list_size(childs) == 2) { + var hori = oppose == ANCHOR.left || oppose == ANCHOR.right; + var ind = hori? childs[| 1].w > childs[| 0].w : childs[| 1].h > childs[| 0].h; + childs[| ind].resize(dw, dh, oppose); + } + + w = max(round(w + dw), min_w); + h = max(round(h + dh), min_h); + + refreshSize(false); + } #endregion + + function setContent(_content = noone, _switch = false) { #region + if(is_array(_content)) + content = array_append(content, _content); + else + array_push(content, _content); + + for( var i = 0, n = array_length(content); i < n; i++ ) + content[i].onSetPanel(self); + + if(_switch) setTab(array_find(content, _content)); + + refresh(); + } #endregion + + function switchContent(_content) { #region + var _ind = array_find(content, _content); + if(_ind == -1) return; + setTab(_ind); + } #endregion + + function split_h(_w) { #region + if(abs(_w) > w) { + print("Error: Split panel larger than size w (" + string(_w) + " > " + string(w) + ")"); + return noone; + } + + if(_w < 0) _w = w + _w; + var _panelParent = new Panel(parent, x, y, w, h); + _panelParent.anchor = anchor; + _panelParent.split = "h"; + + var _panelL = self; + ds_list_add(_panelParent.childs, _panelL); + + var _panelR = new Panel(_panelParent, x + _w, y, w - _w, h); + _panelR.anchor = ANCHOR.right; + + var prev_w = w; + w = _w; + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].w = w; + content[i].onResize(); + } + + if(parent == noone) + PANEL_MAIN = _panelParent; + else + ds_list_delete(parent.childs, ds_list_find_index(parent.childs, self)); + + parent = _panelParent; + anchor = ANCHOR.left; + content = []; + + return [ _panelL, _panelR ]; + } #endregion + + function split_v(_h) { #region + if(abs(_h) > h) { + print("Error: Split panel larger than size h (" + string(_h) + " > " + string(h) + ")"); + return noone; + } + + if(_h < 0) _h = h + _h; + var _panelParent = new Panel(parent, x, y, w, h); + _panelParent.anchor = anchor; + _panelParent.split = "v"; + + var _panelT = self; + ds_list_add(_panelParent.childs, _panelT); + var _panelB = new Panel(_panelParent, x, y + _h, w, h - _h); + _panelB.anchor = ANCHOR.bottom; + + var prev_h = h; + h = _h; + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].h = h; + content[i].onResize(); + } + + if(parent == noone) + PANEL_MAIN = _panelParent; + else + ds_list_delete(parent.childs, ds_list_find_index(parent.childs, self)); + + parent = _panelParent; + anchor = ANCHOR.top; + content = []; + + return [_panelT, _panelB]; + } #endregion + + function stepBegin() { #region + var con = getContent(); + if(FULL_SCREEN_CONTENT != noone && con == FULL_SCREEN_CONTENT && self != FULL_SCREEN_PARENT) return; + + for( var i = 0, n = array_length(content); i < n; i++ ) + content[i].panelStepBegin(self); + + if(o_main.panel_dragging != noone) dragging = -1; + + if(dragging == 1) { + var _mx = clamp(mouse_mx, ui(16), WIN_W - ui(16)); + var dw = round(_mx - drag_sm); + var res = true; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.left: + res &= _panel.resizable(dw, 0, ANCHOR.left); + break; + case ANCHOR.right: + res &= _panel.resizable(-dw, 0, ANCHOR.right); + break; + } + } + + if(res) { + drag_sm = _mx; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.left: + _panel.resize(dw, 0, ANCHOR.left); + break; + case ANCHOR.right: + _panel.resize(-dw, 0, ANCHOR.right); + _panel.move(dw, 0); + break; + } + } + } + + if(mouse_release(mb_left)) { + refreshSize(); + dragging = -1; + } + } else if(dragging == 2) { + var _my = clamp(mouse_my, ui(16), WIN_H - ui(16)); + var dh = round(_my - drag_sm); + var res = true; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.top: + res &= _panel.resizable(0, dh, ANCHOR.top); + break; + case ANCHOR.bottom: + res &= _panel.resizable(0, -dh, ANCHOR.bottom); + break; + } + } + + if(res) { + drag_sm = _my; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.top: + _panel.resize(0, dh, ANCHOR.top); + break; + case ANCHOR.bottom: + _panel.resize(0, -dh, ANCHOR.bottom); + _panel.move(0, dh); + break; + } + } + } + + if(mouse_release(mb_left)) { + refreshSize(); + dragging = -1; + } + } else { + if(con && point_in_rectangle(mouse_mx, mouse_my, x + ui(2), y + ui(2), x + w - ui(4), y + h - ui(4))) { + HOVER = self; + if(mouse_press(mb_any)) + setFocus(self); + if(FOCUS == self && con) + FOCUS_STR = con.context_str; + } else { + for(var i = 0; i < ds_list_size(childs); i++) + childs[| i].stepBegin(); + } + } + } #endregion + + static step = function() { #region + for(var i = 0; i < ds_list_size(childs); i++) + childs[| i].step(); + } #endregion + + static draw = function() { #region + if(hasContent()) { + drawPanel(); + return; + } + + if(ds_list_empty(childs)) + return; + + var min_w = ui(32); + var min_h = ui(32); + if(split == "h") { + min_w = childs[| 0].min_w + childs[| 1].min_w; + min_h = max(childs[| 0].min_h + childs[| 1].min_h); + } else { + min_w = max(childs[| 0].min_w, childs[| 1].min_w); + min_h = childs[| 0].min_h + childs[| 1].min_h; + } + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + _panel.draw(); + + if!(HOVER == noone || is_struct(HOVER)) + continue; + + var p = ui(6 - 1); + switch(_panel.anchor) { + case ANCHOR.left : + if(!point_in_rectangle(mouse_mx, mouse_my, _panel.x + _panel.w - p, _panel.y, _panel.x + _panel.w + p, _panel.y + _panel.h)) + break; + + CURSOR = cr_size_we; + if(mouse_press(mb_left)) { + dragging = 1; + drag_sval = _panel.w; + drag_sm = mouse_mx; + } + break; + case ANCHOR.top : + if(!point_in_rectangle(mouse_mx, mouse_my, _panel.x, _panel.y + _panel.h - p, _panel.x + _panel.w, _panel.y + _panel.h + p)) + break; + + CURSOR = cr_size_ns; + if(mouse_press(mb_left)) { + dragging = 2; + drag_sval = _panel.h; + drag_sm = mouse_my; + } + break; + } + } + + if(self == PANEL_MAIN && o_main.panel_dragging != noone && key_mod_press(CTRL)) + checkHover(); + } #endregion + + function drawTab() { #region + tab_surface = surface_verify(tab_surface, w - padding * 2 + 1, tab_height + ui(4)); + + var tsx = x + padding - 1; + var tsy = y + ui(2); + var msx = mouse_x - tsx; + var msy = mouse_y - tsy; + tab_cover = noone; + + surface_set_target(tab_surface); + DRAW_CLEAR + + var tbx = tab_x + ui(1); + var tby = 0; + var tbh = tab_height + ui(2); + var tabHov = msx < 0 ? 0 : array_length(content) - 1; + + tab_x = lerp_float(tab_x, tab_x_to, 5); + tab_width = 0; + + var rem = -1; + + draw_set_text(f_p3, fa_left, fa_bottom, COLORS._main_text_sub); + for( var i = 0, n = array_length(content); i < n; i++ ) { + var txt = content[i].title; + var icn = content[i].icon; + + var tbw = string_width(txt) + ui(16 + 16); + if(icn != noone) tbw += ui(16 + 4); + var foc = false; + + tab_width += tbw + ui(2); + if(msx >= tbx && msy <= tbx + tbw) + tabHov = i; + + if(tab_holding == content[i]) { + tbx += tbw + ui(2); + continue; + } + + content[i].tab_x = content[i].tab_x == 0? tbx : lerp_float(content[i].tab_x, tbx, 5); + var _tbx = content[i].tab_x; + var _hov = point_in_rectangle(msx, msy, _tbx, tby, _tbx + tbw, tab_height); + var _tdh = tbh + THEME_VALUE.panel_tab_extend; + + if(i == content_index) { + foc = FOCUS == self; + var cc = FOCUS == self? COLORS._main_accent : COLORS.panel_tab; + draw_sprite_stretched_ext(THEME.ui_panel_tab, 1 + (FOCUS == self), _tbx, tby, tbw, _tdh, cc, 1); + if(!foc) + tab_cover = BBOX().fromWH(tsx + _tbx, tsy + tby + tbh - ui(3), tbw, THEME_VALUE.panel_tab_extend); + } else { + var cc = COLORS.panel_tab_inactive; + if(HOVER == self && _hov) + var cc = COLORS.panel_tab_hover; + + draw_sprite_stretched_ext(THEME.ui_panel_tab, 0, _tbx, tby, tbw, _tdh, cc, 1); + } + + var aa = 0.5; + if(point_in_rectangle(msx, msy, _tbx + tbw - ui(16), tby, _tbx + tbw, tab_height)) { + aa = 1; + if(mouse_press(mb_left, FOCUS == self)) + rem = i; + } else if(HOVER == self && _hov) { + if(mouse_press(mb_left, FOCUS == self)) { + setTab(i); + + tab_holding = content[i]; + tab_hold_state = 0; + tab_holding_mx = msx; + tab_holding_my = msy; + tab_holding_sx = tab_holding.tab_x; + } + + if(mouse_press(mb_right, FOCUS == self)) { + var menu = array_clone(border_rb_menu); + if(instanceof(content[i]) == "Panel_Menu") + array_remove(menu, 2); + + menuCall("panel_border_menu",,, menu); + } + + if(mouse_press(mb_middle, FOCUS == self)) + rem = i; + + if(DRAGGING) + setTab(i); + } + + draw_sprite_ui(THEME.tab_exit, 0, _tbx + tbw - ui(12), tab_height / 2 + 1,,,, foc? COLORS.panel_tab_icon : COLORS._main_text_sub, aa); + + if(icn != noone) { + draw_sprite_ui(icn, 0, _tbx + ui(8 + 8), tab_height / 2 + 1,,,, foc? COLORS.panel_tab_icon : COLORS._main_text_sub); + _tbx += ui(20); + } + + draw_set_text(f_p3, fa_left, fa_bottom, foc? COLORS.panel_tab_text : COLORS._main_text_sub); + draw_text_add(_tbx + ui(8), tab_height - ui(4), txt); + + tbx += tbw + ui(2); + } + + if(rem > -1) content[rem].close(); + + tab_width = max(0, tab_width - w + ui(32)); + if(point_in_rectangle(msx, msy, 0, 0, w, tab_height)) { + if(mouse_wheel_up()) tab_x_to = clamp(tab_x_to + ui(64) * SCROLL_SPEED, -tab_width, 0); + if(mouse_wheel_down()) tab_x_to = clamp(tab_x_to - ui(64) * SCROLL_SPEED, -tab_width, 0); + } + + if(tab_holding) { + draw_set_font(f_p3); + + var _tbx = tab_holding.tab_x; + var txt = tab_holding.title; + var icn = tab_holding.icon; + var tbw = string_width(txt) + ui(16 + 16); + if(icn != noone) tbw += ui(16 + 4); + + draw_sprite_stretched_ext(THEME.ui_panel_tab, 2, _tbx, tby, tbw, tbh, COLORS._main_accent, 1); + draw_sprite_ui(THEME.tab_exit, 0, _tbx + tbw - ui(12), tab_height / 2 + 1,,,, COLORS.panel_tab_icon); + + if(icn != noone) { + draw_sprite_ui(icn, 0, _tbx + ui(8 + 8), tab_height / 2 + 1,,,, COLORS.panel_tab_icon); + _tbx += ui(20); + } + draw_set_text(f_p3, fa_left, fa_bottom, COLORS.panel_tab_text); + draw_text_add(_tbx + ui(8), tab_height - ui(4), txt); + + if(tab_hold_state == 0) { + if(point_distance(tab_holding_mx, tab_holding_my, msx, msy) > 8) + tab_hold_state = 1; + } else if(tab_hold_state == 1) { + if(point_in_rectangle(msx, msy, 0, 0, w, tab_height)) { + if(msx < ui(32)) tab_x_to = clamp(tab_x_to + ui(2), -tab_width, 0); + if(msx > w - ui(32)) tab_x_to = clamp(tab_x_to - ui(2), -tab_width, 0); + } + + tab_holding.tab_x = clamp(tab_holding_sx + (msx - tab_holding_mx), 1, w - tbw - ui(4)); + + array_remove(content, tab_holding); + array_insert(content, tabHov, tab_holding); + setTab(array_find(content, tab_holding)); + + if(abs(msy - tab_holding_my) > ui(32)) { + extract(); + tab_holding = noone; + } + } + + if(mouse_release(mb_left)) + tab_holding = noone; + } + surface_reset_target(); + + draw_surface(tab_surface, tsx, tsy); + } #endregion + + function setTab(tabIndex, forceFocus = false) { #region + if(tabIndex < 0) return; + if(tabIndex >= array_length(content)) return; + if(content_index == tabIndex) { + if(forceFocus) content[tabIndex].onFocusBegin(); + return; + } + + var prec = array_safe_get_fast(content, content_index); + if(prec) prec.onFocusEnd(); + + content_index = tabIndex; + + var prec = array_safe_get_fast(content, content_index); + if(prec) prec.onFocusBegin(); + } #endregion + + function drawPanel() { #region + if(w <= ui(16)) return; + + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + if(th < ui(16)) return; + + var con = getContent(); + if(FULL_SCREEN_CONTENT != noone && con == FULL_SCREEN_CONTENT && self != FULL_SCREEN_PARENT) return; + + if(tab) drawTab(); + + var p = ui(6); + var m_in = point_in_rectangle(mouse_mx, mouse_my, tx + p, ty + p, tx + tw - p, ty + th - p); + var m_ot = point_in_rectangle(mouse_mx, mouse_my, tx, ty, tx + tw, ty + th); + mouse_active = m_in; + + var _tw = tw - padding * 2; + var _th = th - padding * 2; + draw_sprite_stretched(THEME.ui_panel_bg, 0, tx + padding, ty + padding, _tw, _th); + + if(!is_surface(mask_surface)) { + mask_surface = surface_create_valid(tw, th); + refresh(); + } + + content_surface = surface_verify(content_surface, tw, th); + + surface_set_target(content_surface); + draw_clear(COLORS.panel_bg_clear); + + if(con) { + min_w = con.min_w; + min_h = con.min_h; + if(tw >= min_w && th >= min_h) + con.draw(self); + else { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text(tw / 2, th / 2, "Panel too small for content"); + } + } else { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text(tw / 2, th / 2, "No content"); + } + + gpu_set_blendmode(bm_subtract); + draw_surface_safe(mask_surface, 0, 0); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + + draw_surface_safe(content_surface, tx, ty); + draw_sprite_stretched(THEME.ui_panel_fg, 0, tx + padding, ty + padding, _tw, _th); + if(tab) draw_sprite_bbox(THEME.ui_panel_tab, 3, tab_cover); + + if(FOCUS == self && parent != noone) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, COLORS._main_accent, 1); + + if(hasContent() && !m_in && m_ot) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, c_white, 0.4); + + if(DOUBLE_CLICK) { + extract(); + panel_mouse = 0; + } else if(mouse_press(mb_right)) { + var menu = array_clone(border_rb_menu); + if(instanceof(getContent()) == "Panel_Menu") + array_remove(menu, 2, border_rb_close); + + menuCall("panel_border_menu",,, menu); + } + } + } + + if(o_main.panel_dragging != noone && m_ot && !key_mod_press(CTRL)) + checkHover(); + } #endregion + + function drawGUI() { #region + for( var i = 0; i < ds_list_size(childs); i++ ) + childs[| i].drawGUI(); + + var con = getContent(); + if(con == noone) return; + con.drawGUI(); + } #endregion + + function extract() { #region + var con = getContent(); + con.dragSurface = surface_clone(content_surface); + o_main.panel_dragging = con; + + array_remove(content, con); + refresh(); + setTab(0); + + HOVER = noone; + FOCUS = noone; + + if(hasContent()) return; + var ind = !ds_list_find_index(parent.childs, self); //index of the other child + var sib = parent.childs[| ind]; + + if(!sib.hasContent() && ds_list_size(sib.childs) == 2) { //other child is compound panel + var gparent = parent.parent; + if(gparent == noone) { + sib.x = PANEL_MAIN.x; sib.y = PANEL_MAIN.y; + sib.w = PANEL_MAIN.w; sib.h = PANEL_MAIN.h; + + PANEL_MAIN = sib; + sib.parent = noone; + PANEL_MAIN.refreshSize(); + } else { + var pind = ds_list_find_index(gparent.childs, parent); //index of parent in grandparent object + gparent.childs[| pind] = sib; //replace parent with sibling + sib.parent = gparent; + gparent.refreshSize(); + } + } else if(sib.hasContent()) { //other child is content panel, set parent to content panel + parent.setContent(sib.content); + ds_list_clear(parent.childs); + } + } #endregion + + function popWindow() { #region + var con = getContent(); + if(con == noone) return; + + dialogPanelCall(con); + extract(); + o_main.panel_dragging = noone; + } #endregion + + function checkHover() { #region + var dx = (mouse_mx - x) / w; + var dy = (mouse_my - y) / h; + var p = ui(8); + + draw_set_color(COLORS._main_accent); + o_main.panel_hovering = self; + + var x0 = x + p; + var y0 = y + p; + var x1 = x + w - p; + var y1 = y + h - p; + var xc = x + w / 2; + var yc = y + h / 2; + + if(point_in_rectangle(mouse_mx, mouse_my, x + w * 1 / 3, y + h * 1 / 3, x + w * 2 / 3, y + h * 2 / 3)) { + o_main.panel_split = 4; + + o_main.panel_draw_x0_to = x + w * 1 / 3; + o_main.panel_draw_y0_to = y + h * 1 / 3; + o_main.panel_draw_x1_to = x + w * 2 / 3; + o_main.panel_draw_y1_to = y + h * 2 / 3; + } else { + if(dx + dy > 1) { + if((1 - dx) + dy > 1) { + o_main.panel_draw_x0_to = x0; + o_main.panel_draw_y0_to = yc; + o_main.panel_draw_x1_to = x1; + o_main.panel_draw_y1_to = y1; + + o_main.panel_split = 3; + } else { + o_main.panel_draw_x0_to = xc; + o_main.panel_draw_y0_to = y0; + o_main.panel_draw_x1_to = x1; + o_main.panel_draw_y1_to = y1; + + o_main.panel_split = 1; + } + } else { + if((1 - dx) + dy > 1) { + o_main.panel_draw_x0_to = x0; + o_main.panel_draw_y0_to = y0; + o_main.panel_draw_x1_to = xc; + o_main.panel_draw_y1_to = y1; + + o_main.panel_split = 2; + } else { + o_main.panel_draw_x0_to = x0; + o_main.panel_draw_y0_to = y0; + o_main.panel_draw_x1_to = x1; + o_main.panel_draw_y1_to = yc; + + o_main.panel_split = 0; + } + } + } + } #endregion + + function onFocusBegin() { INLINE if(FOCUS.getContent()) FOCUS.getContent().onFocusBegin(); } + function onFocusEnd() { INLINE if(FOCUS.getContent()) FOCUS.getContent().onFocusEnd(); } + + function remove(con = getContent()) { #region + var curr = getContent(); + + array_remove(content, con); + if(con) con.onClose(); + if(con == curr) setTab(0, true); + else setTab(array_find(content, curr), true); + + refresh(); + if(hasContent()) return; + if(parent == noone) { + show_message("Can't close main panel."); + return; + } + + ds_list_delete(parent.childs, ds_list_find_index(parent.childs, self)); + var otherPanel = parent.childs[| 0]; + parent.setContent(otherPanel.content); + ds_list_clear(parent.childs); + } #endregion +} #endregion + +function PanelContent() constructor { #region + title = ""; + icon = noone; + context_str = ""; + draggable = true; + expandable = true; + resizable = true; + + auto_pin = false; + panel = noone; + + mx = 0; + my = 0; + x = 0; + y = 0; + w = 640; + h = 480; + padding = ui(16); + title_height = ui(28); + + tab_x = 0; + min_w = ui(40); + min_h = ui(40); + + pFOCUS = false; + pHOVER = false; + + in_dialog = false; + + dragSurface = surface_create(1, 1); + showHeader = true; + + function refresh() { #region + setPanelSize(panel); + onResize(); + } #endregion + + function onResize() {} + + function onFocusBegin() {} + function onFocusEnd() {} + + static initSize = function() {} + + function setPanelSize(panel) { #region + x = panel.tx; + y = panel.ty; + w = panel.tw; + h = panel.th; + } #endregion + + function onSetPanel(panel) { #region + self.panel = panel; + setPanelSize(panel); + initSize(); + onResize(); + } #endregion + + function panelStepBegin(panel) { #region + setPanelSize(panel); + onStepBegin(); + } #endregion + + function onStepBegin() { #region + mx = mouse_mx - x; + my = mouse_my - y; + + stepBegin(); + } #endregion + + function stepBegin() {} + + static draw = function(panel) { #region + self.panel = panel; + if(o_main.panel_dragging == noone) { + pFOCUS = FOCUS == panel/* && panel.mouse_active*/; + pHOVER = !CURSOR_IS_LOCK && HOVER == panel && panel.mouse_active; + } + + drawContent(panel); + } #endregion + + function drawContent(panel) {} + + function drawGUI() {} + + static onFullScreen = function() {} + + function close() { panel.remove(self); } + + static checkClosable = function() { return true; } + + static onClose = function() {} + + static serialize = function() { return { name: instanceof(self) }; } + static deserialize = function(data) { return self; } +} #endregion + +function setFocus(target, fstring = noone) { #region + if((instance_exists(FOCUS) && variable_instance_exists(FOCUS, "onFocusEnd")) || + (is_struct(FOCUS) && struct_has(FOCUS, "onFocusEnd"))) + FOCUS.onFocusEnd(); + + FOCUS = target; + if(fstring != noone) + FOCUS_STR = fstring; + + if((instance_exists(FOCUS) && variable_instance_exists(FOCUS, "onFocusBegin")) || + (is_struct(FOCUS) && struct_has(FOCUS, "onFocusBegin"))) + FOCUS.onFocusBegin(); + +} #endregion \ No newline at end of file diff --git a/#backups/scripts/panel_data/panel_data.gml.backup1 b/#backups/scripts/panel_data/panel_data.gml.backup1 new file mode 100644 index 000000000..c5afe4d30 --- /dev/null +++ b/#backups/scripts/panel_data/panel_data.gml.backup1 @@ -0,0 +1,969 @@ +// 2024-04-30 12:45:13 +enum ANCHOR { + none = 0, + top = 1, + bottom = 2, + left = 4, + right = 8 +} + +function Panel(_parent, _x, _y, _w, _h) constructor { #region + parent = _parent; + if(parent) ds_list_add(parent.childs, self); + + padding = THEME_VALUE.panel_margin; + content = []; + content_index = 0; + childs = ds_list_create(); + anchor = ANCHOR.none; + + x = _x; + y = _y; + w = _w; + h = _h; + tx = x; + ty = y; + tw = w; + th = h; + split = ""; + + tab_width = 0; + tab_height = ui(24); + tab_x = 0; + tab_x_to = 0; + tab_surface = noone; + + min_w = ui(40); + min_h = ui(40); + + dragging = -1; + drag_sval = 0; + drag_sm = 0; + mouse_active = true; + + content_surface = surface_create_valid(w, h); + mask_surface = surface_create_valid(w, h); + + tab_holding = noone; + tab_hold_state = 0; + tab_holding_mx = 0; + tab_holding_my = 0; + tab_holding_sx = 0; + tab_holding_sy = 0; + tab_cover = noone; + + border_rb_close = menuItem(__txt("Close"), function() { #region + var con = getContent(); + if(con == noone) return; + con.close(); + }, THEME.cross); #endregion + + border_rb_menu = [ #region + menuItem(__txt("Move"), function() { + extract(); + panel_mouse = 1; + }), + menuItem(__txtx("panel_pop_out", "Pop out"), function() { popWindow(); }, THEME.node_goto), + border_rb_close + ]; #endregion + + static getContent = function() { return array_safe_get_fast(content, content_index, noone); } + static hasContent = function() { return bool(array_length(content)); } + + function resetMask() { #region + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + + content_surface = surface_verify(content_surface, tw, th); + mask_surface = surface_verify(mask_surface, tw, th); + surface_set_target(mask_surface); + draw_clear(c_black); + gpu_set_blendmode(bm_subtract); + draw_sprite_stretched(THEME.ui_panel_bg, 0, padding, padding, tw - padding * 2, th - padding * 2); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + } resetMask(); #endregion + + function setPadding(padding) { #region + self.padding = padding; + refresh(); + } #endregion + + function refresh() { #region + resetMask(); + + for( var i = 0, n = array_length(content); i < n; i++ ) + content[i].refresh(); + + for( var i = 0; i < ds_list_size(childs); i++ ) + childs[| i].refresh(); + } #endregion + + function move(dx, dy) { #region + x += dx; + y += dy; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + _panel.move(dx, dy); + } + + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].x = x; + content[i].y = y; + } + } #endregion + + function resizable(dw, dh, oppose = ANCHOR.left) { #region + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + + var hori = oppose == ANCHOR.left || oppose == ANCHOR.right; + + if(hasContent()) { + var res = true; + for( var i = 0, n = array_length(content); i < n; i++ ) + res &= hori? tw + dw > content[i].min_w : th + dh > content[i].min_h; + return res; + } + + var _c0 = ds_list_get(childs, 0, noone); + var _c1 = ds_list_get(childs, 1, noone); + + if(_c0 == noone || _c1 == noone) return false; + + var ind = hori? _c1.w > _c0.w : _c1.h > _c0.h; + return childs[| ind].resizable(dw, dh, oppose); + } #endregion + + function refreshSize(recur = true) { #region //refresh content surface after resize + //__debug_counter("refresh size"); + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].w = max(tw, content[i].min_w); + content[i].h = max(th, content[i].min_h); + content[i].onResize(); + } + + if(ds_list_size(childs) == 2) { + //print("=== Refreshing (" + string(w) + ", " + string(h) + ") " + string(split) + " ==="); + + var _tw = childs[| 0].w + childs[| 1].w; + var _th = childs[| 0].h + childs[| 1].h; + + var fixChild = split == "h"? childs[| 1].x < childs[| 0].x : childs[| 1].y < childs[| 0].y; + + childs[| fixChild].x = x; + childs[| fixChild].y = y; + + if(split == "h") { + childs[| fixChild].w = round(childs[| fixChild].w / _tw * w); + childs[| fixChild].h = round(h); + + childs[| !fixChild].x = x + childs[| fixChild].w; + childs[| !fixChild].y = y; + + childs[| !fixChild].w = round(w - childs[| fixChild].w); + childs[| !fixChild].h = round(h); + + childs[| fixChild].anchor = ANCHOR.left; + childs[| !fixChild].anchor = ANCHOR.right; + } else if(split == "v") { + childs[| fixChild].w = round(w); + childs[| fixChild].h = round(childs[| fixChild].h / _th * h); + + childs[| !fixChild].x = x; + childs[| !fixChild].y = y + childs[| fixChild].h; + + childs[| !fixChild].w = round(w); + childs[| !fixChild].h = round(h - childs[| fixChild].h); + + childs[| fixChild].anchor = ANCHOR.top; + childs[| !fixChild].anchor = ANCHOR.bottom; + } + + if(recur) + for(var i = 0; i < ds_list_size(childs); i++) + childs[| i].refreshSize(); + } + + refresh(); + } #endregion + + function resize(dw, dh, oppose = ANCHOR.left) { #region + if(dw == 0 && dh == 0) return; + + if(ds_list_size(childs) == 2) { + var hori = oppose == ANCHOR.left || oppose == ANCHOR.right; + var ind = hori? childs[| 1].w > childs[| 0].w : childs[| 1].h > childs[| 0].h; + childs[| ind].resize(dw, dh, oppose); + } + + w = max(round(w + dw), min_w); + h = max(round(h + dh), min_h); + + refreshSize(false); + } #endregion + + function setContent(_content = noone, _switch = false) { #region + if(is_array(_content)) + content = array_append(content, _content); + else + array_push(content, _content); + + for( var i = 0, n = array_length(content); i < n; i++ ) + content[i].onSetPanel(self); + + if(_switch) setTab(array_find(content, _content)); + + refresh(); + } #endregion + + function switchContent(_content) { #region + var _ind = array_find(content, _content); + if(_ind == -1) return; + setTab(_ind); + } #endregion + + function split_h(_w) { #region + if(abs(_w) > w) { + print("Error: Split panel larger than size w (" + string(_w) + " > " + string(w) + ")"); + return noone; + } + + if(_w < 0) _w = w + _w; + var _panelParent = new Panel(parent, x, y, w, h); + _panelParent.anchor = anchor; + _panelParent.split = "h"; + + var _panelL = self; + ds_list_add(_panelParent.childs, _panelL); + + var _panelR = new Panel(_panelParent, x + _w, y, w - _w, h); + _panelR.anchor = ANCHOR.right; + + var prev_w = w; + w = _w; + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].w = w; + content[i].onResize(); + } + + if(parent == noone) + PANEL_MAIN = _panelParent; + else + ds_list_delete(parent.childs, ds_list_find_index(parent.childs, self)); + + parent = _panelParent; + anchor = ANCHOR.left; + content = []; + + return [ _panelL, _panelR ]; + } #endregion + + function split_v(_h) { #region + if(abs(_h) > h) { + print("Error: Split panel larger than size h (" + string(_h) + " > " + string(h) + ")"); + return noone; + } + + if(_h < 0) _h = h + _h; + var _panelParent = new Panel(parent, x, y, w, h); + _panelParent.anchor = anchor; + _panelParent.split = "v"; + + var _panelT = self; + ds_list_add(_panelParent.childs, _panelT); + var _panelB = new Panel(_panelParent, x, y + _h, w, h - _h); + _panelB.anchor = ANCHOR.bottom; + + var prev_h = h; + h = _h; + for( var i = 0, n = array_length(content); i < n; i++ ) { + content[i].h = h; + content[i].onResize(); + } + + if(parent == noone) + PANEL_MAIN = _panelParent; + else + ds_list_delete(parent.childs, ds_list_find_index(parent.childs, self)); + + parent = _panelParent; + anchor = ANCHOR.top; + content = []; + + return [_panelT, _panelB]; + } #endregion + + function stepBegin() { #region + var con = getContent(); + if(FULL_SCREEN_CONTENT != noone && con == FULL_SCREEN_CONTENT && self != FULL_SCREEN_PARENT) return; + + for( var i = 0, n = array_length(content); i < n; i++ ) + content[i].panelStepBegin(self); + + if(o_main.panel_dragging != noone) dragging = -1; + + if(dragging == 1) { + var _mx = clamp(mouse_mx, ui(16), WIN_W - ui(16)); + var dw = round(_mx - drag_sm); + var res = true; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.left: + res &= _panel.resizable(dw, 0, ANCHOR.left); + break; + case ANCHOR.right: + res &= _panel.resizable(-dw, 0, ANCHOR.right); + break; + } + } + + if(res) { + drag_sm = _mx; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.left: + _panel.resize(dw, 0, ANCHOR.left); + break; + case ANCHOR.right: + _panel.resize(-dw, 0, ANCHOR.right); + _panel.move(dw, 0); + break; + } + } + } + + if(mouse_release(mb_left)) { + refreshSize(); + dragging = -1; + } + } else if(dragging == 2) { + var _my = clamp(mouse_my, ui(16), WIN_H - ui(16)); + var dh = round(_my - drag_sm); + var res = true; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.top: + res &= _panel.resizable(0, dh, ANCHOR.top); + break; + case ANCHOR.bottom: + res &= _panel.resizable(0, -dh, ANCHOR.bottom); + break; + } + } + + if(res) { + drag_sm = _my; + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + switch(_panel.anchor) { + case ANCHOR.top: + _panel.resize(0, dh, ANCHOR.top); + break; + case ANCHOR.bottom: + _panel.resize(0, -dh, ANCHOR.bottom); + _panel.move(0, dh); + break; + } + } + } + + if(mouse_release(mb_left)) { + refreshSize(); + dragging = -1; + } + } else { + if(con && point_in_rectangle(mouse_mx, mouse_my, x + ui(2), y + ui(2), x + w - ui(4), y + h - ui(4))) { + HOVER = self; + if(mouse_press(mb_any)) + setFocus(self); + if(FOCUS == self && con) + FOCUS_STR = con.context_str; + } else { + for(var i = 0; i < ds_list_size(childs); i++) + childs[| i].stepBegin(); + } + } + } #endregion + + static step = function() { #region + for(var i = 0; i < ds_list_size(childs); i++) + childs[| i].step(); + } #endregion + + static draw = function() { #region + if(hasContent()) { + drawPanel(); + return; + } + + if(ds_list_empty(childs)) + return; + + var min_w = ui(32); + var min_h = ui(32); + if(split == "h") { + min_w = childs[| 0].min_w + childs[| 1].min_w; + min_h = max(childs[| 0].min_h + childs[| 1].min_h); + } else { + min_w = max(childs[| 0].min_w, childs[| 1].min_w); + min_h = childs[| 0].min_h + childs[| 1].min_h; + } + + for(var i = 0; i < ds_list_size(childs); i++) { + var _panel = childs[| i]; + _panel.draw(); + + if!(HOVER == noone || is_struct(HOVER)) + continue; + + var p = ui(6 - 1); + switch(_panel.anchor) { + case ANCHOR.left : + if(!point_in_rectangle(mouse_mx, mouse_my, _panel.x + _panel.w - p, _panel.y, _panel.x + _panel.w + p, _panel.y + _panel.h)) + break; + + CURSOR = cr_size_we; + if(mouse_press(mb_left)) { + dragging = 1; + drag_sval = _panel.w; + drag_sm = mouse_mx; + } + break; + case ANCHOR.top : + if(!point_in_rectangle(mouse_mx, mouse_my, _panel.x, _panel.y + _panel.h - p, _panel.x + _panel.w, _panel.y + _panel.h + p)) + break; + + CURSOR = cr_size_ns; + if(mouse_press(mb_left)) { + dragging = 2; + drag_sval = _panel.h; + drag_sm = mouse_my; + } + break; + } + } + + if(self == PANEL_MAIN && o_main.panel_dragging != noone && key_mod_press(CTRL)) + checkHover(); + } #endregion + + function drawTab() { #region + tab_surface = surface_verify(tab_surface, w - padding * 2 + 1, tab_height + ui(4)); + + var tsx = x + padding - 1; + var tsy = y + ui(2); + var msx = mouse_x - tsx; + var msy = mouse_y - tsy; + tab_cover = noone; + + surface_set_target(tab_surface); + DRAW_CLEAR + + var tbx = tab_x + ui(1); + var tby = 0; + var tbh = tab_height + ui(2); + var tabHov = msx < 0 ? 0 : array_length(content) - 1; + + tab_x = lerp_float(tab_x, tab_x_to, 5); + tab_width = 0; + + var rem = -1; + + draw_set_text(f_p3, fa_left, fa_bottom, COLORS._main_text_sub); + for( var i = 0, n = array_length(content); i < n; i++ ) { + var txt = content[i].title; + var icn = content[i].icon; + + var tbw = string_width(txt) + ui(16 + 16); + if(icn != noone) tbw += ui(16 + 4); + var foc = false; + + tab_width += tbw + ui(2); + if(msx >= tbx && msy <= tbx + tbw) + tabHov = i; + + if(tab_holding == content[i]) { + tbx += tbw + ui(2); + continue; + } + + content[i].tab_x = content[i].tab_x == 0? tbx : lerp_float(content[i].tab_x, tbx, 5); + var _tbx = content[i].tab_x; + var _hov = point_in_rectangle(msx, msy, _tbx, tby, _tbx + tbw, tab_height); + var _tdh = tbh + THEME_VALUE.panel_tab_extend; + + if(i == content_index) { + foc = FOCUS == self; + var cc = FOCUS == self? COLORS._main_accent : COLORS.panel_tab; + draw_sprite_stretched_ext(THEME.ui_panel_tab, 1 + (FOCUS == self), _tbx, tby, tbw, _tdh, cc, 1); + if(!foc) + tab_cover = BBOX().fromWH(tsx + _tbx, tsy + tby + tbh - ui(3), tbw, THEME_VALUE.panel_tab_extend); + } else { + var cc = COLORS.panel_tab_inactive; + if(HOVER == self && _hov) + var cc = COLORS.panel_tab_hover; + + draw_sprite_stretched_ext(THEME.ui_panel_tab, 0, _tbx, tby, tbw, _tdh, cc, 1); + } + + var aa = 0.5; + if(point_in_rectangle(msx, msy, _tbx + tbw - ui(16), tby, _tbx + tbw, tab_height)) { + aa = 1; + if(mouse_press(mb_left, FOCUS == self)) + rem = i; + } else if(HOVER == self && _hov) { + if(mouse_press(mb_left, FOCUS == self)) { + setTab(i); + + tab_holding = content[i]; + tab_hold_state = 0; + tab_holding_mx = msx; + tab_holding_my = msy; + tab_holding_sx = tab_holding.tab_x; + } + + if(mouse_press(mb_right, FOCUS == self)) { + var menu = array_clone(border_rb_menu); + if(instanceof(content[i]) == "Panel_Menu") + array_remove(menu, 2); + + menuCall("panel_border_menu",,, menu); + } + + if(mouse_press(mb_middle, FOCUS == self)) + rem = i; + + if(DRAGGING) + setTab(i); + } + + draw_sprite_ui(THEME.tab_exit, 0, _tbx + tbw - ui(12), tab_height / 2 + 1,,,, foc? COLORS.panel_tab_icon : COLORS._main_text_sub, aa); + + if(icn != noone) { + draw_sprite_ui(icn, 0, _tbx + ui(8 + 8), tab_height / 2 + 1,,,, foc? COLORS.panel_tab_icon : COLORS._main_text_sub); + _tbx += ui(20); + } + + draw_set_text(f_p3, fa_left, fa_bottom, foc? COLORS.panel_tab_text : COLORS._main_text_sub); + draw_text_add(_tbx + ui(8), tab_height - ui(4), txt); + + tbx += tbw + ui(2); + } + + if(rem > -1) content[rem].close(); + + tab_width = max(0, tab_width - w + ui(32)); + if(point_in_rectangle(msx, msy, 0, 0, w, tab_height)) { + if(mouse_wheel_up()) tab_x_to = clamp(tab_x_to + ui(64) * SCROLL_SPEED, -tab_width, 0); + if(mouse_wheel_down()) tab_x_to = clamp(tab_x_to - ui(64) * SCROLL_SPEED, -tab_width, 0); + } + + if(tab_holding) { + draw_set_font(f_p3); + + var _tbx = tab_holding.tab_x; + var txt = tab_holding.title; + var icn = tab_holding.icon; + var tbw = string_width(txt) + ui(16 + 16); + if(icn != noone) tbw += ui(16 + 4); + + draw_sprite_stretched_ext(THEME.ui_panel_tab, 2, _tbx, tby, tbw, tbh, COLORS._main_accent, 1); + draw_sprite_ui(THEME.tab_exit, 0, _tbx + tbw - ui(12), tab_height / 2 + 1,,,, COLORS.panel_tab_icon); + + if(icn != noone) { + draw_sprite_ui(icn, 0, _tbx + ui(8 + 8), tab_height / 2 + 1,,,, COLORS.panel_tab_icon); + _tbx += ui(20); + } + draw_set_text(f_p3, fa_left, fa_bottom, COLORS.panel_tab_text); + draw_text_add(_tbx + ui(8), tab_height - ui(4), txt); + + if(tab_hold_state == 0) { + if(point_distance(tab_holding_mx, tab_holding_my, msx, msy) > 8) + tab_hold_state = 1; + } else if(tab_hold_state == 1) { + if(point_in_rectangle(msx, msy, 0, 0, w, tab_height)) { + if(msx < ui(32)) tab_x_to = clamp(tab_x_to + ui(2), -tab_width, 0); + if(msx > w - ui(32)) tab_x_to = clamp(tab_x_to - ui(2), -tab_width, 0); + } + + tab_holding.tab_x = clamp(tab_holding_sx + (msx - tab_holding_mx), 1, w - tbw - ui(4)); + + array_remove(content, tab_holding); + array_insert(content, tabHov, tab_holding); + setTab(array_find(content, tab_holding)); + + if(abs(msy - tab_holding_my) > ui(32)) { + extract(); + tab_holding = noone; + } + } + + if(mouse_release(mb_left)) + tab_holding = noone; + } + surface_reset_target(); + + draw_surface(tab_surface, tsx, tsy); + } #endregion + + function setTab(tabIndex, forceFocus = false) { #region + if(tabIndex < 0) return; + if(tabIndex >= array_length(content)) return; + if(content_index == tabIndex) { + if(forceFocus) content[tabIndex].onFocusBegin(); + return; + } + + var prec = array_safe_get_fast(content, content_index); + if(prec) prec.onFocusEnd(); + + content_index = tabIndex; + + var prec = array_safe_get_fast(content, content_index); + if(prec) prec.onFocusBegin(); + } #endregion + + function drawPanel() { #region + if(w <= ui(16)) return; + + var tab = array_length(content) > 1; + tx = x; ty = y + tab * ui(tab_height); + tw = w; th = h - tab * ui(tab_height); + if(th < ui(16)) return; + + var con = getContent(); + if(FULL_SCREEN_CONTENT != noone && con == FULL_SCREEN_CONTENT && self != FULL_SCREEN_PARENT) return; + + if(tab) drawTab(); + + var p = ui(6); + var m_in = point_in_rectangle(mouse_mx, mouse_my, tx + p, ty + p, tx + tw - p, ty + th - p); + var m_ot = point_in_rectangle(mouse_mx, mouse_my, tx, ty, tx + tw, ty + th); + mouse_active = m_in; + + var _tw = tw - padding * 2; + var _th = th - padding * 2; + draw_sprite_stretched(THEME.ui_panel_bg, 0, tx + padding, ty + padding, _tw, _th); + + if(!is_surface(mask_surface)) { + mask_surface = surface_create_valid(tw, th); + refresh(); + } + + content_surface = surface_verify(content_surface, tw, th); + + surface_set_target(content_surface); + draw_clear(COLORS.panel_bg_clear); + + if(con) { + min_w = con.min_w; + min_h = con.min_h; + if(tw >= min_w && th >= min_h) + con.draw(self); + else { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text(tw / 2, th / 2, "Panel too small for content"); + } + } else { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text(tw / 2, th / 2, "No content"); + } + + gpu_set_blendmode(bm_subtract); + draw_surface_safe(mask_surface, 0, 0); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + + draw_surface_safe(content_surface, tx, ty); + draw_sprite_stretched(THEME.ui_panel_fg, 0, tx + padding, ty + padding, _tw, _th); + if(tab) draw_sprite_bbox(THEME.ui_panel_tab, 3, tab_cover); + + if(FOCUS == self && parent != noone) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, COLORS._main_accent, 1); + + if(hasContent() && !m_in && m_ot) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, tx + padding, ty + padding, tw - padding * 2, th - padding * 2, c_white, 0.4); + + if(DOUBLE_CLICK) { + extract(); + panel_mouse = 0; + } else if(mouse_press(mb_right)) { + var menu = array_clone(border_rb_menu); + if(instanceof(getContent()) == "Panel_Menu") + array_remove(menu, 2, border_rb_close); + + menuCall("panel_border_menu",,, menu); + } + } + } + + if(o_main.panel_dragging != noone && m_ot && !key_mod_press(CTRL)) + checkHover(); + } #endregion + + function drawGUI() { #region + for( var i = 0; i < ds_list_size(childs); i++ ) + childs[| i].drawGUI(); + + var con = getContent(); + if(con == noone) return; + con.drawGUI(); + } #endregion + + function extract() { #region + var con = getContent(); + con.dragSurface = surface_clone(content_surface); + o_main.panel_dragging = con; + + array_remove(content, con); + refresh(); + setTab(0); + + HOVER = noone; + FOCUS = noone; + + if(hasContent()) return; + var ind = !ds_list_find_index(parent.childs, self); //index of the other child + var sib = parent.childs[| ind]; + + if(!sib.hasContent() && ds_list_size(sib.childs) == 2) { //other child is compound panel + var gparent = parent.parent; + if(gparent == noone) { + sib.x = PANEL_MAIN.x; sib.y = PANEL_MAIN.y; + sib.w = PANEL_MAIN.w; sib.h = PANEL_MAIN.h; + + PANEL_MAIN = sib; + sib.parent = noone; + PANEL_MAIN.refreshSize(); + } else { + var pind = ds_list_find_index(gparent.childs, parent); //index of parent in grandparent object + gparent.childs[| pind] = sib; //replace parent with sibling + sib.parent = gparent; + gparent.refreshSize(); + } + } else if(sib.hasContent()) { //other child is content panel, set parent to content panel + parent.setContent(sib.content); + ds_list_clear(parent.childs); + } + } #endregion + + function popWindow() { #region + var con = getContent(); + if(con == noone) return; + + dialogPanelCall(con); + extract(); + o_main.panel_dragging = noone; + } #endregion + + function checkHover() { #region + var dx = (mouse_mx - x) / w; + var dy = (mouse_my - y) / h; + var p = ui(8); + + draw_set_color(COLORS._main_accent); + o_main.panel_hovering = self; + + var x0 = x + p; + var y0 = y + p; + var x1 = x + w - p; + var y1 = y + h - p; + var xc = x + w / 2; + var yc = y + h / 2; + + if(point_in_rectangle(mouse_mx, mouse_my, x + w * 1 / 3, y + h * 1 / 3, x + w * 2 / 3, y + h * 2 / 3)) { + o_main.panel_split = 4; + + o_main.panel_draw_x0_to = x + w * 1 / 3; + o_main.panel_draw_y0_to = y + h * 1 / 3; + o_main.panel_draw_x1_to = x + w * 2 / 3; + o_main.panel_draw_y1_to = y + h * 2 / 3; + } else { + if(dx + dy > 1) { + if((1 - dx) + dy > 1) { + o_main.panel_draw_x0_to = x0; + o_main.panel_draw_y0_to = yc; + o_main.panel_draw_x1_to = x1; + o_main.panel_draw_y1_to = y1; + + o_main.panel_split = 3; + } else { + o_main.panel_draw_x0_to = xc; + o_main.panel_draw_y0_to = y0; + o_main.panel_draw_x1_to = x1; + o_main.panel_draw_y1_to = y1; + + o_main.panel_split = 1; + } + } else { + if((1 - dx) + dy > 1) { + o_main.panel_draw_x0_to = x0; + o_main.panel_draw_y0_to = y0; + o_main.panel_draw_x1_to = xc; + o_main.panel_draw_y1_to = y1; + + o_main.panel_split = 2; + } else { + o_main.panel_draw_x0_to = x0; + o_main.panel_draw_y0_to = y0; + o_main.panel_draw_x1_to = x1; + o_main.panel_draw_y1_to = yc; + + o_main.panel_split = 0; + } + } + } + } #endregion + + function onFocusBegin() { INLINE if(FOCUS.getContent()) FOCUS.getContent().onFocusBegin(); } + function onFocusEnd() { INLINE if(FOCUS.getContent()) FOCUS.getContent().onFocusEnd(); } + + function remove(con = getContent()) { #region + var curr = getContent(); + + array_remove(content, con); + if(con) con.onClose(); + if(con == curr) setTab(0, true); + else setTab(array_find(content, curr), true); + + refresh(); + if(hasContent()) return; + if(parent == noone) { + show_message("Can't close main panel."); + return; + } + + ds_list_delete(parent.childs, ds_list_find_index(parent.childs, self)); + var otherPanel = parent.childs[| 0]; + parent.setContent(otherPanel.content); + ds_list_clear(parent.childs); + } #endregion +} #endregion + +function PanelContent() constructor { #region + title = ""; + icon = noone; + context_str = ""; + draggable = true; + expandable = true; + resizable = true; + + auto_pin = false; + panel = noone; + + mx = 0; + my = 0; + x = 0; + y = 0; + w = 640; + h = 480; + padding = ui(16); + title_height = ui(28); + + tab_x = 0; + min_w = ui(40); + min_h = ui(40); + + pFOCUS = false; + pHOVER = false; + + in_dialog = false; + + dragSurface = surface_create(1, 1); + showHeader = true; + + function refresh() { #region + setPanelSize(panel); + onResize(); + } #endregion + + function onResize() {} + + function onFocusBegin() {} + function onFocusEnd() {} + + static initSize = function() {} + + function setPanelSize(panel) { #region + x = panel.tx; + y = panel.ty; + w = panel.tw; + h = panel.th; + } #endregion + + function onSetPanel(panel) { #region + self.panel = panel; + setPanelSize(panel); + initSize(); + onResize(); + } #endregion + + function panelStepBegin(panel) { #region + setPanelSize(panel); + onStepBegin(); + } #endregion + + function onStepBegin() { #region + mx = mouse_mx - x; + my = mouse_my - y; + + stepBegin(); + } #endregion + + function stepBegin() {} + + static draw = function(panel) { #region + self.panel = panel; + if(o_main.panel_dragging == noone) { + pFOCUS = FOCUS == panel/* && panel.mouse_active*/; + pHOVER = !CURSOR_IS_LOCK && HOVER == panel && panel.mouse_active; + } + + drawContent(panel); + } #endregion + + function drawContent(panel) {} + + function drawGUI() {} + + static onFullScreen = function() {} + + function close() { panel.remove(self); } + + static checkClosable = function() { return true; } + + static onClose = function() {} + + static serialize = function() { return { name: instanceof(self) }; } + static deserialize = function(data) { return self; } +} #endregion + +function setFocus(target, fstring = noone) { #region + if((instance_exists(FOCUS) && variable_instance_exists(FOCUS, "onFocusEnd")) || + (is_struct(FOCUS) && struct_has(FOCUS, "onFocusEnd"))) + FOCUS.onFocusEnd(); + + FOCUS = target; + if(fstring != noone) + FOCUS_STR = fstring; + + if((instance_exists(FOCUS) && variable_instance_exists(FOCUS, "onFocusBegin")) || + (is_struct(FOCUS) && struct_has(FOCUS, "onFocusBegin"))) + FOCUS.onFocusBegin(); + +} #endregion \ No newline at end of file diff --git a/#backups/scripts/panel_function/panel_function.gml.backup0 b/#backups/scripts/panel_function/panel_function.gml.backup0 index bb975fe6b..edc102e49 100644 --- a/#backups/scripts/panel_function/panel_function.gml.backup0 +++ b/#backups/scripts/panel_function/panel_function.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-22 17:29:02 +// 2024-04-30 13:08:47 #region data globalvar PANEL_MAIN, PANEL_MENU, PANEL_PREVIEW, PANEL_INSPECTOR, PANEL_GRAPH, PANEL_ANIMATION, PANEL_COLLECTION; globalvar FULL_SCREEN_PANEL, FULL_SCREEN_CONTENT, FULL_SCREEN_PARENT; @@ -48,11 +48,11 @@ function getPanelFromName(name, create = false) { #region switch(name) { - case "Panel_Menu" : return (create || findPanel(name))? new Panel_Menu() : PANEL_MENU; - case "Panel_Inspector" : return (create || findPanel(name))? new Panel_Inspector() : PANEL_INSPECTOR; - case "Panel_Animation" : return (create || findPanel(name))? new Panel_Animation() : PANEL_ANIMATION; - case "Panel_Preview" : return (create || findPanel(name))? new Panel_Preview() : PANEL_PREVIEW; - case "Panel_Graph" : return (create || findPanel(name))? new Panel_Graph() : PANEL_GRAPH; + case "Panel_Menu" : var p = (create || findPanel(name))? new Panel_Menu() : PANEL_MENU; PANEL_MENU = p; return p; + case "Panel_Inspector" : var p = (create || findPanel(name))? new Panel_Inspector() : PANEL_INSPECTOR; PANEL_INSPECTOR = p; return p; + case "Panel_Animation" : var p = (create || findPanel(name))? new Panel_Animation() : PANEL_ANIMATION; PANEL_ANIMATION = p; return p; + case "Panel_Preview" : var p = (create || findPanel(name))? new Panel_Preview() : PANEL_PREVIEW; PANEL_PREVIEW = p; return p; + case "Panel_Graph" : var p = (create || findPanel(name))? new Panel_Graph() : PANEL_GRAPH; PANEL_GRAPH = p; return p; case "Panel_Collection" : return new Panel_Collection(); case "Panel_Workspace" : return new Panel_Workspace(); @@ -76,6 +76,7 @@ var cont = str.content; if(variable_struct_exists(str, "split")) { + var pan = panel; if(str.split == "v") pan = panel.split_v(ui(str.width)); @@ -87,10 +88,17 @@ loadPanelStruct(pan[1], cont[1]); } } else { + if(!is_array(cont)) cont = [ cont ]; for( var i = 0, n = array_length(cont); i < n; i++ ) { - var _cont = getPanelFromName(cont[i]) - if(_cont != noone) panel.setContent(_cont); + var _content = cont[i]; + var _key = is_struct(_content)? _content.name : _content; + + var _pnCont = getPanelFromName(_key, true); + if(_pnCont == noone) continue; + + panel.setContent(_pnCont); + if(is_struct(_content)) _pnCont.deserialize(_content); } } } #endregion @@ -327,34 +335,33 @@ } } #endregion - function panelSerialize() { #region - var cont = {}; - cont.panel = _panelSerialize(PANEL_MAIN); - return cont; + function panelSerialize(_content = false) { #region + return { panel : _panelSerialize(PANEL_MAIN, _content) }; } #endregion - function _panelSerialize(panel) { #region + function _panelSerialize(_panel, _content = false) { #region var cont = {}; var ind = 0; cont.content = []; - if(panel.split != "" && ds_list_size(panel.childs) == 2) { - cont.split = panel.split; - if(panel.split == "h") { - ind = panel.childs[| 1].w < panel.childs[| 0].w; - cont.width = panel.childs[| ind].w * (panel.childs[| ind].x == panel.x? 1 : -1); + if(_panel.split != "" && ds_list_size(_panel.childs) == 2) { + cont.split = _panel.split; + if(_panel.split == "h") { + ind = _panel.childs[| 1].w < _panel.childs[| 0].w; + cont.width = _panel.childs[| ind].w * (_panel.childs[| ind].x == _panel.x? 1 : -1); } else { - ind = panel.childs[| 1].h < panel.childs[| 0].h; - cont.width = panel.childs[| ind].h * (panel.childs[| ind].y == panel.y? 1 : -1); + ind = _panel.childs[| 1].h < _panel.childs[| 0].h; + cont.width = _panel.childs[| ind].h * (_panel.childs[| ind].y == _panel.y? 1 : -1); } - ind = panel.childs[| 1].x == panel.x && panel.childs[| 1].y == panel.y; - for( var i = 0; i < ds_list_size(panel.childs); i++ ) - cont.content[i] = _panelSerialize(panel.childs[| (ind + i) % 2]); + ind = _panel.childs[| 1].x == _panel.x && _panel.childs[| 1].y == _panel.y; + for( var i = 0; i < ds_list_size(_panel.childs); i++ ) + cont.content[i] = _panelSerialize(_panel.childs[| (ind + i) % 2], _content); + } else { - for( var i = 0, n = array_length(panel.content); i < n; i++ ) - cont.content[i] = instanceof(panel.content[i]); + for( var i = 0, n = array_length(_panel.content); i < n; i++ ) + cont.content[i] = _content? _panel.content[i].serialize() : instanceof(_panel.content[i]); } return cont; diff --git a/#backups/scripts/panel_function/panel_function.gml.backup1 b/#backups/scripts/panel_function/panel_function.gml.backup1 index cbb87a64a..27c60f0f8 100644 --- a/#backups/scripts/panel_function/panel_function.gml.backup1 +++ b/#backups/scripts/panel_function/panel_function.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-22 17:28:16 +// 2024-04-30 13:08:37 #region data globalvar PANEL_MAIN, PANEL_MENU, PANEL_PREVIEW, PANEL_INSPECTOR, PANEL_GRAPH, PANEL_ANIMATION, PANEL_COLLECTION; globalvar FULL_SCREEN_PANEL, FULL_SCREEN_CONTENT, FULL_SCREEN_PARENT; @@ -48,11 +48,11 @@ function getPanelFromName(name, create = false) { #region switch(name) { - case "Panel_Menu" : return (create || findPanel(name))? new Panel_Menu() : PANEL_MENU; - case "Panel_Inspector" : return (create || findPanel(name))? new Panel_Inspector() : PANEL_INSPECTOR; - case "Panel_Animation" : return (create || findPanel(name))? new Panel_Animation() : PANEL_ANIMATION; - case "Panel_Preview" : return (create || findPanel(name))? new Panel_Preview() : PANEL_PREVIEW; - case "Panel_Graph" : return (create || findPanel(name))? new Panel_Graph() : PANEL_GRAPH; + case "Panel_Menu" : var p = (create || findPanel(name))? new Panel_Menu() : PANEL_MENU; PANEL_MENU = p; return p; + case "Panel_Inspector" : var p = (create || findPanel(name))? new Panel_Inspector() : PANEL_INSPECTOR; PANEL_INSPECTOR = p; return p; + case "Panel_Animation" : var p = (create || findPanel(name))? new Panel_Animation() : PANEL_ANIMATION; PANEL_ANIMATION = p; return p; + case "Panel_Preview" : var p = (create || findPanel(name))? new Panel_Preview() : PANEL_PREVIEW; PANEL_PREVIEW = p; return p; + case "Panel_Graph" : var p = (create || findPanel(name))? new Panel_Graph() : PANEL_GRAPH; PANEL_GRAPH = p; return p; case "Panel_Collection" : return new Panel_Collection(); case "Panel_Workspace" : return new Panel_Workspace(); @@ -76,6 +76,7 @@ var cont = str.content; if(variable_struct_exists(str, "split")) { + var pan = panel; if(str.split == "v") pan = panel.split_v(ui(str.width)); @@ -87,10 +88,17 @@ loadPanelStruct(pan[1], cont[1]); } } else { + if(!is_array(cont)) cont = [ cont ]; for( var i = 0, n = array_length(cont); i < n; i++ ) { - var _cont = getPanelFromName(cont[i]) - if(_cont != noone) panel.setContent(_cont); + var _content = cont[i]; + var _key = is_struct(_content)? _content.name : _content; + + var _pnCont = getPanelFromName(_key, true); + if(_pnCont == noone) continue; + + panel.setContent(_pnCont); + if(is_struct(_content)) _pnCont.deserialize(_content); } } } #endregion @@ -327,34 +335,33 @@ } } #endregion - function panelSerialize() { #region - var cont = {}; - cont.panel = _panelSerialize(PANEL_MAIN); - return cont; + function panelSerialize(_content = false) { #region + return { panel : _panelSerialize(PANEL_MAIN, _content) }; } #endregion - function _panelSerialize(panel) { #region + function _panelSerialize(_panel, _content = false) { #region var cont = {}; var ind = 0; cont.content = []; - if(panel.split != "" && ds_list_size(panel.childs) == 2) { - cont.split = panel.split; - if(panel.split == "h") { - ind = panel.childs[| 1].w < panel.childs[| 0].w; - cont.width = panel.childs[| ind].w * (panel.childs[| ind].x == panel.x? 1 : -1); + if(_panel.split != "" && ds_list_size(_panel.childs) == 2) { + cont.split = _panel.split; + if(_panel.split == "h") { + ind = _panel.childs[| 1].w < _panel.childs[| 0].w; + cont.width = _panel.childs[| ind].w * (_panel.childs[| ind].x == _panel.x? 1 : -1); } else { - ind = panel.childs[| 1].h < panel.childs[| 0].h; - cont.width = panel.childs[| ind].h * (panel.childs[| ind].y == panel.y? 1 : -1); + ind = _panel.childs[| 1].h < _panel.childs[| 0].h; + cont.width = _panel.childs[| ind].h * (_panel.childs[| ind].y == _panel.y? 1 : -1); } - ind = panel.childs[| 1].x == panel.x && panel.childs[| 1].y == panel.y; - for( var i = 0; i < ds_list_size(panel.childs); i++ ) - cont.content[i] = _panelSerialize(panel.childs[| (ind + i) % 2]); + ind = _panel.childs[| 1].x == _panel.x && _panel.childs[| 1].y == _panel.y; + for( var i = 0; i < ds_list_size(_panel.childs); i++ ) + cont.content[i] = _panelSerialize(_panel.childs[| (ind + i) % 2], _content); + } else { - for( var i = 0, n = array_length(panel.content); i < n; i++ ) - cont.content[i] = instanceof(panel.content[i]); + for( var i = 0, n = array_length(_panel.content); i < n; i++ ) + cont.content[i] = _content? _panel.content[i].serialize() : instanceof(_panel.content[i]); } return cont; diff --git a/#backups/scripts/panel_graph/panel_graph.gml.backup0 b/#backups/scripts/panel_graph/panel_graph.gml.backup0 index 43942565f..d453640d8 100644 --- a/#backups/scripts/panel_graph/panel_graph.gml.backup0 +++ b/#backups/scripts/panel_graph/panel_graph.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-30 10:46:10 +// 2024-04-30 15:48:57 #region funtion calls function __fnInit_Graph() { __registerFunction("graph_add_node", panel_graph_add_node); @@ -132,14 +132,21 @@ function connectionParameter() constructor { #region } #endregion function Panel_Graph(project = PROJECT) : PanelContent() constructor { - title = __txt("Graph"); + title = __txt("Graph"); title_raw = ""; context_str = "Graph"; - icon = THEME.panel_graph_icon; + icon = THEME.panel_graph_icon; + + function setTitle() { + title_raw = project.path == ""? "New project" : filename_name_only(project.path); + title = title_raw + (project.modified? "*" : ""); + } static setProject = function(project) { self.project = project; nodes_list = project.nodes; + + setTitle(); } setProject(project); @@ -1802,15 +1809,9 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { context_frame_ey = context_frame_sy + 16; } #endregion - function setTitle() { #region - title = title_raw + (project.modified? "*" : ""); - } #endregion - function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<< if(!project.active) return; - if(project.path == "") title_raw = "New project"; - else title_raw = filename_name_only(project.path); dragGraph(); var context = getCurrentContext(); @@ -2075,32 +2076,42 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { var _n0 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[0] : nodes_selecting[1]; var _n1 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[1] : nodes_selecting[0]; - if(_n0.outputs[| 0].type != VALUE_TYPE.surface || _n1.outputs[| 0].type != VALUE_TYPE.surface) return; - var cx = max(_n0.x, _n1.x) + 160; var cy = round((_n0.y + _n1.y) / 2 / 32) * 32; - var _blend = new Node_Blend(cx, cy, getCurrentContext()); - _blend.inputs[| 0].setFrom(_n0.outputs[| 0]); - _blend.inputs[| 1].setFrom(_n1.outputs[| 0]); + var _j0 = _n0.outputs[| 0]; + var _j1 = _n1.outputs[| 0]; + + if(_j0.type == VALUE_TYPE.surface && _j1.type == VALUE_TYPE.surface) { + var _blend = new Node_Blend(cx, cy, getCurrentContext()); + _blend.inputs[| 0].setFrom(_j0); + _blend.inputs[| 1].setFrom(_j1); + + } else if((_j0.type == VALUE_TYPE.integer || _j0.type == VALUE_TYPE.float) && (_j1.type == VALUE_TYPE.integer || _j1.type == VALUE_TYPE.float)) { + var _blend = new Node_Math(cx, cy, getCurrentContext()); + _blend.inputs[| 1].setFrom(_j0); + _blend.inputs[| 2].setFrom(_j1); + + } nodes_selecting = []; } #endregion - + function doCompose() { #region if(array_empty(nodes_selecting)) return; - var cx = nodes_selecting[0].x; - var cy = 0; - var pr = ds_priority_create(); - var amo = array_length(nodes_selecting); - var len = 0; + var cx = nodes_selecting[0].x; + var cy = 0; + var pr = ds_priority_create(); + var amo = array_length(nodes_selecting); + var len = 0; for(var i = 0; i < amo; i++) { var _node = nodes_selecting[i]; if(ds_list_size(_node.outputs) == 0) continue; + if(_node.outputs[| 0].type != VALUE_TYPE.surface) continue; - + cx = max(cx, _node.x); cy += _node.y; @@ -2111,7 +2122,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { cx = cx + 160; cy = round(cy / len / 32) * 32; - var _compose = nodeBuild("Node_Composite", cx, cy); + var _compose = new Node_Composite(cx, cy, getCurrentContext()); repeat(len) { var _node = ds_priority_delete_min(pr); @@ -2340,6 +2351,18 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { static onFullScreen = function() { run_in(1, fullView); } + static serialize = function() { + return { + name: instanceof(self), + project, + }; + } + + static deserialize = function(data) { + setProject(data.project); + return self; + } + function close() { #region var panels = findPanels("Panel_Graph"); for( var i = 0, n = array_length(panels); i < n; i++ ) { diff --git a/#backups/scripts/panel_graph/panel_graph.gml.backup1 b/#backups/scripts/panel_graph/panel_graph.gml.backup1 index 203dce64a..9d34008cc 100644 --- a/#backups/scripts/panel_graph/panel_graph.gml.backup1 +++ b/#backups/scripts/panel_graph/panel_graph.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-30 10:46:07 +// 2024-04-30 15:48:50 #region funtion calls function __fnInit_Graph() { __registerFunction("graph_add_node", panel_graph_add_node); @@ -132,14 +132,21 @@ function connectionParameter() constructor { #region } #endregion function Panel_Graph(project = PROJECT) : PanelContent() constructor { - title = __txt("Graph"); + title = __txt("Graph"); title_raw = ""; context_str = "Graph"; - icon = THEME.panel_graph_icon; + icon = THEME.panel_graph_icon; + + function setTitle() { + title_raw = project.path == ""? "New project" : filename_name_only(project.path); + title = title_raw + (project.modified? "*" : ""); + } static setProject = function(project) { self.project = project; nodes_list = project.nodes; + + setTitle(); } setProject(project); @@ -1802,15 +1809,9 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { context_frame_ey = context_frame_sy + 16; } #endregion - function setTitle() { #region - title = title_raw + (project.modified? "*" : ""); - } #endregion - function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<< if(!project.active) return; - if(project.path == "") title_raw = "New project"; - else title_raw = filename_name_only(project.path); dragGraph(); var context = getCurrentContext(); @@ -2075,32 +2076,42 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { var _n0 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[0] : nodes_selecting[1]; var _n1 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[1] : nodes_selecting[0]; - if(_n0.outputs[| 0].type != VALUE_TYPE.surface || _n1.outputs[| 0].type != VALUE_TYPE.surface) return; - var cx = max(_n0.x, _n1.x) + 160; var cy = round((_n0.y + _n1.y) / 2 / 32) * 32; - var _blend = new Node_Blend(cx, cy, getCurrentContext()); - _blend.inputs[| 0].setFrom(_n0.outputs[| 0]); - _blend.inputs[| 1].setFrom(_n1.outputs[| 0]); + var _j0 = _n0.outputs[| 0]; + var _j1 = _n1.outputs[| 0]; + + if(_j0.type == VALUE_TYPE.surface && _j1.type == VALUE_TYPE.surface) { + var _blend = new Node_Blend(cx, cy, getCurrentContext()); + _blend.inputs[| 0].setFrom(_j0); + _blend.inputs[| 1].setFrom(_j1); + + } else if((_j0.type == VALUE_TYPE.integer || _j0.type == VALUE_TYPE.float) && (_j1.type == VALUE_TYPE.integer || _j1.type == VALUE_TYPE.float)) { + var _blend = new Node_Math(cx, cy, getCurrentContext()); + _blend.inputs[| 1].setFrom(_j0); + _blend.inputs[| 2].setFrom(_j1); + + } nodes_selecting = []; } #endregion - + function doCompose() { #region if(array_empty(nodes_selecting)) return; - var cx = nodes_selecting[0].x; - var cy = 0; - var pr = ds_priority_create(); - var amo = array_length(nodes_selecting); - var len = 0; + var cx = nodes_selecting[0].x; + var cy = 0; + var pr = ds_priority_create(); + var amo = array_length(nodes_selecting); + var len = 0; for(var i = 0; i < amo; i++) { var _node = nodes_selecting[i]; if(ds_list_size(_node.outputs) == 0) continue; + if(_node.outputs[| 0].type != VALUE_TYPE.surface) continue; - + cx = max(cx, _node.x); cy += _node.y; @@ -2111,7 +2122,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { cx = cx + 160; cy = round(cy / len / 32) * 32; - var _compose = nodeBuild("Node_Composite", cx, cy); + var _compose = new Node_Composite(cx, cy, getCurrentContext()); repeat(len) { var _node = ds_priority_delete_min(pr); @@ -2340,6 +2351,18 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { static onFullScreen = function() { run_in(1, fullView); } + static serialize = function() { + return { + name: instanceof(self), + project, + }; + } + + static deserialize = function(data) { + setProject(data.project); + return self; + } + function close() { #region var panels = findPanels("Panel_Graph"); for( var i = 0, n = array_length(panels); i < n; i++ ) { diff --git a/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 b/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 index 97096715c..539546583 100644 --- a/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 +++ b/#backups/scripts/panel_inspector/panel_inspector.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-27 10:52:15 +// 2024-04-30 13:07:08 #region funtion calls function __fnInit_Inspector() { __registerFunction("inspector_copy_prop", panel_inspector_copy_prop); @@ -1023,4 +1023,20 @@ function Panel_Inspector() : PanelContent() constructor { if(!locked && PANEL_GRAPH.getFocusingNode() && inspecting != PANEL_GRAPH.getFocusingNode()) setInspecting(PANEL_GRAPH.getFocusingNode()); } #endregion + + static serialize = function() { + return { + name: instanceof(self), + inspecting, + inspectings, + }; + } + + static deserialize = function(data) { + inspecting = data.inspecting; + inspectings = data.inspectings; + + return self; + } + } \ No newline at end of file diff --git a/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 b/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 index 97096715c..ef119ef64 100644 --- a/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 +++ b/#backups/scripts/panel_inspector/panel_inspector.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-27 10:52:15 +// 2024-04-30 13:07:07 #region funtion calls function __fnInit_Inspector() { __registerFunction("inspector_copy_prop", panel_inspector_copy_prop); @@ -1023,4 +1023,20 @@ function Panel_Inspector() : PanelContent() constructor { if(!locked && PANEL_GRAPH.getFocusingNode() && inspecting != PANEL_GRAPH.getFocusingNode()) setInspecting(PANEL_GRAPH.getFocusingNode()); } #endregion + + static serialize = function() { + return { + name: instanceof(self), + inspecting, + inspectings, + }; + } + + static deserialize = function(data) { + inspecting = data.inspecting; + inspectings = data.inspectings; + + return self; + } + } \ 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 b340e375d..3bb9b0ab3 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-27 10:32:06 +// 2024-04-30 13:08:35 #region funtion calls function __fnInit_Preview() { __registerFunction("preview_focus_content", panel_preview_focus_content); @@ -1776,4 +1776,20 @@ function Panel_Preview() : PanelContent() constructor { ind++; } } #endregion + + + static serialize = function() { + return { + name: instanceof(self), + preview_node, + }; + } + + static deserialize = function(data) { + preview_node = data.preview_node; + + run_in(1, fullView) + return self; + } + } \ No newline at end of file diff --git a/#backups/scripts/panel_preview/panel_preview.gml.backup1 b/#backups/scripts/panel_preview/panel_preview.gml.backup1 index a2d547a34..645898e55 100644 --- a/#backups/scripts/panel_preview/panel_preview.gml.backup1 +++ b/#backups/scripts/panel_preview/panel_preview.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-27 10:32:05 +// 2024-04-30 13:08:33 #region funtion calls function __fnInit_Preview() { __registerFunction("preview_focus_content", panel_preview_focus_content); @@ -1776,4 +1776,20 @@ function Panel_Preview() : PanelContent() constructor { ind++; } } #endregion + + + static serialize = function() { + return { + name: instanceof(self), + preview_node, + }; + } + + static deserialize = function(data) { + preview_node = data.preview_node; + + run_in(1, fullView) + return self; + } + } \ No newline at end of file diff --git a/#backups/scripts/render_data/render_data.gml.backup0 b/#backups/scripts/render_data/render_data.gml.backup0 index 1476372bd..2ab108f7c 100644 --- a/#backups/scripts/render_data/render_data.gml.backup0 +++ b/#backups/scripts/render_data/render_data.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-30 10:57:23 +// 2024-04-30 13:08:55 enum RENDER_TYPE { none = 0, partial = 1, diff --git a/#backups/scripts/render_data/render_data.gml.backup1 b/#backups/scripts/render_data/render_data.gml.backup1 index c0503f038..ea2acb45d 100644 --- a/#backups/scripts/render_data/render_data.gml.backup1 +++ b/#backups/scripts/render_data/render_data.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-29 18:32:52 +// 2024-04-30 13:08:48 enum RENDER_TYPE { none = 0, partial = 1, diff --git a/#backups/scripts/surface_functions/surface_functions.gml.backup0 b/#backups/scripts/surface_functions/surface_functions.gml.backup0 index 1324b9d19..3af28b74f 100644 --- a/#backups/scripts/surface_functions/surface_functions.gml.backup0 +++ b/#backups/scripts/surface_functions/surface_functions.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-26 15:47:55 +// 2024-04-30 13:16:32 #region ==================================== DRAW ==================================== function draw_surface_safe(surface, _x = 0, _y = 0) { #region @@ -133,12 +133,12 @@ } #endregion function surface_valid(surf, w, h, format = surface_rgba8unorm) { #region - INLINE - - if(!is_surface(surf)) return false; - var _sw = surface_get_width(surf); - var _sh = surface_get_height(surf); - var _f = surface_get_format(surf); + INLINE + + if(!is_surface(surf)) return false; + var _sw = surface_get_width(surf); + var _sh = surface_get_height(surf); + var _f = surface_get_format(surf); return _sw == w && _sh == h && _f == format; } #endregion @@ -473,9 +473,9 @@ function surface_valid_size(s) { #region INLINE - if(!is_numeric(s)) return 1; + if(!is_numeric(s)) return 1; if(is_infinity(s)) return 1; - return clamp(round(s), 1, 8196); + return clamp(round(s), 1, 8192); } #endregion function surface_array_free(arr) { #region diff --git a/#backups/scripts/surface_functions/surface_functions.gml.backup1 b/#backups/scripts/surface_functions/surface_functions.gml.backup1 index 1fc3f683f..8381b51f6 100644 --- a/#backups/scripts/surface_functions/surface_functions.gml.backup1 +++ b/#backups/scripts/surface_functions/surface_functions.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-26 15:43:13 +// 2024-04-30 13:16:28 #region ==================================== DRAW ==================================== function draw_surface_safe(surface, _x = 0, _y = 0) { #region @@ -133,12 +133,12 @@ } #endregion function surface_valid(surf, w, h, format = surface_rgba8unorm) { #region - INLINE - - if(!is_surface(surf)) return false; - var _sw = surface_get_width(surf); - var _sh = surface_get_height(surf); - var _f = surface_get_format(surf); + INLINE + + if(!is_surface(surf)) return false; + var _sw = surface_get_width(surf); + var _sh = surface_get_height(surf); + var _f = surface_get_format(surf); return _sw == w && _sh == h && _f == format; } #endregion @@ -219,8 +219,9 @@ function surface_get_pixel_ext(surface, _x, _y) { #region INLINE - - if(!is_surface(surface)) return 0; + + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + if(!surface_exists(surface)) return 0; var px = surface_getpixel_ext(surface, _x, _y); if(is_numeric(px)) return int64(px); @@ -474,7 +475,7 @@ if(!is_numeric(s)) return 1; if(is_infinity(s)) return 1; - return clamp(round(s), 1, 8196); + return clamp(round(s), 1, 8192); } #endregion function surface_array_free(arr) { #region diff --git a/#backups/scripts/windowManager/windowManager.gml.backup0 b/#backups/scripts/windowManager/windowManager.gml.backup0 new file mode 100644 index 000000000..e1d6edc4f --- /dev/null +++ b/#backups/scripts/windowManager/windowManager.gml.backup0 @@ -0,0 +1,258 @@ +// 2024-04-30 12:03:53 +#region defines + globalvar window_resize_padding; window_resize_padding = 6; + globalvar window_minimize_size; window_minimize_size = [ 1920, 1080 ]; + globalvar window_is_maximized; window_is_maximized = false; + globalvar window_is_fullscreen; window_is_fullscreen = false; + globalvar window_drag_status; window_drag_status = 0; + globalvar window_drag_hold; window_drag_hold = 0; + globalvar window_drag_mx; window_drag_mx = 0; + globalvar window_drag_my; window_drag_my = 0; + globalvar window_drag_sx; window_drag_sx = 0; + globalvar window_drag_sy; window_drag_sy = 0; + globalvar window_drag_sw; window_drag_sw = 0; + globalvar window_drag_sh; window_drag_sh = 0; + + globalvar window_min_w; window_min_w = 960; + globalvar window_min_h; window_min_h = 600; + + globalvar window_preminimize_rect; window_preminimize_rect = [ 0, 0, 1, 1 ]; + + #macro DISPLAY_REFRESH CURRENT_PANEL = panelSerialize(true); display_refresh(); +#endregion + +function winManInit() { #region + if(OS == os_macosx) mac_window_init(); + + window_preminimize_rect = [ 0, 0, 1, 1 ]; +} #endregion + +function winMan_getData(curr = true) { #region + INLINE + var _monitors = display_measure_all(); + if(!is_array(_monitors) || array_empty(_monitors)) + return [ 0, 0, display_get_width(), display_get_height(), + 0, 0, display_get_width(), display_get_height(), ]; + + var _x = window_get_x(); + var _y = window_get_y(); + + for( var i = 0, n = array_length(_monitors); i < n; i++ ) { + var _monitor = _monitors[i]; + if(!is_array(_monitor) || array_length(_monitor) < 8) continue; + + if(point_in_rectangle( + _x + WIN_W / 2, + _y + WIN_H / 2, + _monitor[0], + _monitor[1], + _monitor[0] + _monitor[2], + _monitor[1] + _monitor[3] + )) return _monitor; + } + + return _monitors[0]; +} #endregion + +function winMan_setRect(_x, _y, _w, _h) { #region + INLINE + _w = max(window_min_w, _w); + _h = max(window_min_h, _h); + + window_set_rectangle(_x, _y, _w, _h); +} #endregion + +function winMan_isMinimized() { #region + INLINE + if(OS == os_macosx) return false; + return gameframe_is_natively_minimized(); +} #endregion + +function winMan_Maximize() { #region + INLINE + if(gameframe_is_natively_minimized()) return; + window_is_maximized = true; + + var _mon = winMan_getData(); + winMan_setRect(_mon[4], _mon[5], _mon[6], _mon[7]); + gameframe_set_shadow(false); +} #endregion + +function winMan_Unmaximize() { #region + INLINE + if(gameframe_is_natively_minimized()) return; + window_is_maximized = false; + + var _mon = winMan_getData(); + + winMan_setRect( + _mon[4] + _mon[6] / 2 - window_minimize_size[0] / 2, + _mon[5] + _mon[7] / 2 - window_minimize_size[1] / 2, + window_minimize_size[0], + window_minimize_size[1] + ); + gameframe_set_shadow(true); +} #endregion + +function winMan_Minimize() { #region + INLINE + if(gameframe_is_natively_minimized()) return; + gameframe_syscommand(61472); +} #endregion + +function winMan_initDrag(_index) { #region + window_drag_status = _index; + window_drag_hold = 0; + window_drag_mx = mouse_raw_x; + window_drag_my = mouse_raw_y; + window_drag_sx = window_get_x(); + window_drag_sy = window_get_y(); + window_drag_sw = window_get_width(); + window_drag_sh = window_get_height(); +} #endregion + +function winMan_setFullscreen(full) { #region + if(full == window_is_fullscreen) return; + window_is_fullscreen = full; + + var _mon = winMan_getData(); + if(full) { + winMan_setRect(_mon[0], _mon[1], _mon[2], _mon[3]); + gameframe_set_shadow(false); + } else { + if(window_is_maximized) winMan_Maximize(); + else winMan_Unmaximize(); + } + + run_in(5, function() { DISPLAY_REFRESH }); +} #endregion + +function winManStep() { #region + if(OS == os_macosx) { + if(__win_to_dock) { + _window_set_showborder(window_handle(), true); + mac_minimize_to_dock(window_handle()); + __win_to_dock = false; + } else { + if(_window_get_showborder(window_handle())) + _window_set_showborder(window_handle(), false); + } + } + + if(window_drag_status == 0) return; + var _mx = window_drag_mx; + var _my = window_drag_my; + var _sx = window_drag_sx; + var _sy = window_drag_sy; + var _sw = window_drag_sw; + var _sh = window_drag_sh; + + var mx = mouse_raw_x; + var my = mouse_raw_y; + var sx = _sx; + var sy = _sy; + var sw = _sw; + var sh = _sh; + + if(window_drag_status & 0b10000) { + if(window_drag_hold == 0 && window_is_maximized) { + if(point_distance(mx, my, _mx, _my) > 8) + window_drag_hold = 1; + } else { + if(window_is_maximized) { + winMan_Unmaximize(); + window_drag_sw = window_minimize_size[0]; + window_drag_sh = window_minimize_size[1]; + } else { + sx = _sx + (mx - _mx); + sy = _sy + (my - _my); + + winMan_setRect(sx, sy, sw, sh); + } + } + } else { + if(window_drag_status & 0b0001) { + sw = _sw + (mx - _mx); + } + + if(window_drag_status & 0b0010) { + sh = max(window_min_h, _sh - (my - _my)); + sy = _sy + (_sh - sh); + } + + if(window_drag_status & 0b0100) { + sw = max(window_min_w, _sw - (mx - _mx)); + sx = _sx + (_sw - sw); + } + + if(window_drag_status & 0b1000) { + sh = _sh + (my - _my); + } + + winMan_setRect(sx, sy, sw, sh); + + if(mouse_release(mb_left)) { + DISPLAY_REFRESH + } + } + + if(mouse_release(mb_left)) { + window_minimize_size = [ sw, sh ]; + window_drag_status = 0; + } +} #endregion + +function winManDraw() { #region + if(window_is_maximized || window_is_fullscreen) return; + + var pd = window_resize_padding; + var hv = -1; + + var l = mouse_mx > 0 && mouse_mx < pd && mouse_my > 0 && mouse_my < WIN_H; + var r = mouse_mx > WIN_W - pd && mouse_mx < WIN_W && mouse_my > 0 && mouse_my < WIN_H; + var u = mouse_mx > 0 && mouse_mx < WIN_W && mouse_my > 0 && mouse_my < pd; + var d = mouse_mx > 0 && mouse_mx < WIN_W && mouse_my > WIN_H - pd && mouse_my < WIN_H; + + if(r) { + CURSOR = cr_size_we; + hv = 0b0001; + } + + if(u) { + CURSOR = cr_size_ns; + hv = 0b0010; + } + + if(l) { + CURSOR = cr_size_we; + hv = 0b0100; + } + + if(d) { + CURSOR = cr_size_ns; + hv = 0b1000; + } + + if(l && u) { + CURSOR = cr_size_nwse; + hv = 0b0110; + } + + if(r && d) { + CURSOR = cr_size_nwse; + hv = 0b1001; + } + + if(l && d) { + CURSOR = cr_size_nesw; + hv = 0b1100; + } + + if(r && u) { + CURSOR = cr_size_nesw; + hv = 0b0011; + } + + if(hv > -1 && mouse_press(mb_left)) + winMan_initDrag(hv); +} #endregion \ No newline at end of file diff --git a/#backups/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh.backup0 b/#backups/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh.backup0 new file mode 100644 index 000000000..d092f4681 --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh.backup0 @@ -0,0 +1,43 @@ +// 2024-04-30 14:01:28 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform sampler2D surface; +uniform int maxShape; +uniform int ignore; + +void main() { + vec4 zero = vec4(0.); + vec2 pxPos = v_vTexcoord * vec2(float(maxShape), 1.) - 0.5; + + int amo = 0; + vec4 list[1024]; + + for(float i = 0.; i <= dimension.x; i++) + for(float j = 0.; j <= dimension.y; j++) { + if(amo > maxShape) break; + + vec4 col = texture2D( surface, vec2(i, j) / dimension ); + if(ignore == 1 && col == zero) continue; + + bool dup = false; + for(int k = 0; k < amo; k++) { + if(col == list[k]) { + dup = true; + break; + } + } + + if(dup) continue; + + if(floor(pxPos.x - 1.) == float(amo)) { + gl_FragColor = col; + return; + } + list[amo] = col; + amo++; + } + + if(floor(pxPos.x) == 0.) gl_FragColor = vec4(amo, 0., 0., 0.); +} diff --git a/#backups/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh.backup1 b/#backups/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh.backup1 new file mode 100644 index 000000000..a54293abd --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh.backup1 @@ -0,0 +1,43 @@ +// 2024-04-30 14:01:22 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform sampler2D surface; +uniform int maxShape; +uniform int ignore; + +void main() { + vec4 zero = vec4(0.); + vec2 pxPos = v_vTexcoord * vec2(float(maxShape), 1.); + + int amo = 0; + vec4 list[1024]; + + for(float i = 0.; i <= dimension.x; i++) + for(float j = 0.; j <= dimension.y; j++) { + if(amo > maxShape) break; + + vec4 col = texture2D( surface, vec2(i, j) / dimension ); + if(ignore == 1 && col == zero) continue; + + bool dup = false; + for(int k = 0; k < amo; k++) { + if(col == list[k]) { + dup = true; + break; + } + } + + if(dup) continue; + + if(floor(pxPos.x - 1.) == float(amo)) { + gl_FragColor = col; + return; + } + list[amo] = col; + amo++; + } + + if(floor(pxPos.x) == 0.) gl_FragColor = vec4(amo, 0., 0., 0.); +} diff --git a/#backups/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh.backup0 b/#backups/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh.backup0 new file mode 100644 index 000000000..414843c0d --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh.backup0 @@ -0,0 +1,17 @@ +// 2024-04-30 13:45:53 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform int ignore; + +float sampVal(vec4 col) { return length(col.rgb) * col.a; } + +void main() { + vec2 px = v_vTexcoord * dimension - .5; + + if(ignore == 1 && sampVal(texture2D( gm_BaseTexture, v_vTexcoord )) == 0.) + gl_FragColor = vec4(0.); + else + gl_FragColor = vec4(px.x, px.y, px.x, px.y); +} diff --git a/#backups/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh.backup1 b/#backups/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh.backup1 new file mode 100644 index 000000000..28be1691b --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh.backup1 @@ -0,0 +1,17 @@ +// 2024-04-30 13:42:45 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform int ignore; + +float sampVal(vec4 col) { return length(col.rgb) * col.a; } + +void main() { + vec2 px = v_vTexcoord * dimension - .5; + + if(ignore == 1 && sampVal(texture2D( gm_BaseTexture, v_vTexcoord )) == 0.) + gl_FragColor = vec4(0.); + else + gl_FragColor = vec4(px.x, px.y, px.x, px.y); +} diff --git a/#backups/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh.backup0 b/#backups/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh.backup0 new file mode 100644 index 000000000..ff26b0cc9 --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh.backup0 @@ -0,0 +1,42 @@ +// 2024-04-30 14:12:59 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform float threshold; +uniform int ignore; +uniform sampler2D map; + +vec3 sampVal(vec4 col) { return col.rgb * col.a; } + +void main() { + vec3 baseCol = sampVal(texture2D( map, v_vTexcoord )); + + if(ignore == 1 && baseCol == vec3(0.)) { + gl_FragColor = vec4(0.); + return; + } + + vec2 tx = 1. / dimension; + vec4 _c = texture2D( gm_BaseTexture, v_vTexcoord ); + vec2 _index_min = _c.xy; + vec2 _index_max = _c.zw; + + for(float i = -1.; i <= 1.; i++) + for(float j = -1.; j <= 1.; j++) { + vec2 pos = clamp(v_vTexcoord + vec2(i, j) * tx, 0., 1.); + vec3 samCl = sampVal(texture2D( map, pos )); + + if(ignore == 1 && samCl == vec3(0.)) continue; + + if(distance(samCl, baseCol) <= threshold) { + vec4 _col = texture2D( gm_BaseTexture, pos ); + _index_min.x = min(_index_min.x, _col.r); + _index_min.y = min(_index_min.y, _col.g); + + _index_max.x = max(_index_max.x, _col.b); + _index_max.y = max(_index_max.y, _col.a); + } + } + gl_FragColor = vec4(_index_min, _index_max ); +} diff --git a/#backups/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh.backup1 b/#backups/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh.backup1 new file mode 100644 index 000000000..ecff44fd3 --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh.backup1 @@ -0,0 +1,42 @@ +// 2024-04-30 13:49:21 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform float threshold; +uniform int ignore; +uniform sampler2D map; + +vec3 sampVal(vec4 col) { return col.rgb * col.a; } + +void main() { + vec3 baseCol = sampVal(texture2D( map, v_vTexcoord )); + + if(ignore == 1 && baseCol == vec3(0.)) { + gl_FragColor = vec4(0.); + return; + } + + vec2 tx = 1. / dimension; + vec4 _c = texture2D( gm_BaseTexture, v_vTexcoord ); + vec2 _index_min = _c.xy; + vec2 _index_max = _c.zw; + + for(float i = -1.; i <= 1.; i++) + for(float j = -1.; j <= 1.; j++) { + vec2 pos = clamp(v_vTexcoord + vec2(i, j) * tx, 0., 1.); + vec3 samCl = sampVal(texture2D( map, pos )); + + if(ignore == 1 && samCl == vec3(0.)) continue; + + if(distance(samCl, baseCol) <= threshold) { + vec4 _col = texture2D( gm_BaseTexture, pos ); + _index_min.x = min(_index_min.x, _col.r); + _index_min.y = min(_index_min.y, _col.g); + + _index_max.x = max(_index_max.x, _col.b); + _index_max.y = max(_index_max.y, _col.a); + } + } + gl_FragColor = vec4(_index_min, _index_max ); +} diff --git a/#backups/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh.backup0 b/#backups/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh.backup0 new file mode 100644 index 000000000..69a326258 --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh.backup0 @@ -0,0 +1,19 @@ +// 2024-04-30 13:53:11 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform sampler2D original; +uniform vec4 color; + +uniform int override; +uniform vec4 overColor; + +void main() { + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + + gl_FragColor = vec4(0.); + + if(distance(col, color) < 1.) + gl_FragColor = override == 1? overColor : texture2D( original, v_vTexcoord ); + +} diff --git a/#backups/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh.backup1 b/#backups/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh.backup1 new file mode 100644 index 000000000..657460c95 --- /dev/null +++ b/#backups/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh.backup1 @@ -0,0 +1,19 @@ +// 2024-04-30 13:53:09 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform sampler2D original; +uniform vec4 color; + +uniform int override; +uniform vec4 overColor; + +void main() { + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + + gl_FragColor = vec4(0.); + + if(distance(col, color) < 1.) + gl_FragColor = override == 1? overColor : texture2D( original, v_vTexcoord ); + +} diff --git a/scripts/node_cache/node_cache.gml b/scripts/node_cache/node_cache.gml index 6ecaf3f95..f764459d0 100644 --- a/scripts/node_cache/node_cache.gml +++ b/scripts/node_cache/node_cache.gml @@ -36,7 +36,7 @@ function Node_Cache(_x, _y, _group = noone) : __Node_Cache(_x, _y, _group) const } #endregion static update = function() { #region - if(recoverCache()) return; + if(recoverCache() || cache_loading) return; if(!inputs[| 0].value_from) return; if(!inputs[| 0].value_from.node.renderActive) { diff --git a/scripts/node_cache_array/node_cache_array.gml b/scripts/node_cache_array/node_cache_array.gml index 8de2410ad..0629f7b4b 100644 --- a/scripts/node_cache_array/node_cache_array.gml +++ b/scripts/node_cache_array/node_cache_array.gml @@ -45,6 +45,8 @@ function Node_Cache_Array(_x, _y, _group = noone) : __Node_Cache(_x, _y, _group) } #endregion static update = function() { #region + if(cache_loading) return; + if(!inputs[| 0].value_from) return; if(!inputs[| 0].value_from.node.renderActive) { if(!cacheExist(CURRENT_FRAME)) diff --git a/scripts/node_cache_base/node_cache_base.gml b/scripts/node_cache_base/node_cache_base.gml index 9364162d7..baa408f48 100644 --- a/scripts/node_cache_base/node_cache_base.gml +++ b/scripts/node_cache_base/node_cache_base.gml @@ -38,6 +38,7 @@ function __Node_Cache(_x, _y, _group = noone) : Node(_x, _y, _group) constructor static enableNodeGroup = function() { #region if(LOADING || APPENDING) return; + print("Enacle"); for( var i = 0, n = array_length(cache_group_members); i < n; i++ ) cache_group_members[i].renderActive = true; @@ -46,6 +47,7 @@ function __Node_Cache(_x, _y, _group = noone) : Node(_x, _y, _group) constructor static disableNodeGroup = function() { #region if(LOADING || APPENDING) return; + print("Disable"); if(IS_PLAYING && IS_LAST_FRAME) for( var i = 0, n = array_length(cache_group_members); i < n; i++ ) diff --git a/scripts/node_pack_sprites/node_pack_sprites.gml b/scripts/node_pack_sprites/node_pack_sprites.gml index a2ed629f6..0d7f4a098 100644 --- a/scripts/node_pack_sprites/node_pack_sprites.gml +++ b/scripts/node_pack_sprites/node_pack_sprites.gml @@ -37,10 +37,10 @@ function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _sh = surface_get_height_safe(_surf); draw_rectangle( - _x + _s * (_sx + spac), - _y + _s * (_sy + spac), - _x + _s * (_sx + _sw - spac), - _y + _s * (_sy + _sh - spac), true); + _x + _s * (_sx), + _y + _s * (_sy), + _x + _s * (_sx + _sw), + _y + _s * (_sy + _sh), true); } } #endregion @@ -77,14 +77,17 @@ function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _hei = getInputData(3); pack = sprite_pack_skyline(_rects, _wid, _hei); break; + case 1 : var _wid = getInputData(2); pack = sprite_pack_shelf(_rects, _wid); break; + case 2 : var _hei = getInputData(3); pack = sprite_pack_bottom_left(_rects, _hei); break; + case 3 : pack = sprite_pack_best_fit(_rects); break; diff --git a/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml b/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml index a1b11071f..0d81e9d69 100644 --- a/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml +++ b/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml @@ -378,7 +378,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) ww += padd[0] + padd[2]; hh += padd[1] + padd[3]; - _out[i] = surface_verify(array_safe_get_fast(_out, i), ww, hh, cDep); + _out[i] = surface_verify(array_safe_get_fast(_out, i), surface_valid_size(ww), surface_valid_size(hh), cDep); if(clear) surface_clear(_out[i]); } diff --git a/scripts/node_seperate_shape/node_seperate_shape.gml b/scripts/node_seperate_shape/node_seperate_shape.gml index d83d1518e..a4fe1bbd5 100644 --- a/scripts/node_seperate_shape/node_seperate_shape.gml +++ b/scripts/node_seperate_shape/node_seperate_shape.gml @@ -26,26 +26,11 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons ["Override Color", true, 2], 3, ] - attribute_surface_depth(); - - temp_surface = [ surface_create(1, 1), surface_create(1, 1) ]; + temp_surface = [ noone, noone ]; surface_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2); surface_w = 1; surface_h = 1; - attributes.max_shape = 64; - array_push(attributeEditors, ["Maximum shapes", function() { return attributes.max_shape; }, - new textBox(TEXTBOX_INPUT.number, function(val) { - attributes.max_shape = val; - triggerRender(); - })]); - - function get_color_buffer(_x, _y) { - buffer_seek(surface_buffer, buffer_seek_start, (surface_w * _y + _x) * 4); - var c = buffer_read(surface_buffer, buffer_u32); - return c; - } - _prev_type = -1; static onInspector1Update = function() { separateShape(); } @@ -66,23 +51,17 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons var ww = surface_get_width_safe(_inSurf); var hh = surface_get_height_safe(_inSurf); - surface_w = ww; - surface_h = hh; - for(var i = 0; i < 2; i++) { - temp_surface[i] = surface_verify(temp_surface[i], ww, hh, attrDepth()); - - surface_set_target(temp_surface[i]); - DRAW_CLEAR - surface_reset_target(); - } + for(var i = 0; i < 2; i++) temp_surface[i] = surface_verify(temp_surface[i], ww, hh, surface_rgba32float); #region region indexing surface_set_shader(temp_surface[1], sh_seperate_shape_index); - shader_set_i("ignore", _ignore); + shader_set_i("ignore", _ignore); + shader_set_f("dimension", ww, hh); + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, ww, hh); surface_reset_shader(); - + shader_set(sh_seperate_shape_ite); shader_set_i("ignore", _ignore); shader_set_f("dimension", ww, hh); @@ -94,9 +73,9 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons for(var i = 0; i <= iteration; i++) { var bg = i % 2; var fg = !bg; - + surface_set_shader(temp_surface[bg], sh_seperate_shape_ite,, BLEND.over); - draw_surface_safe(temp_surface[fg], 0, 0); + draw_surface_safe(temp_surface[fg]); surface_reset_shader(); res_index = bg; @@ -104,74 +83,72 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons #endregion #region count and match color - var _pixel_surface = surface_create_valid(attributes.max_shape, 1); - surface_set_shader(_pixel_surface, sh_seperate_shape_counter); - shader_set_surface("surface", temp_surface[res_index]); - shader_set_f("dimension", [ ww, hh ]); - shader_set_i("maxShape", attributes.max_shape); - shader_set_i("ignore", _ignore); + var i = 0, pxc = ww * hh; + var reg = ds_map_create(); - draw_sprite_ext(s_fx_pixel, 0, 0, 0, attributes.max_shape, 1, 0, c_white, 1); - surface_reset_shader(); - - var px = surface_get_pixel(_pixel_surface, 0, 0); + var b = buffer_create(pxc * 16, buffer_fixed, 1); + buffer_get_surface(b, temp_surface[res_index], 0); + buffer_seek(b, buffer_seek_start, 0); + + repeat(pxc) { + var _r = buffer_read(b, buffer_f32); + var _g = buffer_read(b, buffer_f32); + var _b = buffer_read(b, buffer_f32); + var _a = buffer_read(b, buffer_f32); + + if(_r == 0 && _g == 0 && _b == 0 && _a == 0) continue; + + reg[? _g * ww + _r] = [ _r, _g, _b, _a ]; + } + + var px = ds_map_size(reg); if(px == 0) return; #endregion #region extract region var _outSurf, _val; _val = array_create(px); - outputs[| 0].setValue(_val); var _atlas = array_create(px); - var _pad = 0; - - buffer_delete(surface_buffer); - surface_buffer = buffer_create(ww * hh * 4, buffer_fixed, 2); - buffer_get_surface(surface_buffer, temp_surface[res_index], 0); + var _reg = ds_map_keys_to_array(reg); + var _ind = 0; for(var i = 0; i < px; i++) { - var ccx = surface_get_pixel_ext(_pixel_surface, 1 + i, 0); - var alpha = (ccx >> 24) & 255; - var blue = (ccx >> 16) & 255; - var green = (ccx >> 8) & 255; - var red = ccx & 255; + var _k = _reg[i]; + var ccx = reg[? _k]; - var min_x = floor(red / 255 * ww); - var min_y = floor(green / 255 * hh); - var max_x = ceil(blue / 255 * ww); - var max_y = ceil(alpha / 255 * hh); - var t = max_y; - var b = min_y; - var l = max_x; - var r = min_x; + var min_x = round(ccx[0]); + var min_y = round(ccx[1]); + var max_x = round(ccx[2]); + var max_y = round(ccx[3]); - for( var j = min_x; j < max_x; j++ ) - for( var k = min_y; k < max_y; k++ ) { - var _sc = get_color_buffer(j, k); - if(_sc != ccx) continue; - - t = min(t, k); - b = max(b, k); - l = min(l, j); - r = max(r, j); - } + var _sw = max_x - min_x + 1; + var _sh = max_y - min_y + 1; - _outSurf = surface_create_valid(r - l + 1 + _pad * 2, b - t + 1 + _pad * 2); - _val[i] = _outSurf; + if(_sw <= 1 || _sh <= 1) continue; + + _outSurf = surface_create_valid(_sw, _sh); + _val[_ind] = _outSurf; surface_set_shader(_outSurf, sh_seperate_shape_sep); shader_set_surface("original", _inSurf); - shader_set_f("color", red, green, blue, alpha); - shader_set_i("override", _ovr); - shader_set_f("overColor", colToVec4(_ovrclr)); - - draw_surface_safe(temp_surface[res_index], -l + _pad, -t + _pad); + shader_set_f("color", ccx); + shader_set_i("override", _ovr); + shader_set_color("overColor", _ovrclr); + + draw_surface_safe(temp_surface[res_index], -min_x, -min_y); surface_reset_shader(); - _atlas[i] = new SurfaceAtlas(_outSurf, l, t).setOrginalSurface(_inSurf); + _atlas[_ind] = new SurfaceAtlas(_outSurf, min_x, min_y).setOrginalSurface(_inSurf); + _ind++; } + array_resize(_val, _ind); + array_resize(_atlas, _ind); + + ds_map_destroy(reg); + + outputs[| 0].setValue(_val); outputs[| 1].setValue(_atlas); #endregion } diff --git a/scripts/pack_best_fit/pack_best_fit.gml b/scripts/pack_best_fit/pack_best_fit.gml index 597b45500..f4001656b 100644 --- a/scripts/pack_best_fit/pack_best_fit.gml +++ b/scripts/pack_best_fit/pack_best_fit.gml @@ -1,31 +1,26 @@ function sprite_pack_best_fit(rectangles) { - array_sort(rectangles, function(rect1, rect2) { - return rect2.w * rect2.h - rect1.w * rect1.h; - }); - var area = new Rectangle(0, 0, 0, 0); + var area = new Rectangle(0, 0, 0, 0); + if(array_length(rectangles) <= 1) return [ area, rectangles ]; - var grW = 1; - var grH = 1; + array_sort(rectangles, function(rect1, rect2) { return rect2.w * rect2.h - rect1.w * rect1.h; }); + + var grW = rectangles[0].w; + var grH = rectangles[0].h; var _or, _nr; - for (var i = 0; i < array_length(rectangles); i++) { + for (var i = 1; i < array_length(rectangles); i++) { _nr = rectangles[i]; - if(i) { - grW = gcd(_nr.w, grW); - grH = gcd(_nr.h, grH); - } else { - grW = _nr.w; - grH = _nr.h; - } + grW = gcd(_nr.w, grW); + grH = gcd(_nr.h, grH); } for (var i = 0; i < array_length(rectangles); i++) { var rect = rectangles[i]; var bestSpace = noone; - var bestArea = new Rectangle(0, 0, 0, 0); + var bestArea = new Rectangle(0, 0, 0, 0); for (var xx = area.x; xx <= area.x + area.w; xx += grW) for (var yy = area.y; yy <= area.y + area.h; yy += grH) { diff --git a/scripts/panel_data/panel_data.gml b/scripts/panel_data/panel_data.gml index 8fab95444..353ed8639 100644 --- a/scripts/panel_data/panel_data.gml +++ b/scripts/panel_data/panel_data.gml @@ -947,6 +947,9 @@ function PanelContent() constructor { #region static checkClosable = function() { return true; } static onClose = function() {} + + static serialize = function() { return { name: instanceof(self) }; } + static deserialize = function(data) { return self; } } #endregion function setFocus(target, fstring = noone) { #region diff --git a/scripts/panel_function/panel_function.gml b/scripts/panel_function/panel_function.gml index 98bedd18d..73f2af178 100644 --- a/scripts/panel_function/panel_function.gml +++ b/scripts/panel_function/panel_function.gml @@ -47,11 +47,11 @@ function getPanelFromName(name, create = false) { #region switch(name) { - case "Panel_Menu" : return (create || findPanel(name))? new Panel_Menu() : PANEL_MENU; - case "Panel_Inspector" : return (create || findPanel(name))? new Panel_Inspector() : PANEL_INSPECTOR; - case "Panel_Animation" : return (create || findPanel(name))? new Panel_Animation() : PANEL_ANIMATION; - case "Panel_Preview" : return (create || findPanel(name))? new Panel_Preview() : PANEL_PREVIEW; - case "Panel_Graph" : return (create || findPanel(name))? new Panel_Graph() : PANEL_GRAPH; + case "Panel_Menu" : var p = (create || findPanel(name))? new Panel_Menu() : PANEL_MENU; PANEL_MENU = p; return p; + case "Panel_Inspector" : var p = (create || findPanel(name))? new Panel_Inspector() : PANEL_INSPECTOR; PANEL_INSPECTOR = p; return p; + case "Panel_Animation" : var p = (create || findPanel(name))? new Panel_Animation() : PANEL_ANIMATION; PANEL_ANIMATION = p; return p; + case "Panel_Preview" : var p = (create || findPanel(name))? new Panel_Preview() : PANEL_PREVIEW; PANEL_PREVIEW = p; return p; + case "Panel_Graph" : var p = (create || findPanel(name))? new Panel_Graph() : PANEL_GRAPH; PANEL_GRAPH = p; return p; case "Panel_Collection" : return new Panel_Collection(); case "Panel_Workspace" : return new Panel_Workspace(); @@ -75,6 +75,7 @@ var cont = str.content; if(variable_struct_exists(str, "split")) { + var pan = panel; if(str.split == "v") pan = panel.split_v(ui(str.width)); @@ -86,10 +87,17 @@ loadPanelStruct(pan[1], cont[1]); } } else { + if(!is_array(cont)) cont = [ cont ]; for( var i = 0, n = array_length(cont); i < n; i++ ) { - var _cont = getPanelFromName(cont[i]) - if(_cont != noone) panel.setContent(_cont); + var _content = cont[i]; + var _key = is_struct(_content)? _content.name : _content; + + var _pnCont = getPanelFromName(_key, true); + if(_pnCont == noone) continue; + + panel.setContent(_pnCont); + if(is_struct(_content)) _pnCont.deserialize(_content); } } } #endregion @@ -326,34 +334,33 @@ } } #endregion - function panelSerialize() { #region - var cont = {}; - cont.panel = _panelSerialize(PANEL_MAIN); - return cont; + function panelSerialize(_content = false) { #region + return { panel : _panelSerialize(PANEL_MAIN, _content) }; } #endregion - function _panelSerialize(panel) { #region + function _panelSerialize(_panel, _content = false) { #region var cont = {}; var ind = 0; cont.content = []; - if(panel.split != "" && ds_list_size(panel.childs) == 2) { - cont.split = panel.split; - if(panel.split == "h") { - ind = panel.childs[| 1].w < panel.childs[| 0].w; - cont.width = panel.childs[| ind].w * (panel.childs[| ind].x == panel.x? 1 : -1); + if(_panel.split != "" && ds_list_size(_panel.childs) == 2) { + cont.split = _panel.split; + if(_panel.split == "h") { + ind = _panel.childs[| 1].w < _panel.childs[| 0].w; + cont.width = _panel.childs[| ind].w * (_panel.childs[| ind].x == _panel.x? 1 : -1); } else { - ind = panel.childs[| 1].h < panel.childs[| 0].h; - cont.width = panel.childs[| ind].h * (panel.childs[| ind].y == panel.y? 1 : -1); + ind = _panel.childs[| 1].h < _panel.childs[| 0].h; + cont.width = _panel.childs[| ind].h * (_panel.childs[| ind].y == _panel.y? 1 : -1); } - ind = panel.childs[| 1].x == panel.x && panel.childs[| 1].y == panel.y; - for( var i = 0; i < ds_list_size(panel.childs); i++ ) - cont.content[i] = _panelSerialize(panel.childs[| (ind + i) % 2]); + ind = _panel.childs[| 1].x == _panel.x && _panel.childs[| 1].y == _panel.y; + for( var i = 0; i < ds_list_size(_panel.childs); i++ ) + cont.content[i] = _panelSerialize(_panel.childs[| (ind + i) % 2], _content); + } else { - for( var i = 0, n = array_length(panel.content); i < n; i++ ) - cont.content[i] = instanceof(panel.content[i]); + for( var i = 0, n = array_length(_panel.content); i < n; i++ ) + cont.content[i] = _content? _panel.content[i].serialize() : instanceof(_panel.content[i]); } return cont; diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index 6a84561f7..1645d71df 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -131,14 +131,21 @@ function connectionParameter() constructor { #region } #endregion function Panel_Graph(project = PROJECT) : PanelContent() constructor { - title = __txt("Graph"); + title = __txt("Graph"); title_raw = ""; context_str = "Graph"; - icon = THEME.panel_graph_icon; + icon = THEME.panel_graph_icon; + + function setTitle() { + title_raw = project.path == ""? "New project" : filename_name_only(project.path); + title = title_raw + (project.modified? "*" : ""); + } static setProject = function(project) { self.project = project; nodes_list = project.nodes; + + setTitle(); } setProject(project); @@ -1801,15 +1808,9 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { context_frame_ey = context_frame_sy + 16; } #endregion - function setTitle() { #region - title = title_raw + (project.modified? "*" : ""); - } #endregion - function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<< if(!project.active) return; - if(project.path == "") title_raw = "New project"; - else title_raw = filename_name_only(project.path); dragGraph(); var context = getCurrentContext(); @@ -2074,32 +2075,42 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { var _n0 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[0] : nodes_selecting[1]; var _n1 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[1] : nodes_selecting[0]; - if(_n0.outputs[| 0].type != VALUE_TYPE.surface || _n1.outputs[| 0].type != VALUE_TYPE.surface) return; - var cx = max(_n0.x, _n1.x) + 160; var cy = round((_n0.y + _n1.y) / 2 / 32) * 32; - var _blend = new Node_Blend(cx, cy, getCurrentContext()); - _blend.inputs[| 0].setFrom(_n0.outputs[| 0]); - _blend.inputs[| 1].setFrom(_n1.outputs[| 0]); + var _j0 = _n0.outputs[| 0]; + var _j1 = _n1.outputs[| 0]; + + if(_j0.type == VALUE_TYPE.surface && _j1.type == VALUE_TYPE.surface) { + var _blend = new Node_Blend(cx, cy, getCurrentContext()); + _blend.inputs[| 0].setFrom(_j0); + _blend.inputs[| 1].setFrom(_j1); + + } else if((_j0.type == VALUE_TYPE.integer || _j0.type == VALUE_TYPE.float) && (_j1.type == VALUE_TYPE.integer || _j1.type == VALUE_TYPE.float)) { + var _blend = new Node_Math(cx, cy, getCurrentContext()); + _blend.inputs[| 1].setFrom(_j0); + _blend.inputs[| 2].setFrom(_j1); + + } nodes_selecting = []; } #endregion - + function doCompose() { #region if(array_empty(nodes_selecting)) return; - var cx = nodes_selecting[0].x; - var cy = 0; - var pr = ds_priority_create(); - var amo = array_length(nodes_selecting); - var len = 0; + var cx = nodes_selecting[0].x; + var cy = 0; + var pr = ds_priority_create(); + var amo = array_length(nodes_selecting); + var len = 0; for(var i = 0; i < amo; i++) { var _node = nodes_selecting[i]; if(ds_list_size(_node.outputs) == 0) continue; + if(_node.outputs[| 0].type != VALUE_TYPE.surface) continue; - + cx = max(cx, _node.x); cy += _node.y; @@ -2110,7 +2121,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { cx = cx + 160; cy = round(cy / len / 32) * 32; - var _compose = nodeBuild("Node_Composite", cx, cy); + var _compose = new Node_Composite(cx, cy, getCurrentContext()); repeat(len) { var _node = ds_priority_delete_min(pr); @@ -2339,6 +2350,18 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { static onFullScreen = function() { run_in(1, fullView); } + static serialize = function() { + return { + name: instanceof(self), + project, + }; + } + + static deserialize = function(data) { + setProject(data.project); + return self; + } + function close() { #region var panels = findPanels("Panel_Graph"); for( var i = 0, n = array_length(panels); i < n; i++ ) { diff --git a/scripts/panel_inspector/panel_inspector.gml b/scripts/panel_inspector/panel_inspector.gml index 509d0a72e..946797247 100644 --- a/scripts/panel_inspector/panel_inspector.gml +++ b/scripts/panel_inspector/panel_inspector.gml @@ -1022,4 +1022,20 @@ function Panel_Inspector() : PanelContent() constructor { if(!locked && PANEL_GRAPH.getFocusingNode() && inspecting != PANEL_GRAPH.getFocusingNode()) setInspecting(PANEL_GRAPH.getFocusingNode()); } #endregion + + static serialize = function() { + return { + name: instanceof(self), + inspecting, + inspectings, + }; + } + + static deserialize = function(data) { + inspecting = data.inspecting; + inspectings = data.inspectings; + + return self; + } + } \ No newline at end of file diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index 1506052b5..b7dad535d 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -1775,4 +1775,20 @@ function Panel_Preview() : PanelContent() constructor { ind++; } } #endregion + + + static serialize = function() { + return { + name: instanceof(self), + preview_node, + }; + } + + static deserialize = function(data) { + preview_node = data.preview_node; + + run_in(1, fullView) + return self; + } + } \ No newline at end of file diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index a8c73d581..9d300cc2c 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -132,12 +132,12 @@ } #endregion function surface_valid(surf, w, h, format = surface_rgba8unorm) { #region - INLINE - - if(!is_surface(surf)) return false; - var _sw = surface_get_width(surf); - var _sh = surface_get_height(surf); - var _f = surface_get_format(surf); + INLINE + + if(!is_surface(surf)) return false; + var _sw = surface_get_width(surf); + var _sh = surface_get_height(surf); + var _f = surface_get_format(surf); return _sw == w && _sh == h && _f == format; } #endregion @@ -472,9 +472,9 @@ function surface_valid_size(s) { #region INLINE - if(!is_numeric(s)) return 1; + if(!is_numeric(s)) return 1; if(is_infinity(s)) return 1; - return clamp(round(s), 1, 8196); + return clamp(round(s), 1, 8192); } #endregion function surface_array_free(arr) { #region diff --git a/scripts/windowManager/windowManager.gml b/scripts/windowManager/windowManager.gml index b66578845..7964947ae 100644 --- a/scripts/windowManager/windowManager.gml +++ b/scripts/windowManager/windowManager.gml @@ -17,7 +17,7 @@ globalvar window_preminimize_rect; window_preminimize_rect = [ 0, 0, 1, 1 ]; - #macro DISPLAY_REFRESH CURRENT_PANEL = panelSerialize(); display_refresh(); + #macro DISPLAY_REFRESH CURRENT_PANEL = panelSerialize(true); display_refresh(); #endregion function winManInit() { #region diff --git a/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh b/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh index 8e2da01a0..426348e30 100644 --- a/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh +++ b/shaders/sh_seperate_shape_counter/sh_seperate_shape_counter.fsh @@ -1,6 +1,3 @@ -// -// Simple passthrough fragment shader -// varying vec2 v_vTexcoord; varying vec4 v_vColour; @@ -10,8 +7,8 @@ uniform int maxShape; uniform int ignore; void main() { - vec4 zero = vec4(0.); - vec2 pxPos = v_vTexcoord * vec2(float(maxShape), 1.); + vec4 zero = vec4(0.); + vec2 pxPos = v_vTexcoord * vec2(float(maxShape), 1.) - 0.5; int amo = 0; vec4 list[1024]; @@ -41,6 +38,5 @@ void main() { amo++; } - if(floor(pxPos.x) == 0.) - gl_FragColor = vec4(float(amo) / 255., 0., 0., 1.); + if(floor(pxPos.x) == 0.) gl_FragColor = vec4(amo, 0., 0., 0.); } diff --git a/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh b/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh index a2c9adca3..5a41eb9b3 100644 --- a/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh +++ b/shaders/sh_seperate_shape_index/sh_seperate_shape_index.fsh @@ -1,16 +1,16 @@ -// -// Simple passthrough fragment shader -// varying vec2 v_vTexcoord; varying vec4 v_vColour; -uniform int ignore; +uniform vec2 dimension; +uniform int ignore; float sampVal(vec4 col) { return length(col.rgb) * col.a; } void main() { + vec2 px = v_vTexcoord * dimension - .5; + if(ignore == 1 && sampVal(texture2D( gm_BaseTexture, v_vTexcoord )) == 0.) gl_FragColor = vec4(0.); else - gl_FragColor = vec4(v_vTexcoord.x, v_vTexcoord.y, v_vTexcoord.x, v_vTexcoord.y); + gl_FragColor = vec4(px.x, px.y, px.x, px.y); } diff --git a/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh b/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh index 2e68e6d72..a06f7ca51 100644 --- a/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh +++ b/shaders/sh_seperate_shape_ite/sh_seperate_shape_ite.fsh @@ -1,6 +1,3 @@ -// -// Simple passthrough fragment shader -// varying vec2 v_vTexcoord; varying vec4 v_vColour; @@ -12,7 +9,6 @@ uniform sampler2D map; vec3 sampVal(vec4 col) { return col.rgb * col.a; } void main() { - vec4 zero = vec4(0.); vec3 baseCol = sampVal(texture2D( map, v_vTexcoord )); if(ignore == 1 && baseCol == vec3(0.)) { @@ -20,16 +16,17 @@ void main() { return; } - vec2 _index_min = v_vTexcoord; - vec2 _index_max = v_vTexcoord; + vec2 tx = 1. / dimension; + vec4 _c = texture2D( gm_BaseTexture, v_vTexcoord ); + vec2 _index_min = _c.xy; + vec2 _index_max = _c.zw; for(float i = -1.; i <= 1.; i++) for(float j = -1.; j <= 1.; j++) { - vec2 pos = clamp(v_vTexcoord + vec2(i, j) / dimension, 0., 1.); + vec2 pos = clamp(v_vTexcoord + vec2(i, j) * tx, 0., 1.); vec3 samCl = sampVal(texture2D( map, pos )); - if(ignore == 1 && samCl == vec3(0.)) - continue; + if(ignore == 1 && samCl == vec3(0.)) continue; if(distance(samCl, baseCol) <= threshold) { vec4 _col = texture2D( gm_BaseTexture, pos ); @@ -40,5 +37,5 @@ void main() { _index_max.y = max(_index_max.y, _col.a); } } - gl_FragColor = vec4(_index_min.x, _index_min.y, _index_max.x, _index_max.y ); + gl_FragColor = vec4(_index_min, _index_max ); } diff --git a/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh b/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh index 452f6b08b..a537889dd 100644 --- a/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh +++ b/shaders/sh_seperate_shape_sep/sh_seperate_shape_sep.fsh @@ -1,6 +1,3 @@ -// -// Simple passthrough fragment shader -// varying vec2 v_vTexcoord; varying vec4 v_vColour; @@ -13,8 +10,9 @@ uniform vec4 overColor; void main() { vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); - if(distance(col * 255., color) < 1.) + gl_FragColor = vec4(0.); + + if(distance(col, color) < 1.) gl_FragColor = override == 1? overColor : texture2D( original, v_vTexcoord ); - else - gl_FragColor = vec4(0.); + }