mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2025-01-26 21:08:18 +01:00
sep shape, graph, ui
This commit is contained in:
parent
bb3693fe4e
commit
0b1af80334
55 changed files with 5490 additions and 298 deletions
71
#backups/scripts/node_cache/node_cache.gml.backup0
Normal file
71
#backups/scripts/node_cache/node_cache.gml.backup0
Normal file
|
@ -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
|
||||
}
|
71
#backups/scripts/node_cache/node_cache.gml.backup1
Normal file
71
#backups/scripts/node_cache/node_cache.gml.backup1
Normal file
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
252
#backups/scripts/node_cache_base/node_cache_base.gml.backup0
Normal file
252
#backups/scripts/node_cache_base/node_cache_base.gml.backup0
Normal file
|
@ -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(); }
|
||||
}
|
252
#backups/scripts/node_cache_base/node_cache_base.gml.backup1
Normal file
252
#backups/scripts/node_cache_base/node_cache_base.gml.backup1
Normal file
|
@ -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(); }
|
||||
}
|
124
#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup0
Normal file
124
#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup0
Normal file
|
@ -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
|
||||
}
|
124
#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup1
Normal file
124
#backups/scripts/node_pack_sprites/node_pack_sprites.gml.backup1
Normal file
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
60
#backups/scripts/pack_best_fit/pack_best_fit.gml.backup0
Normal file
60
#backups/scripts/pack_best_fit/pack_best_fit.gml.backup0
Normal file
|
@ -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 ];
|
||||
}
|
60
#backups/scripts/pack_best_fit/pack_best_fit.gml.backup1
Normal file
60
#backups/scripts/pack_best_fit/pack_best_fit.gml.backup1
Normal file
|
@ -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 ];
|
||||
}
|
969
#backups/scripts/panel_data/panel_data.gml.backup0
Normal file
969
#backups/scripts/panel_data/panel_data.gml.backup0
Normal file
|
@ -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
|
969
#backups/scripts/panel_data/panel_data.gml.backup1
Normal file
969
#backups/scripts/panel_data/panel_data.gml.backup1
Normal file
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++ ) {
|
||||
|
|
|
@ -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++ ) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// 2024-04-30 10:57:23
|
||||
// 2024-04-30 13:08:55
|
||||
enum RENDER_TYPE {
|
||||
none = 0,
|
||||
partial = 1,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 2024-04-29 18:32:52
|
||||
// 2024-04-30 13:08:48
|
||||
enum RENDER_TYPE {
|
||||
none = 0,
|
||||
partial = 1,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
258
#backups/scripts/windowManager/windowManager.gml.backup0
Normal file
258
#backups/scripts/windowManager/windowManager.gml.backup0
Normal file
|
@ -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
|
|
@ -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.);
|
||||
}
|
|
@ -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.);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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 );
|
||||
}
|
|
@ -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 );
|
||||
|
||||
}
|
|
@ -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 );
|
||||
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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++ )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++ ) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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.);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue