- [Canvas] Fix holding shift + ctrl disable mouse click.

This commit is contained in:
Tanasart 2024-05-27 08:41:41 +07:00
parent 6bf7646951
commit 0453a3f58a
15 changed files with 663 additions and 621 deletions

View file

@ -31,6 +31,8 @@ event_inherited();
display_list_size = ui(28); display_list_size = ui(28);
display_list_size_to = display_list_size; display_list_size_to = display_list_size;
right_free = !mouse_click(mb_right);
is_global = PANEL_GRAPH.getCurrentContext() == noone; is_global = PANEL_GRAPH.getCurrentContext() == noone;
#region ---- category ---- #region ---- category ----
@ -59,7 +61,6 @@ event_inherited();
node_menu_selecting = node; node_menu_selecting = node;
var fav = array_exists(global.FAV_NODES, node.node); var fav = array_exists(global.FAV_NODES, node.node);
var menu = [ var menu = [
menuItem(fav? __txtx("add_node_remove_favourite", "Remove from favourite") : __txtx("add_node_add_favourite", "Add to favourite"), menuItem(fav? __txtx("add_node_remove_favourite", "Remove from favourite") : __txtx("add_node_add_favourite", "Add to favourite"),
function() { function() {
@ -482,7 +483,7 @@ event_inherited();
draw_sprite_stretched_ext(THEME.node_active, 0, _boxx, yy, grid_size, grid_size, COLORS._main_accent, 1); draw_sprite_stretched_ext(THEME.node_active, 0, _boxx, yy, grid_size, grid_size, COLORS._main_accent, 1);
if(mouse_release(mb_left, sFOCUS)) if(mouse_release(mb_left, sFOCUS))
buildNode(_node); buildNode(_node);
else if(mouse_release(mb_right, sFOCUS)) else if(mouse_release(mb_right, right_free && sFOCUS))
rightClick(_node); rightClick(_node);
} }
@ -610,7 +611,7 @@ event_inherited();
draw_sprite_stretched_ext(THEME.node_active, 0, ui(16), yy, list_width - ui(32), list_height, COLORS._main_accent, 1); draw_sprite_stretched_ext(THEME.node_active, 0, ui(16), yy, list_width - ui(32), list_height, COLORS._main_accent, 1);
if(mouse_release(mb_left, sFOCUS)) if(mouse_release(mb_left, sFOCUS))
buildNode(_node); buildNode(_node);
else if(mouse_release(mb_right, sFOCUS)) else if(mouse_release(mb_right, right_free && sFOCUS))
rightClick(_node); rightClick(_node);
} }
@ -848,7 +849,7 @@ event_inherited();
node_selecting = i; node_selecting = i;
if(mouse_release(mb_left, sFOCUS)) if(mouse_release(mb_left, sFOCUS))
buildNode(_node, _param); buildNode(_node, _param);
else if(struct_has(_node, "node") && mouse_release(mb_right, sFOCUS)) else if(struct_has(_node, "node") && mouse_release(mb_right, right_free && sFOCUS))
rightClick(_node); rightClick(_node);
} }
@ -966,7 +967,7 @@ event_inherited();
node_selecting = i; node_selecting = i;
if(mouse_release(mb_left, sFOCUS)) if(mouse_release(mb_left, sFOCUS))
buildNode(_node, _param); buildNode(_node, _param);
else if(struct_has(_node, "node") && mouse_release(mb_right, sFOCUS)) else if(struct_has(_node, "node") && mouse_release(mb_right, right_free && sFOCUS))
rightClick(_node); rightClick(_node);
} }

View file

@ -88,4 +88,7 @@ if !ready exit;
node_tooltip = noone; node_tooltip = noone;
ADD_NODE_SCROLL = content_pane.scroll_y_to; ADD_NODE_SCROLL = content_pane.scroll_y_to;
if(mouse_release(mb_right))
right_free = true;
#endregion #endregion

View file

@ -22,6 +22,8 @@ event_inherited();
setFocus(self.id); setFocus(self.id);
function setMenu(_menu, align = fa_left) { function setMenu(_menu, align = fa_left) {
with(_p_dialog) { if(on_top) continue; other.depth = min(depth - 1, other.depth); }
menu = _menu; menu = _menu;
dialog_x = x; dialog_x = x;
dialog_y = y; dialog_y = y;

View file

@ -179,7 +179,7 @@ function areaBox(_onModify, _unit = noone) : widget() constructor {
var cy = array_safe_get_fast(_data, 1); var cy = array_safe_get_fast(_data, 1);
var sw = array_safe_get_fast(_data, 2); var sw = array_safe_get_fast(_data, 2);
var sh = array_safe_get_fast(_data, 3); var sh = array_safe_get_fast(_data, 3);
var ss = onSurfaceSize(); var ss = unit.mode == VALUE_UNIT.reference? [ 1, 1 ] : onSurfaceSize();
onModify(0, ss[0] - (cx + sw)); onModify(0, ss[0] - (cx + sw));
onModify(1, cy - sh); onModify(1, cy - sh);
@ -192,7 +192,7 @@ function areaBox(_onModify, _unit = noone) : widget() constructor {
var t = array_safe_get_fast(_data, 1); var t = array_safe_get_fast(_data, 1);
var l = array_safe_get_fast(_data, 2); var l = array_safe_get_fast(_data, 2);
var b = array_safe_get_fast(_data, 3); var b = array_safe_get_fast(_data, 3);
var ss = onSurfaceSize(); var ss = unit.mode == VALUE_UNIT.reference? [ 1, 1 ] : onSurfaceSize();
onModify(0, l); onModify(0, l);
onModify(1, t); onModify(1, t);

View file

@ -3,6 +3,9 @@ function buttonAnchor(_onClick) : widget() constructor {
index = 4; index = 4;
click = true; click = true;
center = true;
context = noone;
static drawParam = function(params) { static drawParam = function(params) {
return draw(params.x, params.y, params.w, params.h, params.m); return draw(params.x, params.y, params.w, params.h, params.m);
} }
@ -21,6 +24,8 @@ function buttonAnchor(_onClick) : widget() constructor {
for( var i = -1; i <= 1; i++ ) for( var i = -1; i <= 1; i++ )
for( var j = -1; j <= 1; j++ ) { for( var j = -1; j <= 1; j++ ) {
if(!center && i == 0 && j == 0) continue;
var _bx = cx + j * spacing; var _bx = cx + j * spacing;
var _by = cy + i * spacing; var _by = cy + i * spacing;
var _in = (i + 1) * 3 + (j + 1); var _in = (i + 1) * 3 + (j + 1);

View file

@ -22,7 +22,7 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
mouse_cur_x = round((_mx - _x) / _s - 0.5); mouse_cur_x = round((_mx - _x) / _s - 0.5);
mouse_cur_y = round((_my - _y) / _s - 0.5); mouse_cur_y = round((_my - _y) / _s - 0.5);
if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT) && key_mod_press(CTRL)) { if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_presses(SHIFT, CTRL)) {
var aa = point_direction(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y); var aa = point_direction(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y);
var dd = point_distance(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y); var dd = point_distance(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y);
var _a = round(aa / 45) * 45; var _a = round(aa / 45) * 45;

View file

@ -37,14 +37,18 @@
function key_mod_press_any() { function key_mod_press_any() {
INLINE INLINE
return CTRL == KEYBOARD_STATUS.pressing || ALT == KEYBOARD_STATUS.pressing || SHIFT == KEYBOARD_STATUS.pressing; return CTRL == KEYBOARD_STATUS.pressing || ALT == KEYBOARD_STATUS.pressing || SHIFT == KEYBOARD_STATUS.pressing;
} }
function key_mod_press(key) { function key_mod_press(key) { INLINE return key == KEYBOARD_STATUS.pressing; }
function key_mod_presses(keys) {
INLINE INLINE
switch(argument_count) {
return key == KEYBOARD_STATUS.pressing; case 1 : return argument[0] == KEYBOARD_STATUS.pressing;
case 2 : return argument[0] == KEYBOARD_STATUS.pressing && argument[1] == KEYBOARD_STATUS.pressing;
case 3 : return argument[0] == KEYBOARD_STATUS.pressing && argument[1] == KEYBOARD_STATUS.pressing && argument[2] == KEYBOARD_STATUS.pressing;
}
return false;
} }
function key_mod_press_index(keyindex) { function key_mod_press_index(keyindex) {

View file

@ -36,10 +36,10 @@
globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION; globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION;
LATEST_VERSION = 11700; LATEST_VERSION = 11700;
VERSION = 11711; VERSION = 11712;
SAVE_VERSION = 11690; SAVE_VERSION = 11690;
VERSION_STRING = "1.17.1.1"; VERSION_STRING = "1.17.1.2";
BUILD_NUMBER = 11711; BUILD_NUMBER = 11712;
globalvar HOTKEYS, HOTKEY_CONTEXT; globalvar HOTKEYS, HOTKEY_CONTEXT;
HOTKEYS = ds_map_create(); HOTKEYS = ds_map_create();

View file

@ -899,7 +899,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
} }
#endregion #endregion
previewing = 1;
} #endregion } #endregion
static step = function() { #region static step = function() { #region

View file

@ -303,9 +303,9 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
load_group = noone; load_group = noone;
#endregion #endregion
static createNewInput = noone; /////============= NAME =============
static initTooltip = function() { #region static initTooltip = function() {
if(IS_CMD) return; if(IS_CMD) return;
var type_self = instanceof(self); var type_self = instanceof(self);
@ -326,111 +326,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
outputs[| i].name = _ots[i].name; outputs[| i].name = _ots[i].name;
outputs[| i].tooltip = _ots[i].tooltip; outputs[| i].tooltip = _ots[i].tooltip;
} }
} #endregion } run_in(1, initTooltip);
run_in(1, initTooltip);
static resetDefault = function() { #region
var folder = instanceof(self);
if(!ds_map_exists(global.PRESETS_MAP, folder)) return;
var pres = global.PRESETS_MAP[? folder];
for( var i = 0, n = array_length(pres); i < n; i++ ) {
var preset = pres[i];
if(preset.name != "_default") continue;
deserialize(preset.content, true, true);
applyDeserialize(true);
}
doUpdate();
} #endregion
if(!APPENDING && !LOADING)
run_in(1, method(self, resetDefault));
static getInputJunctionIndex = function(index) { #region
INLINE
if(input_display_list == -1 || !use_display_list)
return index;
var jun_list_arr = input_display_list[index];
if(is_array(jun_list_arr)) return noone;
if(is_struct(jun_list_arr)) return noone;
return jun_list_arr;
} #endregion
static getOutputJunctionIndex = function(index) { #region
if(output_display_list == -1)
return index;
return output_display_list[index];
} #endregion
static updateIO = function() { #region
for( var i = 0, n = ds_list_size(inputs); i < n; i++ )
inputs[| i].visible_in_list = false;
inputs_amount = (input_display_list == -1 || !use_display_list)? ds_list_size(inputs) : array_length(input_display_list);
inputs_index = [];
for( var i = 0; i < inputs_amount; i++ ) {
var _input = getInputJunctionIndex(i);
if(_input == noone) continue;
var _inp = inputs[| _input];
if(!is_struct(_inp) || !is_instanceof(_inp, NodeValue)) continue;
array_push(inputs_index, _input);
_inp.visible_in_list = true;
}
inputs_amount = array_length(inputs_index);
outputs_amount = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list);
outputs_index = array_create_ext(outputs_amount, function(index) { return getOutputJunctionIndex(index); });
} #endregion
static setDimension = function(_w = 128, _h = 128, _apply = true) { #region
INLINE
min_w = _w;
min_h = _h;
if(_apply) {
w = _w;
h = _h;
}
} #endregion
static setHeight = function() { #region
w = show_parameter? attributes.node_param_width : min_w;
if(!auto_height) return;
junction_draw_hei_y = show_parameter? 32 : 24;
junction_draw_pad_y = show_parameter? min_h : 32;
var _hi = junction_draw_pad_y + show_parameter * 4;
var _ho = junction_draw_pad_y + show_parameter * 4;
var _prev_surf = previewable && preview_draw &&
( is_surface(getGraphPreviewSurface()) ||
(preview_channel >= 0 && preview_channel < ds_list_size(outputs) && outputs[| preview_channel].type == VALUE_TYPE.surface)
);
for( var i = 0; i < ds_list_size(inputs); i++ ) {
var _inp = inputs[| i];
if(is_instanceof(_inp, NodeValue) && _inp.isVisible())
_hi += junction_draw_hei_y;
}
if(auto_input && dummy_input) _hi += junction_draw_hei_y;
for( var i = 0; i < ds_list_size(outputs); i++ )
if(outputs[| i].isVisible()) _ho += junction_draw_hei_y;
h = max(min_h, _prev_surf * 128, _hi, _ho, attributes.node_height);
fix_h = h;
} #endregion
static setDisplayName = function(_name) { #region static setDisplayName = function(_name) { #region
renamed = true; renamed = true;
@ -444,7 +340,18 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
return self; return self;
} #endregion } #endregion
#region //////////////////////////////// Dynamic IO //////////////////////////////// static getFullName = function() { #region
INLINE
return renamed? "[" + name + "] " + display_name : name;
} #endregion
static getDisplayName = function() { #region
INLINE
return renamed? display_name : name;
} #endregion
/////========== DYNAMIC IO ==========
auto_input = false; auto_input = false;
dyna_input_check_shift = 0; dyna_input_check_shift = 0;
static createNewInput = -1; static createNewInput = -1;
@ -518,8 +425,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
function onInputResize() { refreshDynamicInput(); triggerRender(); } function onInputResize() { refreshDynamicInput(); triggerRender(); }
#endregion //////////////////////////////// Dynamic IO ////////////////////////////////
static getOutput = function(junc = noone) { #region static getOutput = function(junc = noone) { #region
for( var i = 0; i < ds_list_size(outputs); i++ ) { for( var i = 0; i < ds_list_size(outputs); i++ ) {
if(!outputs[| i].visible) continue; if(!outputs[| i].visible) continue;
@ -545,47 +450,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
return noone; return noone;
} #endregion } #endregion
static getFullName = function() { #region /////========== INSPECTOR ===========
INLINE
return renamed? "[" + name + "] " + display_name : name;
} #endregion
static getDisplayName = function() { #region
INLINE
return renamed? display_name : name;
} #endregion
static addInput = function(junctionFrom, shift = input_fix_len) { #region
var targ = getInput(junctionFrom, shift);
if(targ == noone) return;
targ.setFrom(junctionFrom);
} #endregion
static isActiveDynamic = function(frame = CURRENT_FRAME) { #region
if(update_on_frame) return true;
if(!rendered) return true;
force_requeue = false;
for(var i = 0; i < ds_list_size(inputs); i++)
if(inputs[| i].isActiveDynamic(frame)) return true;
return false;
} #endregion
static isInLoop = function() { #region
return array_exists(global.loop_nodes, instanceof(group));
} #endregion
static move = function(_x, _y, _s) { #region
if(x == _x && y == _y) return;
x = _x;
y = _y;
if(!LOADING) PROJECT.modified = true;
} #endregion
#region //// inspector update
static onInspector1Update = noone; static onInspector1Update = noone;
static inspector1Update = function() { INLINE onInspector1Update(); } static inspector1Update = function() { INLINE onInspector1Update(); }
static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; } static hasInspector1Update = function() { INLINE return NODE_HAS_INSP1; }
@ -606,7 +472,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
onInspector2Update = _function; onInspector2Update = _function;
} }
} }
#endregion
/////============= STEP =============
static stepBegin = function() { #region static stepBegin = function() { #region
if(use_cache) cacheArrayCheck(); if(use_cache) cacheArrayCheck();
@ -666,6 +533,181 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static focusStep = function() {} static focusStep = function() {}
static inspectorStep = function() {} static inspectorStep = function() {}
/////========== JUNCTIONS ==========
static getInputJunctionIndex = function(index) { #region
INLINE
if(input_display_list == -1 || !use_display_list)
return index;
var jun_list_arr = input_display_list[index];
if(is_array(jun_list_arr)) return noone;
if(is_struct(jun_list_arr)) return noone;
return jun_list_arr;
} #endregion
static getOutputJunctionIndex = function(index) { #region
if(output_display_list == -1)
return index;
return output_display_list[index];
} #endregion
static updateIO = function() { #region
for( var i = 0, n = ds_list_size(inputs); i < n; i++ )
inputs[| i].visible_in_list = false;
inputs_amount = (input_display_list == -1 || !use_display_list)? ds_list_size(inputs) : array_length(input_display_list);
inputs_index = [];
for( var i = 0; i < inputs_amount; i++ ) {
var _input = getInputJunctionIndex(i);
if(_input == noone) continue;
var _inp = inputs[| _input];
if(!is_struct(_inp) || !is_instanceof(_inp, NodeValue)) continue;
array_push(inputs_index, _input);
_inp.visible_in_list = true;
}
inputs_amount = array_length(inputs_index);
outputs_amount = output_display_list == -1? ds_list_size(outputs) : array_length(output_display_list);
outputs_index = array_create_ext(outputs_amount, function(index) { return getOutputJunctionIndex(index); });
} #endregion
static setHeight = function() { #region
w = show_parameter? attributes.node_param_width : min_w;
if(!auto_height) return;
junction_draw_hei_y = show_parameter? 32 : 24;
junction_draw_pad_y = show_parameter? min_h : 32;
var _hi = junction_draw_pad_y + show_parameter * 4;
var _ho = junction_draw_pad_y + show_parameter * 4;
var _prev_surf = previewable && preview_draw &&
( is_surface(getGraphPreviewSurface()) ||
(preview_channel >= 0 && preview_channel < ds_list_size(outputs) && outputs[| preview_channel].type == VALUE_TYPE.surface)
);
for( var i = 0; i < ds_list_size(inputs); i++ ) {
var _inp = inputs[| i];
if(is_instanceof(_inp, NodeValue) && _inp.isVisible())
_hi += junction_draw_hei_y;
}
if(auto_input && dummy_input) _hi += junction_draw_hei_y;
for( var i = 0; i < ds_list_size(outputs); i++ )
if(outputs[| i].isVisible()) _ho += junction_draw_hei_y;
h = max(min_h, _prev_surf * 128, _hi, _ho, attributes.node_height);
fix_h = h;
} #endregion
static getJunctionList = function() { #region ////getJunctionList
var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list);
inputDisplayList = [];
for(var i = 0; i < amo; i++) {
var ind = getInputJunctionIndex(i);
if(ind == noone) continue;
var jun = ds_list_get(inputs, ind, noone);
if(jun == noone || is_undefined(jun)) continue;
if(!jun.isVisible()) continue;
array_push(inputDisplayList, jun);
}
if(auto_input && dummy_input) array_push(inputDisplayList, dummy_input);
}#endregion
static onValidate = function() { #region
value_validation[VALIDATION.pass] = 0;
value_validation[VALIDATION.warning] = 0;
value_validation[VALIDATION.error] = 0;
for( var i = 0; i < ds_list_size(inputs); i++ ) {
var jun = inputs[| i];
if(jun.value_validation)
value_validation[jun.value_validation]++;
}
} #endregion
static getJunctionTos = function() { #region
var _vto = array_create(ds_list_size(outputs));
for (var j = 0, m = ds_list_size(outputs); j < m; j++)
_vto[j] = array_clone(outputs[| j].value_to);
return _vto;
} #endregion
static checkConnectGroup = function(_io) { #region
var _y = y;
var _n = noone;
for(var i = 0; i < ds_list_size(inputs); i++) {
var _in = inputs[| i];
if(_in.value_from == noone) continue;
if(_in.value_from.node.group == group) continue;
var _ind = string(_in.value_from);
_io.map[$ _ind] = _in.value_from;
if(struct_has(_io.inputs, _ind))
array_push(_io.inputs[$ _ind ], _in);
else
_io.inputs[$ _ind ] = [ _in ];
}
for(var i = 0; i < ds_list_size(outputs); i++) {
var _ou = outputs[| i];
for(var j = 0; j < array_length(_ou.value_to); j++) {
var _to = _ou.value_to[j];
if(_to.value_from != _ou) continue;
if(!_to.node.active) continue;
if(_to.node.group == group) continue;
var _ind = string(_ou);
_io.map[$ _ind] = _ou;
if(struct_has(_io.outputs, _ind))
array_push(_io.outputs[$ _ind ], _to);
else
_io.outputs[$ _ind ] = [ _to ];
}
}
} #endregion
/////============ INPUTS ============
static resetDefault = function() {
var folder = instanceof(self);
if(!ds_map_exists(global.PRESETS_MAP, folder)) return;
var pres = global.PRESETS_MAP[? folder];
for( var i = 0, n = array_length(pres); i < n; i++ ) {
var preset = pres[i];
if(preset.name != "_default") continue;
deserialize(preset.content, true, true);
applyDeserialize(true);
}
doUpdate();
} if(!APPENDING && !LOADING) run_in(1, method(self, resetDefault));
static addInput = function(junctionFrom, shift = input_fix_len) { #region
var targ = getInput(junctionFrom, shift);
if(targ == noone) return;
targ.setFrom(junctionFrom);
} #endregion
static getInputData = function(index, def = 0) { #region static getInputData = function(index, def = 0) { #region
INLINE INLINE
@ -691,6 +733,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
} }
} #endregion } #endregion
/////============ UPDATE ============
static forceUpdate = function() { #region static forceUpdate = function() { #region
input_hash = ""; input_hash = "";
doUpdate(); doUpdate();
@ -752,13 +796,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
LOG_BLOCK_END(); LOG_BLOCK_END();
} #endregion } #endregion
static cacheCheck = function() { #region
INLINE
if(cache_group) cache_group.enableNodeGroup();
if(group != noone) group.cacheCheck();
} #endregion
static valueUpdate = function(index) { #region static valueUpdate = function(index) { #region
onValueUpdate(index); onValueUpdate(index);
@ -782,6 +819,19 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static onValueUpdate = function(index = 0) {} static onValueUpdate = function(index = 0) {}
static onValueFromUpdate = function(index) {} static onValueFromUpdate = function(index) {}
/////============ RENDER ============
static isActiveDynamic = function(frame = CURRENT_FRAME) { #region
if(update_on_frame) return true;
if(!rendered) return true;
force_requeue = false;
for(var i = 0; i < ds_list_size(inputs); i++)
if(inputs[| i].isActiveDynamic(frame)) return true;
return false;
} #endregion
static triggerRender = function() { #region static triggerRender = function() { #region
LOG_BLOCK_START(); LOG_BLOCK_START();
LOG_IF(global.FLAG.render == 1, $"Trigger render for {self}"); LOG_IF(global.FLAG.render == 1, $"Trigger render for {self}");
@ -964,14 +1014,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
return nodes; return nodes;
} #endregion } #endregion
static isTerminal = function() { #region /////============= DRAW =============
for( var i = 0; i < ds_list_size(outputs); i++ ) {
var _to = outputs[| i].getJunctionTo();
if(array_length(_to)) return false;
}
return true;
} #endregion
static onInspect = function() {} static onInspect = function() {}
@ -1004,24 +1047,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
getJunctionList(); getJunctionList();
} run_in(1, function() { refreshNodeDisplay(); }); #endregion } run_in(1, function() { refreshNodeDisplay(); }); #endregion
static getJunctionList = function() { #region ////getJunctionList
var amo = input_display_list == -1? ds_list_size(inputs) : array_length(input_display_list);
inputDisplayList = [];
for(var i = 0; i < amo; i++) {
var ind = getInputJunctionIndex(i);
if(ind == noone) continue;
var jun = ds_list_get(inputs, ind, noone);
if(jun == noone || is_undefined(jun)) continue;
if(!jun.isVisible()) continue;
array_push(inputDisplayList, jun);
}
if(auto_input && dummy_input) array_push(inputDisplayList, dummy_input);
}#endregion
static preDraw = function(_x, _y, _s) { #region static preDraw = function(_x, _y, _s) { #region
var xx = x * _s + _x; var xx = x * _s + _x;
var yy = y * _s + _y; var yy = y * _s + _y;
@ -1702,87 +1727,42 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static drawAnimationTimeline = function(_w, _h, _s) {} static drawAnimationTimeline = function(_w, _h, _s) {}
/////============ PREVIEW ============
static getPreviewValues = function() { #region
if(preview_channel >= ds_list_size(outputs)) return noone;
switch(outputs[| preview_channel].type) {
case VALUE_TYPE.surface :
case VALUE_TYPE.dynaSurface :
break;
default :
return noone;
}
return outputs[| preview_channel].getValue();
} #endregion
static getPreviewBoundingBox = function() { #region
var _surf = getPreviewValues();
if(is_array(_surf))
_surf = array_safe_get_fast(_surf, preview_index, noone);
if(!is_surface(_surf)) return noone;
return BBOX().fromWH(preview_x, preview_y, surface_get_width_safe(_surf), surface_get_height_safe(_surf));
} #endregion
/////============= CACHE =============
static cacheCheck = function() { #region
INLINE
if(cache_group) cache_group.enableNodeGroup();
if(group != noone) group.cacheCheck();
} #endregion
static getAnimationCacheExist = function(frame) { return cacheExist(frame); } static getAnimationCacheExist = function(frame) { return cacheExist(frame); }
static enable = function() { INLINE active = true; timeline_item.active = true; }
static disable = function() { INLINE active = false; timeline_item.active = false; }
static onDestroy = function() {}
static destroy = function(_merge = false, record = true) { #region
if(!active) return;
disable();
ds_list_remove(group == noone? PROJECT.nodes : group.getNodeList(), self);
if(PANEL_GRAPH.node_hover == self) PANEL_GRAPH.node_hover = noone;
PANEL_GRAPH.nodes_selecting = [];
if(PANEL_INSPECTOR.inspecting == self) PANEL_INSPECTOR.inspecting = noone;
PANEL_PREVIEW.removeNodePreview(self);
for(var i = 0; i < ds_list_size(outputs); i++) {
var jun = outputs[| i];
for(var j = 0; j < array_length(jun.value_to); j++) {
var _vt = jun.value_to[j];
if(_vt.value_from == noone) break;
if(_vt.value_from.node != self) break;
_vt.removeFrom(false);
if(!_merge) continue;
for( var k = 0; k < ds_list_size(inputs); k++ ) {
if(inputs[| k].value_from == noone) continue;
if(_vt.setFrom(inputs[| k].value_from)) break;
}
}
jun.value_to = [];
}
for( var i = 0; i < ds_list_size(inputs); i++ )
inputs[| i].destroy();
for( var i = 0; i < ds_list_size(outputs); i++ )
outputs[| i].destroy();
onDestroy();
if(group) group.refreshNodes();
if(record) recordAction(ACTION_TYPE.node_delete, self);
RENDER_ALL_REORDER
} #endregion
static onRestore = function() {}
static restore = function() { #region
if(active) return;
enable();
ds_list_add(group == noone? PROJECT.nodes : group.getNodeList(), self);
onRestore();
if(group) group.refreshNodes();
RENDER_ALL_REORDER
} #endregion
static onValidate = function() { #region
value_validation[VALIDATION.pass] = 0;
value_validation[VALIDATION.warning] = 0;
value_validation[VALIDATION.error] = 0;
for( var i = 0; i < ds_list_size(inputs); i++ ) {
var jun = inputs[| i];
if(jun.value_validation)
value_validation[jun.value_validation]++;
}
} #endregion
static clearInputCache = function() { #region static clearInputCache = function() { #region
for( var i = 0; i < ds_list_size(inputs); i++ ) for( var i = 0; i < ds_list_size(inputs); i++ )
inputs[| i].cache_value[0] = false; inputs[| i].cache_value[0] = false;
@ -1886,45 +1866,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
} }
} #endregion } #endregion
static checkConnectGroup = function(_io) { #region /////============= TOOLS =============
var _y = y;
var _n = noone;
for(var i = 0; i < ds_list_size(inputs); i++) {
var _in = inputs[| i];
if(_in.value_from == noone) continue;
if(_in.value_from.node.group == group) continue;
var _ind = string(_in.value_from);
_io.map[$ _ind] = _in.value_from;
if(struct_has(_io.inputs, _ind))
array_push(_io.inputs[$ _ind ], _in);
else
_io.inputs[$ _ind ] = [ _in ];
}
for(var i = 0; i < ds_list_size(outputs); i++) {
var _ou = outputs[| i];
for(var j = 0; j < array_length(_ou.value_to); j++) {
var _to = _ou.value_to[j];
if(_to.value_from != _ou) continue;
if(!_to.node.active) continue;
if(_to.node.group == group) continue;
var _ind = string(_ou);
_io.map[$ _ind] = _ou;
if(struct_has(_io.outputs, _ind))
array_push(_io.outputs[$ _ind ], _to);
else
_io.outputs[$ _ind ] = [ _to ];
}
}
} #endregion
static isNotUsingTool = function() { return PANEL_PREVIEW.tool_current == noone; }
static isUsingTool = function(index = undefined, subtool = noone) { #region static isUsingTool = function(index = undefined, subtool = noone) { #region
if(tools == -1) if(tools == -1)
@ -1949,80 +1891,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
return _tool.selecting == subtool; return _tool.selecting == subtool;
} #endregion } #endregion
static clone = function(target = PANEL_GRAPH.getCurrentContext()) { #region static isNotUsingTool = function() { return PANEL_PREVIEW.tool_current == noone; }
CLONING = true;
var _type = instanceof(self);
var _node = nodeBuild(_type, x, y, target);
CLONING = false;
LOADING_VERSION = SAVE_VERSION;
if(!_node) return;
CLONING = true;
var _nid = _node.node_id;
_node.deserialize(serialize());
_node.postDeserialize();
_node.applyDeserialize();
_node.node_id = _nid;
PROJECT.nodeMap[? node_id] = self;
PROJECT.nodeMap[? _nid] = _node;
CLONING = false;
refreshTimeline();
onClone(_node, target);
return _node;
} #endregion
static onClone = function(_NewNode, target = PANEL_GRAPH.getCurrentContext()) {}
static droppable = function(dragObj) { #region
for( var i = 0; i < ds_list_size(inputs); i++ ) {
if(dragObj.type == inputs[| i].drop_key)
return true;
}
return false;
} #endregion
on_drop_file = noone;
static onDrop = function(dragObj) { #region
if(dragObj.type == "Asset" && is_callable(on_drop_file)) {
on_drop_file(dragObj.data.path);
return;
}
for( var i = 0; i < ds_list_size(inputs); i++ ) {
if(dragObj.type == inputs[| i].drop_key) {
inputs[| i].setValue(dragObj.data);
return;
}
}
} #endregion
static getPreviewValues = function() { #region
if(preview_channel >= ds_list_size(outputs)) return noone;
switch(outputs[| preview_channel].type) {
case VALUE_TYPE.surface :
case VALUE_TYPE.dynaSurface :
break;
default :
return noone;
}
return outputs[| preview_channel].getValue();
} #endregion
static getPreviewBoundingBox = function() { #region
var _surf = getPreviewValues();
if(is_array(_surf))
_surf = array_safe_get_fast(_surf, preview_index, noone);
if(!is_surface(_surf)) return noone;
return BBOX().fromWH(preview_x, preview_y, surface_get_width_safe(_surf), surface_get_height_safe(_surf));
} #endregion
static getTool = function() { return self; } static getTool = function() { return self; }
@ -2042,16 +1911,9 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static drawTools = function(_mx, _my, xx, yy, tool_size, hover, focus) { return 0; } static drawTools = function(_mx, _my, xx, yy, tool_size, hover, focus) { return 0; }
static getJunctionTos = function() { #region /////=========== SERIALIZE ===========
var _vto = array_create(ds_list_size(outputs));
for (var j = 0, m = ds_list_size(outputs); j < m; j++)
_vto[j] = array_clone(outputs[| j].value_to);
return _vto;
} #endregion
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static serialize = function(scale = false, preset = false) { #region
static serialize = function(scale = false, preset = false) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SERIALIZE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if(!active) return; if(!active) return;
var _map = {}; var _map = {};
@ -2114,7 +1976,9 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static doSerialize = function(_map) {} static doSerialize = function(_map) {}
static processSerialize = function(_map) {} static processSerialize = function(_map) {}
static deserialize = function(_map, scale = false, preset = false) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DESERIALIZE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /////========== DESERIALIZE ==========
static deserialize = function(_map, scale = false, preset = false) { #region
load_map = _map; load_map = _map;
load_scale = scale; load_scale = scale;
renamed = struct_try_get(load_map, "renamed", false); renamed = struct_try_get(load_map, "renamed", false);
@ -2124,7 +1988,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
else node_id = load_map.id; else node_id = load_map.id;
PROJECT.nodeMap[? node_id] = self; PROJECT.nodeMap[? node_id] = self;
//print($"Adding node {node_id} to {PROJECT.path} [{ds_map_size(PROJECT.nodeMap)}]");
if(struct_has(load_map, "name")) if(struct_has(load_map, "name"))
setDisplayName(load_map.name); setDisplayName(load_map.name);
@ -2145,7 +2008,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
} }
if(struct_has(load_map, "attri")) if(struct_has(load_map, "attri"))
attributeDeserialize(load_map.attri); attributeDeserialize(CLONING? variable_clone(load_map.attri) : load_map.attri);
if(struct_has(load_map, "buffer")) { if(struct_has(load_map, "buffer")) {
var _bufferKey = struct_key(bufferStore); var _bufferKey = struct_key(bufferStore);
@ -2178,12 +2041,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
var _input_fix_len = load_map.input_fix_len; var _input_fix_len = load_map.input_fix_len;
var _data_length = load_map.data_length; var _data_length = load_map.data_length;
//print($"Balancing IO: {input_fix_len} => {load_map.input_fix_len} : {data_length} => {load_map.data_length}");
//print($"IO size before: {array_length(load_map.inputs)}");
//for( var i = 0, n = array_length(load_map.inputs); i < n; i++ )
// print($"{i}: {load_map.inputs[i].name}");
var _dynamic_inputs = (array_length(load_map.inputs) - _input_fix_len) / _data_length; var _dynamic_inputs = (array_length(load_map.inputs) - _input_fix_len) / _data_length;
if(frac(_dynamic_inputs) != 0) { if(frac(_dynamic_inputs) != 0) {
noti_warning("LOAD: Uneven dynamic input."); noti_warning("LOAD: Uneven dynamic input.");
@ -2207,9 +2064,6 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
repeat(_pad_fix) repeat(_pad_fix)
array_insert(load_map.inputs, _input_fix_len, noone); array_insert(load_map.inputs, _input_fix_len, noone);
//print($"IO size after: {array_length(load_map.inputs)}");
//for( var i = 0, n = array_length(load_map.inputs); i < n; i++ )
// print($"{i}: {load_map.inputs[i] == noone? "noone" : load_map.inputs[i].name}");
} #endregion } #endregion
static inputGenerate = function() { #region //Generate input for dynamic input nodes static inputGenerate = function() { #region //Generate input for dynamic input nodes
@ -2217,15 +2071,11 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
return; return;
var _dynamic_inputs = (array_length(load_map.inputs) - input_fix_len) / data_length; var _dynamic_inputs = (array_length(load_map.inputs) - input_fix_len) / data_length;
//print($"Node {name} create {_dynamic_inputs} inputs for data length {data_length}");
repeat(_dynamic_inputs) repeat(_dynamic_inputs)
createNewInput(); createNewInput();
} #endregion } #endregion
static attributeDeserialize = function(attr) { #region static attributeDeserialize = function(attr) { #region
if(struct_has(attributes, "use_project_dimension") && !struct_has(attr, "use_project_dimension"))
attributes.use_project_dimension = false;
struct_append(attributes, attr); struct_append(attributes, attr);
} #endregion } #endregion
@ -2319,7 +2169,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static postLoad = function() {} static postLoad = function() {}
static resetAnimation = function() {} /////=========== CLEAN UP ===========
static cleanUp = function() { #region static cleanUp = function() { #region
for( var i = 0; i < ds_list_size(inputs); i++ ) for( var i = 0; i < ds_list_size(inputs); i++ )
@ -2341,7 +2191,164 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
static onCleanUp = function() {} static onCleanUp = function() {}
// helper function /////============ ACTION ============
static setDimension = function(_w = 128, _h = 128, _apply = true) { #region
INLINE
min_w = _w;
min_h = _h;
if(_apply) {
w = _w;
h = _h;
}
} #endregion
static move = function(_x, _y, _s) { #region
if(x == _x && y == _y) return;
x = _x;
y = _y;
if(!LOADING) PROJECT.modified = true;
} #endregion
static enable = function() { INLINE active = true; timeline_item.active = true; }
static disable = function() { INLINE active = false; timeline_item.active = false; }
static onDestroy = function() {}
static destroy = function(_merge = false, record = true) { #region
if(!active) return;
disable();
ds_list_remove(group == noone? PROJECT.nodes : group.getNodeList(), self);
if(PANEL_GRAPH.node_hover == self) PANEL_GRAPH.node_hover = noone;
PANEL_GRAPH.nodes_selecting = [];
if(PANEL_INSPECTOR.inspecting == self) PANEL_INSPECTOR.inspecting = noone;
PANEL_PREVIEW.removeNodePreview(self);
for(var i = 0; i < ds_list_size(outputs); i++) {
var jun = outputs[| i];
for(var j = 0; j < array_length(jun.value_to); j++) {
var _vt = jun.value_to[j];
if(_vt.value_from == noone) break;
if(_vt.value_from.node != self) break;
_vt.removeFrom(false);
if(!_merge) continue;
for( var k = 0; k < ds_list_size(inputs); k++ ) {
if(inputs[| k].value_from == noone) continue;
if(_vt.setFrom(inputs[| k].value_from)) break;
}
}
jun.value_to = [];
}
for( var i = 0; i < ds_list_size(inputs); i++ )
inputs[| i].destroy();
for( var i = 0; i < ds_list_size(outputs); i++ )
outputs[| i].destroy();
onDestroy();
if(group) group.refreshNodes();
if(record) recordAction(ACTION_TYPE.node_delete, self);
RENDER_ALL_REORDER
} #endregion
static onRestore = function() {}
static restore = function() { #region
if(active) return;
enable();
ds_list_add(group == noone? PROJECT.nodes : group.getNodeList(), self);
onRestore();
if(group) group.refreshNodes();
RENDER_ALL_REORDER
} #endregion
static droppable = function(dragObj) { #region
for( var i = 0; i < ds_list_size(inputs); i++ ) {
if(dragObj.type == inputs[| i].drop_key)
return true;
}
return false;
} #endregion
on_drop_file = noone;
static onDrop = function(dragObj) { #region
if(dragObj.type == "Asset" && is_callable(on_drop_file)) {
on_drop_file(dragObj.data.path);
return;
}
for( var i = 0; i < ds_list_size(inputs); i++ ) {
if(dragObj.type == inputs[| i].drop_key) {
inputs[| i].setValue(dragObj.data);
return;
}
}
} #endregion
static clone = function(target = PANEL_GRAPH.getCurrentContext()) { #region
CLONING = true;
var _type = instanceof(self);
var _node = nodeBuild(_type, x, y, target);
CLONING = false;
LOADING_VERSION = SAVE_VERSION;
if(!_node) return;
CLONING = true;
var _nid = _node.node_id;
_node.deserialize(serialize());
_node.postDeserialize();
_node.applyDeserialize();
_node.node_id = _nid;
PROJECT.nodeMap[? node_id] = self;
PROJECT.nodeMap[? _nid] = _node;
CLONING = false;
refreshTimeline();
onClone(_node, target);
return _node;
} #endregion
static onClone = function(_NewNode, target = PANEL_GRAPH.getCurrentContext()) {}
/////============= MISC =============
static isInLoop = function() { #region
return array_exists(global.loop_nodes, instanceof(group));
} #endregion
static isTerminal = function() { #region
for( var i = 0; i < ds_list_size(outputs); i++ ) {
var _to = outputs[| i].getJunctionTo();
if(array_length(_to)) return false;
}
return true;
} #endregion
static resetAnimation = function() {}
static attrDepth = function() { #region static attrDepth = function() { #region
if(struct_has(attributes, "color_depth")) { if(struct_has(attributes, "color_depth")) {
var form = attributes.color_depth; var form = attributes.color_depth;

View file

@ -1,7 +1,9 @@
function Node_Outline(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { function Node_Outline(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
name = "Outline"; name = "Outline";
attributes.filter = array_create(9, 1);
filtering_vl = false; filtering_vl = false;
filter_button = new buttonAnchor(function(ind) { filter_button = new buttonAnchor(function(ind) {
if(mouse_press(mb_left)) if(mouse_press(mb_left))
filtering_vl = !attributes.filter[ind]; filtering_vl = !attributes.filter[ind];
@ -70,8 +72,6 @@ function Node_Outline(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
attribute_surface_depth(); attribute_surface_depth();
attribute_oversample(); attribute_oversample();
attributes.filter = array_create(9, 1);
static step = function() { #region static step = function() { #region
var _wid = getInputData(1); var _wid = getInputData(1);
var _side = getInputData(5); var _side = getInputData(5);

View file

@ -1,88 +1,3 @@
function nodeValueUnit(_nodeValue) constructor { #region
self._nodeValue = _nodeValue;
mode = VALUE_UNIT.constant;
reference = noone;
triggerButton = button(function() {
mode = !mode;
_nodeValue.cache_value[0] = false;
_nodeValue.unitConvert(mode);
_nodeValue.node.doUpdate();
});
triggerButton.icon_blend = COLORS._main_icon_light;
triggerButton.icon = THEME.unit_ref;
triggerButton.tooltip = new tooltipSelector("Unit", ["Pixel", "Fraction"]);
static setMode = function(type) { #region
if(type == "constant" && mode == VALUE_UNIT.constant) return;
if(type == "relative" && mode == VALUE_UNIT.reference) return;
mode = type == "constant"? VALUE_UNIT.constant : VALUE_UNIT.reference;
_nodeValue.cache_value[0] = false;
_nodeValue.unitConvert(mode);
_nodeValue.node.doUpdate();
} #endregion
static draw = function(_x, _y, _w, _h, _m) { #region
triggerButton.icon_index = mode;
triggerButton.tooltip.index = mode;
triggerButton.draw(_x, _y, _w, _h, _m, THEME.button_hide);
} #endregion
static invApply = function(value, index = 0) { #region
if(mode == VALUE_UNIT.constant)
return value;
if(reference == noone)
return value;
return convertUnit(value, VALUE_UNIT.reference, index);
} #endregion
static apply = function(value, index = 0) { #region
if(mode == VALUE_UNIT.constant) return value;
if(reference == noone) return value;
return convertUnit(value, VALUE_UNIT.constant, index);
} #endregion
static convertUnit = function(value, unitTo, index = 0) { #region
var disp = _nodeValue.display_type;
var base = reference(index);
var inv = unitTo == VALUE_UNIT.reference;
if(!is_array(base) && !is_array(value))
return inv? value / base : value * base;
if(!is_array(base) && is_array(value)) {
var _val = array_create(array_length(value));
for( var i = 0, n = array_length(value); i < n; i++ )
_val[i] = inv? value[i] / base : value[i] * base;
return _val;
}
if(is_array(base) && !is_array(value))
return value;
var _val = array_clone(value);
switch(disp) {
case VALUE_DISPLAY.padding :
case VALUE_DISPLAY.vector :
case VALUE_DISPLAY.vector_range :
for( var i = 0, n = array_length(value); i < n; i++ )
_val[i] = inv? value[i] / base[i % 2] : value[i] * base[i % 2];
return _val;
case VALUE_DISPLAY.area :
for( var i = 0; i < 4; i++ )
_val[i] = inv? value[i] / base[i % 2] : value[i] * base[i % 2];
return _val;
}
return value;
} #endregion
} #endregion
function nodeValue(_name, _node, _connect, _type, _value, _tooltip = "") { return new NodeValue(_name, _node, _connect, _type, _value, _tooltip); } function nodeValue(_name, _node, _connect, _type, _value, _tooltip = "") { return new NodeValue(_name, _node, _connect, _type, _value, _tooltip); }
function nodeValueMap(_name, _node, _junc = noone) { return new NodeValue(_name, _node, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone).setVisible(false, false).setMapped(_junc); } function nodeValueMap(_name, _node, _junc = noone) { return new NodeValue(_name, _node, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone).setVisible(false, false).setMapped(_junc); }
function nodeValueGradientRange(_name, _node, _junc = noone) { return new NodeValue(_name, _node, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 1, 0 ]).setDisplay(VALUE_DISPLAY.gradient_range).setVisible(false, false).setMapped(_junc); } function nodeValueGradientRange(_name, _node, _junc = noone) { return new NodeValue(_name, _node, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 1, 0 ]).setDisplay(VALUE_DISPLAY.gradient_range).setVisible(false, false).setMapped(_junc); }
@ -346,7 +261,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
static resetValue = function() { #region static resetValue = function() { #region
unit.mode = def_unit; unit.mode = def_unit;
setValue(unit.apply(def_val)); setValue(unit.apply(variable_clone(def_val)));
attributes.mapped = false; attributes.mapped = false;
is_modified = false; is_modified = false;
@ -1085,10 +1000,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
if(struct_has(nodeFrom.display_data, "onSurfaceSize")) { if(struct_has(nodeFrom.display_data, "onSurfaceSize")) {
var surf = nodeFrom.display_data.onSurfaceSize(); var surf = nodeFrom.display_data.onSurfaceSize();
var ww = surf[0];
var hh = surf[1];
var dispType = array_safe_get_fast(value, 5, AREA_MODE.area); var dispType = array_safe_get_fast(value, 5, AREA_MODE.area);
switch(dispType) { switch(dispType) {
@ -1096,6 +1007,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
break; break;
case AREA_MODE.padding : case AREA_MODE.padding :
var ww = unit.mode == VALUE_UNIT.reference? 1 : surf[0];
var hh = unit.mode == VALUE_UNIT.reference? 1 : surf[1];
var cx = (ww - value[0] + value[2]) / 2 var cx = (ww - value[0] + value[2]) / 2
var cy = (value[1] + hh - value[3]) / 2; var cy = (value[1] + hh - value[3]) / 2;
var sw = abs((ww - value[0]) - value[2]) / 2; var sw = abs((ww - value[0]) - value[2]) / 2;
@ -1448,13 +1362,13 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
} #endregion } #endregion
show_val = []; show_val = [];
static showValue = function() { #region static showValue = function() { #region ////showValue
INLINE INLINE
var val = 0; var val = 0;
if(value_from != noone || is_anim || expUse) if(value_from != noone || is_anim || expUse)
val = getValue(CURRENT_FRAME, false, 0, true, true); val = getValue(CURRENT_FRAME, false);
else if(sep_axis) { else if(sep_axis) {
show_val = array_verify(show_val, array_length(animators)); show_val = array_verify(show_val, array_length(animators));

View file

@ -432,3 +432,98 @@ function isGraphable(prop) { #region
return false; return false;
} #endregion } #endregion
function nodeValueUnit(_nodeValue) constructor { #region
self._nodeValue = _nodeValue;
mode = VALUE_UNIT.constant;
reference = noone;
triggerButton = button(function() {
mode = !mode;
_nodeValue.cache_value[0] = false;
_nodeValue.unitConvert(mode);
_nodeValue.node.doUpdate();
});
triggerButton.icon_blend = COLORS._main_icon_light;
triggerButton.icon = THEME.unit_ref;
triggerButton.tooltip = new tooltipSelector("Unit", ["Pixel", "Fraction"]);
static setMode = function(type) { #region
if(type == "constant" && mode == VALUE_UNIT.constant) return;
if(type == "relative" && mode == VALUE_UNIT.reference) return;
mode = type == "constant"? VALUE_UNIT.constant : VALUE_UNIT.reference;
_nodeValue.cache_value[0] = false;
_nodeValue.unitConvert(mode);
_nodeValue.node.doUpdate();
} #endregion
static draw = function(_x, _y, _w, _h, _m) { #region
triggerButton.icon_index = mode;
triggerButton.tooltip.index = mode;
triggerButton.draw(_x, _y, _w, _h, _m, THEME.button_hide);
} #endregion
static invApply = function(value, index = 0) { #region
if(mode == VALUE_UNIT.constant)
return value;
if(reference == noone)
return value;
return convertUnit(value, VALUE_UNIT.reference, index);
} #endregion
static apply = function(value, index = 0) { #region
if(mode == VALUE_UNIT.constant) return value;
if(reference == noone) return value;
return convertUnit(value, VALUE_UNIT.constant, index);
} #endregion
static convertUnit = function(value, unitTo, index = 0) { #region
var disp = _nodeValue.display_type;
var base = reference(index);
var inv = unitTo == VALUE_UNIT.reference;
if(!is_array(base)) {
if(inv) base = base == 0? 0 : 1 / base;
if(!is_array(value))
return value * base;
var _val = array_create(array_length(value));
for( var i = 0, n = array_length(value); i < n; i++ )
_val[i] = value[i] * base;
return _val;
} else if(is_array(value)) {
if(inv) {
base = [
base[0] == 0? 0 : 1 / base[0],
base[1] == 0? 0 : 1 / base[1],
];
}
switch(disp) {
case VALUE_DISPLAY.padding :
case VALUE_DISPLAY.vector :
case VALUE_DISPLAY.vector_range :
var _val = array_create(array_length(value));
for( var i = 0, n = array_length(value); i < n; i++ )
_val[i] = value[i] * base[i % 2];
return _val;
case VALUE_DISPLAY.area :
var _val = array_clone(value);
for( var i = 0; i < 4; i++ )
_val[i] = value[i] * base[i % 2];
return _val;
}
}
return value;
} #endregion
} #endregion

View file

@ -1217,10 +1217,12 @@ function Panel_Preview() : PanelContent() constructor {
mouse_on_preview = 0; mouse_on_preview = 0;
} }
var _dragging = key_mod_press(CTRL) && !key_mod_press(SHIFT) && !key_mod_press(ALT);
var overlayHover = tool_hovering == noone && !overlay_hovering; var overlayHover = tool_hovering == noone && !overlay_hovering;
overlayHover &= active && isHover; overlayHover &= active && isHover;
overlayHover &= point_in_rectangle(mx, my, (_node.tools != -1) * toolbar_width, toolbar_height, w, h - toolbar_height); overlayHover &= point_in_rectangle(mx, my, (_node.tools != -1) * toolbar_width, toolbar_height, w, h - toolbar_height);
overlayHover &= !key_mod_press(CTRL); overlayHover &= !_dragging;
var params = { w, h, toolbar_height }; var params = { w, h, toolbar_height };
var mouse_free = false; var mouse_free = false;

View file

@ -53,13 +53,23 @@ function preview_overlay_area_padding(interact, active, _x, _y, _s, _mx, _my, _s
else if(drag_type == 4) _b = value_snap(drag_sy - (_my - drag_my) / _s, _sny); else if(drag_type == 4) _b = value_snap(drag_sy - (_my - drag_my) / _s, _sny);
if(drag_type) { if(drag_type) {
var _val = array_clone(showValue()); var _svl = showValue();
if(drag_type == 1) _val[0] = _r; var _sval = array_clone(_svl);
else if(drag_type == 2) _val[1] = _t; if(unit.mode == VALUE_UNIT.reference) {
else if(drag_type == 3) _val[2] = _l; var _ref = unit.reference();
else if(drag_type == 4) _val[3] = _b; _sval[0] *= _ref[0];
_sval[1] *= _ref[1];
_sval[2] *= _ref[0];
_sval[3] *= _ref[1];
}
if(setValueInspector(_val)) UNDO_HOLDING = true; if(drag_type == 1) _sval[0] = _r;
else if(drag_type == 2) _sval[1] = _t;
else if(drag_type == 3) _sval[2] = _l;
else if(drag_type == 4) _sval[3] = _b;
if(setValueInspector(_sval))
UNDO_HOLDING = true;
if(mouse_release(mb_left)) { if(mouse_release(mb_left)) {
drag_type = 0; drag_type = 0;