Pixel-Composer/scripts/node_value/node_value.gml

2521 lines
72 KiB
Plaintext
Raw Normal View History

2023-08-19 12:42:50 +02:00
#region ---- global names ----
global.junctionEndName = [ "Hold", "Loop", "Ping pong", "Wrap" ];
global.displaySuffix_Range = [ "min", "max" ];
global.displaySuffix_Area = [ "x", "y", "w", "h", "shape" ];
2023-08-19 12:42:50 +02:00
global.displaySuffix_Padding = [ "right", "top", "left", "bottom" ];
global.displaySuffix_VecRange = [ "x min", "x max", "y min", "y max" ];
global.displaySuffix_Axis = [ "x", "y", "z", "w" ];
2023-08-19 12:42:50 +02:00
#endregion
2022-01-13 05:24:03 +01:00
enum JUNCTION_CONNECT {
input,
output
}
enum VALUE_TYPE {
integer = 0,
float = 1,
boolean = 2,
color = 3,
surface = 4,
path = 5,
curve = 6,
text = 7,
object = 8,
2022-01-25 14:13:47 +01:00
node = 9,
2022-12-13 09:20:36 +01:00
d3object = 10,
2022-01-25 10:58:11 +01:00
2022-01-25 14:13:47 +01:00
any = 11,
2023-02-14 02:51:14 +01:00
pathnode = 12,
particle = 13,
rigid = 14,
fdomain = 15,
2023-03-11 01:40:17 +01:00
struct = 16,
2023-03-19 09:17:39 +01:00
strands = 17,
mesh = 18,
2023-03-28 06:58:28 +02:00
trigger = 19,
2023-04-16 15:26:52 +02:00
atlas = 20,
2023-03-28 06:58:28 +02:00
2023-05-22 20:31:55 +02:00
d3vertex = 21,
2023-05-28 20:00:51 +02:00
gradient = 22,
armature = 23,
2023-06-24 22:12:35 +02:00
buffer = 24,
2023-05-03 21:42:17 +02:00
2023-07-21 12:40:20 +02:00
pbBox = 25,
2023-08-14 19:22:04 +02:00
d3Mesh = 26,
d3Light = 27,
d3Camera = 28,
d3Scene = 29,
d3Material = 30,
2023-08-14 19:22:04 +02:00
dynaSurface = 31,
PCXnode = 32,
2023-09-08 21:37:36 +02:00
audioBit = 33,
2023-03-28 06:58:28 +02:00
action = 99,
2022-01-13 05:24:03 +01:00
}
enum VALUE_DISPLAY {
_default,
none,
2022-01-13 05:24:03 +01:00
range,
//Int
enum_scroll,
enum_button,
rotation,
rotation_range,
2023-09-11 16:08:58 +02:00
rotation_random,
2022-01-13 05:24:03 +01:00
slider,
slider_range,
//Color
palette,
//Int array
padding,
vector,
vector_range,
area,
2023-06-21 20:36:53 +02:00
transform,
2023-07-21 12:40:20 +02:00
corner,
2023-08-08 20:33:17 +02:00
toggle,
2023-09-15 20:12:02 +02:00
matrix,
2022-01-13 05:24:03 +01:00
//Curve
curve,
//Misc
puppet_control,
button,
label,
//Array
path_array,
//Text
2023-09-07 20:59:14 +02:00
codeLUA,
codeHLSL,
2023-02-21 04:48:50 +01:00
text_array,
2023-08-31 18:49:57 +02:00
text_box,
2022-01-13 05:24:03 +01:00
//path
path_save,
2022-09-27 06:37:28 +02:00
path_load,
2022-12-16 09:18:09 +01:00
path_font,
2023-05-03 21:42:17 +02:00
2023-08-30 16:40:45 +02:00
//d3d
2023-05-03 21:42:17 +02:00
d3vertex,
2023-08-30 16:40:45 +02:00
d3quarternion,
2022-01-13 05:24:03 +01:00
}
2023-08-19 12:42:50 +02:00
enum KEYFRAME_END {
hold,
loop,
ping,
wrap,
}
enum VALIDATION {
pass,
warning,
error
}
enum VALUE_UNIT {
constant,
reference
}
2023-09-28 13:15:29 +02:00
enum VALUE_TAG {
2023-10-06 11:51:11 +02:00
updateInTrigger = -2,
updateOutTrigger = -3,
none = 0
2023-09-28 13:15:29 +02:00
}
2023-08-19 12:42:50 +02:00
function value_color(i) { #region
2023-02-14 02:51:14 +01:00
static JUNCTION_COLORS = [
2023-10-15 15:04:42 +02:00
#ff9166, //int
#ffe478, //float
#8c3f5d, //bool
#8fde5d, //color
#ff6b97, //surface
#eb004b, //path
#c2c2d1, //curve
#66ffe3, //text
#ffb5b5, //object
#4da6ff, //node
2023-02-14 02:51:14 +01:00
#c1007c, //3D
2023-10-15 15:04:42 +02:00
#808080, //any
#ffb5b5, //path
#8fde5d, //particle
#88ffe9, //rigid
2023-02-14 02:51:14 +01:00
#4da6ff, //fdomain
2023-10-15 15:04:42 +02:00
#8c3f5d, //struct
#ff9166, //strand
#c2c2d1, //mesh
#8fde5d, //trigger
#ff6b97, //atlas
2023-05-03 21:42:17 +02:00
#c1007c, //d3vertex
2023-10-15 15:04:42 +02:00
#8fde5d, //gradient
#ff9166, //armature
#808080, //buffer
#ff6b97, //pbBox
#4da6ff, //d3Mesh
#4da6ff, //d3Light
#4da6ff, //d3Camera
#4da6ff, //d3Scene
#ff6b97, //d3Material
#ff6b97, //dynaSurf
2023-09-11 16:08:58 +02:00
#c2c2d1, //PCX
2023-10-15 15:04:42 +02:00
#8fde5d, //audiobit
];
if(i == 99) return $5dde8f;
return JUNCTION_COLORS[safe_mod(max(0, i), array_length(JUNCTION_COLORS))];
} #endregion
function value_color_bg(i) { #region
return #3b3b4e;
} #endregion
function value_color_bg_array(i) { #region
static JUNCTION_COLORS = [
#e36956, //int
#ff9166, //float
#5e315b, //bool
#3ca370, //color
#bd4882, //surface
#bb003c, //path
#83839b, //curve
#4da6ff, //text
#e28989, //object
#4b5bab, //node
#64003f, //3D
#4d4d4d, //any
#e28989, //path
#3ca370, //particle
#4da6ff, //rigid
#4b5bab, //fdomain
#5e315b, //struct
#e36956, //strand
#83839b, //mesh
#3ca370, //trigger
#9e2a69, //atlas
#64003f, //d3vertex
#3ca370, //gradient
#e36956, //armature
#4d4d4d, //buffer
#bd4882, //pbBox
#4b5bab, //d3Mesh
#4b5bab, //d3Light
#4b5bab, //d3Camera
#4b5bab, //d3Scene
#bd4882, //d3Material
#bd4882, //dynaSurf
#83839b, //PCX
#3ca370, //audiobit
2023-02-14 02:51:14 +01:00
];
2023-03-28 06:58:28 +02:00
if(i == 99) return $5dde8f;
2022-01-13 05:24:03 +01:00
return JUNCTION_COLORS[safe_mod(max(0, i), array_length(JUNCTION_COLORS))];
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
function value_bit(i) { #region
2022-01-13 05:24:03 +01:00
switch(i) {
case VALUE_TYPE.integer : return 1 << 0 | 1 << 1;
2022-12-23 04:45:52 +01:00
case VALUE_TYPE.float : return 1 << 2 | 1 << 1;
case VALUE_TYPE.boolean : return 1 << 3 | 1 << 1;
case VALUE_TYPE.color : return 1 << 4;
2023-05-28 20:00:51 +02:00
case VALUE_TYPE.gradient : return 1 << 25;
case VALUE_TYPE.dynaSurface :
2023-10-06 11:51:11 +02:00
case VALUE_TYPE.surface : return 1 << 5 | 1 << 23;
2022-01-13 05:24:03 +01:00
case VALUE_TYPE.path : return 1 << 10;
2023-01-25 06:49:00 +01:00
case VALUE_TYPE.text : return 1 << 10;
2023-02-14 02:51:14 +01:00
case VALUE_TYPE.object : return 1 << 13;
case VALUE_TYPE.d3object : return 1 << 14;
2023-05-03 21:42:17 +02:00
case VALUE_TYPE.d3vertex : return 1 << 24;
2023-02-14 02:51:14 +01:00
case VALUE_TYPE.pathnode : return 1 << 15;
case VALUE_TYPE.particle : return 1 << 16;
case VALUE_TYPE.rigid : return 1 << 17;
case VALUE_TYPE.fdomain : return 1 << 18;
2023-03-11 01:40:17 +01:00
case VALUE_TYPE.struct : return 1 << 19;
2023-03-19 09:17:39 +01:00
case VALUE_TYPE.strands : return 1 << 20;
case VALUE_TYPE.mesh : return 1 << 21;
2023-06-24 22:12:35 +02:00
case VALUE_TYPE.armature : return 1 << 26 | 1 << 19;
2023-02-14 02:51:14 +01:00
case VALUE_TYPE.node : return 1 << 32;
2022-01-13 05:24:03 +01:00
2023-06-24 22:12:35 +02:00
case VALUE_TYPE.buffer : return 1 << 27;
2023-07-21 12:40:20 +02:00
case VALUE_TYPE.pbBox : return 1 << 28;
2023-03-28 06:58:28 +02:00
case VALUE_TYPE.trigger : return 1 << 22;
case VALUE_TYPE.action : return 1 << 22 | 1 << 3;
2023-08-14 19:22:04 +02:00
case VALUE_TYPE.d3Mesh : return 1 << 29;
case VALUE_TYPE.d3Light : return 1 << 29;
case VALUE_TYPE.d3Camera : return 1 << 29;
case VALUE_TYPE.d3Scene : return 1 << 29 | 1 << 30;
2023-08-24 11:59:05 +02:00
case VALUE_TYPE.d3Material : return 1 << 33;
2023-09-11 16:08:58 +02:00
case VALUE_TYPE.PCXnode : return 1 << 34;
case VALUE_TYPE.audioBit : return 1 << 35;
2023-09-11 16:08:58 +02:00
2023-02-14 02:51:14 +01:00
case VALUE_TYPE.any : return ~0 & ~(1 << 32);
2022-01-13 05:24:03 +01:00
}
return 0;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
function value_type_directional(f, t) { #region
2023-05-28 20:00:51 +02:00
if(f == VALUE_TYPE.surface && t == VALUE_TYPE.integer) return true;
if(f == VALUE_TYPE.surface && t == VALUE_TYPE.float) return true;
2022-12-23 04:45:52 +01:00
2023-02-14 02:51:14 +01:00
if(f == VALUE_TYPE.integer && t == VALUE_TYPE.text) return true;
if(f == VALUE_TYPE.float && t == VALUE_TYPE.text) return true;
if(f == VALUE_TYPE.boolean && t == VALUE_TYPE.text) return true;
2022-12-23 04:45:52 +01:00
2023-05-28 20:00:51 +02:00
if(f == VALUE_TYPE.integer && t == VALUE_TYPE.color) return true;
if(f == VALUE_TYPE.float && t == VALUE_TYPE.color) return true;
if(f == VALUE_TYPE.color && t == VALUE_TYPE.integer) return true;
if(f == VALUE_TYPE.color && t == VALUE_TYPE.float ) return true;
if(f == VALUE_TYPE.color && t == VALUE_TYPE.gradient) return true;
2022-12-23 04:45:52 +01:00
2023-03-19 09:17:39 +01:00
if(f == VALUE_TYPE.strands && t == VALUE_TYPE.pathnode ) return true;
2023-10-27 15:42:17 +02:00
if(f == VALUE_TYPE.color && t == VALUE_TYPE.struct ) return true;
if(f == VALUE_TYPE.mesh && t == VALUE_TYPE.struct ) return true;
if(f == VALUE_TYPE.particle && t == VALUE_TYPE.struct ) return true;
2023-03-19 09:17:39 +01:00
if(f == VALUE_TYPE.surface && t == VALUE_TYPE.d3Material ) return true;
2022-01-13 05:24:03 +01:00
return false;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-09-22 17:01:56 +02:00
function value_type_from_string(str) { #region
switch(str) {
case "integer" : return VALUE_TYPE.integer;
case "float" : return VALUE_TYPE.float;
case "boolean" : return VALUE_TYPE.boolean;
case "color" : return VALUE_TYPE.color;
case "surface" : return VALUE_TYPE.surface;
2023-09-22 17:01:56 +02:00
case "path" : return VALUE_TYPE.path;
case "curve" : return VALUE_TYPE.curve;
case "text" : return VALUE_TYPE.text;
case "object" : return VALUE_TYPE.object;
case "node" : return VALUE_TYPE.node;
case "d3object" : return VALUE_TYPE.d3object;
2023-09-22 17:01:56 +02:00
case "any" : return VALUE_TYPE.any;
2023-09-22 17:01:56 +02:00
case "pathnode" : return VALUE_TYPE.pathnode;
case "particle" : return VALUE_TYPE.particle;
case "rigid" : return VALUE_TYPE.rigid;
case "fdomain" : return VALUE_TYPE.fdomain;
case "struct" : return VALUE_TYPE.struct;
case "strands" : return VALUE_TYPE.strands;
case "mesh" : return VALUE_TYPE.mesh;
case "trigger" : return VALUE_TYPE.trigger;
2023-09-22 17:01:56 +02:00
case "d3vertex" : return VALUE_TYPE.d3vertex;
case "gradient" : return VALUE_TYPE.gradient;
case "armature" : return VALUE_TYPE.armature;
case "buffer" : return VALUE_TYPE.buffer;
2023-09-22 17:01:56 +02:00
case "pbBox" : return VALUE_TYPE.pbBox;
2023-09-22 17:01:56 +02:00
case "d3Mesh" : return VALUE_TYPE.d3Mesh;
case "d3Light" : return VALUE_TYPE.d3Light;
case "d3Camera" : return VALUE_TYPE.d3Camera;
case "d3Scene" : return VALUE_TYPE.d3Scene;
case "d3Material" : return VALUE_TYPE.d3Material;
2023-09-22 17:01:56 +02:00
case "dynaSurface" : return VALUE_TYPE.dynaSurface;
case "PCXnode" : return VALUE_TYPE.PCXnode;
2023-10-09 16:07:33 +02:00
case "audioBit" : return VALUE_TYPE.audioBit;
2023-09-22 17:01:56 +02:00
case "action" : return VALUE_TYPE.action;
}
return VALUE_TYPE.any;
} #endregion
2023-08-19 12:42:50 +02:00
function typeArray(_type) { #region
2022-01-13 05:24:03 +01:00
switch(_type) {
case VALUE_DISPLAY.range :
case VALUE_DISPLAY.vector_range :
case VALUE_DISPLAY.rotation_range :
2023-09-19 12:53:24 +02:00
case VALUE_DISPLAY.rotation_random :
2022-01-13 05:24:03 +01:00
case VALUE_DISPLAY.slider_range :
case VALUE_DISPLAY.vector :
case VALUE_DISPLAY.padding :
case VALUE_DISPLAY.area :
case VALUE_DISPLAY.puppet_control :
2023-09-15 20:12:02 +02:00
case VALUE_DISPLAY.matrix :
2023-06-23 15:39:24 +02:00
case VALUE_DISPLAY.transform :
2022-01-13 05:24:03 +01:00
case VALUE_DISPLAY.curve :
case VALUE_DISPLAY.path_array :
case VALUE_DISPLAY.palette :
2023-02-21 04:48:50 +01:00
case VALUE_DISPLAY.text_array :
2023-05-03 21:42:17 +02:00
case VALUE_DISPLAY.d3vertex :
2023-08-30 16:40:45 +02:00
case VALUE_DISPLAY.d3quarternion :
2023-02-28 09:43:01 +01:00
return 1;
2022-01-13 05:24:03 +01:00
}
return 0;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
function typeCompatible(fromType, toType, directional_cast = true) { #region
2023-02-14 02:51:14 +01:00
if(value_bit(fromType) & value_bit(toType) != 0)
return true;
if(!directional_cast)
return false;
return value_type_directional(fromType, toType);
2023-08-19 12:42:50 +02:00
} #endregion
2023-02-14 02:51:14 +01:00
2023-08-19 12:42:50 +02:00
function typeIncompatible(from, to) { #region
2023-02-19 02:13:19 +01:00
if(from.type == VALUE_TYPE.surface && (to.type == VALUE_TYPE.integer || to.type == VALUE_TYPE.float)) {
switch(to.display_type) {
case VALUE_DISPLAY.area :
2023-09-15 20:12:02 +02:00
case VALUE_DISPLAY.matrix :
2023-02-19 02:13:19 +01:00
case VALUE_DISPLAY.vector_range :
case VALUE_DISPLAY.puppet_control :
case VALUE_DISPLAY.padding :
2023-03-11 01:40:17 +01:00
case VALUE_DISPLAY.curve :
return true;
2023-02-19 02:13:19 +01:00
}
}
return false;
2023-08-19 12:42:50 +02:00
} #endregion
2023-01-09 03:14:20 +01:00
2023-08-19 12:42:50 +02:00
function isGraphable(prop) { #region
2023-05-16 21:28:16 +02:00
if(prop.type == VALUE_TYPE.integer || prop.type == VALUE_TYPE.float) {
if(prop.display_type == VALUE_DISPLAY.puppet_control)
return false;
2023-03-05 07:16:44 +01:00
return true;
2023-05-16 21:28:16 +02:00
}
2023-03-05 07:16:44 +01:00
if(prop.type == VALUE_TYPE.color && prop.display_type == VALUE_DISPLAY._default)
return true;
2022-01-13 05:24:03 +01:00
return false;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-09-09 13:52:16 +02:00
function nodeValueUnit(_nodeValue) constructor { #region
self._nodeValue = _nodeValue;
2022-12-27 04:00:50 +01:00
mode = VALUE_UNIT.constant;
reference = noone;
triggerButton = button(function() {
mode = !mode;
2023-09-09 13:52:16 +02:00
_nodeValue.cache_value[0] = false;
_nodeValue.unitConvert(mode);
_nodeValue.node.doUpdate();
2022-12-27 04:00:50 +01:00
});
triggerButton.icon_blend = COLORS._main_icon_light;
2023-09-07 20:59:14 +02:00
triggerButton.icon = THEME.unit_ref;
triggerButton.tooltip = new tooltipSelector("Unit", ["Pixel", "Fraction"]);
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
static setMode = function(type) { #region
2023-08-02 19:11:57 +02:00
if(type == "constant" && mode == VALUE_UNIT.constant) return;
if(type == "relative" && mode == VALUE_UNIT.reference) return;
mode = type == "constant"? VALUE_UNIT.constant : VALUE_UNIT.reference;
2023-09-09 13:52:16 +02:00
_nodeValue.cache_value[0] = false;
_nodeValue.unitConvert(mode);
_nodeValue.node.doUpdate();
2023-08-19 12:42:50 +02:00
} #endregion
2023-08-02 19:11:57 +02:00
2023-08-19 12:42:50 +02:00
static draw = function(_x, _y, _w, _h, _m) { #region
2022-12-27 04:00:50 +01:00
triggerButton.icon_index = mode;
2023-09-07 20:59:14 +02:00
triggerButton.tooltip.index = mode;
2022-12-27 04:00:50 +01:00
triggerButton.draw(_x, _y, _w, _h, _m, THEME.button_hide);
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
static invApply = function(value, index = 0) { #region
2022-12-27 04:00:50 +01:00
if(mode == VALUE_UNIT.constant)
return value;
if(reference == noone)
return value;
return convertUnit(value, VALUE_UNIT.reference, index);
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
static apply = function(value, index = 0) { #region
2023-09-09 13:52:16 +02:00
if(mode == VALUE_UNIT.constant) return value;
if(reference == noone) return value;
2022-12-27 04:00:50 +01:00
return convertUnit(value, VALUE_UNIT.constant, index);
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
static convertUnit = function(value, unitTo, index = 0) { #region
2023-09-09 13:52:16 +02:00
var disp = _nodeValue.display_type;
2022-12-27 04:00:50 +01:00
var base = reference(index);
2023-09-09 13:52:16 +02:00
var inv = unitTo == VALUE_UNIT.reference;
2022-12-27 04:00:50 +01:00
2022-12-27 13:30:02 +01:00
if(!is_array(base) && !is_array(value))
2022-12-27 04:00:50 +01:00
return inv? value / base : value * base;
2022-12-27 13:30:02 +01:00
if(!is_array(base) && is_array(value)) {
2023-09-14 16:29:39 +02:00
var _val = array_create(array_length(value));
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(value); i < n; i++ )
2023-09-14 16:29:39 +02:00
_val[i] = inv? value[i] / base : value[i] * base;
return _val;
2022-12-27 04:00:50 +01:00
}
2023-09-09 13:52:16 +02:00
if(is_array(base) && !is_array(value))
2022-12-27 04:00:50 +01:00
return value;
2023-09-14 16:29:39 +02:00
var _val = array_create(array_length(value));
2022-12-27 04:00:50 +01:00
switch(disp) {
case VALUE_DISPLAY.padding :
case VALUE_DISPLAY.vector :
case VALUE_DISPLAY.vector_range :
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(value); i < n; i++ )
2023-09-14 16:29:39 +02:00
_val[i] = inv? value[i] / base[i % 2] : value[i] * base[i % 2];
return _val;
2022-12-27 04:00:50 +01:00
case VALUE_DISPLAY.area :
for( var i = 0; i < 4; i++ )
2023-09-14 16:29:39 +02:00
_val[i] = inv? value[i] / base[i % 2] : value[i] * base[i % 2];
return _val;
2022-12-27 04:00:50 +01:00
}
return value;
2023-08-19 12:42:50 +02:00
} #endregion
} #endregion
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
function nodeValue(_name, _node, _connect, _type, _value, _tooltip = "") { return new NodeValue(_name, _node, _connect, _type, _value, _tooltip); }
2023-03-28 06:58:28 +02:00
2023-02-14 02:51:14 +01:00
function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constructor {
2023-10-06 11:51:11 +02:00
static DISPLAY_DATA_KEYS = [ "linked", "angle_display", "bone_id", "area_type", "unit", "atlas_crop" ];
2023-08-19 12:42:50 +02:00
#region ---- main ----
node = _node;
x = node.x;
y = node.y;
index = _connect == JUNCTION_CONNECT.input? ds_list_size(node.inputs) : ds_list_size(node.outputs);
type = _type;
forward = true;
_initName = _name;
static updateName = function(_name) {
name = _name;
2023-10-12 14:14:08 +02:00
internalName = string_to_var(name);
name_custom = true;
} updateName(_name);
name_custom = false;
2023-09-11 16:08:58 +02:00
switch(type) {
case VALUE_TYPE.PCXnode :
accept_array = false;
break;
}
2023-08-19 12:42:50 +02:00
if(struct_has(node, "inputMap")) {
if(_connect == JUNCTION_CONNECT.input) node.inputMap[? internalName] = self;
else if(_connect == JUNCTION_CONNECT.output) node.outputMap[? internalName] = self;
}
tooltip = _tooltip;
editWidget = noone;
2023-09-28 13:15:29 +02:00
tags = VALUE_TAG.none;
2023-08-19 12:42:50 +02:00
#endregion
2023-03-02 07:59:14 +01:00
2023-08-19 12:42:50 +02:00
#region ---- connection ----
connect_type = _connect;
value_from = noone;
value_to = ds_list_create();
value_to_arr = [];
accept_array = true;
array_depth = 0;
auto_connect = true;
setFrom_condition = -1;
2023-10-07 09:09:18 +02:00
onSetFrom = noone;
onSetTo = noone;
2023-08-19 12:42:50 +02:00
#endregion
2023-03-21 03:01:53 +01:00
2023-08-19 12:42:50 +02:00
#region ---- animation ----
key_inter = CURVE_TYPE.linear;
is_anim = false;
sep_axis = false;
2023-10-09 07:36:20 +02:00
animable = true;
2023-08-19 12:42:50 +02:00
sepable = is_array(_value) && array_length(_value) > 1;
animator = new valueAnimator(_value, self, false);
animators = [];
if(is_array(_value))
for( var i = 0, n = array_length(_value); i < n; i++ ) {
animators[i] = new valueAnimator(_value[i], self, true);
animators[i].index = i;
}
on_end = KEYFRAME_END.hold;
loop_range = -1;
#endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
#region ---- value ----
def_val = _value;
def_length = is_array(def_val)? array_length(def_val) : 0;
2023-08-19 12:42:50 +02:00
unit = new nodeValueUnit(self);
dyna_depo = ds_list_create();
is_changed = true;
2023-09-09 13:52:16 +02:00
cache_value = [ false, false, undefined, undefined ];
2023-08-19 12:42:50 +02:00
cache_array = [ false, false ];
use_cache = true;
process_array = true;
2023-09-18 13:54:55 +02:00
dynamic_array = false;
2023-08-19 12:42:50 +02:00
validateValue = true;
fullUpdate = false;
attributes = {};
2023-10-07 09:09:18 +02:00
node.inputs_data[index] = _value;
2023-10-12 14:14:08 +02:00
node.input_value_map[$ internalName] = _value;
2023-08-19 12:42:50 +02:00
#endregion
2023-05-03 21:42:17 +02:00
2023-08-19 12:42:50 +02:00
#region ---- draw ----
draw_line_shift_x = 0;
draw_line_shift_y = 0;
draw_line_thick = 1;
draw_line_shift_hover = false;
draw_line_blend = 1;
drawLineIndex = 1;
draw_line_vb = noone;
draw_junction_index = type;
2023-08-19 12:42:50 +02:00
junction_drawing = [ THEME.node_junctions_single, type ];
drag_type = 0;
drag_mx = 0;
drag_my = 0;
drag_sx = 0;
drag_sy = 0;
2023-10-15 15:04:42 +02:00
color = -1;
color_display = 0;
2023-08-19 12:42:50 +02:00
#endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
#region ---- timeline ----
show_graph = false;
graph_h = ui(64);
#endregion
2023-08-19 12:42:50 +02:00
#region ---- inspector ----
2023-09-11 16:08:58 +02:00
visible = _connect == JUNCTION_CONNECT.output || _type == VALUE_TYPE.surface || _type == VALUE_TYPE.path || _type == VALUE_TYPE.PCXnode;
2023-08-19 12:42:50 +02:00
show_in_inspector = true;
2023-01-09 03:14:20 +01:00
2023-08-19 12:42:50 +02:00
display_type = VALUE_DISPLAY._default;
if(_type == VALUE_TYPE.curve) display_type = VALUE_DISPLAY.curve;
else if(_type == VALUE_TYPE.d3vertex) display_type = VALUE_DISPLAY.d3vertex;
2023-10-06 11:51:11 +02:00
display_data = { update: method(node, node.triggerRender) };
display_attribute = noone;
popup_dialog = noone;
2023-08-19 12:42:50 +02:00
#endregion
2023-04-15 14:48:29 +02:00
2023-08-19 12:42:50 +02:00
#region ---- graph ----
value_validation = VALIDATION.pass;
error_notification = noone;
extract_node = "";
#endregion
2023-03-08 07:35:51 +01:00
2023-08-19 12:42:50 +02:00
#region ---- expression ----
expUse = false;
expression = "";
expTree = noone;
2023-10-12 14:14:08 +02:00
expContext = {
name: name,
node_name: node.display_name,
value: 0,
node_values: node.input_value_map,
};
2023-08-19 12:42:50 +02:00
express_edit = new textArea(TEXTBOX_INPUT.text, function(str) {
expression = str;
expressionUpdate();
});
express_edit.autocomplete_server = pxl_autocomplete_server;
2023-10-12 14:14:08 +02:00
express_edit.autocomplete_context = expContext;
2023-08-19 12:42:50 +02:00
express_edit.function_guide_server = pxl_function_guide_server;
express_edit.parser_server = pxl_document_parser;
2023-09-07 20:59:14 +02:00
express_edit.format = TEXT_AREA_FORMAT.codeLUA;
2023-08-19 12:42:50 +02:00
express_edit.font = f_code;
express_edit.boxColor = COLORS._main_value_positive;
express_edit.align = fa_left;
#endregion
2023-05-28 20:00:51 +02:00
2023-08-19 12:42:50 +02:00
#region ---- serialization ----
con_node = -1;
con_index = -1;
#endregion
2023-07-21 12:40:20 +02:00
2023-08-19 12:42:50 +02:00
static setDefault = function(vals) { #region
2023-02-14 02:51:14 +01:00
if(LOADING || APPENDING) return self;
ds_list_clear(animator.values);
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(vals); i < n; i++ )
2023-02-14 02:51:14 +01:00
ds_list_add(animator.values, new valueKey(vals[i][0], vals[i][1], animator));
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-02-14 02:51:14 +01:00
static getName = function() { #region
if(name_custom) return name;
return __txt_junction_name(instanceof(node), connect_type, index, name);
} #endregion
2023-05-16 21:28:16 +02:00
static resetValue = function() { setValue(def_val); }
2023-08-19 12:42:50 +02:00
static setUnitRef = function(ref, mode = VALUE_UNIT.constant) { #region
2023-03-08 07:35:51 +01:00
unit.reference = ref;
unit.mode = mode;
cache_value[0] = false;
2022-12-27 04:00:50 +01:00
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
static setVisible = function(inspector) { #region
2023-02-14 02:51:14 +01:00
if(connect_type == JUNCTION_CONNECT.input) {
show_in_inspector = inspector;
visible = argument_count > 1? argument[1] : visible;
} else
visible = inspector;
2022-01-13 05:24:03 +01:00
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
static setDisplay = function(_type = VALUE_DISPLAY._default, _data = {}) { #region
2023-03-05 07:16:44 +01:00
display_type = _type;
display_data = _data;
2022-01-13 05:24:03 +01:00
resetDisplay();
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-10-09 07:36:20 +02:00
static setAnimable = function(_anim) { #region
animable = _anim;
return self;
} #endregion
2023-08-19 12:42:50 +02:00
static rejectArray = function() { #region
2022-12-21 02:30:23 +01:00
accept_array = false;
2022-01-13 05:24:03 +01:00
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static uncache = function() { #region
2023-07-25 20:12:40 +02:00
use_cache = false;
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-07-25 20:12:40 +02:00
2023-08-19 12:42:50 +02:00
static setArrayDepth = function(aDepth) { #region
2023-03-07 14:29:47 +01:00
array_depth = aDepth;
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-03-07 14:29:47 +01:00
2023-09-18 13:54:55 +02:00
static setArrayDynamic = function() { #region
dynamic_array = true;
return self;
} #endregion
2023-08-19 12:42:50 +02:00
static rejectConnect = function() { #region
2023-02-14 02:51:14 +01:00
auto_connect = false;
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-02-14 02:51:14 +01:00
2023-08-19 12:42:50 +02:00
static rejectArrayProcess = function() { #region
2023-05-28 20:00:51 +02:00
process_array = false;
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-05-28 20:00:51 +02:00
2023-08-19 12:42:50 +02:00
static nonForward = function() { #region
2023-06-01 10:32:21 +02:00
forward = false;
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-06-01 10:32:21 +02:00
2023-08-19 12:42:50 +02:00
static nonValidate = function() { #region
2023-06-04 12:38:40 +02:00
validateValue = false;
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-06-04 12:38:40 +02:00
2023-08-19 12:42:50 +02:00
static isAnimable = function() { #region
2023-09-11 16:08:58 +02:00
if(type == VALUE_TYPE.PCXnode) return false;
2023-02-21 04:48:50 +01:00
if(display_type == VALUE_DISPLAY.text_array) return false;
2023-10-09 07:36:20 +02:00
return animable;
2023-08-19 12:42:50 +02:00
} #endregion
2023-01-09 03:14:20 +01:00
2023-08-19 12:42:50 +02:00
static setDropKey = function() { #region
2023-03-26 07:13:36 +02:00
switch(type) {
case VALUE_TYPE.integer : drop_key = "Number"; break;
case VALUE_TYPE.float : drop_key = "Number"; break;
case VALUE_TYPE.boolean : drop_key = "Bool"; break;
case VALUE_TYPE.color :
switch(display_type) {
case VALUE_DISPLAY.palette : drop_key = "Palette"; break;
default : drop_key = "Color";
}
break;
2023-05-28 20:00:51 +02:00
case VALUE_TYPE.gradient : drop_key = "Gradient"; break;
2023-03-26 07:13:36 +02:00
case VALUE_TYPE.path : drop_key = "Asset"; break;
case VALUE_TYPE.text : drop_key = "Text"; break;
case VALUE_TYPE.pathnode : drop_key = "Path"; break;
case VALUE_TYPE.struct : drop_key = "Struct"; break;
default:
drop_key = "None";
}
} setDropKey(); #endregion
2023-03-26 07:13:36 +02:00
static resetDisplay = function() { #region //////////////////// RESET DISPLAY ////////////////////
2022-01-13 05:24:03 +01:00
editWidget = noone;
switch(display_type) {
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.button : #region
2023-10-06 11:51:11 +02:00
editWidget = button(method(node, display_data.onClick));
editWidget.text = display_data.name;
2023-10-03 07:14:28 +02:00
if(!struct_has(display_data, "output")) display_data.output = false;
2022-01-13 05:24:03 +01:00
visible = false;
2023-08-19 12:42:50 +02:00
return; #endregion
2022-01-13 05:24:03 +01:00
}
switch(type) {
case VALUE_TYPE.float :
case VALUE_TYPE.integer :
2023-02-14 02:51:14 +01:00
var _txt = TEXTBOX_INPUT.number;
2023-01-09 03:14:20 +01:00
2023-08-19 12:42:50 +02:00
switch(display_type) {
case VALUE_DISPLAY._default : #region
2022-12-18 03:20:38 +01:00
editWidget = new textBox(_txt, function(val) {
2023-02-14 02:51:14 +01:00
return setValueDirect(val);
2022-01-13 05:24:03 +01:00
} );
editWidget.slidable = true;
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.slide_speed = 1;
if(struct_has(display_data, "slide_speed")) editWidget.slide_speed = display_data.slide_speed;
if(struct_has(display_data, "unit")) editWidget.unit = display_data.unit;
if(struct_has(display_data, "side_button")) editWidget.side_button = display_data.side_button;
2023-01-09 03:14:20 +01:00
extract_node = "Node_Number";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.range : #region
2022-01-13 05:24:03 +01:00
editWidget = new rangeBox(_txt, function(index, val) {
2023-03-21 03:01:53 +01:00
return setValueDirect(val, index);
2022-01-13 05:24:03 +01:00
} );
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
if(!struct_has(display_data, "linked")) display_data.linked = false;
2023-01-09 03:14:20 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
animators[i].suffix = " " + array_safe_get(global.displaySuffix_Range, i);
2023-01-09 03:14:20 +01:00
extract_node = "Node_Number";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.vector : #region
2023-01-09 03:14:20 +01:00
var val = animator.getValue();
var len = array_length(val);
2023-09-15 20:12:02 +02:00
if(len <= 4) {
editWidget = new vectorBox(len, function(index, val) {
2023-03-21 03:01:53 +01:00
return setValueDirect(val, index);
2022-12-27 04:00:50 +01:00
}, unit );
if(struct_has(display_data, "label")) editWidget.axis = display_data.label;
if(struct_has(display_data, "linkable")) editWidget.linkable = display_data.linkable;
if(struct_has(display_data, "per_line")) editWidget.per_line = display_data.per_line;
if(struct_has(display_data, "linked")) editWidget.linked = display_data.linked;
if(struct_has(display_data, "side_button")) editWidget.side_button = display_data.side_button;
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
2023-09-15 20:12:02 +02:00
if(len == 2) {
2023-07-15 20:01:29 +02:00
extract_node = [ "Node_Vector2", "Node_Path" ];
2023-09-15 20:12:02 +02:00
} else if(len == 3)
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector3";
2023-09-15 20:12:02 +02:00
else if(len == 4)
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector4";
2022-01-13 05:24:03 +01:00
}
2023-03-21 03:01:53 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-28 06:58:28 +02:00
animators[i].suffix = " " + string(array_safe_get(global.displaySuffix_Axis, i));
2023-03-21 03:01:53 +01:00
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.vector_range : #region
2023-01-09 03:14:20 +01:00
var val = animator.getValue();
editWidget = new vectorRangeBox(array_length(val), _txt, function(index, val) {
2023-03-21 03:01:53 +01:00
return setValueDirect(val, index);
2022-12-27 04:00:50 +01:00
}, unit );
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
if(!struct_has(display_data, "linked")) display_data.linked = false;
2023-01-09 03:14:20 +01:00
if(array_length(val) == 2)
extract_node = "Node_Vector2";
else if(array_length(val) == 3)
extract_node = "Node_Vector3";
else if(array_length(val) == 4)
extract_node = "Node_Vector4";
2023-03-21 03:01:53 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-28 06:58:28 +02:00
animators[i].suffix = " " + string(array_safe_get(global.displaySuffix_VecRange, i));
2023-03-21 03:01:53 +01:00
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.rotation : #region
2023-10-03 11:27:36 +02:00
var _step = struct_try_get(display_data, "step", -1);
2023-03-21 03:01:53 +01:00
editWidget = new rotator(function(val) {
return setValueDirect(val);
2023-10-03 11:27:36 +02:00
}, _step );
2023-01-09 03:14:20 +01:00
extract_node = "Node_Number";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.rotation_range : #region
2022-01-13 05:24:03 +01:00
editWidget = new rotatorRange(function(index, val) {
2023-03-21 03:01:53 +01:00
return setValueDirect(val, index);
2022-01-13 05:24:03 +01:00
} );
2023-01-09 03:14:20 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
animators[i].suffix = " " + array_safe_get(global.displaySuffix_Range, i);
2023-09-11 16:08:58 +02:00
extract_node = "Node_Vector2";
break; #endregion
case VALUE_DISPLAY.rotation_random: #region
editWidget = new rotatorRandom(function(index, val) {
return setValueDirect(val, index);
} );
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector2";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.slider : #region
var _range = struct_try_get(display_data, "range", [ 0, 1, 0.01 ]);
editWidget = new slider(_range[0], _range[1], _range[2], function(val) {
2023-02-14 02:51:14 +01:00
return setValueDirect(toNumber(val));
2022-01-13 05:24:03 +01:00
} );
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
2023-01-09 03:14:20 +01:00
2023-10-08 04:14:35 +02:00
if(struct_has(display_data, "update_stat"))
editWidget.update_stat = display_data.update_stat;
2023-01-09 03:14:20 +01:00
extract_node = "Node_Number";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.slider_range : #region
var _range = struct_try_get(display_data, "range", [ 0, 1, 0.01 ]);
editWidget = new sliderRange(_range[0], _range[1], _range[2], function(index, val) {
2023-03-21 03:01:53 +01:00
return setValueDirect(val, index);
2022-01-13 05:24:03 +01:00
} );
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
2023-01-09 03:14:20 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
animators[i].suffix = " " + array_safe_get(global.displaySuffix_Range, i);
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector2";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.area : #region
2022-01-13 05:24:03 +01:00
editWidget = new areaBox(function(index, val) {
2023-03-21 03:01:53 +01:00
return setValueDirect(val, index);
2022-12-27 04:00:50 +01:00
}, unit);
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
if(struct_has(display_data, "onSurfaceSize")) editWidget.onSurfaceSize = display_data.onSurfaceSize;
2023-01-09 03:14:20 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-23 13:38:50 +01:00
animators[i].suffix = " " + array_safe_get(global.displaySuffix_Area, i, "");
2023-03-21 03:01:53 +01:00
display_data.area_type = AREA_MODE.area;
2023-01-09 03:14:20 +01:00
extract_node = "Node_Area";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.padding : #region
2022-01-13 05:24:03 +01:00
editWidget = new paddingBox(function(index, val) {
2023-03-21 03:01:53 +01:00
//var _val = animator.getValue();
//_val[index] = val;
return setValueDirect(val, index);
2022-12-27 04:00:50 +01:00
}, unit);
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
2023-01-09 03:14:20 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-07-21 12:40:20 +02:00
animators[i].suffix = " " + array_safe_get(global.displaySuffix_Padding, i);
extract_node = "Node_Vector4";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.corner : #region
2023-07-21 12:40:20 +02:00
editWidget = new cornerBox(function(index, val) {
return setValueDirect(val, index);
}, unit);
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
animators[i].suffix = " " + array_safe_get(global.displaySuffix_Padding, i);
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector4";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.puppet_control : #region
2022-09-23 13:28:42 +02:00
editWidget = new controlPointBox(function(index, val) {
2023-03-21 03:01:53 +01:00
//var _val = animator.getValue();
//_val[index] = val;
return setValueDirect(val, index);
2022-09-23 13:28:42 +02:00
});
2023-01-09 03:14:20 +01:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.enum_scroll : #region
if(!is_struct(display_data)) display_data = { data: display_data };
var choices = __txt_junction_data(instanceof(node), connect_type, index, display_data.data);
editWidget = new scrollBox(choices, function(val) {
2022-01-13 05:24:03 +01:00
if(val == -1) return;
2023-02-14 02:51:14 +01:00
return setValueDirect(toNumber(val));
2022-01-13 05:24:03 +01:00
} );
if(struct_has(display_data, "update_hover"))
editWidget.update_hover = display_data.update_hover;
2023-01-09 03:14:20 +01:00
2023-02-14 02:51:14 +01:00
rejectConnect();
2023-08-19 12:42:50 +02:00
key_inter = CURVE_TYPE.cut;
2023-01-09 03:14:20 +01:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.enum_button : #region
if(!is_struct(display_data)) display_data = { data: display_data };
var choices = __txt_junction_data(instanceof(node), connect_type, index, display_data.data);
editWidget = new buttonGroup(choices, function(val) {
2023-02-14 02:51:14 +01:00
return setValueDirect(val);
2022-01-13 05:24:03 +01:00
} );
2023-01-09 03:14:20 +01:00
2023-02-14 02:51:14 +01:00
rejectConnect();
2023-08-19 12:42:50 +02:00
key_inter = CURVE_TYPE.cut;
2023-01-09 03:14:20 +01:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-09-15 20:12:02 +02:00
case VALUE_DISPLAY.matrix : #region
editWidget = new matrixGrid(_txt, display_data.size, function(index, val) {
return setValueDirect(val, index);
2023-01-04 02:30:04 +01:00
}, unit );
2023-02-14 02:51:14 +01:00
if(type == VALUE_TYPE.integer) editWidget.setSlideSpeed(1);
2023-01-09 03:14:20 +01:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
animators[i].suffix = " " + string(i);
2023-06-21 20:36:53 +02:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.transform : #region
2023-06-23 15:39:24 +02:00
editWidget = new transformBox(function(index, val) {
2023-06-21 20:36:53 +02:00
var _val = animator.getValue();
_val[index] = val;
return setValueDirect(_val);
});
2023-07-05 15:09:52 +02:00
extract_node = "Node_Transform_Array";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.toggle : #region
editWidget = new toggleGroup(display_data.data, function(val) {
2023-08-08 20:33:17 +02:00
return setValueDirect(val);
} );
rejectConnect();
2023-08-19 12:42:50 +02:00
key_inter = CURVE_TYPE.cut;
2023-08-08 20:33:17 +02:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_DISPLAY.d3quarternion : #region
editWidget = new quarternionBox(function(index, val) {
return setValueDirect(val, index);
});
extract_node = "Node_Vector4";
display_data.angle_display = QUARTERNION_DISPLAY.quarterion;
break; #endregion
2022-01-13 05:24:03 +01:00
}
break;
2023-08-19 12:42:50 +02:00
case VALUE_TYPE.boolean : #region
2022-01-13 05:24:03 +01:00
editWidget = new checkBox(function() {
2023-02-14 02:51:14 +01:00
return setValueDirect(!animator.getValue());
2022-01-13 05:24:03 +01:00
} );
2023-01-09 03:14:20 +01:00
2023-08-19 12:42:50 +02:00
key_inter = CURVE_TYPE.cut;
2023-01-09 03:14:20 +01:00
extract_node = "Node_Boolean";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_TYPE.color : #region
2022-01-13 05:24:03 +01:00
switch(display_type) {
case VALUE_DISPLAY._default :
2023-02-28 09:43:01 +01:00
editWidget = new buttonColor(function(color) {
2023-02-14 02:51:14 +01:00
return setValueDirect(color);
2022-01-13 05:24:03 +01:00
} );
2023-01-09 03:14:20 +01:00
2023-03-05 07:16:44 +01:00
graph_h = ui(16);
2023-01-09 03:14:20 +01:00
extract_node = "Node_Color";
break;
2022-01-13 05:24:03 +01:00
case VALUE_DISPLAY.palette :
2023-02-28 09:43:01 +01:00
editWidget = new buttonPalette(function(color) {
2023-02-14 02:51:14 +01:00
return setValueDirect(color);
2022-01-13 05:24:03 +01:00
} );
2023-01-09 03:14:20 +01:00
extract_node = "Node_Palette";
break;
2022-01-13 05:24:03 +01:00
}
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_TYPE.gradient : #region
2023-05-28 20:00:51 +02:00
editWidget = new buttonGradient(function(gradient) {
return setValueDirect(gradient);
} );
extract_node = "Node_Gradient_Out";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_TYPE.path : #region
2022-01-13 05:24:03 +01:00
switch(display_type) {
case VALUE_DISPLAY.path_array :
editWidget = new pathArrayBox(node, display_data.filter, function(path) { setValueDirect(path); } );
2023-01-01 02:06:02 +01:00
break;
case VALUE_DISPLAY.path_load :
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) { setValueDirect(str); } );
2023-01-01 02:06:02 +01:00
editWidget.align = fa_left;
editWidget.side_button = button(function() {
var path = get_open_filename(display_data.filter, "");
key_release();
if(path == "") return noone;
return setValueDirect(path);
}, THEME.button_path_icon);
2023-01-09 03:14:20 +01:00
extract_node = "Node_String";
2022-01-13 05:24:03 +01:00
break;
case VALUE_DISPLAY.path_save :
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) { setValueDirect(str); } );
2023-01-01 02:06:02 +01:00
editWidget.align = fa_left;
editWidget.side_button = button(function() {
var path = get_save_filename(display_data.filter, "");
key_release();
if(path == "") return noone;
return setValueDirect(path);
}, THEME.button_path_icon);
2023-01-09 03:14:20 +01:00
extract_node = "Node_String";
2022-01-13 05:24:03 +01:00
break;
2023-01-01 02:06:02 +01:00
2022-12-16 09:18:09 +01:00
case VALUE_DISPLAY.path_font :
2023-01-17 08:11:55 +01:00
editWidget = new fontScrollBox(
2022-12-16 09:18:09 +01:00
function(val) {
2023-03-08 12:14:01 +01:00
return setValueDirect(DIRECTORY + "Fonts/" + FONT_INTERNAL[val]);
2022-12-16 09:18:09 +01:00
}
);
break;
2022-01-13 05:24:03 +01:00
}
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_TYPE.curve : #region
2022-01-13 05:24:03 +01:00
display_type = VALUE_DISPLAY.curve;
2023-02-14 02:51:14 +01:00
editWidget = new curveBox(function(_modified) {
return setValueDirect(_modified);
});
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_TYPE.text : #region
2023-02-21 04:48:50 +01:00
switch(display_type) {
case VALUE_DISPLAY._default :
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) {
return setValueDirect(str);
});
extract_node = "Node_String";
break;
2023-08-31 18:49:57 +02:00
case VALUE_DISPLAY.text_box :
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) {
return setValueDirect(str);
});
extract_node = "Node_String";
break;
2023-02-21 04:48:50 +01:00
2023-09-07 20:59:14 +02:00
case VALUE_DISPLAY.codeLUA :
2023-02-21 04:48:50 +01:00
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) {
return setValueDirect(str);
});
editWidget.font = f_code;
2023-09-07 20:59:14 +02:00
editWidget.format = TEXT_AREA_FORMAT.codeLUA;
editWidget.min_lines = 4;
extract_node = "Node_String";
break;
case VALUE_DISPLAY.codeHLSL:
2023-09-07 20:59:14 +02:00
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) {
return setValueDirect(str);
});
editWidget.autocomplete_server = hlsl_autocomplete_server;
editWidget.function_guide_server = hlsl_function_guide_server;
editWidget.parser_server = hlsl_document_parser;
editWidget.autocomplete_object = node;
2023-09-07 20:59:14 +02:00
editWidget.font = f_code;
editWidget.format = TEXT_AREA_FORMAT.codeHLSL;
2023-02-21 04:48:50 +01:00
editWidget.min_lines = 4;
extract_node = "Node_String";
break;
case VALUE_DISPLAY.text_array :
editWidget = new textArrayBox(function() { return animator.values[| 0].value; }, display_data.data, function() { node.doUpdate(); });
2023-02-21 04:48:50 +01:00
break;
2023-01-04 02:30:04 +01:00
}
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-24 19:44:12 +02:00
case VALUE_TYPE.d3Material :
2023-08-19 12:42:50 +02:00
case VALUE_TYPE.surface : #region
2023-02-14 02:51:14 +01:00
editWidget = new surfaceBox(function(ind) {
return setValueDirect(ind);
} );
2023-10-06 11:51:11 +02:00
if(!struct_has(display_data, "atlas")) display_data.atlas = true;
2022-09-27 06:37:28 +02:00
show_in_inspector = true;
2023-07-18 17:51:40 +02:00
extract_node = "Node_Canvas";
2023-08-19 12:42:50 +02:00
break; #endregion
case VALUE_TYPE.pathnode : #region
2023-07-15 20:01:29 +02:00
extract_node = "Node_Path";
2023-08-19 12:42:50 +02:00
break; #endregion
}
for( var i = 0, n = ds_list_size(animator.values); i < n; i++ ) {
animator.values[| i].ease_in_type = key_inter;
animator.values[| i].ease_out_type = key_inter;
2022-01-13 05:24:03 +01:00
}
2023-03-26 07:13:36 +02:00
setDropKey();
} resetDisplay(); #endregion
2022-01-13 05:24:03 +01:00
2023-10-07 16:23:40 +02:00
static setType = function(_type) { #region
if(type == _type) return false;
type = _type;
draw_junction_index = type;
return true;
} #endregion
static setExpression = function(_expression) { #region
expUse = true;
expression = _expression;
expressionUpdate();
} #endregion
2023-08-19 12:42:50 +02:00
static expressionUpdate = function() { #region
expTree = evaluateFunctionList(expression);
resetCache();
2023-06-17 14:30:49 +02:00
node.triggerRender();
2023-08-19 12:42:50 +02:00
} #endregion
2023-06-17 14:30:49 +02:00
2023-08-19 12:42:50 +02:00
static onValidate = function() { #region
2023-06-04 12:38:40 +02:00
if(!validateValue) return;
2022-11-03 11:44:49 +01:00
var _val = value_validation, str = "";
value_validation = VALIDATION.pass;
switch(type) {
case VALUE_TYPE.path:
switch(display_type) {
case VALUE_DISPLAY.path_load:
2022-09-23 13:28:42 +02:00
var path = animator.getValue();
2022-12-27 13:30:02 +01:00
if(is_array(path)) path = path[0];
2023-10-18 14:58:55 +02:00
if(!is_string(path) || path == "") {
str = $"Path invalid: {path}";
break;
}
if(try_get_path(path) == -1) {
value_validation = VALIDATION.error;
2023-10-18 14:58:55 +02:00
str = $"File not exist: {path}";
2022-11-03 11:44:49 +01:00
}
break;
case VALUE_DISPLAY.path_array:
2022-09-23 13:28:42 +02:00
var paths = animator.getValue();
2022-09-21 06:09:40 +02:00
if(is_array(paths)) {
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(paths); i < n; i++ ) {
2022-12-27 13:30:02 +01:00
if(try_get_path(paths[i]) != -1) continue;
value_validation = VALIDATION.error;
2023-01-04 02:30:04 +01:00
str = "File not exist: " + string(paths[i]);
}
2022-11-03 11:44:49 +01:00
} else {
value_validation = VALIDATION.error;
2023-01-04 02:30:04 +01:00
str = "File not exist: " + string(paths);
2022-11-03 11:44:49 +01:00
}
break;
}
break;
}
2022-12-27 13:30:02 +01:00
node.onValidate();
2022-12-27 13:30:02 +01:00
if(_val == value_validation) return self;
#region notification
2022-11-03 11:44:49 +01:00
if(value_validation == VALIDATION.error && error_notification == noone) {
error_notification = noti_error(str);
2023-01-25 06:49:00 +01:00
error_notification.onClick = function() { PANEL_GRAPH.focusNode(node); };
2022-11-03 11:44:49 +01:00
}
if(value_validation == VALIDATION.pass && error_notification != noone) {
noti_remove(error_notification);
error_notification = noone;
}
2022-12-27 13:30:02 +01:00
#endregion
2022-11-03 11:44:49 +01:00
return self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-08-19 12:42:50 +02:00
static valueProcess = function(value, nodeFrom, applyUnit = true, arrIndex = 0) { #region
2023-01-17 08:11:55 +01:00
var typeFrom = nodeFrom.type;
var display = nodeFrom.display_type;
#region color compatibility [ color, palette, gradient ]
if(type == VALUE_TYPE.gradient && typeFrom == VALUE_TYPE.color) {
2023-10-03 11:27:36 +02:00
if(is_instanceof(value, gradientObject))
return value;
2023-10-03 11:27:36 +02:00
if(is_array(value)) {
var amo = array_length(value);
var grad = array_create(amo);
for( var i = 0; i < amo; i++ )
grad[i] = new gradientKey(i / amo, value[i]);
var g = new gradientObject();
g.keys = grad;
return g;
}
2023-10-03 11:27:36 +02:00
if(is_real(value)) return new gradientObject(value);
return new gradientObject(0);
}
2023-01-01 02:06:02 +01:00
if(display_type == VALUE_DISPLAY.palette && !is_array(value)) {
return [ value ];
}
#endregion
2023-02-14 02:51:14 +01:00
if(display_type == VALUE_DISPLAY.area) { #region
var dispType = struct_try_get(nodeFrom.display_data, "area_type");
var surfGet = struct_try_get(nodeFrom.display_data, "onSurfaceSize");
if(!applyUnit) return value;
if(!is_callable(surfGet)) return value;
2023-08-01 11:16:23 +02:00
var surf = surfGet();
if(!is_array(surf)) return value;
2023-08-01 11:16:23 +02:00
var ww = surf[0];
var hh = surf[1];
switch(dispType) {
case AREA_MODE.area :
return value;
case AREA_MODE.padding :
var cx = (ww - value[0] + value[2]) / 2
var cy = (value[1] + hh - value[3]) / 2;
var sw = abs((ww - value[0]) - value[2]) / 2;
var sh = abs(value[1] - (hh - value[3])) / 2;
return [cx, cy, sw, sh, value[4]];
case AREA_MODE.two_point :
var cx = (value[0] + value[2]) / 2
var cy = (value[1] + value[3]) / 2;
var sw = abs(value[0] - value[2]) / 2;
var sh = abs(value[1] - value[3]) / 2;
return [cx, cy, sw, sh, value[4]];
}
} #endregion
2023-08-01 11:16:23 +02:00
if(display_type == VALUE_DISPLAY.d3quarternion) { #region
var dispType = struct_try_get(nodeFrom.display_data, "angle_display");
switch(dispType) {
case QUARTERNION_DISPLAY.quarterion : return value;
case QUARTERNION_DISPLAY.euler :
var euler = new BBMOD_Quaternion().FromEuler(value[0], value[1], value[2]).ToArray();
return euler;
}
} #endregion
if(type == VALUE_TYPE.text) { #region
2023-02-21 04:48:50 +01:00
switch(display_type) {
case VALUE_DISPLAY.text_array : return value;
default: return string_real(value);
2023-02-21 04:48:50 +01:00
}
} #endregion
2023-01-01 02:06:02 +01:00
if(typeFrom == VALUE_TYPE.surface && type == VALUE_TYPE.d3Material) { #region
if(!is_array(value)) return new __d3dMaterial(value);
var _val = array_create(array_length(value));
for( var i = 0, n = array_length(value); i < n; i++ )
_val[i] = new __d3dMaterial(value[i]);
return _val;
} #endregion
2023-01-01 02:06:02 +01:00
2023-03-02 07:59:14 +01:00
if((typeFrom == VALUE_TYPE.integer || typeFrom == VALUE_TYPE.float || typeFrom == VALUE_TYPE.boolean) && type == VALUE_TYPE.color)
return value >= 1? value : make_color_hsv(0, 0, value * 255);
2023-01-01 02:06:02 +01:00
if(typeFrom == VALUE_TYPE.boolean && type == VALUE_TYPE.text)
return value? "true" : "false";
2023-01-09 03:14:20 +01:00
2023-09-09 13:52:16 +02:00
if(type == VALUE_TYPE.integer || type == VALUE_TYPE.float) { #region
2023-01-01 02:06:02 +01:00
if(typeFrom == VALUE_TYPE.text)
value = toNumber(value);
2023-09-09 13:52:16 +02:00
//print($"{name} get value {value} ({applyUnit})");
//printCallStack();
//print("=======================");
if(applyUnit) return unit.apply(value, arrIndex);
} #endregion
2023-03-28 06:58:28 +02:00
if(type == VALUE_TYPE.surface && connect_type == JUNCTION_CONNECT.input && !is_surface(value) && def_val == USE_DEF)
return DEF_SURFACE;
2022-12-23 04:45:52 +01:00
return value;
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-16 09:18:09 +01:00
2023-08-19 12:42:50 +02:00
static resetCache = function() { cache_value[0] = false; }
2023-07-25 20:12:40 +02:00
2023-10-09 16:07:33 +02:00
static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { #region
2023-06-13 14:42:06 +02:00
if(type == VALUE_TYPE.trigger)
useCache = false;
2023-09-09 13:52:16 +02:00
2023-07-14 20:34:35 +02:00
global.cache_call++;
2023-07-25 20:12:40 +02:00
if(useCache && use_cache) {
2023-05-16 21:28:16 +02:00
var cache_hit = cache_value[0];
2023-10-07 16:23:40 +02:00
cache_hit &= !isActiveDynamic() || cache_value[1] == _time;
2023-05-16 21:28:16 +02:00
cache_hit &= cache_value[2] != undefined;
2023-09-09 13:52:16 +02:00
cache_hit &= cache_value[3] == applyUnit;
2023-05-16 21:28:16 +02:00
cache_hit &= connect_type == JUNCTION_CONNECT.input;
2023-07-28 19:41:57 +02:00
cache_hit &= unit.reference == noone || unit.mode == VALUE_UNIT.constant;
//cache_hit &= !expUse;
2023-07-23 20:21:35 +02:00
2023-07-14 20:34:35 +02:00
if(cache_hit) {
global.cache_hit++;
2023-10-02 14:41:44 +02:00
return cache_value[2];
2023-07-14 20:34:35 +02:00
}
2023-05-16 21:28:16 +02:00
}
2023-02-14 02:51:14 +01:00
2023-09-09 13:52:16 +02:00
var val = _getValue(_time, applyUnit, arrIndex, log);
2023-02-14 02:51:14 +01:00
2023-10-06 11:51:11 +02:00
draw_junction_index = type;
2023-10-07 16:23:40 +02:00
if(type == VALUE_TYPE.surface || type == VALUE_TYPE.any) {
2023-10-06 11:51:11 +02:00
var _sval = val;
if(is_array(_sval) && !array_empty(_sval))
_sval = _sval[0];
if(is_instanceof(_sval, SurfaceAtlas))
draw_junction_index = VALUE_TYPE.atlas;
}
2023-05-16 21:28:16 +02:00
if(useCache) {
2023-07-23 20:21:35 +02:00
is_changed = !isEqual(cache_value[2], val);
2023-05-16 21:28:16 +02:00
cache_value[0] = true;
2023-07-23 20:21:35 +02:00
cache_value[1] = _time;
2023-05-16 21:28:16 +02:00
}
2023-02-14 02:51:14 +01:00
cache_value[2] = array_clone(val);
2023-09-09 13:52:16 +02:00
cache_value[3] = applyUnit;
2023-07-23 20:21:35 +02:00
2023-09-14 16:29:39 +02:00
return val;
2023-08-19 12:42:50 +02:00
} #endregion
2023-02-14 02:51:14 +01:00
2023-10-09 16:07:33 +02:00
static __getAnimValue = function(_time = CURRENT_FRAME) { #region
2023-03-21 03:01:53 +01:00
if(sep_axis) {
var val = [];
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
val[i] = animators[i].getValue(_time);
return val;
2023-09-09 13:52:16 +02:00
}
var _val = animator.getValue(_time);
return _val;
2023-08-19 12:42:50 +02:00
} #endregion
2023-03-21 03:01:53 +01:00
static arrayBalance = function(val) { #region //Balance array (generate uniform array from single values)
2023-08-24 11:59:05 +02:00
if(!is_array(def_val))
return val;
2023-08-24 11:59:05 +02:00
2023-09-18 13:54:55 +02:00
if(isDynamicArray(display_type))
return val;
2023-08-24 11:59:05 +02:00
if(isArray(val))
return val;
2023-09-18 13:54:55 +02:00
if(!is_array(val))
2023-09-18 13:54:55 +02:00
return array_create(def_length, val);
else if(array_length(val) < def_length) {
2023-09-18 13:54:55 +02:00
var _val = array_create(def_length);
for( var i = 0; i < def_length; i++ )
_val[i] = array_safe_get(val, i, 0);
return _val;
2023-08-24 11:59:05 +02:00
}
return val;
} #endregion
2023-10-09 16:07:33 +02:00
static _getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, log = false) { #region
2022-12-10 05:06:01 +01:00
var _val = getValueRecursive(_time);
2022-01-18 05:31:19 +01:00
var val = _val[0];
2022-12-23 04:45:52 +01:00
var nod = _val[1];
var typ = nod.type;
var dis = nod.display_type;
2022-01-18 05:31:19 +01:00
if(connect_type == JUNCTION_CONNECT.output)
return val;
2023-01-25 06:49:00 +01:00
if(typ == VALUE_TYPE.surface && (type == VALUE_TYPE.integer || type == VALUE_TYPE.float) && accept_array) { //Dimension conversion
2022-01-18 05:31:19 +01:00
if(is_array(val)) {
2023-01-01 02:06:02 +01:00
var eqSize = true;
var sArr = [];
var _osZ = 0;
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(val); i < n; i++ ) {
2023-01-01 02:06:02 +01:00
if(!is_surface(val[i])) continue;
2023-09-08 21:37:36 +02:00
var surfSz = [ surface_get_width_safe(val[i]), surface_get_height_safe(val[i]) ];
2023-01-01 02:06:02 +01:00
array_push(sArr, surfSz);
if(i && !array_equals(surfSz, _osZ))
eqSize = false;
_osZ = surfSz;
}
if(eqSize) return _osZ;
return sArr;
} else if (is_surface(val))
2023-09-08 21:37:36 +02:00
return [ surface_get_width_safe(val), surface_get_height_safe(val) ];
2023-01-01 02:06:02 +01:00
return [1, 1];
}
2022-01-18 05:31:19 +01:00
val = arrayBalance(val);
2022-01-13 05:24:03 +01:00
2023-09-18 13:54:55 +02:00
if(isArray(val) && array_length(val) < 1024) { //Process data
var _val = array_create(array_length(val));
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(val); i < n; i++ )
2023-09-18 13:54:55 +02:00
_val[i] = valueProcess(val[i], nod, applyUnit, arrIndex);
return _val;
}
2022-12-16 09:18:09 +01:00
2023-09-18 13:54:55 +02:00
return valueProcess(val, nod, applyUnit, arrIndex);
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-10-09 16:07:33 +02:00
static getValueRecursive = function(_time = CURRENT_FRAME) { #region
var val = [ __getAnimValue(_time), self ];
2022-01-13 05:24:03 +01:00
if(type == VALUE_TYPE.trigger && connect_type == JUNCTION_CONNECT.output) //trigger event will not propagate from input to output, need to be done manually
return val;
2023-06-13 14:42:06 +02:00
if(value_from && value_from != self)
val = value_from.getValueRecursive(_time);
2022-01-13 05:24:03 +01:00
2023-07-11 20:36:44 +02:00
if(expUse && is_struct(expTree) && expTree.validate()) {
2023-07-14 20:34:35 +02:00
//print($"========== EXPRESSION CALLED ==========");
//print(debug_get_callstack(8));
if(global.EVALUATE_HEAD != noone && global.EVALUATE_HEAD == self) {
noti_warning($"Expression evaluation error : recursive call detected.");
2023-07-14 20:34:35 +02:00
} else {
//print($"==================== EVAL BEGIN {expTree} ====================");
2023-08-02 19:11:57 +02:00
//printCallStack();
2023-07-29 10:10:48 +02:00
2023-07-14 20:34:35 +02:00
global.EVALUATE_HEAD = self;
2023-10-12 14:14:08 +02:00
expContext = {
2023-07-14 20:34:35 +02:00
name: name,
node_name: node.display_name,
2023-10-12 14:14:08 +02:00
value: val[0],
node_values: node.input_value_map,
2023-07-14 20:34:35 +02:00
};
2023-08-02 19:11:57 +02:00
2023-10-12 14:14:08 +02:00
var _exp_res = expTree.eval(variable_clone(expContext));
//print(json_stringify(expTree, true));
//print($"======= {_exp_res}");
2023-08-02 19:11:57 +02:00
if(is_undefined(_exp_res)) {
val[0] = 0;
noti_warning("Expression not returning any values.");
} else
val[0] = _exp_res;
2023-07-14 20:34:35 +02:00
global.EVALUATE_HEAD = noone;
}
return val;
}
2023-04-15 14:48:29 +02:00
return val;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static setAnim = function(anim) { #region
2023-10-14 08:00:35 +02:00
if(is_anim == anim) return;
is_anim = anim;
2023-10-14 08:00:35 +02:00
if(is_anim) {
2023-10-09 16:07:33 +02:00
animator.values[| 0].time = CURRENT_FRAME;
for( var i = 0, n = array_length(animators); i < n; i++ ) {
animators[i].values[| 0].time = CURRENT_FRAME;
}
} else {
ds_list_clear(animator.values);
animator.values[| 0] = new valueKey(0, animator.getValue(), animator);
for( var i = 0, n = array_length(animators); i < n; i++ ) {
ds_list_clear(animators[i].values);
animators[i].values[| 0] = new valueKey(0, animators[i].getValue(), animators[i]);
}
}
2023-10-14 08:00:35 +02:00
node.refreshTimeline();
2023-08-19 12:42:50 +02:00
} #endregion
2023-03-21 03:01:53 +01:00
2023-10-07 16:23:40 +02:00
static isActiveDynamic = function() { #region
gml_pragma("forceinline");
if(value_from != noone) return false;
2023-05-03 21:42:17 +02:00
if(expUse) {
if(!is_struct(expTree)) return false;
2023-10-07 16:23:40 +02:00
var res = expTree.isDynamic();
2023-10-02 14:41:44 +02:00
2023-05-03 21:42:17 +02:00
switch(res) {
case EXPRESS_TREE_ANIM.none : return false;
case EXPRESS_TREE_ANIM.base_value : return is_anim;
case EXPRESS_TREE_ANIM.animated : return true;
}
}
return is_anim;
2023-08-19 12:42:50 +02:00
} #endregion
2023-03-21 03:01:53 +01:00
2023-08-19 12:42:50 +02:00
static showValue = function() { #region
2023-08-02 19:11:57 +02:00
var useCache = true;
if(display_type == VALUE_DISPLAY.area)
useCache = false;
2023-09-09 13:52:16 +02:00
var val = getValue(, false, 0, useCache, true);
2023-08-01 11:16:23 +02:00
if(isArray(val)) {
2022-01-13 05:24:03 +01:00
if(array_length(val) == 0) return 0;
2023-05-16 21:28:16 +02:00
var v = val[safe_mod(node.preview_index, array_length(val))];
if(array_length(v) >= 100) return $"[{array_length(v)}]";
2022-01-13 05:24:03 +01:00
}
2023-09-14 16:29:39 +02:00
2023-10-06 11:51:11 +02:00
if(editWidget != noone && instanceof(editWidget) == "textBox" && string_length(string(val)) > 1024)
2023-09-14 16:29:39 +02:00
val = $"[Long string ({string_length(string(val))} char)]";
2022-01-13 05:24:03 +01:00
return val;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-09-18 13:54:55 +02:00
static isDynamicArray = function() { #region
if(dynamic_array) return true;
switch(display_type) {
case VALUE_DISPLAY.curve :
case VALUE_DISPLAY.palette :
return true;
}
return false;
} #endregion
2023-08-19 12:42:50 +02:00
static isArray = function(val = undefined) { #region
2023-02-14 02:51:14 +01:00
if(val == undefined) {
2023-10-28 04:07:43 +02:00
if(cache_array[0]) return cache_array[1];
2023-02-14 02:51:14 +01:00
val = getValue();
}
cache_array[0] = true;
2023-02-21 04:48:50 +01:00
if(!is_array(val)) { //Value is array
2023-02-14 02:51:14 +01:00
cache_array[1] = false;
return cache_array[1];
}
2023-02-21 04:48:50 +01:00
if(array_depth == 0 && !typeArray(display_type)) { //Value is not an array by default, and no array depth enforced
2023-02-14 02:51:14 +01:00
cache_array[1] = true;
return cache_array[1];
}
2023-02-21 04:48:50 +01:00
var ar = val;
repeat(array_depth + typeArray(display_type)) { //Recursively get the first member of subarray to check if value has depth of "array_depth" or not
if(!is_array(ar) || !array_length(ar)) { //empty array
cache_array[1] = false;
return cache_array[1];
}
2022-12-23 04:45:52 +01:00
2023-02-21 04:48:50 +01:00
ar = ar[0];
2023-02-14 02:51:14 +01:00
}
2022-01-13 05:24:03 +01:00
2023-02-21 04:48:50 +01:00
cache_array[1] = is_array(ar);
2023-02-14 02:51:14 +01:00
return cache_array[1];
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static arrayLength = function(val = undefined) { #region
2023-10-28 04:07:43 +02:00
if(val == undefined) val = getValue();
2023-02-28 09:43:01 +01:00
if(!isArray(val))
2023-09-18 13:54:55 +02:00
return -1;
2023-02-28 09:43:01 +01:00
if(array_depth == 0 && !typeArray(display_type))
return array_length(val);
2023-08-24 11:59:05 +02:00
var ar = val;
var _depth = max(0, array_depth + typeArray(display_type) - 1);
repeat(_depth)
2023-02-28 09:43:01 +01:00
ar = ar[0];
return array_length(ar);
2023-08-19 12:42:50 +02:00
} #endregion
2023-02-28 09:43:01 +01:00
2023-10-09 16:07:33 +02:00
static setValue = function(val = 0, record = true, time = CURRENT_FRAME, _update = true) { #region
2022-12-27 04:00:50 +01:00
val = unit.invApply(val);
2023-03-21 03:01:53 +01:00
return setValueDirect(val, noone, record, time, _update);
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-27 04:00:50 +01:00
static overrideValue = function(_val) { #region
ds_list_clear(animator.values);
ds_list_add(animator.values, new valueKey(0, _val, animator));
for( var i = 0, n = array_length(animators); i < n; i++ ) {
ds_list_clear(animators[i].values);
ds_list_add(animators[i].values, new valueKey(0, array_safe_get(_val, i), animators[i]));
}
} #endregion
2023-10-09 16:07:33 +02:00
static setValueDirect = function(val = 0, index = noone, record = true, time = CURRENT_FRAME, _update = true) { #region
2023-03-21 03:01:53 +01:00
var updated = false;
if(sep_axis) {
if(index == noone) {
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-03-21 03:01:53 +01:00
updated |= animators[i].setValue(val[i], connect_type == JUNCTION_CONNECT.input && record, time);
} else
updated = animators[index].setValue(val, connect_type == JUNCTION_CONNECT.input && record, time);
} else {
if(index != noone) {
2023-07-21 12:40:20 +02:00
var _val = variable_clone(animator.getValue(time));
2023-03-21 03:01:53 +01:00
_val[index] = val;
updated = animator.setValue(_val, connect_type == JUNCTION_CONNECT.input && record, time);
2023-08-08 18:45:00 +02:00
} else
2023-03-21 03:01:53 +01:00
updated = animator.setValue(val, connect_type == JUNCTION_CONNECT.input && record, time);
}
2022-01-13 05:24:03 +01:00
2023-06-23 15:39:24 +02:00
if(type == VALUE_TYPE.gradient) updated = true;
if(display_type == VALUE_DISPLAY.palette) updated = true;
2023-01-04 02:30:04 +01:00
2023-10-06 11:51:11 +02:00
if(!updated) return false;
draw_junction_index = type;
if(type == VALUE_TYPE.surface) {
var _sval = val;
if(is_array(_sval) && !array_empty(_sval))
_sval = _sval[0];
if(is_instanceof(_sval, SurfaceAtlas))
draw_junction_index = VALUE_TYPE.atlas;
2022-01-13 05:24:03 +01:00
}
2023-10-06 11:51:11 +02:00
if(connect_type == JUNCTION_CONNECT.output) return;
if(is_instanceof(node, Node))
node.setInputData(self.index, animator.getValue(time));
2023-10-06 11:51:11 +02:00
if(tags != VALUE_TAG.none) return true;
2023-10-08 08:02:38 +02:00
if(_update) {
if(!IS_PLAYING) node.triggerRender();
2023-10-08 08:02:38 +02:00
node.valueUpdate(self.index);
node.clearCacheForward();
}
if(fullUpdate && !IS_PLAYING) RENDER_ALL
2023-10-06 11:51:11 +02:00
if(!LOADING) PROJECT.modified = true;
cache_value[0] = false;
onValidate();
2023-02-14 02:51:14 +01:00
2023-10-06 11:51:11 +02:00
return true;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static isConnectable = function(_valueFrom, checkRecur = true, log = false) { #region
2023-01-09 03:14:20 +01:00
if(_valueFrom == -1 || _valueFrom == undefined || _valueFrom == noone) {
2023-01-25 06:49:00 +01:00
if(log)
noti_warning("LOAD: Cannot set node connection from " + string(_valueFrom) + " to " + string(name) + " of node " + string(node.name) + ".",, node);
return false;
2022-01-13 05:24:03 +01:00
}
2022-01-25 10:58:11 +01:00
if(_valueFrom == value_from) {
2023-06-19 20:28:30 +02:00
print("whaT");
return false;
2022-01-13 05:24:03 +01:00
}
if(_valueFrom == self) {
2023-01-25 06:49:00 +01:00
if(log)
noti_warning("setFrom: Self connection is not allowed.",, node);
return false;
2022-01-13 05:24:03 +01:00
}
2023-03-05 07:16:44 +01:00
if(!typeCompatible(_valueFrom.type, type)) {
2023-02-14 02:51:14 +01:00
if(log)
2023-07-25 20:12:40 +02:00
noti_warning($"setFrom: Type mismatch {_valueFrom.type} to {type}",, node);
return false;
2023-02-19 02:13:19 +01:00
}
if(typeIncompatible(_valueFrom, self)) {
if(log)
noti_warning("setFrom: Type mismatch",, node);
return false;
2022-01-13 05:24:03 +01:00
}
if(connect_type == _valueFrom.connect_type) {
2023-01-25 06:49:00 +01:00
if(log)
noti_warning("setFrom: Connect type mismatch",, node);
return false;
2022-01-13 05:24:03 +01:00
}
if(checkRecur && _valueFrom.searchNodeBackward(node)) {
2023-01-25 06:49:00 +01:00
if(log)
2023-03-05 07:16:44 +01:00
noti_warning("setFrom: Cyclic connection not allowed.",, node);
return false;
2022-01-13 05:24:03 +01:00
}
2023-02-14 02:51:14 +01:00
if(!accept_array && isArray(_valueFrom.getValue())) {
2023-01-25 06:49:00 +01:00
if(log)
noti_warning("setFrom: Array mismatch",, node);
return false;
2022-01-13 05:24:03 +01:00
}
2023-01-25 06:49:00 +01:00
if(!accept_array && _valueFrom.type == VALUE_TYPE.surface && (type == VALUE_TYPE.integer || type == VALUE_TYPE.float)) {
if(log)
noti_warning("setFrom: Array mismatch",, node);
return false;
2022-01-25 10:58:11 +01:00
}
2023-01-25 06:49:00 +01:00
return true;
2023-08-19 12:42:50 +02:00
} #endregion
2023-01-25 06:49:00 +01:00
2023-10-27 13:55:31 +02:00
static isLeaf = function() { gml_pragma("forceinline"); return value_from == noone; }
static isRendered = function() { #region
if(type == VALUE_TYPE.node) return true;
if( value_from == noone) return true;
if(!value_from.node.active) return true;
if(!value_from.node.isRenderActive()) return true;
return value_from.node.rendered;
} #endregion
2023-08-19 12:42:50 +02:00
static setFrom = function(_valueFrom, _update = true, checkRecur = true, log = false) { #region
2023-09-17 13:23:24 +02:00
//print($"Connecting {_valueFrom.name} to {name}");
2023-02-14 02:51:14 +01:00
if(_valueFrom == noone)
return removeFrom();
2023-03-28 06:58:28 +02:00
2023-07-25 20:12:40 +02:00
if(!isConnectable(_valueFrom, checkRecur, log))
return -1;
2023-01-25 06:49:00 +01:00
2023-03-28 06:58:28 +02:00
if(setFrom_condition != -1 && !setFrom_condition(_valueFrom))
2023-07-25 20:12:40 +02:00
return -2;
2023-02-14 02:51:14 +01:00
2023-01-25 06:49:00 +01:00
if(value_from != noone)
ds_list_remove(value_from.value_to, self);
2022-01-25 10:58:11 +01:00
2022-09-23 13:28:42 +02:00
var _o = animator.getValue();
2022-01-13 05:24:03 +01:00
recordAction(ACTION_TYPE.junction_connect, self, value_from);
value_from = _valueFrom;
ds_list_add(_valueFrom.value_to, self);
//show_debug_message("connected " + name + " to " + _valueFrom.name)
2022-01-13 05:24:03 +01:00
2023-02-14 02:51:14 +01:00
node.valueUpdate(index, _o);
2023-01-04 02:30:04 +01:00
if(_update && connect_type == JUNCTION_CONNECT.input) {
2023-11-02 14:37:13 +01:00
node.valueFromUpdate(index);
2022-12-12 09:08:03 +01:00
node.triggerRender();
2023-02-23 07:02:19 +01:00
node.clearCacheForward();
2023-03-29 15:02:03 +02:00
2023-03-31 06:59:08 +02:00
UPDATE |= RENDER_TYPE.partial;
2022-12-12 09:08:03 +01:00
}
2023-02-14 02:51:14 +01:00
cache_array[0] = false;
cache_value[0] = false;
2023-09-09 13:52:16 +02:00
if(!LOADING) {
draw_line_shift_x = 0;
draw_line_shift_y = 0;
PROJECT.modified = true;
}
2023-03-28 06:58:28 +02:00
2023-10-07 16:23:40 +02:00
RENDER_ALL_REORDER
2023-10-07 09:09:18 +02:00
if(onSetFrom != noone) onSetFrom(_valueFrom);
if(_valueFrom.onSetTo != noone) _valueFrom.onSetTo(self);
return true;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static removeFrom = function(_remove_list = true) { #region
2023-02-14 02:51:14 +01:00
recordAction(ACTION_TYPE.junction_disconnect, self, value_from);
2022-01-26 06:57:34 +01:00
if(_remove_list && value_from != noone)
2022-01-25 10:58:11 +01:00
ds_list_remove(value_from.value_to, self);
2022-01-13 05:24:03 +01:00
value_from = noone;
2023-01-04 02:30:04 +01:00
if(connect_type == JUNCTION_CONNECT.input)
2023-11-02 14:37:13 +01:00
node.valueFromUpdate(index);
2023-04-14 12:23:25 +02:00
node.clearCacheForward();
2023-02-14 02:51:14 +01:00
PROJECT.modified = true;
2023-10-02 10:45:30 +02:00
2023-10-07 16:23:40 +02:00
RENDER_ALL_REORDER
2023-02-14 02:51:14 +01:00
return false;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static getShowString = function() { #region
2022-01-13 05:24:03 +01:00
var val = showValue();
2023-02-17 04:48:54 +01:00
return string_real(val);
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static setString = function(str) { #region
2022-09-23 13:28:42 +02:00
var _o = animator.getValue();
2022-01-13 05:24:03 +01:00
if(string_pos(",", str) > 0) {
string_replace(str, "[", "");
string_replace(str, "]", "");
var ss = str, pos, val = [], ind = 0;
while(string_length(ss) > 0) {
pos = string_pos(",", ss);
if(pos == 0) {
val[ind++] = toNumber(ss);
ss = "";
} else {
val[ind++] = toNumber(string_copy(ss, 1, pos - 1));
ss = string_copy(ss, pos + 1, string_length(ss) - pos);
}
}
var _t = typeArray(display_type);
if(_t) {
2023-02-14 02:51:14 +01:00
if(array_length(_o) == array_length(val) || _t == 2)
2022-01-13 05:24:03 +01:00
setValue(val);
} else if(array_length(val) > 0) {
setValue(val[0]);
}
} else {
if(is_array(_o)) {
setValue(array_create(array_length(_o), toNumber(str)));
} else {
setValue(toNumber(str));
}
}
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static checkConnection = function(_remove_list = true) { #region
2023-10-27 13:55:31 +02:00
if(isLeaf()) return;
2022-01-26 06:57:34 +01:00
if(value_from.node.active) return;
removeFrom(_remove_list);
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static searchNodeBackward = function(_node) { #region
2022-01-13 05:24:03 +01:00
if(node == _node) return true;
for(var i = 0; i < ds_list_size(node.inputs); i++) {
var _in = node.inputs[| i].value_from;
if(_in && _in.searchNodeBackward(_node))
return true;
}
return false;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static unitConvert = function(mode) { #region
2022-12-27 04:00:50 +01:00
var _v = animator.values;
for( var i = 0; i < ds_list_size(_v); i++ )
_v[| i].value = unit.convertUnit(_v[| i].value, mode);
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-27 04:00:50 +01:00
2023-08-19 12:42:50 +02:00
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
2023-04-05 20:13:27 +02:00
if(type != VALUE_TYPE.integer && type != VALUE_TYPE.float) return -1;
2023-08-02 19:11:57 +02:00
if(value_from != noone) return -1;
if(expUse) return -1;
2023-01-01 02:06:02 +01:00
2023-04-05 20:13:27 +02:00
switch(display_type) {
case VALUE_DISPLAY._default :
var _angle = argument_count > 8? argument[ 8] : 0;
var _scale = argument_count > 9? argument[ 9] : 1;
var _spr = argument_count > 10? argument[10] : THEME.anchor_selector;
2023-10-27 13:55:31 +02:00
return preview_overlay_scalar(isLeaf(), active, _x, _y, _s, _mx, _my, _snx, _sny, _angle, _scale, _spr);
2022-01-13 05:24:03 +01:00
2023-04-05 20:13:27 +02:00
case VALUE_DISPLAY.rotation :
var _rad = argument_count > 8? argument[ 8] : 64;
2023-10-27 13:55:31 +02:00
return preview_overlay_rotation(isLeaf(), active, _x, _y, _s, _mx, _my, _snx, _sny, _rad);
2022-01-13 05:24:03 +01:00
2023-04-05 20:13:27 +02:00
case VALUE_DISPLAY.vector :
var _spr = argument_count > 8? argument[8] : THEME.anchor_selector;
var _sca = argument_count > 9? argument[9] : 1;
2023-10-27 13:55:31 +02:00
return preview_overlay_vector(isLeaf(), active, _x, _y, _s, _mx, _my, _snx, _sny, _spr);
2022-01-13 05:24:03 +01:00
2023-04-05 20:13:27 +02:00
case VALUE_DISPLAY.area :
var _flag = argument_count > 8? argument[8] : 0b0011;
2023-10-27 13:55:31 +02:00
return preview_overlay_area(isLeaf(), active, _x, _y, _s, _mx, _my, _snx, _sny, _flag, struct_try_get(display_data, "onSurfaceSize"));
2022-09-23 13:28:42 +02:00
2023-04-05 20:13:27 +02:00
case VALUE_DISPLAY.puppet_control :
2023-10-27 13:55:31 +02:00
return preview_overlay_puppet(isLeaf(), active, _x, _y, _s, _mx, _my, _snx, _sny);
2022-01-13 05:24:03 +01:00
}
2023-04-05 20:13:27 +02:00
2023-01-17 08:11:55 +01:00
return -1;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static drawJunction = function(_s, _mx, _my, sca = 1) { #region
2023-10-15 15:04:42 +02:00
var _bgC, _fgC;
if(color == -1) {
_bgC = isArray()? value_color_bg_array(draw_junction_index) : value_color_bg(draw_junction_index);
_fgC = value_color(draw_junction_index);
2023-03-28 06:58:28 +02:00
} else {
2023-10-18 14:58:55 +02:00
_bgC = isArray()? merge_color(color, colorMultiply(color, CDEF.main_dkgrey), 0.5) : value_color_bg(draw_junction_index);
2023-10-15 15:04:42 +02:00
_fgC = color;
2023-03-28 06:58:28 +02:00
}
2022-09-27 06:37:28 +02:00
color_display = type == VALUE_TYPE.action? #8fde5d : _fgC;
if(!isVisible()) return false;
var ss = max(0.25, _s / 2);
var hov = PANEL_GRAPH.pHOVER && (PANEL_GRAPH.node_hovering == noone || PANEL_GRAPH.node_hovering == node);
var is_hover = hov && point_in_circle(_mx, _my, x, y, 10 * _s * sca);
var _bgS = THEME.node_junctions_bg;
var _fgS = is_hover? THEME.node_junctions_outline_hover : THEME.node_junctions_outline;
2023-10-15 15:04:42 +02:00
if(type == VALUE_TYPE.action) {
draw_sprite_ext(THEME.node_junction_inspector, is_hover, x, y, ss, ss, 0, c_white, 1);
} else {
draw_sprite_ext(_bgS, draw_junction_index, x, y, ss, ss, 0, _bgC, 1);
draw_sprite_ext(_fgS, draw_junction_index, x, y, ss, ss, 0, _fgC, 1);
}
2023-07-12 16:28:32 +02:00
2022-09-27 06:37:28 +02:00
return is_hover;
2023-08-19 12:42:50 +02:00
} #endregion
2022-09-27 06:37:28 +02:00
2023-08-19 12:42:50 +02:00
static drawNameBG = function(_s) { #region
2022-09-27 06:37:28 +02:00
if(!isVisible()) return false;
draw_set_text(f_p1, fa_left, fa_center);
2022-12-10 05:06:01 +01:00
2023-03-28 06:58:28 +02:00
var tw = string_width(name) + 32;
2022-09-27 06:37:28 +02:00
var th = string_height(name) + 16;
2023-03-28 06:58:28 +02:00
if(type == VALUE_TYPE.action) {
var tx = x;
draw_sprite_stretched_ext(THEME.node_junction_name_bg, 0, tx - tw / 2, y - th, tw, th, c_white, 0.5);
} else if(connect_type == JUNCTION_CONNECT.input) {
2022-09-27 06:37:28 +02:00
var tx = x - 12 * _s;
2023-03-28 06:58:28 +02:00
draw_sprite_stretched_ext(THEME.node_junction_name_bg, 0, tx - tw + 16, y - th / 2, tw, th, c_white, 0.5);
2022-09-27 06:37:28 +02:00
} else {
var tx = x + 12 * _s;
2023-03-28 06:58:28 +02:00
draw_sprite_stretched_ext(THEME.node_junction_name_bg, 0, tx - 16, y - th / 2, tw, th, c_white, 0.5);
2022-01-26 06:57:34 +01:00
}
2023-08-19 12:42:50 +02:00
} #endregion
static drawName = function(_s, _mx, _my) { #region
2022-09-27 06:37:28 +02:00
if(!isVisible()) return false;
2022-01-26 06:57:34 +01:00
2023-02-23 07:02:19 +01:00
var _hover = PANEL_GRAPH.pHOVER && point_in_circle(_mx, _my, x, y, 10 * _s);
2022-11-18 03:20:31 +01:00
var _draw_cc = _hover? COLORS._main_text : COLORS._main_text_sub;
2022-09-27 06:37:28 +02:00
draw_set_text(f_p1, fa_left, fa_center, _draw_cc);
2023-03-28 06:58:28 +02:00
if(type == VALUE_TYPE.action) {
var tx = x;
draw_set_text(f_p1, fa_center, fa_center, _draw_cc);
2023-05-28 20:00:51 +02:00
draw_text(tx, y - (line_get_height() + 16) / 2, name);
2023-03-28 06:58:28 +02:00
} else if(connect_type == JUNCTION_CONNECT.input) {
2022-09-27 06:37:28 +02:00
var tx = x - 12 * _s;
draw_set_halign(fa_right);
draw_text(tx, y, name);
} else {
var tx = x + 12 * _s;
draw_set_halign(fa_left);
draw_text(tx, y, name);
}
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-26 06:57:34 +01:00
2023-08-31 18:49:57 +02:00
static drawConnections = function(params = {}) { #region
2023-11-01 08:10:25 +01:00
var log = struct_try_get(params, "log", false);
2023-10-27 13:55:31 +02:00
if(isLeaf()) return noone;
2023-07-25 20:12:40 +02:00
if(!value_from.node.active) return noone;
if(!isVisible()) return noone;
2023-08-31 18:49:57 +02:00
var _x = params.x;
var _y = params.y;
var _s = params.s;
var mx = params.mx;
var my = params.my;
var _active = params.active;
var cur_layer = params.cur_layer;
var max_layer = params.max_layer;
var aa = struct_try_get(params, "aa", 1);
2023-08-31 19:56:23 +02:00
var high = struct_try_get(params, "highlight", 0);
2023-08-31 18:49:57 +02:00
var bg = struct_try_get(params, "bg", c_black);
2023-07-25 20:12:40 +02:00
var hovering = noone;
var jx = x;
var jy = y;
2023-07-25 20:12:40 +02:00
var frx = value_from.x;
var fry = value_from.y;
2023-11-01 08:10:25 +01:00
if(struct_has(params, "minx")) {
var minx = params.minx;
var miny = params.miny;
var maxx = params.maxx;
var maxy = params.maxy;
2023-07-25 20:12:40 +02:00
if(jx < minx && frx < minx) return noone;
if(jx > maxx && frx > maxx) return noone;
if(jy < miny && fry < miny) return noone;
if(jy > maxy && fry > maxy) return noone;
}
2023-08-31 18:49:57 +02:00
2023-07-25 20:12:40 +02:00
var shx = draw_line_shift_x * _s;
var shy = draw_line_shift_y * _s;
2023-09-09 13:52:16 +02:00
2023-07-25 20:12:40 +02:00
var cx = round((frx + jx) / 2 + shx);
var cy = round((fry + jy) / 2 + shy);
var hover = false;
2023-10-31 05:30:42 +01:00
var th = max(1, PREFERENCES.connection_line_width * _s);
2023-07-25 20:12:40 +02:00
draw_line_shift_hover = false;
var downDirection = type == VALUE_TYPE.action || value_from.type == VALUE_TYPE.action;
if(PANEL_GRAPH.pHOVER)
2023-10-31 05:30:42 +01:00
switch(PREFERENCES.curve_connection_line) {
2023-07-25 20:12:40 +02:00
case 0 :
hover = distance_to_line(mx, my, jx, jy, frx, fry) < max(th * 2, 6);
break;
case 1 :
if(downDirection)
hover = distance_to_curve_corner(mx, my, jx, jy, frx, fry, _s) < max(th * 2, 6);
else
hover = distance_to_curve(mx, my, jx, jy, frx, fry, cx, cy, _s) < max(th * 2, 6);
2023-08-13 09:00:58 +02:00
if(PANEL_GRAPH.value_focus == noone)
2023-07-25 20:12:40 +02:00
draw_line_shift_hover = hover;
break;
case 2 :
if(downDirection)
hover = distance_to_elbow_corner(mx, my, frx, fry, jx, jy) < max(th * 2, 6);
else
hover = distance_to_elbow(mx, my, frx, fry, jx, jy, cx, cy, _s, value_from.drawLineIndex, drawLineIndex) < max(th * 2, 6);
2023-08-13 09:00:58 +02:00
if(PANEL_GRAPH.value_focus == noone)
2023-07-25 20:12:40 +02:00
draw_line_shift_hover = hover;
break;
case 3 :
if(downDirection)
hover = distance_to_elbow_diag_corner(mx, my, frx, fry, jx, jy) < max(th * 2, 6);
else
hover = distance_to_elbow_diag(mx, my, frx, fry, jx, jy, cx, cy, _s, value_from.drawLineIndex, drawLineIndex) < max(th * 2, 6);
2023-08-13 09:00:58 +02:00
if(PANEL_GRAPH.value_focus == noone)
2023-07-25 20:12:40 +02:00
draw_line_shift_hover = hover;
break;
}
if(_active && hover)
hovering = self;
var thicken = false;
thicken |= PANEL_GRAPH.nodes_junction_d == self;
2023-08-13 09:00:58 +02:00
thicken |= _active && PANEL_GRAPH.junction_hovering == self && PANEL_GRAPH.value_focus == noone;
2023-07-25 20:12:40 +02:00
thicken |= instance_exists(o_dialog_add_node) && o_dialog_add_node.junction_hovering == self;
th *= thicken? 2 : 1;
2023-10-31 05:30:42 +01:00
var corner = PREFERENCES.connection_line_corner * _s;
2023-07-25 20:12:40 +02:00
var ty = LINE_STYLE.solid;
if(type == VALUE_TYPE.node)
ty = LINE_STYLE.dashed;
2023-08-31 18:49:57 +02:00
var c0, c1;
2023-10-12 07:07:24 +02:00
var _selc = node.active_draw_index == 0 || value_from.node.active_draw_index == 0 || node.branch_drawing;
2023-08-31 18:49:57 +02:00
2023-10-12 07:07:24 +02:00
if(!thicken && (high == 1 && key_mod_press(ALT) || high == 2)) {
2023-10-31 05:30:42 +01:00
var _fade = PREFERENCES.connection_line_highlight_fade;
2023-08-31 19:56:23 +02:00
var _colr = _selc? 1 : _fade;
2023-08-31 18:49:57 +02:00
2023-10-15 15:04:42 +02:00
c0 = merge_color(bg, value_from.color_display, _colr);
c1 = merge_color(bg, color_display, _colr);
2023-08-31 18:49:57 +02:00
} else {
2023-10-15 15:04:42 +02:00
c0 = value_from.color_display;
c1 = color_display;
2023-08-31 18:49:57 +02:00
}
2023-07-25 20:12:40 +02:00
var ss = _s * aa;
jx *= aa;
jy *= aa;
frx *= aa;
fry *= aa;
th *= aa;
cx *= aa;
cy *= aa;
corner *= aa;
th = max(1, round(th));
2023-08-31 19:56:23 +02:00
2023-07-25 20:12:40 +02:00
draw_set_color(c0);
var fromIndex = value_from.drawLineIndex;
var toIndex = drawLineIndex;
2023-10-31 05:30:42 +01:00
switch(PREFERENCES.curve_connection_line) {
2023-07-25 20:12:40 +02:00
case 0 :
if(ty == LINE_STYLE.solid) draw_line_width_color(jx, jy, frx, fry, th, c1, c0);
else draw_line_dashed_color(jx, jy, frx, fry, th, c1, c0, 12 * ss);
2023-07-25 20:12:40 +02:00
break;
case 1 :
if(downDirection) draw_line_curve_corner(jx, jy, frx, fry, ss, th, c0, c1);
else draw_line_curve_color(jx, jy, frx, fry, cx, cy, ss, th, c0, c1, ty);
2023-07-25 20:12:40 +02:00
break;
case 2 :
if(downDirection) draw_line_elbow_corner(frx, fry, jx, jy, ss, th, c0, c1, corner, fromIndex, toIndex, ty);
else draw_line_elbow_color(frx, fry, jx, jy, cx, cy, ss, th, c0, c1, corner, fromIndex, toIndex, ty);
2023-07-25 20:12:40 +02:00
break;
case 3 :
if(downDirection) draw_line_elbow_diag_corner(frx, fry, jx, jy, ss, th, c0, c1, corner, fromIndex, toIndex, ty);
else draw_line_elbow_diag_color(frx, fry, jx, jy, cx, cy, ss, th, c0, c1, corner, fromIndex, toIndex, ty);
2023-07-25 20:12:40 +02:00
break;
}
return hovering;
2023-08-19 12:42:50 +02:00
} #endregion
2023-07-25 20:12:40 +02:00
static drawConnectionMouse = function(params, _mx, _my, target) { #region
var ss = params.s;
var aa = struct_try_get(params, "aa", 1);
2023-08-13 09:00:58 +02:00
var drawCorner = type == VALUE_TYPE.action;
2023-08-13 09:51:36 +02:00
if(target != noone)
2023-08-13 09:00:58 +02:00
drawCorner |= target.type == VALUE_TYPE.action;
2023-10-31 05:30:42 +01:00
var corner = PREFERENCES.connection_line_corner * ss;
var th = max(1, PREFERENCES.connection_line_width * ss);
2023-08-13 09:00:58 +02:00
var sx = x;
var sy = y;
corner *= aa;
th *= aa;
ss *= aa;
sx *= aa;
sy *= aa;
_mx *= aa;
_my *= aa;
2023-10-15 15:04:42 +02:00
var col = color_display;
2023-08-13 09:00:58 +02:00
draw_set_color(col);
var _action = type == VALUE_TYPE.action;
var _output = connect_type == JUNCTION_CONNECT.output;
2023-10-31 05:30:42 +01:00
switch(PREFERENCES.curve_connection_line) {
case 0 : draw_line_width(sx, sy, _mx, _my, th); break;
2023-08-13 09:00:58 +02:00
case 1 :
if(drawCorner) {
if(_action) draw_line_curve_corner(_mx, _my, sx, sy, ss, th, col, col);
else draw_line_curve_corner(sx, sy, _mx, _my, ss, th, col, col);
2023-08-13 09:00:58 +02:00
} else {
if(_output) draw_line_curve_color(_mx, _my, sx, sy,,, ss, th, col, col);
else draw_line_curve_color(sx, sy, _mx, _my,,, ss, th, col, col);
2023-08-13 09:00:58 +02:00
}
break;
case 2 :
if(drawCorner) {
if(_action) draw_line_elbow_corner(_mx, _my, sx, sy, ss, th, col, col, corner);
else draw_line_elbow_corner(sx, sy, _mx, _my, ss, th, col, col, corner);
2023-08-13 09:00:58 +02:00
} else {
if(_output) draw_line_elbow_color(sx, sy, _mx, _my,,, ss, th, col, col, corner);
else draw_line_elbow_color(_mx, _my, sx, sy,,, ss, th, col, col, corner);
2023-08-13 09:00:58 +02:00
}
break;
case 3 :
if(drawCorner) {
if(_action) draw_line_elbow_diag_corner(_mx, _my, sx, sy, ss, th, col, col, corner);
else draw_line_elbow_diag_corner(sx, sy, _mx, _my, ss, th, col, col, corner);
2023-08-13 09:00:58 +02:00
} else {
if(_output) draw_line_elbow_diag_color(sx, sy, _mx, _my,,, ss, th, col, col, corner);
else draw_line_elbow_diag_color(_mx, _my, sx, sy,,, ss, th, col, col, corner);
2023-08-13 09:00:58 +02:00
}
break;
}
2023-08-19 12:42:50 +02:00
} #endregion
static isVisible = function() { #region
2023-10-06 11:51:11 +02:00
if(!node.active) return false;
2023-02-14 02:51:14 +01:00
2023-10-06 11:51:11 +02:00
if(connect_type == JUNCTION_CONNECT.output)
return visible || !ds_list_empty(value_to);
if(value_from) return true;
if(!visible) return false;
if(is_array(node.input_display_list))
return array_exists(node.input_display_list, index);
return true;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static extractNode = function(_type = extract_node) { #region
2023-07-15 20:01:29 +02:00
if(_type == "") return noone;
2023-01-09 03:14:20 +01:00
2023-07-15 20:01:29 +02:00
var ext = nodeBuild(_type, node.x, node.y);
2023-01-25 06:49:00 +01:00
ext.x -= ext.w + 32;
2023-07-15 20:01:29 +02:00
for( var i = 0; i < ds_list_size(ext.outputs); i++ ) {
if(setFrom(ext.outputs[| i])) break;
}
2023-01-25 06:49:00 +01:00
var animFrom = animator.values;
var len = 2;
2023-07-15 20:01:29 +02:00
switch(_type) {
2023-01-25 06:49:00 +01:00
case "Node_Vector4": len++;
case "Node_Vector3": len++;
case "Node_Vector2":
for( var j = 0; j < len; j++ ) {
var animTo = ext.inputs[| j].animator;
var animLs = animTo.values;
2023-04-21 19:08:10 +02:00
ext.inputs[| j].setAnim(is_anim);
2023-01-25 06:49:00 +01:00
ds_list_clear(animLs);
}
for( var i = 0; i < ds_list_size(animFrom); i++ ) {
for( var j = 0; j < len; j++ ) {
var animTo = ext.inputs[| j].animator;
var animLs = animTo.values;
var a = animFrom[| i].clone(animTo);
a.value = a.value[j];
ds_list_add(animLs, a);
}
}
break;
2023-07-15 20:01:29 +02:00
case "Node_Path":
break;
2023-01-25 06:49:00 +01:00
default:
var animTo = ext.inputs[| 0].animator;
var animLs = animTo.values;
2023-04-21 19:08:10 +02:00
ext.inputs[| 0].setAnim(is_anim);
2023-01-25 06:49:00 +01:00
ds_list_clear(animLs);
for( var i = 0; i < ds_list_size(animFrom); i++ )
ds_list_add(animLs, animFrom[| i].clone(animTo));
break;
}
2023-01-09 03:14:20 +01:00
2023-03-28 06:58:28 +02:00
ext.doUpdate();
2023-08-19 12:42:50 +02:00
} #endregion
2023-01-09 03:14:20 +01:00
2023-10-18 14:58:55 +02:00
static hasJunctionFrom = function() { gml_pragma("forceinline"); return value_from != noone; }
2023-08-19 12:42:50 +02:00
static getJunctionTo = function() { #region
2023-10-06 11:51:11 +02:00
var to = [];
2023-06-01 10:32:21 +02:00
for(var j = 0; j < ds_list_size(value_to); j++) {
var _to = value_to[| j];
2023-10-27 13:55:31 +02:00
if(!_to.node.active || _to.isLeaf()) continue;
2023-06-01 10:32:21 +02:00
if(_to.value_from != self) continue;
array_push(to, _to);
}
return to;
2023-08-19 12:42:50 +02:00
} #endregion
2023-06-01 10:32:21 +02:00
2023-08-19 12:42:50 +02:00
static dragValue = function() { #region
2023-03-26 07:13:36 +02:00
if(drop_key == "None") return;
DRAGGING = {
type: drop_key,
data: showValue(),
}
if(type == VALUE_TYPE.path) {
DRAGGING.data = new FileObject(node.name, DRAGGING.data);
DRAGGING.data.getSpr();
}
if(connect_type == JUNCTION_CONNECT.input)
DRAGGING.from = self;
2023-08-19 12:42:50 +02:00
} #endregion
2023-03-26 07:13:36 +02:00
2023-08-19 12:42:50 +02:00
static serialize = function(scale = false, preset = false) { #region
2023-06-13 14:42:06 +02:00
var _map = {};
2022-01-13 05:24:03 +01:00
2023-06-13 14:42:06 +02:00
_map.visible = visible;
_map.color = color;
2023-04-07 21:25:27 +02:00
if(connect_type == JUNCTION_CONNECT.output)
return _map;
2023-07-15 20:01:29 +02:00
_map.name = name;
2023-06-13 14:42:06 +02:00
_map.on_end = on_end;
2023-07-12 21:00:05 +02:00
_map.loop_range = loop_range;
2023-06-13 14:42:06 +02:00
_map.unit = unit.mode;
_map.sep_axis = sep_axis;
_map.shift_x = draw_line_shift_x;
_map.shift_y = draw_line_shift_y;
2023-09-28 13:15:29 +02:00
if(!preset && value_from) {
_map.from_node = value_from.node.node_id;
2023-10-06 11:51:11 +02:00
if(value_from.tags != 0) _map.from_index = value_from.tags;
else _map.from_index = value_from.index;
2023-09-28 13:15:29 +02:00
} else {
_map.from_node = -1;
_map.from_index = -1;
}
2023-06-13 14:42:06 +02:00
_map.global_use = expUse;
_map.global_key = expression;
_map.anim = is_anim;
2023-03-21 03:01:53 +01:00
2023-06-13 14:42:06 +02:00
_map.raw_value = animator.serialize(scale);
2023-03-21 03:01:53 +01:00
2023-06-13 14:42:06 +02:00
var _anims = [];
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2023-06-13 14:42:06 +02:00
array_push(_anims, animators[i].serialize(scale));
_map.animators = _anims;
_map.display_data = display_data;
_map.attributes = attributes;
_map.name_custom = name_custom;
2022-01-13 05:24:03 +01:00
return _map;
2023-08-19 12:42:50 +02:00
} #endregion
2022-12-21 02:30:23 +01:00
2023-08-19 12:42:50 +02:00
static applyDeserialize = function(_map, scale = false, preset = false) { #region
2022-12-22 03:09:55 +01:00
if(_map == undefined) return;
2023-06-17 18:59:20 +02:00
if(_map == noone) return;
if(!is_struct(_map)) return;
2023-01-01 02:06:02 +01:00
2023-06-17 18:59:20 +02:00
visible = struct_try_get(_map, "visible", visible);
color = struct_try_get(_map, "color", -1);
2023-04-07 21:25:27 +02:00
if(connect_type == JUNCTION_CONNECT.output)
return;
2023-10-18 14:58:55 +02:00
//print($" > Applying deserialize to junction {name} 0");
2023-06-13 14:42:06 +02:00
on_end = struct_try_get(_map, "on_end");
2023-07-12 21:00:05 +02:00
loop_range = struct_try_get(_map, "loop_range", -1);
2023-06-13 14:42:06 +02:00
unit.mode = struct_try_get(_map, "unit");
expUse = struct_try_get(_map, "global_use");
expression = struct_try_get(_map, "global_key");
2023-07-12 21:00:05 +02:00
expTree = evaluateFunctionList(expression);
2023-04-15 14:48:29 +02:00
2023-06-13 14:42:06 +02:00
sep_axis = struct_try_get(_map, "sep_axis");
2023-10-18 14:58:55 +02:00
setAnim(struct_try_get(_map, "anim"));
2023-03-21 03:01:53 +01:00
2023-06-13 14:42:06 +02:00
draw_line_shift_x = struct_try_get(_map, "shift_x");
draw_line_shift_y = struct_try_get(_map, "shift_y");
2022-12-27 04:00:50 +01:00
name_custom = struct_try_get(_map, "name_custom", false);
2023-10-15 15:04:42 +02:00
if(name_custom) name = struct_try_get(_map, "name", name);
2023-06-13 14:42:06 +02:00
animator.deserialize(struct_try_get(_map, "raw_value"), scale);
2022-12-27 13:30:02 +01:00
2023-06-13 14:42:06 +02:00
if(struct_has(_map, "animators")) {
2023-06-17 14:30:49 +02:00
var anims = _map.animators;
var amo = min(array_length(anims), array_length(animators));
for( var i = 0; i < amo; i++ )
2023-06-13 14:42:06 +02:00
animators[i].deserialize(anims[i], scale);
2023-03-21 03:01:53 +01:00
}
2023-02-14 02:51:14 +01:00
if(!preset) {
2023-06-13 14:42:06 +02:00
con_node = struct_try_get(_map, "from_node", -1);
con_index = struct_try_get(_map, "from_index", -1);
2023-02-14 02:51:14 +01:00
}
2022-01-13 05:24:03 +01:00
if(struct_has(_map, "display_data")) {
for( var i = 0, n = array_length(DISPLAY_DATA_KEYS); i < n; i++ )
struct_try_override(display_data, _map.display_data, DISPLAY_DATA_KEYS[i]);
}
2022-12-27 13:30:02 +01:00
2023-05-16 21:28:16 +02:00
if(APPENDING) def_val = getValue(0);
2023-10-07 16:23:40 +02:00
if(connect_type == JUNCTION_CONNECT.input && index >= 0) {
2023-10-14 08:00:35 +02:00
var _value = animator.getValue(0);
node.inputs_data[index] = _value;
node.input_value_map[$ internalName] = _value;
2023-10-07 16:23:40 +02:00
}
onValidate();
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
2023-08-19 12:42:50 +02:00
static connect = function(log = false) { #region
2022-09-21 06:09:40 +02:00
if(con_node == -1 || con_index == -1)
return true;
2022-01-13 05:24:03 +01:00
2022-09-21 06:09:40 +02:00
var _node = con_node;
2022-12-21 02:30:23 +01:00
if(APPENDING) {
2022-09-21 06:09:40 +02:00
_node = GetAppendID(con_node);
2023-02-28 09:43:01 +01:00
if(_node == noone)
2022-12-21 02:30:23 +01:00
return true;
}
2023-08-08 18:45:00 +02:00
2023-07-06 19:49:16 +02:00
if(!ds_map_exists(PROJECT.nodeMap, _node)) {
2023-06-13 14:42:06 +02:00
var txt = $"Node connect error : Node ID {_node} not found.";
log_warning("LOAD", $"[Connect] {txt}", node);
2022-12-21 02:30:23 +01:00
return false;
}
2022-01-19 03:05:13 +01:00
2023-07-06 19:49:16 +02:00
var _nd = PROJECT.nodeMap[? _node];
2022-12-21 02:30:23 +01:00
var _ol = ds_list_size(_nd.outputs);
2023-02-14 02:51:14 +01:00
2023-07-25 20:12:40 +02:00
if(log) log_warning("LOAD", $"[Connect] Reconnecting {node.name} to {_nd.name}", node);
2023-10-06 11:51:11 +02:00
if(con_index == VALUE_TAG.updateInTrigger) setFrom(_nd.updatedInTrigger);
else if(con_index == VALUE_TAG.updateOutTrigger) setFrom(_nd.updatedOutTrigger);
else if(con_index < _ol) {
2023-07-25 20:12:40 +02:00
var _set = setFrom(_nd.outputs[| con_index], false, true);
if(_set) return true;
if(_set == -1) log_warning("LOAD", $"[Connect] Connection conflict {node.name} to {_nd.name} : Not connectable.", node);
else if(_set == -2) log_warning("LOAD", $"[Connect] Connection conflict {node.name} to {_nd.name} : Condition not met.", node);
2022-12-21 02:30:23 +01:00
return false;
2022-01-13 05:24:03 +01:00
}
2023-07-25 20:12:40 +02:00
log_warning("LOAD", $"[Connect] Connection conflict {node.name} to {_nd.name} : Output not exist.", node);
2022-01-19 03:05:13 +01:00
return false;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-19 06:11:17 +01:00
2023-08-19 12:42:50 +02:00
static destroy = function() { #region
2023-02-23 07:02:19 +01:00
if(error_notification != noone) {
noti_remove(error_notification);
error_notification = noone;
}
2023-08-19 12:42:50 +02:00
} #endregion
2023-02-23 07:02:19 +01:00
2023-08-19 12:42:50 +02:00
static cleanUp = function() { #region
2022-01-19 06:11:17 +01:00
ds_list_destroy(value_to);
2022-09-23 13:28:42 +02:00
animator.cleanUp();
delete animator;
2023-08-19 12:42:50 +02:00
} #endregion
2022-01-13 05:24:03 +01:00
}