Pixel-Composer/scripts/node_value/node_value.gml

2567 lines
76 KiB
Text
Raw Normal View History

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); }
2024-08-20 10:15:53 +02:00
function nodeValueMap(_name, _node, _junc = noone) { return new NodeValue(_name, _node, CONNECT_TYPE.input, VALUE_TYPE.surface, noone).setVisible(false, false).setMapped(_junc); }
function nodeValueGradientRange(_name, _node, _junc = noone) { return new NodeValue(_name, _node, CONNECT_TYPE.input, VALUE_TYPE.float, [ 0, 0, 1, 0 ])
.setDisplay(VALUE_DISPLAY.gradient_range).setVisible(false, false).setMapped(_junc); }
2024-08-27 05:30:03 +02:00
2024-11-07 07:59:04 +01:00
function nodeValueSeed(_node, _type = VALUE_TYPE.float, _name = "Seed") {
var _val = new NodeValue(_name, _node, CONNECT_TYPE.input, _type, seed_random(6), "");
var _rFun = function() /*=>*/ { randomize(); setValue(seed_random(6)); };
_rFun = method(_val, _rFun);
_val.setDisplay(VALUE_DISPLAY._default, { side_button : button(_rFun).setIcon(THEME.icon_random, 0, COLORS._main_icon) });
return _val;
}
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 {
2024-08-13 13:17:45 +02:00
static DISPLAY_DATA_KEYS = [ "linked", "angle_display", "bone_id", "unit", "atlas_crop" ];
2023-08-19 12:42:50 +02:00
#region ---- main ----
2024-08-14 09:55:53 +02:00
active = true;
from = noone;
node = _node;
x = node.x;
y = node.y;
rx = x;
ry = y;
tags = VALUE_TAG.none;
index = array_length(node.inputs);
type = _type;
forward = true;
2023-08-19 12:42:50 +02:00
_initName = _name;
2023-11-20 05:10:55 +01:00
node.will_setHeight = true;
static updateName = function(_name) {
2024-08-14 09:55:53 +02:00
name = _name;
internalName = string_to_var(name);
name_custom = true;
} updateName(_name);
name_custom = false;
2023-09-11 16:08:58 +02:00
2023-08-19 12:42:50 +02:00
if(struct_has(node, "inputMap")) {
2024-08-20 10:15:53 +02:00
if(_connect == CONNECT_TYPE.input) node.inputMap[? internalName] = self;
else if(_connect == CONNECT_TYPE.output) node.outputMap[? internalName] = self;
2023-08-19 12:42:50 +02:00
}
2024-03-19 09:49:29 +01:00
tooltip = _tooltip;
editWidget = noone;
editWidgetRaw = noone;
2024-03-26 04:03:45 +01:00
graphWidget = noone;
2024-03-28 14:18:02 +01:00
graphWidgetH = 0;
2024-03-29 05:20:49 +01:00
graphWidgetP = new widgetParam(0, 0, 0, 0, 0);
2024-03-19 09:49:29 +01:00
mapWidget = noone;
2023-12-07 15:08:09 +01:00
active_tooltip = "";
2023-09-28 13:15:29 +02:00
2024-08-14 09:55:53 +02:00
is_dummy = false;
dummy_get = noone;
dummy_undo = -1;
dummy_redo = -1;
2024-05-23 02:17:13 +02:00
2024-08-14 09:55:53 +02:00
bypass_junc = noone;
2024-08-20 10:15:53 +02:00
if(_connect == CONNECT_TYPE.input) {
bypass_junc = new __NodeValue_Input_Bypass(self, _name, _node, _type, index);
2024-08-14 09:55:53 +02:00
node.input_bypass[index] = bypass_junc;
}
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 ----
2023-12-19 14:30:34 +01:00
connect_type = _connect;
value_from = noone;
value_from_loop = noone;
value_to = [];
value_to_loop = [];
2023-08-19 12:42:50 +02:00
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 ----
if(_type == VALUE_TYPE.color) {
if(is_array(_value)) for( var i = 0, n = array_length(_value); i < n; i++ ) _value[i] = cola(_value[i]);
else _value = cola(_value);
}
2023-08-19 12:42:50 +02:00
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
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 ----
2024-08-18 05:30:20 +02:00
static setDefValue = function(_value) {
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;
}
def_val = array_clone(_value);
}
2024-08-13 13:17:45 +02:00
2024-08-18 05:30:20 +02:00
setDefValue(_value);
2024-08-14 05:28:46 +02:00
def_length = is_array(def_val)? array_length(def_val) : 0;
def_depth = array_get_depth(def_val);
unit = new nodeValueUnit(self);
def_unit = VALUE_UNIT.constant;
dyna_depo = ds_list_create();
value_tag = "";
is_modified = false;
cache_value = [ false, false, undefined, undefined ];
cache_array = [ false, false ];
use_cache = true;
record_value = true;
2023-08-19 12:42:50 +02:00
process_array = true;
2023-09-18 13:54:55 +02:00
dynamic_array = false;
2023-08-19 12:42:50 +02:00
validateValue = true;
2024-04-08 14:52:24 +02:00
runInUI = false;
2023-08-19 12:42:50 +02:00
2024-08-14 05:28:46 +02:00
fullUpdate = false;
attributes = {};
2024-08-20 10:15:53 +02:00
if(_connect == CONNECT_TYPE.input) {
2024-08-18 05:10:39 +02:00
node.inputs_data[index] = _value;
node.input_value_map[$ internalName] = _value;
}
2024-01-08 08:10:50 +01:00
2024-04-01 11:10:01 +02:00
__curr_get_val = [ 0, 0 ];
2024-08-14 05:28:46 +02:00
validator = noone;
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;
2024-01-26 14:38:50 +01:00
draw_line_feed = false;
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 ];
2024-04-03 09:40:37 +02:00
hover_in_graph = false;
2023-08-19 12:42:50 +02:00
drag_type = 0;
drag_mx = 0;
drag_my = 0;
drag_sx = 0;
drag_sy = 0;
2024-06-04 06:48:23 +02:00
drag_rx = 0;
drag_ry = 0;
2023-10-15 15:04:42 +02:00
color = -1;
color_display = 0;
2023-11-27 11:40:28 +01:00
draw_bg = c_black;
draw_fg = c_black;
draw_blend = 1;
draw_blend_color = 1;
2024-10-02 10:26:08 +02:00
__overlay_hover = [];
overlay_draw_text = true;
overlay_text_valign = fa_top;
graph_selecting = false;
2024-11-01 05:57:42 +01:00
custom_icon = noone;
custom_color = noone;
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;
show_graphs = array_create(array_safe_length(_value));
2024-07-06 10:31:26 +02:00
graph_h = ui(96);
2023-08-19 12:42:50 +02:00
#endregion
2023-08-19 12:42:50 +02:00
#region ---- inspector ----
2024-08-20 10:15:53 +02:00
visible = _connect == CONNECT_TYPE.output || _type == VALUE_TYPE.surface || _type == VALUE_TYPE.path || _type == VALUE_TYPE.PCXnode;
visible_manual = 0;
2023-08-19 12:42:50 +02:00
show_in_inspector = true;
2024-03-29 05:20:49 +01:00
visible_in_list = true;
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
2024-03-31 11:10:14 +02:00
display_data = {};
2023-10-06 11:51:11 +02:00
display_attribute = noone;
popup_dialog = noone;
type_array = typeArray(self);
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;
con_tag = 0;
2023-08-19 12:42:50 +02:00
#endregion
2023-07-21 12:40:20 +02:00
/////============= META =============
static setDummy = function(get_node, _dummy_undo = -1, _dummy_redo = -1) {
2024-05-23 02:17:13 +02:00
is_dummy = true;
dummy_get = get_node;
dummy_undo = _dummy_undo;
dummy_redo = _dummy_redo;
2024-05-23 02:17:13 +02:00
return self;
}
2024-05-23 02:17:13 +02:00
static setActive = function(_active, _tooltip) {
INLINE
active = _active;
active_tooltip = _tooltip;
2023-02-14 02:51:14 +01:00
return self;
}
2023-02-14 02:51:14 +01:00
static setWindows = function() {
INLINE
setActive(OS == os_windows, "Not available on MacOS");
return self;
}
2024-08-07 11:48:39 +02:00
static setTooltip = function(_tip) { tooltip = _tip; return self; }
2024-11-01 05:57:42 +01:00
static setIcon = function(_ico, _colr) { custom_icon = _ico; custom_color = _colr; return self; }
static nonValidate = function() {
validateValue = false;
return self;
}
static nonForward = function() {
forward = false;
return self;
}
/////============= NAME =============
static getName = function() {
if(name_custom) return name;
return __txt_junction_name(instanceof(node), connect_type, index, name);
}
static setName = function(_name) {
2023-11-20 05:10:55 +01:00
INLINE
name = _name;
return self;
}
2023-11-20 05:10:55 +01:00
/////============= VALUE ============
static setType = function(_type) {
if(type == _type) return false;
2023-12-07 15:08:09 +01:00
type = _type;
draw_junction_index = type;
updateColor();
2024-08-14 09:55:53 +02:00
if(bypass_junc) bypass_junc.setType(_type);
return true;
}
2023-12-07 15:08:09 +01:00
static setDefault = function(vals) {
if(LOADING || APPENDING) return self;
2023-12-07 15:08:09 +01:00
animator.values = [];
for( var i = 0, n = array_length(vals); i < n; i++ )
array_push(animator.values, new valueKey(vals[i][0], vals[i][1], animator));
2023-12-07 15:08:09 +01:00
return self;
}
2023-12-07 15:08:09 +01:00
static resetValue = function() {
2023-11-26 13:16:38 +01:00
unit.mode = def_unit;
setValue(unit.apply(variable_clone(def_val)));
2024-03-02 10:08:44 +01:00
attributes.mapped = false;
2023-11-26 13:16:38 +01:00
is_modified = false;
}
2023-05-16 21:28:16 +02:00
static setUnitRef = function(ref, mode = VALUE_UNIT.constant) {
express_edit.side_button = unit.triggerButton;
2024-08-18 05:30:20 +02:00
display_data.onSurfaceSize = ref;
if(editWidget) {
editWidget.unit = unit;
2024-08-18 05:30:20 +02:00
editWidget.onSurfaceSize = ref;
}
2024-06-04 06:48:23 +02:00
2023-03-08 07:35:51 +01:00
unit.reference = ref;
unit.mode = mode;
2023-11-26 13:16:38 +01:00
def_unit = mode;
2023-03-08 07:35:51 +01:00
cache_value[0] = false;
2022-12-27 04:00:50 +01:00
return self;
}
2022-12-27 04:00:50 +01:00
static setValidator = function(val) {
validator = val;
return self;
}
static rejectArray = function() { accept_array = false; return self; }
static setArrayDepth = function(aDepth) { array_depth = aDepth; return self; }
static setArrayDynamic = function() { dynamic_array = true; return self; }
2023-09-18 13:54:55 +02:00
static rejectArrayProcess = function() {
2023-05-28 20:00:51 +02:00
process_array = false;
return self;
}
2023-05-28 20:00:51 +02:00
static setDropKey = function() {
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();
2023-03-26 07:13:36 +02:00
2024-06-13 07:19:25 +02:00
mappedJunc = noone;
mapped_vec4 = false;
2024-08-09 13:30:09 +02:00
static setMappable = function(index, vec4 = false) {
attributes.mapped = false;
attributes.map_index = index;
2024-08-09 13:30:09 +02:00
mapped_vec4 = vec4;
if(arrayLength == arrayLengthSimple)
arrayLength = __arrayLength;
mapButton = button(function() {
attributes.mapped = !attributes.mapped;
2024-06-09 06:27:50 +02:00
if(type == VALUE_TYPE.integer || type == VALUE_TYPE.float) {
if(attributes.mapped) setValue(mapped_vec4? [ 0, 0, 0, 0 ] : [ 0, 0 ]);
else setValue(def_val);
setArrayDepth(attributes.mapped);
}
node.triggerRender();
})
.setIcon( THEME.value_use_surface, [ function() { return attributes.mapped; } ], COLORS._main_icon )
.setTooltip("Toggle map");
switch(type) {
case VALUE_TYPE.gradient :
mapWidget = noone;
break;
default :
2024-06-13 07:19:25 +02:00
mapWidget = vec4?
new vectorRangeBox(4, TEXTBOX_INPUT.number, function(val, index) { return setValueDirect(val, index); }) :
new rangeBox( TEXTBOX_INPUT.number, function(val, index) { return setValueDirect(val, index); });
mapWidget.side_button = mapButton;
break;
}
editWidget.side_button = mapButton;
return self;
2024-08-09 13:30:09 +02:00
}
static setMapped = function(junc) {
mappedJunc = junc;
isTimelineVisible = function() { INLINE return is_anim && value_from == noone && mappedJunc.attributes.mapped; }
return self;
}
static mappableStep = function() {
editWidget = mapWidget && attributes.mapped? mapWidget : editWidgetRaw;
setArrayDepth(attributes.mapped);
2024-08-08 06:57:51 +02:00
var inp = node.inputs[attributes.map_index];
var vis = attributes.mapped && show_in_inspector;
if(inp.visible != vis) {
inp.visible = vis;
node.refreshNodeDisplay();
}
2024-06-09 06:27:50 +02:00
}
/////========== ANIMATION ==========
static setAnimable = function(_anim) {
animable = _anim;
return self;
}
static isAnimable = function() {
if(type == VALUE_TYPE.PCXnode) return false;
if(display_type == VALUE_DISPLAY.text_array) return false;
return animable;
}
static setAnim = function(anim, record = false) {
if(is_anim == anim) return;
if(record) {
recordAction(ACTION_TYPE.custom, function(data) {
setAnim(data.is_anim);
data.is_anim = !data.is_anim;
2024-09-03 11:49:51 +02:00
}, { is_anim, tooltip : $"Toggle '{name}' animation" });
}
is_anim = anim;
if(is_anim) {
if(array_empty(animator.values))
array_push(animator.values, new valueKey(CURRENT_FRAME, animator.getValue(), animator));
animator.values[0].time = CURRENT_FRAME;
animator.updateKeyMap();
for( var i = 0, n = array_length(animators); i < n; i++ ) {
if(array_length(animators[i].values))
array_push(animators[i].values, new valueKey(CURRENT_FRAME, animators[i].getValue(), animators[i]));
animators[i].values[0].time = CURRENT_FRAME;
animators[i].updateKeyMap();
}
} else {
var _val = animator.getValue();
animator.values = [];
animator.values[0] = new valueKey(0, _val, animator);
animator.updateKeyMap();
for( var i = 0, n = array_length(animators); i < n; i++ ) {
var _val = animators[i].getValue();
animators[i].values = [];
animators[i].values[0] = new valueKey(0, _val, animators[i]);
animators[i].updateKeyMap();
}
}
if(type == VALUE_TYPE.gradient && struct_has(attributes, "map_index"))
2024-08-08 06:57:51 +02:00
node.inputs[attributes.map_index + 1].setAnim(anim);
node.refreshTimeline();
}
/////============ DISPLAY ===========
static setVisible = function(inspector) {
var v = visible;
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.input) {
show_in_inspector = inspector;
visible = argument_count > 1? argument[1] : visible;
} else
visible = inspector;
node.will_setHeight |= visible != v;
return self;
}
static forceVisible = function(_vis) {
visible = _vis;
show_in_inspector = _vis;
visible_manual = 0;
node.will_setHeight = true;
return self;
}
2024-10-06 03:25:07 +02:00
static isVisible = function() {
if(!node.active) return false;
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.output) {
if(!array_empty(value_to)) return true;
if(visible_manual != 0) return visible_manual == 1;
return visible;
}
if(value_from) return true;
if(visible_manual != 0) return visible_manual == 1;
if(!visible) return false;
if(index == -1) return true;
return visible_in_list;
}
2024-08-08 06:57:51 +02:00
static setDisplay = function(_type = VALUE_DISPLAY._default, _data = {}) {
display_type = _type;
display_data = _data;
type_array = typeArray(self);
resetDisplay();
return self;
2024-08-08 06:57:51 +02:00
}
2024-08-13 13:17:45 +02:00
static resetDisplay = function() {
2022-01-13 05:24:03 +01:00
editWidget = noone;
switch(display_type) {
2024-08-27 05:30:03 +02:00
case VALUE_DISPLAY.button :
2024-09-03 11:49:51 +02:00
var _onClick = struct_has(display_data, "onClick")? method(node, display_data.onClick) : function() /*=>*/ { setAnim(true, true); setValueDirect(true); };
2024-04-08 07:13:46 +02:00
editWidget = button(_onClick).setText(struct_try_get(display_data, "name", "Trigger"));
runInUI = struct_try_get(display_data, "UI", false);
2023-10-03 07:14:28 +02:00
2022-01-13 05:24:03 +01:00
visible = false;
2024-04-08 07:13:46 +02:00
rejectArray();
2024-08-27 05:30:03 +02:00
return;
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
2024-03-24 04:58:08 +01:00
editWidget = new textBox(_txt, function(val) { return setValueInspector(val); } );
2024-05-17 15:25:01 +02:00
if(struct_has(display_data, "unit")) editWidget.unit = display_data.unit;
if(struct_has(display_data, "front_button")) editWidget.front_button = display_data.front_button;
2023-01-09 03:14:20 +01:00
extract_node = "Node_Number";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.range : #region
editWidget = new rangeBox(_txt, function(val, index) { return setValueInspector(val, index); } );
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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + array_safe_get_fast(global.displaySuffix_Range, i);
2023-03-21 03:01:53 +01:00
2023-01-09 03:14:20 +01:00
extract_node = "Node_Number";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
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(val, index) { return setValueInspector(val, index); }, 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;
2023-09-15 20:12:02 +02:00
if(len == 2) {
var _dim = struct_try_get(display_data, "useGlobal", true);
2023-07-15 20:01:29 +02:00
extract_node = [ "Node_Vector2", "Node_Path" ];
2024-05-19 07:55:09 +02:00
if(_dim && array_equals(def_val, DEF_SURF)) {
node.attributes.use_project_dimension = true;
editWidget.side_button = button(function() /*=>*/ {
node.attributes.use_project_dimension = !node.attributes.use_project_dimension;
node.triggerRender();
}).setIcon(THEME.node_use_project, 0, COLORS._main_icon).setTooltip("Use project dimension");
}
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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + string(array_safe_get_fast(global.displaySuffix_Axis, i));
2023-03-21 03:01:53 +01:00
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
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(val, index) { return setValueInspector(val, index); }, unit );
if(!struct_has(display_data, "linked")) display_data.linked = false;
if(!struct_has(display_data, "ranged")) display_data.ranged = false;
2023-01-09 03:14:20 +01:00
2024-05-25 04:51:52 +02: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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + string(array_safe_get_fast(global.displaySuffix_VecRange, i));
2023-03-21 03:01:53 +01:00
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
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) {
2024-02-01 05:26:02 +01:00
return setValueInspector(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
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.rotation_range : #region
editWidget = new rotatorRange(function(val, index) { return setValueInspector(val, index); } );
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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + array_safe_get_fast(global.displaySuffix_Range, i);
2023-03-21 03:01:53 +01:00
2023-09-11 16:08:58 +02:00
extract_node = "Node_Vector2";
break; #endregion
2024-05-25 04:51:52 +02:00
case VALUE_DISPLAY.rotation_random : #region
editWidget = new rotatorRandom(function(val, index) { return setValueInspector(val, index); } );
2023-09-11 16:08:58 +02:00
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector2";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.slider : #region
2024-07-26 09:38:39 +02:00
var _range = struct_try_get(display_data, "range", [ 0, 1 ]);
2024-03-24 04:58:08 +01:00
editWidget = new textBox(TEXTBOX_INPUT.number, function(val) { return setValueInspector(toNumber(val)); } )
2024-07-26 09:38:39 +02:00
.setSlideRange(_range[0], _range[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
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.slider_range : #region
var _range = struct_try_get(display_data, "range", [ 0, 1, 0.01 ]);
2024-03-24 04:58:08 +01:00
editWidget = new sliderRange(_range[2], type == VALUE_TYPE.integer, [ _range[0], _range[1] ],
function(val, index) { return setValueInspector(val, index); } );
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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + array_safe_get_fast(global.displaySuffix_Range, i);
2023-03-21 03:01:53 +01:00
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector2";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.area : #region
editWidget = new areaBox(function(val, index) { return setValueInspector(val, index); }, unit);
2023-11-23 13:39:35 +01:00
2024-03-31 05:36:11 +02:00
editWidget.onSurfaceSize = struct_try_get(display_data, "onSurfaceSize", noone);
editWidget.showShape = struct_try_get(display_data, "useShape", true);
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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + array_safe_get_fast(global.displaySuffix_Area, i, "");
2023-03-21 03:01:53 +01:00
2023-01-09 03:14:20 +01:00
extract_node = "Node_Area";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.padding : #region
editWidget = new paddingBox(function(val, index) { return setValueInspector(val, index); }, unit);
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++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + array_safe_get_fast(global.displaySuffix_Padding, i);
2023-07-21 12:40:20 +02:00
extract_node = "Node_Vector4";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.corner : #region
editWidget = new cornerBox(function(val, index) { return setValueInspector(val, index); }, unit);
2023-07-21 12:40:20 +02:00
2023-07-25 20:12:40 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
2024-03-31 05:36:11 +02:00
animators[i].suffix = " " + array_safe_get_fast(global.displaySuffix_Padding, i);
2023-03-21 03:01:53 +01:00
2023-01-09 03:14:20 +01:00
extract_node = "Node_Vector4";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.puppet_control : #region
editWidget = new controlPointBox(function(val, index) { return setValueInspector(val, index); });
2023-01-09 03:14:20 +01:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
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) /*=>*/ { if(val == -1) return; return setValueInspector(toNumber(val)); } );
if(struct_has(display_data, "update_hover")) editWidget.update_hover = display_data.update_hover;
if(struct_has(display_data, "horizontal")) editWidget.horizontal = display_data.horizontal;
if(struct_has(display_data, "item_pad")) editWidget.item_pad = display_data.item_pad;
if(struct_has(display_data, "text_pad")) editWidget.text_pad = display_data.text_pad;
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-08-19 12:42:50 +02:00
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);
2024-05-25 04:51:52 +02:00
editWidget = new buttonGroup(choices, function(val) { return setValueInspector(val); } );
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(val, index) { return setValueInspector(val, index); }, unit );
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++ )
2024-05-17 15:25:01 +02:00
animators[i].suffix = $" {i}";
extract_node = "";
break; #endregion
case VALUE_DISPLAY.boolean_grid : #region
editWidget = new matrixGrid(_txt, display_data.size, function(val, index) { return setValueInspector(val, index); }, unit );
2024-05-17 15:25:01 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
animators[i].suffix = $" {i}";
2023-03-21 03:01:53 +01:00
2023-06-21 20:36:53 +02:00
extract_node = "";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.transform : #region
editWidget = new transformBox(function(val, index) { return setValueInspector(val, index); });
2023-06-21 20:36:53 +02:00
2023-07-05 15:09:52 +02:00
extract_node = "Node_Transform_Array";
2023-08-19 12:42:50 +02:00
break; #endregion
2023-08-19 12:42:50 +02:00
case VALUE_DISPLAY.toggle : #region
2024-05-25 04:51:52 +02:00
editWidget = new toggleGroup(display_data.data, function(val) { return setValueInspector(val); } );
2023-08-08 20:33:17 +02:00
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(val, index) { return setValueInspector(val, index); });
extract_node = "Node_Vector4";
display_data.angle_display = QUARTERNION_DISPLAY.euler;
break; #endregion
2024-01-23 11:01:19 +01:00
case VALUE_DISPLAY.path_anchor : #region
editWidget = new pathAnchorBox(function(val, index) { return setValueInspector(val, index); });
2024-01-23 11:01:19 +01:00
extract_node = "Node_Path_Anchor";
break; #endregion
2022-01-13 05:24:03 +01:00
}
2024-07-26 09:38:39 +02:00
if(editWidget && struct_has(editWidget, "setSlideType")) editWidget.setSlideType(type == VALUE_TYPE.integer);
2022-01-13 05:24:03 +01:00
break;
2024-04-08 07:13:46 +02:00
case VALUE_TYPE.boolean : #region
2024-08-27 05:30:03 +02:00
if(name == "Active") editWidget = new checkBoxActive(function() /*=>*/ {return setValueInspector(!animator.getValue())} );
else editWidget = new checkBox( function() /*=>*/ {return setValueInspector(!animator.getValue())} );
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
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.color :
2022-01-13 05:24:03 +01:00
switch(display_type) {
case VALUE_DISPLAY._default :
2024-09-24 11:51:04 +02:00
editWidget = new buttonColor(function(_color) /*=>*/ {return setValueInspector(_color)});
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;
2024-05-25 04:51:52 +02:00
2022-01-13 05:24:03 +01:00
case VALUE_DISPLAY.palette :
2024-09-24 11:51:04 +02:00
editWidget = new buttonPalette(function(_color) /*=>*/ {return setValueInspector(_color)});
2023-01-09 03:14:20 +01:00
extract_node = "Node_Palette";
break;
2022-01-13 05:24:03 +01:00
}
2024-08-13 13:17:45 +02:00
break;
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.gradient :
2024-08-27 05:30:03 +02:00
editWidget = new buttonGradient(function(gradient) /*=>*/ {return setValueInspector(gradient)});
2023-05-28 20:00:51 +02:00
extract_node = "Node_Gradient_Out";
2024-08-13 13:17:45 +02:00
break;
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.path :
2022-01-13 05:24:03 +01:00
switch(display_type) {
case VALUE_DISPLAY.path_array :
2024-08-27 05:30:03 +02:00
editWidget = new pathArrayBox(self, display_data.filter, function(path) /*=>*/ {return setValueInspector(path)});
2023-01-01 02:06:02 +01:00
break;
2024-05-25 04:51:52 +02:00
2023-01-01 02:06:02 +01:00
case VALUE_DISPLAY.path_load :
2024-08-27 05:30:03 +02:00
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
2024-08-27 05:30:03 +02:00
editWidget.align = fa_left;
editWidget.side_button = button(function() {
2024-05-16 15:28:45 +02:00
var path = display_data.filter == "dir"? get_directory("") : get_open_filename_pxc(display_data.filter, "");
key_release();
if(path == "") return noone;
2024-02-01 05:26:02 +01:00
return setValueInspector(path);
2024-08-27 05:30:03 +02:00
}, THEME.button_path_icon).setTooltip(__txt("Open Explorer..."));
2023-01-09 03:14:20 +01:00
2024-08-27 13:42:29 +02:00
editWidget.front_button = button(function() {
var project = PROJECT;
if(project.path == "") {
noti_warning("Save the current project first.")
return;
}
var _pth = getValue();
if(!file_exists(_pth)) return;
var _nam = filename_name(_pth);
var _dir = filename_dir(project.path);
var _newpath = _dir + "/" + _nam;
file_copy(_pth, _newpath);
setValue("./" + _nam);
}).setIcon(THEME.copy_20, 0, COLORS._main_icon).setTooltip(__txt("Copy to Project"));
2023-01-09 03:14:20 +01:00
extract_node = "Node_String";
2022-01-13 05:24:03 +01:00
break;
2022-01-13 05:24:03 +01:00
case VALUE_DISPLAY.path_save :
2024-08-27 05:30:03 +02:00
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
2023-01-01 02:06:02 +01:00
editWidget.align = fa_left;
editWidget.side_button = button(function() {
2024-05-16 15:28:45 +02:00
var path = get_save_filename_pxc(display_data.filter, "");
key_release();
if(path == "") return noone;
2024-02-01 05:26:02 +01:00
return setValueInspector(path);
2024-08-27 05:30:03 +02:00
}, THEME.button_path_icon).setTooltip(__txt("Open Explorer..."));
2023-01-09 03:14:20 +01:00
2024-08-27 13:42:29 +02:00
editWidget.front_button = button(function() {
var project = PROJECT;
if(project.path == "") {
noti_warning("Save the current project first.")
return;
}
var _pth = getValue();
var _nam = filename_name(_pth);
var _dir = filename_dir(project.path);
setValue("./" + _nam);
}).setIcon(THEME.copy_20, 0, COLORS._main_icon).setTooltip(__txt("Make Relative"));
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 :
2024-08-27 05:30:03 +02:00
editWidget = new fontScrollBox(function(val) /*=>*/ {return setValueInspector(FONT_INTERNAL[val])});
2022-12-16 09:18:09 +01:00
break;
2024-11-01 05:57:42 +01:00
default :
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
break;
2022-01-13 05:24:03 +01:00
}
2024-08-13 13:17:45 +02:00
break;
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.curve :
2022-01-13 05:24:03 +01:00
display_type = VALUE_DISPLAY.curve;
2024-08-27 05:30:03 +02:00
editWidget = new curveBox(function(_modified) /*=>*/ {return setValueInspector(_modified)});
2024-08-13 13:17:45 +02:00
break;
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.text :
2023-02-21 04:48:50 +01:00
switch(display_type) {
case VALUE_DISPLAY._default :
2024-08-27 05:30:03 +02:00
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
2023-02-21 04:48:50 +01:00
extract_node = "Node_String";
break;
2023-08-31 18:49:57 +02:00
case VALUE_DISPLAY.text_box :
2024-08-27 05:30:03 +02:00
editWidget = new textBox(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
2023-08-31 18:49:57 +02:00
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 :
2024-08-27 05:30:03 +02:00
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
extract_node = "Node_String";
2023-02-21 04:48:50 +01:00
2024-08-27 05:30:03 +02:00
editWidget.font = f_code;
editWidget.format = TEXT_AREA_FORMAT.codeLUA;
2023-09-07 20:59:14 +02:00
editWidget.min_lines = 4;
break;
2023-12-05 13:49:18 +01:00
case VALUE_DISPLAY.codeHLSL:
2024-08-27 05:30:03 +02:00
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
2023-09-07 20:59:14 +02:00
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-12-05 13:49:18 +01: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;
2023-12-05 13:49:18 +01:00
case VALUE_DISPLAY.text_tunnel :
2024-08-27 05:30:03 +02:00
editWidget = new textArea(TEXTBOX_INPUT.text, function(str) /*=>*/ {return setValueInspector(str)});
editWidget.autocomplete_server = tunnel_autocomplete_server;
2023-12-05 13:49:18 +01:00
extract_node = "Node_String";
break;
2023-02-21 04:48:50 +01:00
case VALUE_DISPLAY.text_array :
2024-08-27 05:30:03 +02:00
editWidget = new textArrayBox(function() /*=>*/ {return animator.values[0].value}, display_data.data, function() /*=>*/ {return node.doUpdate()});
2023-02-21 04:48:50 +01:00
break;
2023-01-04 02:30:04 +01:00
}
2024-08-13 13:17:45 +02:00
break;
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.d3Material :
2024-08-27 05:30:03 +02:00
show_in_inspector = true;
2024-04-08 07:13:46 +02:00
editWidget = new materialBox(function(ind) {
var res = setValueInspector(ind);
node.triggerRender();
return res;
} );
2023-10-06 11:51:11 +02:00
if(!struct_has(display_data, "atlas")) display_data.atlas = true;
2023-07-18 17:51:40 +02:00
extract_node = "Node_Canvas";
2024-08-13 13:17:45 +02:00
break;
2024-08-13 13:17:45 +02:00
case VALUE_TYPE.surface :
2024-08-27 05:30:03 +02:00
show_in_inspector = true;
editWidget = new surfaceBox(function(ind) /*=>*/ {return setValueInspector(ind)});
2024-04-08 07:13:46 +02:00
if(!struct_has(display_data, "atlas")) display_data.atlas = true;
extract_node = "Node_Canvas";
2024-08-13 13:17:45 +02:00
break;
case VALUE_TYPE.dynaSurface : editWidget = new surfaceDynaBox(); break;
case VALUE_TYPE.pathnode : editWidget = new pathnodeBox(self); extract_node = "Node_Path"; break;
case VALUE_TYPE.tileset : editWidget = new tilesetBox(self); extract_node = "Node_Tile_Tileset"; break;
case VALUE_TYPE.armature : editWidget = new armatureBox(self); break;
case VALUE_TYPE.mesh : editWidget = new meshBox(self); break;
case VALUE_TYPE.struct : editWidget = new outputStructBox(); break;
case VALUE_TYPE.particle : editWidget = noone; break;
2024-11-07 07:59:04 +01:00
default : editWidget = new outputBox(); break;
2023-08-19 12:42:50 +02:00
}
2024-05-26 04:51:14 +02:00
if(is_struct(display_data) && struct_has(display_data, "side_button") && editWidget.side_button == noone)
2024-05-24 07:44:36 +02:00
editWidget.side_button = display_data.side_button;
2024-03-19 09:49:29 +01:00
editWidgetRaw = editWidget;
2024-03-31 11:10:14 +02:00
if(editWidget) graphWidget = editWidget.clone();
2024-03-19 09:49:29 +01:00
for( var i = 0, n = array_length(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();
2024-08-13 13:17:45 +02:00
}
resetDisplay();
2022-01-13 05:24:03 +01:00
/////============ RENDER ============
2024-08-06 14:04:41 +02:00
static isRendered = function() {
if(type == VALUE_TYPE.node) return true;
if(value_from == noone) return true;
2023-12-22 14:46:54 +01:00
var controlNode = value_from.from? value_from.from : value_from.node;
if(!controlNode.active) return true;
if(!controlNode.isRenderActive()) return true;
2023-12-08 12:53:31 +01:00
return controlNode.rendered;
2024-08-06 14:04:41 +02:00
}
2023-12-08 12:53:31 +01:00
2024-08-06 14:04:41 +02:00
static isActiveDynamic = function() {
2023-11-27 11:40:28 +01:00
INLINE
if(value_from_loop) return true;
if(value_from != noone) return false;
2023-10-07 16:23:40 +02:00
if(expUse) {
if(!is_struct(expTree)) return false;
var res = expTree.isDynamic();
switch(res) {
case EXPRESS_TREE_ANIM.none : return false;
case EXPRESS_TREE_ANIM.base_value : force_requeue = true; return is_anim;
case EXPRESS_TREE_ANIM.animated : force_requeue = true; return true;
}
}
2023-10-07 16:23:40 +02:00
return is_anim;
2024-08-06 14:04:41 +02:00
}
__init_dynamic = true;
static isDynamic = function() {
INLINE
if(__init_dynamic) { __init_dynamic = false; return true; }
if(!IS_PLAYING) return true;
if(value_from_loop) return true;
if(value_from != noone) return true;
if(expUse) {
if(!is_struct(expTree)) return false;
var res = expTree.isDynamic();
switch(res) {
case EXPRESS_TREE_ANIM.none : return false;
case EXPRESS_TREE_ANIM.base_value : force_requeue = true; return is_anim;
case EXPRESS_TREE_ANIM.animated : force_requeue = true; return true;
}
}
return is_anim;
}
2023-10-07 16:23:40 +02:00
/////============= CACHE ============
2024-03-14 14:35:19 +01:00
static uncache = function() {
use_cache = false;
return self;
}
static resetCache = function() { cache_value[0] = false; }
2023-06-17 14:30:49 +02:00
/////============== GET =============
static valueProcess = function(value, nodeFrom = undefined, applyUnit = true, arrIndex = 0) {
var typeFrom = nodeFrom == undefined? VALUE_TYPE.any : nodeFrom.type;
2023-01-17 08:11:55 +01:00
if(applyUnit && display_type == VALUE_DISPLAY.d3quarternion && display_data.angle_display == QUARTERNION_DISPLAY.euler)
return quarternionFromEuler(value[0], value[1], value[2]);
if(type == VALUE_TYPE.gradient && typeFrom == VALUE_TYPE.color) { // color compatibility [ color, palette, gradient ]
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;
}
return is_real(value)? new gradientObject(value) : new gradientObject(cola(c_black));
}
if(display_type == VALUE_DISPLAY.palette && !is_array(value)) return [ value ];
2023-02-14 02:51:14 +01:00
if(display_type == VALUE_DISPLAY.area) {
if(!is_undefined(nodeFrom) && struct_has(nodeFrom.display_data, "onSurfaceSize")) {
var surf = nodeFrom.display_data.onSurfaceSize();
2024-03-31 05:36:11 +02:00
var dispType = array_safe_get_fast(value, 5, AREA_MODE.area);
2024-03-31 05:36:11 +02:00
switch(dispType) {
case AREA_MODE.area :
break;
2023-08-01 11:16:23 +02:00
2024-03-31 05:36:11 +02:00
case AREA_MODE.padding :
var ww = unit.mode == VALUE_UNIT.reference? 1 : surf[0];
var hh = unit.mode == VALUE_UNIT.reference? 1 : surf[1];
2024-03-31 05:36:11 +02:00
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;
2024-03-31 05:36:11 +02:00
value = [cx, cy, sw, sh, value[4], value[5]];
break;
2023-08-01 11:16:23 +02:00
2024-03-31 05:36:11 +02:00
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;
2024-03-28 08:33:28 +01:00
2024-03-31 05:36:11 +02:00
value = [cx, cy, sw, sh, value[4], value[5]];
break;
}
2023-08-01 11:16:23 +02:00
}
2024-03-31 05:36:11 +02:00
return applyUnit? unit.apply(value, arrIndex) : value;
}
2023-08-01 11:16:23 +02:00
if(type == VALUE_TYPE.text) return display_type == VALUE_DISPLAY.text_array? value : string_real(value);
2023-01-01 02:06:02 +01:00
if(typeNumeric(typeFrom) && type == VALUE_TYPE.color) return value >= 1? value : make_color_rgb(value * 255, value * 255, value * 255);
if(typeFrom == VALUE_TYPE.boolean && type == VALUE_TYPE.text) return value? "true" : "false";
2023-01-09 03:14:20 +01:00
if(type == VALUE_TYPE.integer || type == VALUE_TYPE.float) {
if(typeFrom == VALUE_TYPE.text) value = toNumber(value);
2023-01-01 02:06:02 +01:00
2024-04-13 07:32:04 +02:00
value = applyUnit? unit.apply(value, arrIndex) : value;
if(validator != noone) value = validator.validate(value);
2024-04-13 07:32:04 +02:00
return value;
}
2023-03-28 06:58:28 +02:00
2024-08-20 10:15:53 +02:00
if(type == VALUE_TYPE.surface && connect_type == CONNECT_TYPE.input && !is_surface(value) && def_val == USE_DEF)
2023-03-28 06:58:28 +02:00
return DEF_SURFACE;
2022-12-23 04:45:52 +01:00
return value;
}
2022-12-16 09:18:09 +01:00
static getStaticValue = function() { INLINE return array_empty(animator.values)? 0 : animator.values[0].value; }
2024-07-07 09:08:13 +02:00
static getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, useCache = false, log = false) { //// Get value
draw_junction_index = type;
2023-06-13 14:42:06 +02:00
if(type == VALUE_TYPE.trigger)
2024-04-08 07:13:46 +02:00
return _getValue(_time, false, 0, false);
2023-09-09 13:52:16 +02:00
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-11-17 06:24:31 +01:00
cache_hit &= !isActiveDynamic(_time) || 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;
2024-08-20 10:15:53 +02:00
cache_hit &= connect_type == CONNECT_TYPE.input;
2023-07-28 19:41:57 +02:00
cache_hit &= unit.reference == noone || unit.mode == VALUE_UNIT.constant;
2023-07-23 20:21:35 +02:00
if(cache_hit) return cache_value[2];
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);
2024-04-24 03:46:53 +02:00
if(!accept_array && array_get_depth(val) > def_depth) { noti_warning($"{name} does not accept array data.", noone, node); return 0; }
2023-02-14 02:51:14 +01:00
2023-10-07 16:23:40 +02:00
if(type == VALUE_TYPE.surface || type == VALUE_TYPE.any) {
var _sval = array_valid(val)? val[0] : val;
2024-07-07 09:08:13 +02:00
if(is_instanceof(_sval, SurfaceAtlas))
2023-10-06 11:51:11 +02:00
draw_junction_index = VALUE_TYPE.atlas;
}
2023-05-16 21:28:16 +02:00
if(useCache) {
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
2024-04-01 11:10:01 +02:00
cache_value[2] = val;
2023-09-09 13:52:16 +02:00
cache_value[3] = applyUnit;
2024-04-01 11:10:01 +02:00
2023-09-14 16:29:39 +02:00
return val;
2024-07-07 09:08:13 +02:00
}
2023-02-14 02:51:14 +01:00
2024-07-07 09:08:13 +02:00
static _getValue = function(_time = CURRENT_FRAME, applyUnit = true, arrIndex = 0, log = false) {
2024-04-01 11:10:01 +02:00
getValueRecursive(self.__curr_get_val, _time);
var val = __curr_get_val[0];
var nod = __curr_get_val[1];
2024-08-09 13:30:09 +02:00
var typ = nod.type;
2022-12-23 04:45:52 +01:00
var dis = nod.display_type;
2022-01-18 05:31:19 +01:00
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.output) return val;
2024-07-07 09:08:13 +02:00
if(typ == VALUE_TYPE.surface && (type == VALUE_TYPE.integer || type == VALUE_TYPE.float)) { // 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;
var surfSz = surface_get_dimension(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) ];
2024-04-11 05:51:13 +02:00
return [ 1, 1 ];
2024-07-07 09:08:13 +02:00
}
2022-01-18 05:31:19 +01:00
2024-07-07 09:08:13 +02:00
if(type == VALUE_TYPE.d3Material) {
2024-04-08 07:13:46 +02:00
if(nod == self) {
return def_val;
} else if(typ == VALUE_TYPE.surface) {
if(!is_array(val)) return def_val.clone(val);
var _val = array_create(array_length(val));
for( var i = 0, n = array_length(val); i < n; i++ )
_val[i] = def_val.clone(val[i]);
2024-04-08 07:13:46 +02:00
return _val;
}
2024-07-07 09:08:13 +02:00
}
2024-04-08 07:13:46 +02:00
2024-04-23 11:53:16 +02:00
if(PROJECT.attributes.strict) return val;
val = arrayBalance(val);
2022-01-13 05:24:03 +01:00
2024-07-07 09:08:13 +02:00
if(isArray(val) && array_length(val) < 1024) { // Process data
2023-09-18 13:54:55 +02:00
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);
2023-09-18 13:54:55 +02:00
return _val;
2024-07-07 09:08:13 +02:00
}
2022-12-16 09:18:09 +01:00
var _val = valueProcess(val, nod, applyUnit, arrIndex);
return _val;
2024-07-07 09:08:13 +02:00
}
2022-01-13 05:24:03 +01:00
static getValueRecursive = function(arr = __curr_get_val, _time = CURRENT_FRAME) {
2022-01-13 05:24:03 +01:00
2023-12-19 14:30:34 +01:00
if(value_from_loop && value_from_loop.bypassConnection() && value_from_loop.junc_out)
2024-04-01 11:10:01 +02:00
value_from_loop.getValue(arr);
2023-12-19 14:30:34 +01:00
else if(value_from && value_from != self)
2024-04-01 11:10:01 +02:00
value_from.getValueRecursive(arr, _time);
2022-01-13 05:24:03 +01:00
2024-08-08 06:57:51 +02:00
else {
arr[@ 0] = __getAnimValue(_time);
arr[@ 1] = self;
}
2024-09-19 07:36:57 +02:00
if(!expUse || expTree == noone || !expTree.validate()) return;
2023-07-14 20:34:35 +02:00
2024-08-06 14:04:41 +02:00
if(global.EVALUATE_HEAD == self) {
noti_warning($"Expression evaluation error : recursive call detected.");
return;
}
if(global.EVALUATE_HEAD == noone) {
global.EVALUATE_HEAD = self;
expContext = {
name : name,
node_name : node.display_name,
value : arr[0],
node_values : node.input_value_map,
};
var _exp_res = expTree.eval(variable_clone(expContext));
printIf(global.LOG_EXPRESSION, $">>>> Result = {_exp_res}");
2024-04-30 05:57:34 +02:00
2024-08-06 14:04:41 +02:00
if(is_undefined(_exp_res)) {
arr[@ 0] = 0;
noti_warning("Expression returns undefine values.");
} else
arr[@ 0] = _exp_res;
}
2024-08-06 14:04:41 +02:00
global.EVALUATE_HEAD = noone;
}
2022-01-13 05:24:03 +01:00
2024-08-06 12:39:22 +02:00
static arrayBalance = function(val) {
if(!is_array(def_val)) return val;
if(isDynamicArray()) return val;
if(isArray(val)) return val;
if(!is_array(val)) return array_create(def_length, val);
2024-04-24 03:46:53 +02:00
if(array_length(val) < def_length) {
val = array_clone(val, 1);
2024-04-24 03:46:53 +02:00
array_resize(val, def_length);
}
2024-04-24 03:46:53 +02:00
return val;
2024-08-06 12:39:22 +02:00
}
2024-04-24 03:46:53 +02:00
2024-08-06 12:39:22 +02:00
static __getAnimValue = function(_time = CURRENT_FRAME) {
2024-04-23 11:53:16 +02:00
if(!is_anim) {
if(sep_axis) {
2024-07-03 05:24:37 +02:00
var val = array_create(array_length(animators));
2024-04-23 11:53:16 +02:00
for( var i = 0, n = array_length(animators); i < n; i++ )
val[i] = animators[i].processType(animators[i].values[0].value);
2024-04-23 11:53:16 +02:00
return val;
}
if(array_empty(animator.values)) return 0;
2024-04-23 11:53:16 +02:00
return animator.processType(animator.values[0].value);
2024-04-23 11:53:16 +02:00
}
if(sep_axis) {
var val = [];
for( var i = 0, n = array_length(animators); i < n; i++ )
val[i] = animators[i].getValue(_time);
return val;
}
return animator.getValue(_time);
2024-08-06 12:39:22 +02:00
}
2024-04-23 11:53:16 +02:00
static isTimelineVisible = function() { INLINE return is_anim && value_from == noone; }
2023-03-21 03:01:53 +01:00
2024-03-31 11:10:14 +02:00
show_val = [];
static __showValue = function() {
2024-03-31 11:10:14 +02:00
INLINE
2023-08-02 19:11:57 +02:00
2024-04-03 09:40:37 +02:00
var val = 0;
2023-08-01 11:16:23 +02:00
2024-03-31 11:10:14 +02:00
if(value_from != noone || is_anim || expUse)
val = getValue(CURRENT_FRAME, false);
2024-03-31 11:10:14 +02:00
else if(sep_axis) {
show_val = array_verify(show_val, array_length(animators));
for( var i = 0, n = array_length(animators); i < n; i++ )
show_val[i] = array_empty(animators[i].values)? 0 : animators[i].processType(animators[i].values[0].value);
2024-03-31 11:10:14 +02:00
val = show_val;
2024-04-03 09:40:37 +02:00
} else
val = array_empty(animator.values)? 0 : animator.processType(animator.values[0].value);
2023-09-14 16:29:39 +02:00
2022-01-13 05:24:03 +01:00
return val;
2024-08-06 14:04:41 +02:00
}
2022-01-13 05:24:03 +01:00
static showValue = function() { ////showValue
return __showValue();
}
2024-08-06 14:04:41 +02:00
static unitConvert = function(mode) {
var _v = animator.values;
2024-08-19 06:16:12 +02:00
for( var i = 0; i < array_length(_v); i++ )
_v[i].value = unit.convertUnit(_v[i].value, mode);
2024-08-06 14:04:41 +02:00
}
2024-08-06 14:04:41 +02:00
static isDynamicArray = function() {
2023-09-18 13:54:55 +02:00
if(dynamic_array) return true;
switch(display_type) {
case VALUE_DISPLAY.curve :
case VALUE_DISPLAY.palette :
return true;
}
return false;
2024-08-06 14:04:41 +02:00
}
static isArray = function(val = undefined) {
2024-08-08 06:57:51 +02:00
val ??= getValue();
return __array_get_depth(val) > array_depth + type_array;
}
2022-01-13 05:24:03 +01:00
2024-08-09 13:30:09 +02:00
__is_array = false;
__array_length = -1;
static __arrayLength = function(val = undefined) {
val ??= getValue();
2023-02-28 09:43:01 +01:00
var _vdp = array_depth + type_array;
var _dep = array_get_depth(val);
__is_array = _dep > 0;
2024-08-08 06:57:51 +02:00
return _dep > _vdp? array_length(val) : -1;
2024-08-06 14:04:41 +02:00
}
2023-02-28 09:43:01 +01:00
static arrayLengthSimple = function(val = undefined) {
val ??= getValue();
__is_array = is_array(val);
return __is_array? array_length(val) : -1;
}
2024-08-09 13:30:09 +02:00
arrayLength = __arrayLength;
/////============== SET =============
2024-08-24 12:17:52 +02:00
static onValidate = function() {
if(!validateValue) return;
var _val = value_validation, str = "";
value_validation = VALIDATION.pass;
switch(type) {
case VALUE_TYPE.path:
switch(display_type) {
case VALUE_DISPLAY.path_load:
var path = animator.getValue();
if(is_array(path)) path = path[0];
if(!is_string(path) || path == "") {
str = $"Path invalid: {path}";
break;
}
if(path_get(path) == -1) {
value_validation = VALIDATION.error;
str = $"File not exist: {path}";
}
break;
case VALUE_DISPLAY.path_array:
var paths = animator.getValue();
if(is_array(paths)) {
for( var i = 0, n = array_length(paths); i < n; i++ ) {
if(path_get(paths[i]) != -1) continue;
value_validation = VALIDATION.error;
str = $"File not exist: {paths[i]}";
}
} else {
value_validation = VALIDATION.error;
str = $"File not exist: {paths}";
}
break;
}
break;
}
node.onValidate();
if(_val == value_validation) return self;
#region notification
if(value_validation == VALIDATION.error && error_notification == noone) {
error_notification = noti_error(str);
error_notification.onClick = function() { PANEL_GRAPH.focusNode(node); };
}
if(value_validation == VALIDATION.pass && error_notification != noone) {
noti_remove(error_notification);
error_notification = noone;
}
#endregion
return self;
2024-08-24 12:17:52 +02:00
}
static setValue = function(val = 0, record = true, time = CURRENT_FRAME, _update = true) { ////Set value
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);
}
2022-12-27 04:00:50 +01:00
2024-08-24 12:17:52 +02:00
static overrideValue = function(_val) {
animator.values = [];
array_push(animator.values, new valueKey(0, _val, animator));
for( var i = 0, n = array_length(animators); i < n; i++ ) {
animators[i].values = [];
array_push(animators[i].values, new valueKey(0, array_safe_get_fast(_val, i), animators[i]));
}
2024-08-24 12:17:52 +02:00
}
static setValueInspector = function(_val = 0, index = noone, time = CURRENT_FRAME) { // This should be in panel_graph not here.
2024-02-01 05:26:02 +01:00
INLINE
2024-02-01 05:26:02 +01:00
var res = false;
if(PANEL_INSPECTOR && PANEL_INSPECTOR.inspectGroup == 1) {
var ind = self.index;
for( var i = 0, n = array_length(PANEL_INSPECTOR.inspectings); i < n; i++ ) {
var _node = PANEL_INSPECTOR.inspectings[i];
2024-08-08 06:57:51 +02:00
if(ind >= array_length(_node.inputs)) continue;
2024-02-01 05:26:02 +01:00
var r = _node.inputs[ind].setValueDirect(_val, index, true, time);
2024-02-01 05:26:02 +01:00
if(_node == node) res = r;
}
2024-08-14 05:28:46 +02:00
} else
res = setValueDirect(_val, index, true, time);
2024-08-14 05:28:46 +02:00
2024-02-01 05:26:02 +01:00
return res;
2024-08-14 05:28:46 +02:00
}
2024-02-01 05:26:02 +01:00
2024-08-06 14:04:41 +02:00
static setValueDirect = function(val = 0, index = noone, record = true, time = CURRENT_FRAME, _update = true) {
2023-11-24 10:41:53 +01:00
is_modified = true;
2023-03-21 03:01:53 +01:00
var updated = false;
2024-01-26 14:38:50 +01:00
var _val = val;
2024-08-20 10:15:53 +02:00
var _inp = connect_type == CONNECT_TYPE.input;
2024-08-14 05:28:46 +02:00
record &= record_value & _inp;
2023-03-21 03:01:53 +01:00
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++ )
2024-08-14 05:28:46 +02:00
updated |= animators[i].setValue(val[i], record, time);
2023-03-21 03:01:53 +01:00
} else
2024-08-14 05:28:46 +02:00
updated = animators[index].setValue(val, record, time);
2024-04-08 14:52:24 +02:00
2023-03-21 03:01:53 +01:00
} else {
if(index != noone) {
2024-01-26 14:38:50 +01:00
_val = animator.getValue(time);
if(_inp) _val = variable_clone(_val);
2023-03-21 03:01:53 +01:00
_val[index] = val;
2024-01-26 14:38:50 +01:00
}
2024-08-14 05:28:46 +02:00
updated = animator.setValue(_val, record, time);
2023-03-21 03:01:53 +01:00
}
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
2024-08-07 11:48:39 +02:00
if(!updated) return false; /////////////////////////////////////////////////////////////////////////////////
if(is_instanceof(self, __NodeValue_Dimension))
2024-08-23 06:14:52 +02:00
node.attributes.use_project_dimension = false;
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.input && self.index >= 0) {
2024-08-06 14:04:41 +02:00
var _val = animator.getValue(time);
2024-08-07 11:48:39 +02:00
node.inputs_data[self.index] = _val; // setInputData(self.index, _val);
2024-08-06 14:04:41 +02:00
node.input_value_map[$ internalName] = _val;
}
2023-10-06 11:51:11 +02:00
draw_junction_index = type;
if(type == VALUE_TYPE.surface) {
var _sval = val;
if(is_array(_sval) && !array_empty(_sval))
_sval = _sval[0];
2023-10-06 11:51:11 +02:00
if(is_instanceof(_sval, SurfaceAtlas))
draw_junction_index = VALUE_TYPE.atlas;
2022-01-13 05:24:03 +01:00
}
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.output) {
2023-11-27 11:40:28 +01:00
if(self.index == 0) {
node.preview_value = getValue();
node.preview_array = $"[{array_shape(node.preview_value)}]";
2023-11-27 11:40:28 +01:00
}
return;
}
2023-10-06 11:51:11 +02:00
2024-03-31 11:10:14 +02:00
if(tags == VALUE_TAG.updateInTrigger || tags == VALUE_TAG.updateOutTrigger) return true;
2023-10-06 11:51:11 +02:00
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();
}
2023-11-22 10:21:50 +01:00
if(fullUpdate) 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;
2024-08-06 14:04:41 +02:00
}
2022-01-13 05:24:03 +01:00
static getString = function() {
var val = showValue();
if(type == VALUE_TYPE.text) return val;
return json_beautify(val);
}
static setString = function(str) {
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.output) return;
if(type == VALUE_TYPE.text) { setValue(str); return; }
var _dat = json_try_parse(str);
2024-08-08 06:57:51 +02:00
if(type_array && !is_array(_dat)) _dat = [ _dat ];
setValue(_dat);
}
/////=========== CONNECT ===========
static rejectConnect = function() {
auto_connect = false;
return self;
}
static isConnectable = function(_valueFrom, checkRecur = true, _log = false) {
2024-07-04 13:51:04 +02:00
2023-01-09 03:14:20 +01:00
if(_valueFrom == -1 || _valueFrom == undefined || _valueFrom == noone) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning($"LOAD: Cannot set node connection from {_valueFrom} to {name} of node {node.name}.",, node);
2023-12-19 14:30:34 +01:00
return -1;
2022-01-13 05:24:03 +01:00
}
2022-01-25 10:58:11 +01:00
if(_valueFrom == value_from) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning("whaT");
return -2;
2022-01-13 05:24:03 +01:00
}
if(_valueFrom == self) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning("setFrom: Self connection is not allowed.",, node);
return -3;
2022-01-13 05:24:03 +01:00
}
2023-03-05 07:16:44 +01:00
if(!typeCompatible(_valueFrom.type, type)) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning($"Connection error: Incompatible type {_valueFrom.type} to {type}",, node);
return -4;
2023-02-19 02:13:19 +01:00
}
if(typeIncompatible(_valueFrom, self)) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning("Connection error: Incompatible type",, node);
return -5;
2022-01-13 05:24:03 +01:00
}
if(connect_type == _valueFrom.connect_type) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning("setFrom: Connect type mismatch",, node);
return -6;
2022-01-13 05:24:03 +01:00
}
if(checkRecur && _valueFrom.searchNodeBackward(node)) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning("setFrom: Cyclic connection not allowed.",, node);
return -7;
2022-01-13 05:24:03 +01:00
}
2023-02-14 02:51:14 +01:00
if(!accept_array && isArray(_valueFrom.getValue())) {
noti_warning($"Connection error: {name} does not support array input.",, node);
return -8;
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)) {
2024-07-04 13:51:04 +02:00
if(_log) noti_warning("setFrom: Array mismatch",, node);
return -9;
}
2023-12-03 05:02:04 +01:00
return 1;
}
static isConnectableStrict = function(_valueFrom) { return bool(value_bit(type) & value_bit(_valueFrom.type)); }
2023-10-27 13:55:31 +02:00
2024-05-23 14:40:30 +02:00
static triggerSetFrom = function() { node.valueUpdate(index); }
static setFrom = function(_valueFrom, _update = true, checkRecur = true, log = false) { //// Set from
if(is_dummy && dummy_get != noone) {
2024-05-23 10:59:39 +02:00
var _targ = dummy_get();
dummy_target = _targ;
UNDO_HOLDING = true;
var _res = _targ.setFrom(_valueFrom, _update, checkRecur, log);
UNDO_HOLDING = false;
recordAction(ACTION_TYPE.junction_connect, self, [ _targ, _valueFrom ]);
return _res;
}
2023-02-14 02:51:14 +01:00
if(_valueFrom == noone)
return removeFrom();
2023-03-28 06:58:28 +02:00
run_in(2, function() /*=>*/ { updateColor(getValue()); });
2023-12-19 14:30:34 +01:00
var conn = isConnectable(_valueFrom, checkRecur, log);
if(conn < 0) return conn;
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)
2023-12-19 14:30:34 +01:00
array_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;
2023-12-19 14:30:34 +01:00
array_push(_valueFrom.value_to, self);
2022-01-13 05:24:03 +01:00
2023-02-14 02:51:14 +01:00
node.valueUpdate(index, _o);
2024-08-20 10:15:53 +02:00
if(_update && connect_type == CONNECT_TYPE.input) {
2023-11-02 14:37:13 +01:00
node.valueFromUpdate(index);
node.refreshNodeDisplay();
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;
}
2022-01-13 05:24:03 +01:00
static removeFrom = function(_remove_list = true) {
run_in(2, function() /*=>*/ { updateColor(getValue()); });
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)
2023-12-19 14:30:34 +01:00
array_remove(value_from.value_to, self);
2022-01-13 05:24:03 +01:00
value_from = noone;
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.input)
2023-11-02 14:37:13 +01:00
node.valueFromUpdate(index);
2023-04-14 12:23:25 +02:00
node.clearCacheForward();
node.refreshNodeDisplay();
2023-02-14 02:51:14 +01:00
PROJECT.modified = true;
2023-12-19 14:30:34 +01:00
2023-10-07 16:23:40 +02:00
RENDER_ALL_REORDER
2023-02-14 02:51:14 +01:00
return false;
}
2022-01-13 05:24:03 +01:00
static removeFromLoop = function(_remove_list = true) {
2023-12-19 14:30:34 +01:00
if(value_from_loop != noone)
2024-04-08 07:13:46 +02:00
value_from_loop.destroy();
2023-12-19 14:30:34 +01:00
PROJECT.modified = true;
}
2023-12-19 14:30:34 +01:00
static checkConnection = function(_remove_list = true) {
if(value_from == noone) return;
2022-01-26 06:57:34 +01:00
if(value_from.node.active) return;
removeFrom(_remove_list);
}
2022-01-13 05:24:03 +01:00
static searchNodeBackward = function(_node) {
2022-01-13 05:24:03 +01:00
if(node == _node) return true;
2024-08-08 06:57:51 +02:00
for(var i = 0; i < array_length(node.inputs); i++) {
var _in = node.inputs[i].value_from;
2022-01-13 05:24:03 +01:00
if(_in && _in.searchNodeBackward(_node))
return true;
}
return false;
}
2022-01-13 05:24:03 +01:00
static hasJunctionFrom = function() { INLINE return value_from != noone || value_from_loop != noone; }
static getJunctionTo = function() {
var _junc_to = [];
for(var i = 0; i < array_length(value_to); i++) {
var _to = value_to[i];
if(!_to.node.active || _to.value_from == noone) continue;
if(_to.value_from != self) continue;
array_push(_junc_to, _to);
}
return _junc_to;
}
/////============= DRAW =============
2024-09-24 11:51:04 +02:00
static setColor = function(_color) {
color = color_real(_color);
2024-09-24 11:51:04 +02:00
updateColor();
return self;
}
static updateColor = function(val = undefined) {
INLINE
if(color == -1) {
draw_bg = is_array(val)? value_color_bg_array(draw_junction_index) : value_color_bg(draw_junction_index);
draw_fg = value_color(draw_junction_index);
2024-09-24 11:51:04 +02:00
} else {
draw_bg = is_array(val)? merge_color(color, colorMultiply(color, CDEF.main_dkgrey), 0.5) : value_color_bg(draw_junction_index);
draw_fg = color;
}
color_display = type == VALUE_TYPE.action? #8fde5d : draw_fg;
} updateColor();
2022-12-27 04:00:50 +01:00
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
2023-08-02 19:11:57 +02:00
if(expUse) return -1;
2023-01-01 02:06:02 +01:00
2024-03-14 14:35:19 +01:00
var arc = 9;
switch(type) {
case VALUE_TYPE.integer :
case VALUE_TYPE.float :
if(value_from != noone) return -1;
switch(display_type) {
case VALUE_DISPLAY._default :
case VALUE_DISPLAY.slider :
var _angle = argument_count > arc + 0? argument[arc + 0] : 0;
var _scale = argument_count > arc + 1? argument[arc + 1] : 1;
var _spr = argument_count > arc + 2? argument[arc + 2] : 0;
return preview_overlay_scalar(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _angle, _scale, _spr);
case VALUE_DISPLAY.rotation :
var _rad = argument_count > arc + 0? argument[ arc + 0] : 64;
return preview_overlay_rotation(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _rad);
case VALUE_DISPLAY.vector :
var _typ = argument_count > arc + 0? argument[arc + 0] : 0;
var _sca = argument_count > arc + 1? argument[arc + 1] : 1;
return preview_overlay_vector(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _typ);
2022-01-13 05:24:03 +01:00
case VALUE_DISPLAY.gradient_range :
var _dim = argument[arc];
2022-09-23 13:28:42 +02:00
if(mappedJunc.attributes.mapped)
return preview_overlay_gradient_range(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _dim);
break;
case VALUE_DISPLAY.area :
var _flag = argument_count > arc + 0? argument[arc + 0] : 0b0011;
return preview_overlay_area(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _flag, struct_try_get(display_data, "onSurfaceSize"));
case VALUE_DISPLAY.puppet_control :
return preview_overlay_puppet(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
}
break;
case VALUE_TYPE.pathnode :
var _path = getValue();
if(struct_has(_path, "drawOverlay"))
return _path.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
break;
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;
}
2022-01-13 05:24:03 +01:00
2024-07-10 11:48:23 +02:00
static drawJunction_fast = function(_s, _mx, _my) {
2024-03-31 11:10:14 +02:00
INLINE
2024-05-23 10:59:39 +02:00
var hov = PANEL_GRAPH.pHOVER && (PANEL_GRAPH.node_hovering == noone || PANEL_GRAPH.node_hovering == node);
2024-07-10 11:48:23 +02:00
var _d = node.junction_draw_hei_y * _s;
var _hov = hov && point_in_rectangle(_mx, _my, x - 6 * _s, y - _d / 2, x + 6 * _s, y + _d / 2 - 1);
2024-05-23 10:59:39 +02:00
var _aa = 0.75 + (!is_dummy * 0.25);
2024-07-10 11:48:23 +02:00
hover_in_graph = _hov;
2024-03-31 11:10:14 +02:00
2024-11-01 05:57:42 +01:00
draw_set_color(custom_color == noone? draw_fg : custom_color);
2024-05-23 10:59:39 +02:00
draw_set_alpha(_aa);
2024-07-10 11:48:23 +02:00
if(node.previewable)
draw_circle(x, y, _s * 6, false);
else if(index == -1)
draw_rectangle( x - _s * 4, y - _s * 1.5,
x + _s * 4, y + _s * 1.5, false);
else
draw_rectangle( x - _s * 1.5, y - _s * 4,
x + _s * 1.5, y + _s * 4, false);
2024-05-23 10:59:39 +02:00
draw_set_alpha(1);
return _hov;
2024-07-10 11:48:23 +02:00
}
2024-03-31 11:10:14 +02:00
2024-07-10 11:48:23 +02:00
static drawJunction = function(_s, _mx, _my) {
2024-03-31 11:10:14 +02:00
_s /= 2;
var hov = PANEL_GRAPH.pHOVER && (PANEL_GRAPH.node_hovering == noone || PANEL_GRAPH.node_hovering == node);
2024-07-10 11:48:23 +02:00
var _d = node.junction_draw_hei_y * _s;
2024-05-22 04:46:29 +02:00
var is_hover = hov && point_in_rectangle(_mx, _my, x - _d, y - _d, x + _d - 1, y + _d - 1);
2024-04-03 09:40:37 +02:00
hover_in_graph = is_hover;
2024-11-01 05:57:42 +01:00
if(custom_icon != noone) {
__draw_sprite_ext(custom_icon, 0, x, y, _s, _s, 0, c_white, 1);
} else if(is_dummy) {
2024-05-23 10:59:39 +02:00
__draw_sprite_ext(THEME.node_junction_add, is_hover, x, y, _s, _s, 0, c_white, 0.5 + 0.5 * is_hover);
} else if(type == VALUE_TYPE.action) {
2023-11-27 11:40:28 +01:00
var _cbg = c_white;
if(draw_blend != -1)
_cbg = merge_color(draw_blend_color, _cbg, draw_blend);
2024-03-31 11:10:14 +02:00
__draw_sprite_ext(THEME.node_junction_inspector, is_hover, x, y, _s, _s, 0, _cbg, 1);
2023-10-15 15:04:42 +02:00
} else {
2023-11-27 11:40:28 +01:00
var _cbg = draw_bg;
var _cfg = draw_fg;
if(draw_blend != -1) {
_cbg = merge_color(draw_blend_color, _cbg, draw_blend);
_cfg = merge_color(draw_blend_color, _cfg, draw_blend);
}
var _bgS, _fgS;
if(_s > .5) {
_bgS = THEME.node_junctions_bg_x2;
_fgS = is_hover? THEME.node_junctions_outline_hover_x2 : THEME.node_junctions_outline_x2;
} else {
_bgS = THEME.node_junctions_bg;
_fgS = is_hover? THEME.node_junctions_outline_hover : THEME.node_junctions_outline;
_s *= 2;
}
2024-11-02 05:10:04 +01:00
if(graph_selecting) __draw_sprite_ext(THEME.node_junction_selecting, 0, x, y, _s, _s, 0, _cfg, .8);
graph_selecting = false;
2024-03-31 11:10:14 +02:00
__draw_sprite_ext(_bgS, draw_junction_index, x, y, _s, _s, 0, _cbg, 1);
gpu_set_blendmode_ext_sepalpha(bm_src_alpha, bm_inv_src_alpha, bm_one, bm_one);
2024-03-31 11:10:14 +02:00
__draw_sprite_ext(_fgS, draw_junction_index, x, y, _s, _s, 0, _cfg, 1);
gpu_set_blendmode(bm_normal);
2023-10-15 15:04:42 +02:00
}
2023-07-12 16:28:32 +02:00
2022-09-27 06:37:28 +02:00
return is_hover;
2024-07-10 11:48:23 +02:00
}
2022-09-27 06:37:28 +02:00
2024-07-10 11:48:23 +02:00
static drawNameBG = function(_s) {
var _f = node.previewable? f_p1 : f_p3;
draw_set_text(_f, 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);
2024-07-10 11:48:23 +02:00
2024-08-20 10:15:53 +02:00
} else if(connect_type == CONNECT_TYPE.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);
2024-07-10 11:48:23 +02:00
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
}
2024-07-10 11:48:23 +02:00
}
2023-08-19 12:42:50 +02:00
2024-07-10 11:48:23 +02:00
static drawName = function(_s, _mx, _my) {
2024-04-03 09:40:37 +02:00
var _draw_cc = COLORS._main_text;
2024-07-10 11:48:23 +02:00
var _draw_aa = 0.6 + hover_in_graph * 0.4;
var _f = node.previewable? f_p1 : f_p3;
draw_set_text(_f, fa_left, fa_center, _draw_cc);
draw_set_alpha(_draw_aa);
2022-09-27 06:37:28 +02:00
2023-03-28 06:58:28 +02:00
if(type == VALUE_TYPE.action) {
var tx = x;
2024-07-10 11:48:23 +02:00
draw_set_text(_f, fa_center, fa_center, _draw_cc);
draw_text_add(tx, y - (line_get_height() + 16) / 2, name);
2024-04-03 09:40:37 +02:00
2024-08-20 10:15:53 +02:00
} else if(connect_type == CONNECT_TYPE.input) {
2022-09-27 06:37:28 +02:00
var tx = x - 12 * _s;
draw_set_halign(fa_right);
2024-07-10 11:48:23 +02:00
draw_text_add(tx, y, name);
2024-04-03 09:40:37 +02:00
2022-09-27 06:37:28 +02:00
} else {
var tx = x + 12 * _s;
draw_set_halign(fa_left);
2024-07-10 11:48:23 +02:00
draw_text_add(tx, y, name);
2024-04-03 09:40:37 +02:00
2022-09-27 06:37:28 +02:00
}
draw_set_alpha(1);
2024-07-10 11:48:23 +02:00
}
2022-01-26 06:57:34 +01:00
static drawConnectionsRaw = function(params = {}) { return drawJuncConnection(value_from, self, params); }
static drawConnections = function(params = {}) {
2024-08-14 09:55:53 +02:00
if(value_from == noone || !value_from.node.active || !isVisible()) return noone;
2023-12-19 14:30:34 +01:00
return drawJuncConnection(value_from, self, params);
}
2023-07-25 20:12:40 +02:00
static drawConnectionMouse = function(params, _mx, _my, target = noone) {
var ss = params.s;
2024-01-26 14:38:50 +01:00
var aa = 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;
var _fade = PREFERENCES.connection_line_highlight_fade;
2024-11-01 05:57:42 +01:00
var col = custom_color == noone? merge_color(_fade, color_display, .5) : custom_color;
2023-08-13 09:00:58 +02:00
draw_set_color(col);
var _action = type == VALUE_TYPE.action;
2024-08-20 10:15:53 +02:00
var _output = connect_type == CONNECT_TYPE.output;
2024-11-08 04:36:54 +01:00
var _drawParam = {
corner : corner,
extend : PREFERENCES.connection_line_extend,
fromIndex : 1,
toIndex : 1,
type : LINE_STYLE.solid,
}
2023-10-31 05:30:42 +01:00
switch(PREFERENCES.curve_connection_line) {
2024-11-08 04:36:54 +01:00
case 0 :
if(drawCorner) draw_line_width(sx, sy, _mx, _my, th);
else {
if(_output) draw_line_connect(sx, sy, _mx, _my, ss, th, col, col, _drawParam);
else draw_line_connect(_mx, _my, sx, sy, ss, th, col, col, _drawParam);
}
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;
2023-08-13 09:00:58 +02:00
case 2 :
if(drawCorner) {
2024-11-08 04:36:54 +01:00
if(_action) draw_line_elbow_corner(_mx, _my, sx, sy, ss, th, col, col, _drawParam);
else draw_line_elbow_corner(sx, sy, _mx, _my, ss, th, col, col, _drawParam);
2023-08-13 09:00:58 +02:00
} else {
2024-11-08 04:36:54 +01:00
if(_output) draw_line_elbow_color(sx, sy, _mx, _my,,, ss, th, col, col, _drawParam);
else draw_line_elbow_color(_mx, _my, sx, sy,,, ss, th, col, col, _drawParam);
2023-08-13 09:00:58 +02:00
}
break;
2023-08-13 09:00:58 +02:00
case 3 :
if(drawCorner) {
2024-11-08 04:36:54 +01:00
if(_action) draw_line_elbow_diag_corner(_mx, _my, sx, sy, ss, th, col, col, _drawParam);
else draw_line_elbow_diag_corner(sx, sy, _mx, _my, ss, th, col, col, _drawParam);
2023-08-13 09:00:58 +02:00
} else {
2024-11-08 04:36:54 +01:00
if(_output) draw_line_elbow_diag_color(sx, sy, _mx, _my,,, ss, th, col, col, _drawParam);
else draw_line_elbow_diag_color(_mx, _my, sx, sy,,, ss, th, col, col, _drawParam);
2023-08-13 09:00:58 +02:00
}
break;
}
2024-11-01 05:57:42 +01:00
if(custom_icon == noone) {
__draw_sprite_ext(THEME.node_junctions_bg_x2, draw_junction_index, _mx, _my, ss / 2, ss / 2, 0, draw_bg, 1);
__draw_sprite_ext(THEME.node_junctions_outline_x2, draw_junction_index, _mx, _my, ss / 2, ss / 2, 0, col, 1);
} else
__draw_sprite_ext(custom_icon, draw_junction_index, _mx, _my, ss / 2, ss / 2, 0, c_white, 1);
}
/////========== EXPRESSION ==========
2023-01-09 03:14:20 +01:00
static setUseExpression = function(useExp) {
INLINE
if(expUse == useExp) return;
expUse = useExp;
node.triggerRender();
}
2023-10-18 14:58:55 +02:00
static setExpression = function(_expression) {
expUse = true;
expression = _expression;
expressionUpdate();
}
2023-06-01 10:32:21 +02:00
static expressionUpdate = function() {
expTree = evaluateFunctionList(expression);
resetCache();
node.triggerRender();
}
2023-03-26 07:13:36 +02:00
/////=========== SERIALIZE ===========
static serialize = function(scale = false, preset = false) {
2023-06-13 14:42:06 +02:00
var _map = {};
2022-01-13 05:24:03 +01:00
_map.visible = visible;
_map.visible_manual = visible_manual;
_map.color = color;
2023-04-07 21:25:27 +02:00
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.output)
2023-04-07 21:25:27 +02:00
return _map;
_map.name = name;
_map.on_end = on_end;
_map.loop_range = loop_range;
_map.unit = unit.mode;
_map.sep_axis = sep_axis;
_map.shift_x = draw_line_shift_x;
_map.shift_y = draw_line_shift_y;
_map.is_modified = is_modified;
_map.from_node = -1;
_map.from_index = -1;
_map.from_tag = 0;
2023-09-28 13:15:29 +02:00
if(!preset && value_from) {
_map.from_node = value_from.node.node_id;
_map.from_index = value_from.index;
_map.from_tag = value_from.tags;
2023-09-28 13:15:29 +02:00
}
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;
2024-08-14 09:55:53 +02:00
_map.bypass = bypass_junc? bypass_junc.visible : false;
2022-01-13 05:24:03 +01:00
return _map;
}
2022-12-21 02:30:23 +01:00
static applyDeserialize = function(_map, scale = false, preset = false) {
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
visible = struct_try_get(_map, "visible", visible);
visible_manual = struct_try_get(_map, "visible_manual", visible_manual);
color = struct_try_get(_map, "color", -1);
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.output)
2023-04-07 21:25:27 +02:00
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");
2023-11-24 10:41:53 +01:00
is_modified = struct_try_get(_map, "is_modified", true);
2022-12-27 04:00:50 +01:00
2023-12-22 14:46:54 +01:00
struct_append(attributes, struct_try_get(_map, "attributes"))
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);
2024-08-14 09:55:53 +02:00
if(bypass_junc) bypass_junc.visible = struct_try_get(_map, "bypass", false);
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) {
con_node = struct_try_get(_map, "from_node", -1)
2023-06-13 14:42:06 +02:00
con_index = struct_try_get(_map, "from_index", -1);
con_tag = struct_try_get(_map, "from_tag", -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
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.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
}
postApplyDeserialize();
2023-12-22 14:46:54 +01:00
attributeApply();
onValidate();
}
2022-01-13 05:24:03 +01:00
static postApplyDeserialize = function() {}
2024-10-02 10:26:08 +02:00
static attributeApply = function() {
2024-03-19 09:49:29 +01:00
if(struct_has(attributes, "mapped") && attributes.mapped)
mappableStep();
}
2023-12-22 14:46:54 +01:00
static connect = function(log = false) {
2024-11-12 04:15:04 +01:00
if(con_node == -1 || con_index == -1) return true;
// print($"{node} | {con_node} : {con_index}");
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];
2024-08-08 06:57:51 +02:00
var _ol = array_length(_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);
switch(con_tag) {
case VALUE_TAG.updateInTrigger : return setFrom(_nd.updatedInTrigger);
case VALUE_TAG.updateOutTrigger : return setFrom(_nd.updatedOutTrigger);
case VALUE_TAG.matadata : return setFrom(_nd.junc_meta[con_index]);
2024-08-14 09:55:53 +02:00
default :
if(con_index < _ol) {
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);
return false;
}
if(con_index >= 1000) { //connect bypass
var _inp = array_safe_get_fast(_nd.inputs, con_index - 1000, noone);
if(_inp == noone) return false;
var _set = setFrom(_inp.bypass_junc, false, true);
if(_set) return true;
if(_set == -1) log_warning("LOAD", $"[Connect] Connection conflict {node.name} to {_nd.name} (bypass) : Not connectable.", node);
else if(_set == -2) log_warning("LOAD", $"[Connect] Connection conflict {node.name} to {_nd.name} (bypass) : Condition not met.", node);
return false;
}
break;
2022-01-13 05:24:03 +01:00
}
log_warning("LOAD", $"[Connect] Connection conflict {node.name} to {_nd.name} : Output not exist [{con_index}].", node);
2022-01-19 03:05:13 +01:00
return false;
}
2022-01-19 06:11:17 +01:00
/////============= MISC =============
static extractNode = function(_type = extract_node) {
if(_type == "") return noone;
2024-11-13 08:35:04 +01:00
var ext = nodeBuild(_type, node.x, node.y).skipDefault();
ext.x -= ext.w + 32;
2024-11-13 08:35:04 +01:00
for( var i = 0; i < array_length(ext.outputs); i++ )
2024-08-08 06:57:51 +02:00
if(setFrom(ext.outputs[i])) break;
var len = 2;
switch(_type) {
case "Node_Vector4": len++;
case "Node_Vector3": len++;
case "Node_Vector2":
for( var j = 0; j < len; j++ ) {
2024-11-13 08:35:04 +01:00
var _in = ext.inputs[j];
2024-11-13 08:35:04 +01:00
_in.setAnim(is_anim);
_in.animator.values = [];
}
2024-11-13 08:35:04 +01:00
for( var i = 0; i < array_length(animator.values); i++ ) {
var _arrVal = animator.values[i];
for( var j = 0; j < len; j++ ) {
2024-11-13 08:35:04 +01:00
var _in = ext.inputs[j];
var _kf = _arrVal.clone(_in.animator);
_kf.value = _kf.value[j];
2024-11-13 08:35:04 +01:00
array_push(_in.animator.values, _kf);
}
2024-11-13 08:35:04 +01:00
}
break;
}
2024-11-13 08:35:04 +01:00
ext.triggerRender();
}
static dragValue = function() {
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();
}
2024-08-20 10:15:53 +02:00
if(connect_type == CONNECT_TYPE.input)
DRAGGING.from = self;
}
static destroy = function() {
2023-02-23 07:02:19 +01:00
if(error_notification != noone) {
noti_remove(error_notification);
error_notification = noone;
}
}
2023-02-23 07:02:19 +01:00
static cleanUp = function() {}
2024-01-26 14:38:50 +01:00
2024-08-20 10:15:53 +02:00
static toString = function() { return (connect_type == CONNECT_TYPE.input? "Input" : "Output") + $" junction {index} of [{name}]: {node}"; }
2024-08-13 13:17:45 +02:00
2023-12-19 14:30:34 +01:00
}
/////========== FUNCTIONS ==========
function drawJuncConnection(from, to, params) {
2023-12-19 14:30:34 +01:00
#region parameters
2024-01-26 14:38:50 +01:00
var log = params.log;
var high = params.highlight;
var bg = params.bg;
var aa = params.aa;
2023-12-19 14:30:34 +01: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 hovering = noone;
var jx = to.x;
var jy = to.y;
var frx = from.x;
var fry = from.y;
var fromIndex = from.drawLineIndex;
var toIndex = to.drawLineIndex;
var _loop = struct_try_get(params, "loop");
2024-01-26 14:38:50 +01:00
if(params.minx != 0 && params.maxx != 0) {
2023-12-19 14:30:34 +01:00
var minx = params.minx;
var miny = params.miny;
var maxx = params.maxx;
var maxy = params.maxy;
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;
}
2024-01-26 14:38:50 +01:00
var shx = to.draw_line_shift_x * _s;
var shy = to.draw_line_shift_y * _s;
2023-12-19 14:30:34 +01:00
var cx = round((frx + jx) / 2 + shx);
var cy = round((fry + jy) / 2 + shy);
var hover = false;
2024-01-26 14:38:50 +01:00
var th = max(1, PREFERENCES.connection_line_width * _s);
to.draw_line_shift_hover = false;
2023-12-19 14:30:34 +01:00
var downDirection = to.type == VALUE_TYPE.action || from.type == VALUE_TYPE.action;
#endregion
#region +++++ CHECK HOVER +++++
2024-11-08 04:36:54 +01:00
var _drawParam = {
extend : PREFERENCES.connection_line_extend,
fromIndex : fromIndex,
toIndex : toIndex,
}
2023-12-19 14:30:34 +01:00
var hovDist = max(th * 2, 6);
2023-12-20 14:02:49 +01:00
if(PANEL_GRAPH.pHOVER) {
if(_loop || from.node == to.node) {
2024-01-10 06:36:33 +01:00
hover = distance_line_feedback(mx, my, jx, jy, frx, fry, _s) < hovDist;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
} else {
2024-11-08 04:36:54 +01:00
var _hdist = 999999;
2023-12-20 14:02:49 +01:00
switch(PREFERENCES.curve_connection_line) {
case 0 :
2024-11-08 04:36:54 +01:00
if(downDirection) _hdist = distance_to_line(mx, my, jx, jy, frx, fry);
else _hdist = distance_to_linear_connection(mx, my, frx, fry, jx, jy, _s, _drawParam);
2023-12-20 14:02:49 +01:00
break;
2023-12-19 14:30:34 +01:00
2024-11-08 04:36:54 +01:00
case 1 :
if(downDirection) _hdist = distance_to_curve_corner(mx, my, jx, jy, frx, fry, _s);
else _hdist = distance_to_curve(mx, my, jx, jy, frx, fry, cx, cy, _s);
2023-12-20 14:02:49 +01:00
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
case 2 :
2024-11-08 04:36:54 +01:00
if(downDirection) _hdist = distance_to_elbow_corner(mx, my, frx, fry, jx, jy);
else _hdist = distance_to_elbow(mx, my, frx, fry, jx, jy, cx, cy, _s, _drawParam);
2023-12-20 14:02:49 +01:00
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
case 3 :
2024-11-08 04:36:54 +01:00
if(downDirection) _hdist = distance_to_elbow_diag_corner(mx, my, frx, fry, jx, jy);
else _hdist = distance_to_elbow_diag(mx, my, frx, fry, jx, jy, cx, cy, _s, _drawParam);
2023-12-20 14:02:49 +01:00
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
}
2024-11-08 04:36:54 +01:00
hover = _hdist < hovDist;
if(PANEL_GRAPH.value_focus == noone) to.draw_line_shift_hover = hover;
2023-12-20 14:02:49 +01:00
}
}
2023-12-19 14:30:34 +01:00
if(_active && hover)
hovering = self;
#endregion
#region draw parameters
var thicken = false;
thicken |= PANEL_GRAPH.nodes_junction_d == self;
thicken |= _active && PANEL_GRAPH.junction_hovering == self && PANEL_GRAPH.value_focus == noone;
thicken |= instance_exists(o_dialog_add_node) && o_dialog_add_node.junction_hovering == self;
th *= thicken? 2 : 1;
var corner = PREFERENCES.connection_line_corner * _s;
var ty = LINE_STYLE.solid;
2024-03-21 13:57:44 +01:00
if(to.type == VALUE_TYPE.node || struct_try_get(params, "dashed"))
2023-12-19 14:30:34 +01:00
ty = LINE_STYLE.dashed;
2023-12-19 14:30:34 +01:00
var c0, c1;
var _selc = to.node.branch_drawing && from.node.branch_drawing;
if(high) {
var _fade = PREFERENCES.connection_line_highlight_fade;
var _colr = _selc? 1 : _fade;
2024-11-01 05:57:42 +01:00
c0 = merge_color(bg, from.custom_color == noone? from.color_display : from.custom_color, _colr);
c1 = merge_color(bg, to.custom_color == noone? to.color_display : to.custom_color, _colr);
2023-12-19 14:30:34 +01:00
to.draw_blend_color = bg;
to.draw_blend = _colr;
from.draw_blend = max(from.draw_blend, _colr);
} else {
2024-11-01 05:57:42 +01:00
c0 = from.custom_color == noone? from.color_display : from.custom_color;
c1 = to.custom_color == noone? to.color_display : to.custom_color;
2023-12-19 14:30:34 +01:00
to.draw_blend_color = bg;
to.draw_blend = -1;
}
#endregion
#region +++++ DRAW LINE +++++
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));
draw_set_color(c0);
if(_loop || from.node == to.node) {
2023-12-20 14:02:49 +01:00
draw_line_feedback(jx, jy, frx, fry, th, c1, c0, ss);
} else {
2024-11-08 04:36:54 +01:00
_drawParam.corner = corner;
_drawParam.type = ty;
2023-12-20 14:02:49 +01:00
switch(PREFERENCES.curve_connection_line) {
case 0 :
2024-11-12 04:15:04 +01:00
if(downDirection) draw_line_width_color(jx, jy, frx, fry, th, c0, c1);
else draw_line_connect(frx, fry, jx, jy, ss, th, c0, c1, _drawParam);
2023-12-20 14:02:49 +01:00
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
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);
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
case 2 :
2024-11-08 04:36:54 +01:00
if(downDirection) draw_line_elbow_corner(frx, fry, jx, jy, ss, th, c0, c1, _drawParam);
else draw_line_elbow_color(frx, fry, jx, jy, cx, cy, ss, th, c0, c1, _drawParam);
2023-12-20 14:02:49 +01:00
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
case 3 :
2024-11-08 04:36:54 +01:00
if(downDirection) draw_line_elbow_diag_corner(frx, fry, jx, jy, ss, th, c0, c1, _drawParam);
else draw_line_elbow_diag_color(frx, fry, jx, jy, cx, cy, ss, th, c0, c1, _drawParam);
2023-12-20 14:02:49 +01:00
break;
2024-11-08 04:36:54 +01:00
2023-12-20 14:02:49 +01:00
}
}
draw_set_alpha(1);
2023-12-19 14:30:34 +01:00
#endregion
return hovering;
}