diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 9d1b5d912..ed937bc0c 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -425,6 +425,7 @@ {"name":"s_node_path_l_system","order":10,"path":"sprites/s_node_path_l_system/s_node_path_l_system.yy",}, {"name":"s_node_noise_cell","order":10,"path":"sprites/s_node_noise_cell/s_node_noise_cell.yy",}, {"name":"s_node_atlas_set","order":1,"path":"sprites/s_node_atlas_set/s_node_atlas_set.yy",}, + {"name":"timeline_data","order":18,"path":"scripts/timeline_data/timeline_data.yy",}, {"name":"panel_preview_3d_setting","order":4,"path":"scripts/panel_preview_3d_setting/panel_preview_3d_setting.yy",}, {"name":"node_colorize","order":4,"path":"scripts/node_colorize/node_colorize.yy",}, {"name":"sh_fd_subtract_pressure_gradient_glsl","order":12,"path":"shaders/sh_fd_subtract_pressure_gradient_glsl/sh_fd_subtract_pressure_gradient_glsl.yy",}, @@ -846,6 +847,7 @@ {"name":"s_node_mirror","order":3,"path":"sprites/s_node_mirror/s_node_mirror.yy",}, {"name":"s_node_blur_simple","order":43,"path":"sprites/s_node_blur_simple/s_node_blur_simple.yy",}, {"name":"theme_definition","order":14,"path":"scripts/theme_definition/theme_definition.yy",}, + {"name":"project_data","order":17,"path":"scripts/project_data/project_data.yy",}, {"name":"node_VFX_spawner","order":1,"path":"scripts/node_VFX_spawner/node_VFX_spawner.yy",}, {"name":"_draw_defines","order":21,"path":"scripts/_draw_defines/_draw_defines.yy",}, {"name":"sh_color_replace","order":8,"path":"shaders/sh_color_replace/sh_color_replace.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index fac45f373..46dd7f004 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -627,7 +627,6 @@ {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_tool_side.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_toolbar_shadow.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_toolbar.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, - {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ui_label_bg.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ui_panel_active.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ui_panel_bg.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ui_panel_fg.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/UI",}, @@ -753,7 +752,7 @@ "isEcma": false, "LibraryEmitters": [], "MetaData": { - "IDEVersion": "2023.8.1.102", + "IDEVersion": "2023.8.2.108", }, "resources": [ {"id":{"name":"s_node_corner","path":"sprites/s_node_corner/s_node_corner.yy",},}, @@ -986,6 +985,7 @@ {"id":{"name":"s_node_path_l_system","path":"sprites/s_node_path_l_system/s_node_path_l_system.yy",},}, {"id":{"name":"s_node_noise_cell","path":"sprites/s_node_noise_cell/s_node_noise_cell.yy",},}, {"id":{"name":"s_node_atlas_set","path":"sprites/s_node_atlas_set/s_node_atlas_set.yy",},}, + {"id":{"name":"timeline_data","path":"scripts/timeline_data/timeline_data.yy",},}, {"id":{"name":"panel_preview_3d_setting","path":"scripts/panel_preview_3d_setting/panel_preview_3d_setting.yy",},}, {"id":{"name":"node_colorize","path":"scripts/node_colorize/node_colorize.yy",},}, {"id":{"name":"sh_fd_subtract_pressure_gradient_glsl","path":"shaders/sh_fd_subtract_pressure_gradient_glsl/sh_fd_subtract_pressure_gradient_glsl.yy",},}, @@ -1473,6 +1473,7 @@ {"id":{"name":"draw_enable_alphablend","path":"scripts/draw_enable_alphablend/draw_enable_alphablend.yy",},}, {"id":{"name":"s_node_blur_simple","path":"sprites/s_node_blur_simple/s_node_blur_simple.yy",},}, {"id":{"name":"theme_definition","path":"scripts/theme_definition/theme_definition.yy",},}, + {"id":{"name":"project_data","path":"scripts/project_data/project_data.yy",},}, {"id":{"name":"node_VFX_spawner","path":"scripts/node_VFX_spawner/node_VFX_spawner.yy",},}, {"id":{"name":"s_node_equation","path":"sprites/s_node_equation/s_node_equation.yy",},}, {"id":{"name":"_draw_defines","path":"scripts/_draw_defines/_draw_defines.yy",},}, diff --git a/datafiles/data/themes/default.zip b/datafiles/data/themes/default.zip index eb37a5009..8a6e340fa 100644 Binary files a/datafiles/data/themes/default.zip and b/datafiles/data/themes/default.zip differ diff --git a/scripts/append_function/append_function.gml b/scripts/append_function/append_function.gml index 8370855e5..58b5cc5bd 100644 --- a/scripts/append_function/append_function.gml +++ b/scripts/append_function/append_function.gml @@ -145,6 +145,11 @@ function __APPEND_MAP(_map, context = PANEL_GRAPH.getCurrentContext()) { refreshNodeMap(); + if(struct_has(_map, "timelines")) { + var _time = new timelineItemGroup().deserialize(_map.timelines); + array_append(PROJECT.timelines.contents, _time.contents); + } + return node_create; } diff --git a/scripts/draw_tooltip/draw_tooltip.gml b/scripts/draw_tooltip/draw_tooltip.gml index 3f81361a1..04fd850fe 100644 --- a/scripts/draw_tooltip/draw_tooltip.gml +++ b/scripts/draw_tooltip/draw_tooltip.gml @@ -61,6 +61,8 @@ function draw_tooltip_gradient(clr) { } function draw_tooltip_surface_array(surf) { + if(!is_array(surf) || array_empty(surf)) return; + if(is_instanceof(surf[0], SurfaceAtlas)) { draw_tooltip_atlas(surf); return; diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 0916cf93b..f2873aed3 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -15,88 +15,6 @@ ALWAYS_FULL = false; #endregion -#region project - function Project() constructor { - active = true; /// @is {bool} - - path = ""; /// @is {string} - version = SAVE_VERSION; /// @is {number} - seed = irandom_range(100000, 999999); /// @is {number} - - modified = false; /// @is {bool} - readonly = false; /// @is {bool} - - nodes = ds_list_create(); - nodeMap = ds_map_create(); - nodeNameMap = ds_map_create(); - nodeTopo = ds_list_create(); - - animator = new AnimationManager(); - - globalNode = new Node_Global(); - - previewGrid = { - show : false, - snap : false, - size : [ 16, 16 ], - opacity : 0.5, - color : COLORS.panel_preview_grid, - } - - graphGrid = { - show : true, - snap : true, - size : 32, - opacity : 0.05, - color : c_white, - } - - addons = {}; - - onion_skin = { - enabled: false, - range: [ -1, 1 ], - step: 1, - color: [ c_red, c_blue ], - alpha: 0.5, - on_top: true, - }; - - attributes = { - surface_dimension: [ 32, 32 ], - palette: [ c_black, c_white ] - } - - attributeEditor = [ - [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; return true; }) ], - [ "Palette", "palette", new buttonPalette(function(pal) { attributes.palette = pal; return true; }) ], - ] - - static cleanup = function() { - if(!ds_map_empty(nodeMap)) - array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { - var _node = nodeMap[? _key]; - _node.active = false; - _node.cleanUp(); - }); - - ds_list_destroy(nodes); - ds_map_destroy(nodeMap); - ds_map_destroy(nodeNameMap); - - gc_collect(); - } - } - - globalvar PROJECTS; /// @is {Project[]} - globalvar PROJECT; /// @is {Project} - - function __initProject() { - PROJECT = new Project(); - PROJECTS = [ PROJECT ]; - } -#endregion - #region main globalvar OS, DEBUG, THEME, COLOR_KEYS; OS = os_type; @@ -108,10 +26,10 @@ globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER; - VERSION = 11541; + VERSION = 11542; SAVE_VERSION = 11530; - VERSION_STRING = "1.15.4.1"; - BUILD_NUMBER = 11541; + VERSION_STRING = "1.15.4.2"; + BUILD_NUMBER = 11542; globalvar APPEND_MAP; APPEND_MAP = ds_map_create(); diff --git a/scripts/load_function/load_function.gml b/scripts/load_function/load_function.gml index e7583b2ab..011bf30cd 100644 --- a/scripts/load_function/load_function.gml +++ b/scripts/load_function/load_function.gml @@ -199,15 +199,6 @@ function __LOAD_PATH(path, readonly = false, safe_mode = false, override = false log_warning("LOAD, connect", exception_print(e)); } - //try { - // for(var i = 0; i < ds_list_size(create_list); i++) - // create_list[| i].doUpdate(); - //} catch(e) { - // log_warning("LOAD, update", exception_print(e)); - //} - - //Render(); - if(!ds_queue_empty(CONNECTION_CONFLICT)) { var pass = 0; @@ -215,8 +206,8 @@ function __LOAD_PATH(path, readonly = false, safe_mode = false, override = false while(++pass < 4 && !ds_queue_empty(CONNECTION_CONFLICT)) { var size = ds_queue_size(CONNECTION_CONFLICT); log_message("LOAD", $"[Connect] {size} Connection conflict(s) detected (pass: {pass})"); - repeat(size) - ds_queue_dequeue(CONNECTION_CONFLICT).connect(); + repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).connect(); + repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).postConnect(); Render(); } @@ -251,5 +242,8 @@ function __LOAD_PATH(path, readonly = false, safe_mode = false, override = false refreshNodeMap(); + if(struct_has(_load_content, "timelines")) + PROJECT.timelines.deserialize(_load_content.timelines); + return true; } \ No newline at end of file diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 715ad4262..a23d460eb 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -85,6 +85,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x draw_droppable = false; junction_draw_pad_y = 32; + + branch_drawing = false; #endregion #region ---- junctions ---- @@ -186,6 +188,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x #endregion #region ---- timeline ---- + timeline_item = new timelineItemNode(self); anim_priority = ds_map_size(PROJECT.nodeMap); anim_show = true; @@ -705,10 +708,21 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x static onPreDraw = function(_x, _y, _s, _iny, _outy) {} + static isHighlightingInGraph = function() { #region + var _high = struct_try_get(display_parameter, "highlight", 0); + var high = (_high == 1 && key_mod_press(ALT) || _high == 2); + + var _selc = active_draw_index == 0 || branch_drawing; + return !high || _selc; + } #endregion + static drawNodeBase = function(xx, yy, _s) { #region if(draw_graph_culled) return; if(!active) return; + var aa = 0.25 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; + draw_sprite_stretched_ext(bg_spr, 0, xx, yy, w * _s, h * _s, color, aa); } #endregion @@ -746,6 +760,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x draw_name = true; var aa = 0.25 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; + draw_sprite_stretched_ext(THEME.node_bg_name, 0, xx, yy, w * _s, ui(20), color, aa); var cc = COLORS._main_text; @@ -758,6 +774,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var ts = clamp(power(_s, 0.5), 0.5, 1); var aa = 0.5 + 0.5 * renderActive; + if(!isHighlightingInGraph()) aa *= 0.25; + draw_set_alpha(aa); if(icon && _s > 0.75) { @@ -1109,7 +1127,20 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x previewing = 0; } #endregion - static drawActive = function(_x, _y, _s, ind = 0) { active_draw_index = ind; } + static drawBranch = function() { #region + if(branch_drawing) return; + branch_drawing = true; + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) { + if(inputs[| i].value_from == noone) continue; + inputs[| i].value_from.node.drawBranch(); + } + } #endregion + + static drawActive = function(_x, _y, _s, ind = 0) { #region + active_draw_index = ind; + + if(PREF_MAP[? "connection_line_highlight_all"]) drawBranch(); + } #endregion static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) {} diff --git a/scripts/node_image_splice_sheet/node_image_splice_sheet.gml b/scripts/node_image_splice_sheet/node_image_splice_sheet.gml index cd33a2d98..53cc43ba1 100644 --- a/scripts/node_image_splice_sheet/node_image_splice_sheet.gml +++ b/scripts/node_image_splice_sheet/node_image_splice_sheet.gml @@ -30,7 +30,7 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Horizontal", "Vertical"]); inputs[| 10] = nodeValue("Auto fill", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, 0, "Automatically set amount based on sprite size.") - .setDisplay(VALUE_DISPLAY.button, { name: "Auto fill", onClick: function() { + .setDisplay(VALUE_DISPLAY.button, { name: "Auto fill", onClick: function() { #region var _sur = getInputData(0); if(!is_surface(_sur) || _sur == DEF_SURFACE) return; var ww = surface_get_width_safe(_sur); @@ -47,13 +47,11 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru var fill_w = floor((ww - _offs[0]) / sh_w); var fill_h = floor((hh - _offs[1]) / sh_h); - if(_orie == 0) - inputs[| 3].setValue([ fill_w, fill_h ]); - else - inputs[| 3].setValue([ fill_h, fill_w ]); + if(_orie == 0) inputs[| 3].setValue([ fill_w, fill_h ]); + else inputs[| 3].setValue([ fill_h, fill_w ]); - inspector1Update(); - } }); + doUpdate(); + } }); #endregion inputs[| 11] = nodeValue("Sync animation", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, 0) .setDisplay(VALUE_DISPLAY.button, { name: "Sync frames", onClick: function() { @@ -92,10 +90,14 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru curr_amo = [0, 0]; sprite_valid = []; + spliceSurf = noone; static getPreviewValues = function() { return getInputData(0); } - function getSpritePosition(index) { + static onValueFromUpdate = function() { _inSurf = noone; } + static onValueUpdate = function() { _inSurf = noone; } + + function getSpritePosition(index) { #region var _dim = curr_dim; var _col = curr_amo[0]; var _off = curr_off; @@ -114,9 +116,9 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru return [_x, _y]; else return [_y, _x]; - } + } #endregion - static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { + static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region var _inSurf = getInputData(0); if(!is_surface(_inSurf)) return; @@ -259,9 +261,9 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru } } #endregion - } + } #endregion - static step = function() { + static step = function() { #region var _out = getInputData(7); var _filt = getInputData(12); var _flty = getInputData(13); @@ -270,17 +272,13 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru inputs[| 8].setVisible(!_out); inputs[| 13].setVisible(_filt); inputs[| 14].setVisible(_filt && _flty); - } + } #endregion - static onInspector1Update = function() { - if(isInLoop()) Render(); - else doInspectorAction(); - } - - static doInspectorAction = function() { + static spliceSprite = function() { #region var _atl = []; var _inSurf = getInputData(0); - if(!is_surface(_inSurf)) return; + if(spliceSurf == _inSurf) return; + spliceSurf = _inSurf; var _outSurf = outputs[| 0].getValue(); var _out = getInputData(7); @@ -366,10 +364,10 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru buffer_delete(_buff); surface_free(_empS); - } + } #endregion - static update = function(frame = CURRENT_FRAME) { - if(isInLoop()) doInspectorAction(); + static update = function(frame = CURRENT_FRAME) { #region + spliceSprite(); var _out = getInputData(7); if(_out == 1) { @@ -385,5 +383,5 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru var ind = safe_mod(CURRENT_FRAME * _spd, array_length(surf_array)); outputs[| 0].setValue(array_safe_get(surf_array, ind)); } - } + } #endregion } \ No newline at end of file diff --git a/scripts/node_pb_draw/node_pb_draw.gml b/scripts/node_pb_draw/node_pb_draw.gml index 09a7cbcd5..3d4c0a046 100644 --- a/scripts/node_pb_draw/node_pb_draw.gml +++ b/scripts/node_pb_draw/node_pb_draw.gml @@ -13,6 +13,10 @@ function Node_PB_Draw(_x, _y, _group = noone) : Node_PB(_x, _y, _group) construc static getGraphPreviewSurface = function() { var _nbox = outputs[| 0].getValue(); if(_nbox == noone) return noone; + if(is_array(_nbox)) { + if(array_empty(_nbox)) return noone; + _nbox = _nbox[0]; + } return _nbox.content; } @@ -20,7 +24,7 @@ function Node_PB_Draw(_x, _y, _group = noone) : Node_PB(_x, _y, _group) construc #macro PB_DRAW_CREATE_MASK _nbox.mask = surface_verify(_nbox.mask, _nbox.w, _nbox.h); \ surface_set_shader(_nbox.mask, sh_pb_to_mask); \ - draw_surface_safe(_nbox.content, -_pbox.x, -_pbox.y); \ + draw_surface_safe(_nbox.content, 0, 0); \ surface_reset_shader(); #macro PB_DRAW_APPLY_MASK if(_mask) { \ diff --git a/scripts/node_pb_draw_diamond/node_pb_draw_diamond.gml b/scripts/node_pb_draw_diamond/node_pb_draw_diamond.gml index ec7cec9b1..8fa7fb15a 100644 --- a/scripts/node_pb_draw_diamond/node_pb_draw_diamond.gml +++ b/scripts/node_pb_draw_diamond/node_pb_draw_diamond.gml @@ -18,8 +18,8 @@ function Node_PB_Draw_Diamond(_x, _y, _group = noone) : Node_PB_Draw(_x, _y, _gr var x0 = 0; var y0 = 0; - var x1 = _pbox.w; - var y1 = _pbox.h; + var x1 = _pbox.w + !(_pbox.w % 2); + var y1 = _pbox.h + !(_pbox.h % 2); var xc = _pbox.w / 2; var yc = _pbox.h / 2; diff --git a/scripts/node_pb_fx/node_pb_fx.gml b/scripts/node_pb_fx/node_pb_fx.gml index 7603c3c0c..38b2bb311 100644 --- a/scripts/node_pb_fx/node_pb_fx.gml +++ b/scripts/node_pb_fx/node_pb_fx.gml @@ -14,15 +14,15 @@ function Node_PB_Fx(_x, _y, _group = noone) : Node_PB(_x, _y, _group) constructo \ var _pbox = new __pbBox(); \ \ - _pbox.w = surface_get_width_safe(_surf); \ - _pbox.h = surface_get_height_safe(_surf); \ + _pbox.w = surface_get_width_safe(_surf); \ + _pbox.h = surface_get_height_safe(_surf); \ \ - _pbox.layer_w = surface_get_width_safe(_surf); \ - _pbox.layer_h = surface_get_height_safe(_surf); \ + _pbox.layer_w = surface_get_width_safe(_surf); \ + _pbox.layer_h = surface_get_height_safe(_surf); \ \ _pbox.mask = surface_create(_pbox.w, _pbox.h); \ surface_set_shader(_pbox.mask, sh_pb_to_mask); \ - draw_surface_safe(_surf, 0, 0); \ + draw_surface_safe(_surf, 0, 0); \ surface_reset_shader(); \ \ return _pbox; \ diff --git a/scripts/node_pb_fx_brick/node_pb_fx_brick.gml b/scripts/node_pb_fx_brick/node_pb_fx_brick.gml index d593c6aa5..302f6a302 100644 --- a/scripts/node_pb_fx_brick/node_pb_fx_brick.gml +++ b/scripts/node_pb_fx_brick/node_pb_fx_brick.gml @@ -27,6 +27,7 @@ function Node_PB_Fx_Brick(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) c static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_hash/node_pb_fx_hash.gml b/scripts/node_pb_fx_hash/node_pb_fx_hash.gml index d7b34bc4e..da42eee8a 100644 --- a/scripts/node_pb_fx_hash/node_pb_fx_hash.gml +++ b/scripts/node_pb_fx_hash/node_pb_fx_hash.gml @@ -23,6 +23,7 @@ function Node_PB_Fx_Hash(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) co static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_highlight/node_pb_fx_highlight.gml b/scripts/node_pb_fx_highlight/node_pb_fx_highlight.gml index 888025188..af2b58235 100644 --- a/scripts/node_pb_fx_highlight/node_pb_fx_highlight.gml +++ b/scripts/node_pb_fx_highlight/node_pb_fx_highlight.gml @@ -82,6 +82,7 @@ function Node_PB_Fx_Highlight(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _grou static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_outline/node_pb_fx_outline.gml b/scripts/node_pb_fx_outline/node_pb_fx_outline.gml index 541b2e1f3..a88a50394 100644 --- a/scripts/node_pb_fx_outline/node_pb_fx_outline.gml +++ b/scripts/node_pb_fx_outline/node_pb_fx_outline.gml @@ -15,6 +15,7 @@ function Node_PB_Fx_Outline(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_radial/node_pb_fx_radial.gml b/scripts/node_pb_fx_radial/node_pb_fx_radial.gml index 80e6a3259..4d839012b 100644 --- a/scripts/node_pb_fx_radial/node_pb_fx_radial.gml +++ b/scripts/node_pb_fx_radial/node_pb_fx_radial.gml @@ -11,6 +11,7 @@ function Node_PB_Fx_Radial(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_shading/node_pb_fx_shading.gml b/scripts/node_pb_fx_shading/node_pb_fx_shading.gml index fc39caa09..5501e6f7f 100644 --- a/scripts/node_pb_fx_shading/node_pb_fx_shading.gml +++ b/scripts/node_pb_fx_shading/node_pb_fx_shading.gml @@ -13,6 +13,7 @@ function Node_PB_Fx_Shading(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_stack/node_pb_fx_stack.gml b/scripts/node_pb_fx_stack/node_pb_fx_stack.gml index f18f51627..6022b03ca 100644 --- a/scripts/node_pb_fx_stack/node_pb_fx_stack.gml +++ b/scripts/node_pb_fx_stack/node_pb_fx_stack.gml @@ -27,6 +27,7 @@ function Node_PB_Fx_Stack(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) c static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_pb_fx_strip/node_pb_fx_strip.gml b/scripts/node_pb_fx_strip/node_pb_fx_strip.gml index a25514760..7451810bf 100644 --- a/scripts/node_pb_fx_strip/node_pb_fx_strip.gml +++ b/scripts/node_pb_fx_strip/node_pb_fx_strip.gml @@ -17,6 +17,7 @@ function Node_PB_Fx_Strip(_x, _y, _group = noone) : Node_PB_Fx(_x, _y, _group) c static processData = function(_outSurf, _data, _output_index, _array_index) { var _pbox = _data[0]; if(_pbox == noone) return _pbox; + if(!is_surface(_pbox.content)) return _pbox; var _nbox = _pbox.clone(); diff --git a/scripts/node_text/node_text.gml b/scripts/node_text/node_text.gml index a94310fee..9c2b796a8 100644 --- a/scripts/node_text/node_text.gml +++ b/scripts/node_text/node_text.gml @@ -42,10 +42,12 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons inputs[| 14] = nodeValue("Path shift", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0); + inputs[| 15] = nodeValue("Scale to fit", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + input_display_list = [ ["Output", true], 9, 6, 10, ["Text", false], 0, 13, 14, 7, 8, - ["Font", false], 1, 2, 3, 11, 12, + ["Font", false], 1, 2, 15, 3, 11, 12, ["Rendering", false], 5, ]; @@ -85,6 +87,7 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons inputs[| 8].setVisible(_dimt == 0 || _use_path); inputs[| 9].setVisible(!_use_path); inputs[| 14].setVisible( _use_path); + inputs[| 15].setVisible(_dimt == 0 && !_use_path); } #endregion static processData = function(_outSurf, _data, _output_index, _array_index) { #region @@ -102,6 +105,7 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var _line = _data[12]; var _path = _data[13]; var _pthS = _data[14]; + var _scaF = _data[15]; generateFont(_font, _size, _aa); draw_set_font(font); @@ -137,6 +141,7 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons hh = __temp_hh; var _use_path = _path != noone && struct_has(_path, "getPointDistance"); + var _ss = 1; if(_use_path || _dim_type == 0) { _sw = _dim[0]; @@ -146,6 +151,9 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons _sh = hh; } + if(_dim_type == 0 && !_use_path && _scaF) + _ss = min(_sw / ww, _sh / hh); + _sw += _padd[PADDING.left] + _padd[PADDING.right]; _sh += _padd[PADDING.top] + _padd[PADDING.bottom]; _outSurf = surface_verify(_outSurf, _sw, _sh, attrDepth()); @@ -153,9 +161,9 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons var tx = 0, ty = _padd[PADDING.top], _ty = 0; if(_dim_type == 0) { switch(_vali) { - case 0 : ty = _padd[PADDING.top]; break; - case 1 : ty = (_sh - hh) / 2; break; - case 2 : ty = _sh - _padd[PADDING.bottom] - hh; break; + case 0 : ty = _padd[PADDING.top]; break; + case 1 : ty = (_sh - hh * _ss) / 2; break; + case 2 : ty = _sh - _padd[PADDING.bottom] - hh * _ss; break; } } @@ -205,21 +213,22 @@ function Node_Text(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) cons if(_dim_type == 0) switch(_hali) { - case 0 : tx = _padd[PADDING.left]; break; - case 1 : tx = (_sw - _line_width) / 2; break; - case 2 : tx = _sw - _padd[PADDING.right] - _line_width; break; + case 0 : tx = _padd[PADDING.left]; break; + case 1 : tx = (_sw - _line_width * _ss) / 2; break; + case 2 : tx = _sw - _padd[PADDING.right] - _line_width * _ss; break; } __temp_tx = tx; __temp_ty = ty; + __temp_ss = _ss; __temp_trck = _trck; string_foreach(_str_line, function(_chr, _ind) { - draw_text(__temp_tx, __temp_ty, _chr); - __temp_tx += string_width(_chr) + __temp_trck; + draw_text_transformed(__temp_tx, __temp_ty, _chr, __temp_ss, __temp_ss, 0); + __temp_tx += (string_width(_chr) + __temp_trck) * __temp_ss; }); - ty += line_get_height() + _line; + ty += (line_get_height() + _line) * _ss; } } surface_reset_shader(); diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 95efd55ec..28474f6ba 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -2048,10 +2048,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru ty = LINE_STYLE.dashed; var c0, c1; - var _high = high * PREF_MAP[? "connection_line_highlight"]; - var _selc = node.active_draw_index == 0 || value_from.node.active_draw_index == 0; + var _selc = node.active_draw_index == 0 || value_from.node.active_draw_index == 0 || node.branch_drawing; - if(!thicken && (_high == 1 && key_mod_press(ALT) || _high == 2)) { + if(!thicken && (high == 1 && key_mod_press(ALT) || high == 2)) { var _fade = PREF_MAP[? "connection_line_highlight_fade"]; var _colr = _selc? 1 : _fade; diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index 7d735d8f7..8dee93e9f 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -92,7 +92,12 @@ function Panel_Animation() : PanelContent() constructor { #endregion #region ---- nodes ---- - node_ordering = noone; + _node_ordering = noone; + node_ordering = noone; + node_ordering_mx = noone; + node_ordering_my = noone; + node_ordering_dx = noone; + node_ordering_dy = noone; node_name_type = 0; #endregion @@ -1030,7 +1035,7 @@ function Panel_Animation() : PanelContent() constructor { } else draw_sprite_ui_uniform(THEME.timeline_clock, 1, ui(22), ty - 1, 1, COLORS._main_icon); - var hov = pHOVER && point_in_rectangle(msx, msy, 0, ty - ui(8), w, ty + ui(8)); + var hov = node_ordering == noone && pHOVER && point_in_rectangle(msx, msy, 0, ty - ui(8), w, ty + ui(8)); if(hov) { value_hovering = animator.prop; if(mouse_click(mb_left, pFOCUS)) @@ -1046,13 +1051,97 @@ function Panel_Animation() : PanelContent() constructor { draw_set_alpha(1); } #endregion + function drawDopesheetLabelNode(_node, _x, _y, _ys, msx, msy, _drawAnimator = true) { #region + var _inContext = _node == PROJECT.globalNode || _node.group == PANEL_GRAPH.getCurrentContext(); + var aa = _inContext? 1 : 0.9; + + var lable_w = tool_width; + var lable_h = ui(20); + var hovering_priority = undefined; + + if(pHOVER && point_in_rectangle(msx, msy, _x + ui(20), _y - ui(10), _x + lable_w, _y + ui(10))) { + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, _x, _y - ui(10), lable_w, lable_h, COLORS.panel_animation_dope_bg_hover, aa); + if(mouse_press(mb_left, pFOCUS)) { + _node_ordering = _node; + node_ordering_mx = msx; + node_ordering_my = msy; + + node_ordering_dx = msx - _x; + node_ordering_dy = msy - _y; + } + } else + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, _x, _y - ui(10), lable_w, lable_h, COLORS.panel_animation_dope_bg, aa); + + if(_node == PANEL_INSPECTOR.getInspecting()) + draw_sprite_stretched_ext(THEME.ui_panel_fg, 1, _x, _y - ui(10), lable_w, lable_h, COLORS._main_accent, 1); + else + draw_sprite_stretched_ext(THEME.ui_panel_fg, 1, _x, _y - ui(10), lable_w, lable_h, COLORS.panel_animation_node_outline, 1); + + var tx = _x + tool_width - ui(10); + if(buttonInstant(THEME.button_hide, tx - ui(8), _y - ui(8), ui(16), ui(16), [msx, msy], pFOCUS, pHOVER, + __txtx("panel_animation_goto", "Go to node"), THEME.animate_node_go, 0, COLORS._main_icon) == 2) { + graphFocusNode(_node); + } + + if(pHOVER && point_in_rectangle(msx, msy, _x, _y - ui(10), _x + ui(20), _y + ui(10))) { + draw_sprite_ui_uniform(THEME.arrow, _node.anim_show? 3 : 0, _x + ui(10), _y, 1, COLORS._main_icon_light, 1); + if(mouse_press(mb_left, pFOCUS)) + _node.anim_show = !_node.anim_show; + } else + draw_sprite_ui_uniform(THEME.arrow, _node.anim_show? 3 : 0, _x + ui(10), _y, 1, COLORS._main_icon, 0.75); + + draw_set_font(f_p3); + var nodeName = $"[{_node.name}] "; + var tw = string_width(nodeName); + + draw_set_color(node_ordering == _node? COLORS._main_text_accent : COLORS._main_text); + var txx = _x + ui(20); + + if(node_name_type == 0 || node_name_type == 1 || _node.display_name == "") { + draw_set_alpha(0.4); + draw_text_add(txx, _y - ui(2), nodeName); + txx += tw; + } + + draw_set_font(f_p2); + if(node_name_type == 0 || node_name_type == 2) { + draw_set_alpha(0.9); + draw_text_add(txx, _y - ui(2), _node.display_name); + } + + draw_set_alpha(1); + + if(!_node.anim_show) { + if(pHOVER && msy > _ys) + hovering_priority = _node.anim_priority + 0.5; + return hovering_priority; + } + + if(!_drawAnimator) return hovering_priority; + + for( var j = 0; j < ds_list_size(_node.inputs); j++ ) { + var prop = _node.inputs[| j]; + if(!prop.is_anim) continue; + + if(prop.sep_axis) { + for( var i = 0, n = array_length(prop.animators); i < n; i++ ) + drawDopesheetLabelAnimator(_node, prop.animators[i], msx, msy); + } else + drawDopesheetLabelAnimator(_node, prop.animator, msx, msy); + } //end prop loop + + if(pHOVER && msy > _ys) + hovering_priority = _node.anim_priority + 0.5; + + return hovering_priority; + } #endregion + function drawDopesheetLabel() { #region surface_set_target(ds_name_surface); draw_clear_alpha(COLORS.panel_bg_clear, 0); var msx = mx - ui(8); var msy = my - ui(8); - var lable_w = tool_width; var _node = noone; var _node_y = 0; draw_set_text(f_p2, fa_left, fa_center); @@ -1067,91 +1156,33 @@ function Panel_Animation() : PanelContent() constructor { for( var i = 0; i < ds_list_size(anim_properties); i++ ) { _node = anim_properties[| i]; var _inContext = _node == PROJECT.globalNode || _node.group == PANEL_GRAPH.getCurrentContext(); - - var aa = _inContext? 1 : 0.9; var _node_y = _node.dopesheet_y; if(!show_node_outside_context && !_inContext) continue; + if(node_ordering == _node) continue; var _node_y_start = _node_y; _node_y += dope_sheet_node_padding; - if(pHOVER && point_in_rectangle(msx, msy, ui(20), _node_y - ui(10), lable_w, _node_y + ui(10))) { - draw_sprite_stretched_ext(THEME.ui_label_bg, 0, 0, _node_y - ui(10), lable_w, ui(20), COLORS.panel_animation_dope_bg_hover, aa); - if(mouse_press(mb_left, pFOCUS)) - node_ordering = _node; - } else - draw_sprite_stretched_ext(THEME.ui_label_bg, 0, 0, _node_y - ui(10), lable_w, ui(20), COLORS.panel_animation_dope_bg, aa); - - if(_node == PANEL_INSPECTOR.getInspecting()) - draw_sprite_stretched_ext(THEME.node_active, 0, 0, _node_y - ui(10), lable_w, ui(20), COLORS._main_accent, 1); - - var tx = tool_width - ui(10); - if(buttonInstant(THEME.button_hide, tx - ui(8), _node_y - ui(8), ui(16), ui(16), [msx, msy], pFOCUS, pHOVER, - __txtx("panel_animation_goto", "Go to node"), THEME.animate_node_go, 0, COLORS._main_icon) == 2) { - graphFocusNode(_node); - } - - if(pHOVER && point_in_rectangle(msx, msy, 0, _node_y - ui(10), ui(20), _node_y + ui(10))) { - draw_sprite_ui_uniform(THEME.arrow, _node.anim_show? 3 : 0, ui(10), _node_y, 1, COLORS._main_icon_light, 1); - if(mouse_press(mb_left, pFOCUS)) - _node.anim_show = !_node.anim_show; - } else - draw_sprite_ui_uniform(THEME.arrow, _node.anim_show? 3 : 0, ui(10), _node_y, 1, COLORS._main_icon, 0.75); - - draw_set_font(f_p3); - var nodeName = $"[{_node.anim_priority}] [{_node.name}] "; - var tw = string_width(nodeName); - - draw_set_color(node_ordering == _node? COLORS._main_text_accent : COLORS._main_text); - var txx = ui(20); - - if(node_name_type == 0 || node_name_type == 1 || _node.display_name == "") { - draw_set_alpha(0.4); - draw_text_add(txx, _node_y - ui(2), nodeName); - txx += tw; - } - - draw_set_font(f_p2); - if(node_name_type == 0 || node_name_type == 2) { - draw_set_alpha(0.9); - draw_text_add(txx, _node_y - ui(2), _node.display_name); - } - - draw_set_alpha(1); - - if(!_node.anim_show) { - if(pHOVER && msy > _node_y_start) - hovering_priority = _node.anim_priority + 0.5; - continue; - } - - var ty = 0; - - for( var j = 0; j < ds_list_size(_node.inputs); j++ ) { - var prop = _node.inputs[| j]; - if(!prop.is_anim) continue; - - if(prop.sep_axis) { - for( var i = 0, n = array_length(prop.animators); i < n; i++ ) { - drawDopesheetLabelAnimator(_node, prop.animators[i], msx, msy); - ty = prop.animators[i].dopesheet_y - 1; - } - } else { - drawDopesheetLabelAnimator(_node, prop.animator, msx, msy); - ty = prop.animator.dopesheet_y - 1; - } - } //end prop loop - - if(pHOVER && msy > _node_y_start) - hovering_priority = _node.anim_priority + 0.5; + var _hov = drawDopesheetLabelNode(_node, 0, _node_y, _node_y_start, msx, msy); + if(_hov != undefined) + hovering_priority = _hov; } //end node loop + if(_node_ordering != noone) { + if(point_distance(msx, msy, node_ordering_mx, node_ordering_my) > 4) { + node_ordering = _node_ordering; + _node_ordering = noone; + } + } + if(node_ordering != noone) { rearrange_priority(node_ordering, hovering_priority); - - if(mouse_release(mb_left)) - node_ordering = noone; + } + + if(mouse_release(mb_left)) { + _node_ordering = noone; + node_ordering = noone; } surface_reset_target(); @@ -1231,7 +1262,7 @@ function Panel_Animation() : PanelContent() constructor { key_y += dope_sheet_node_padding; - draw_sprite_stretched_ext(THEME.ui_label_bg, 0, 0, key_y - ui(10), bar_show_w, ui(20), COLORS.panel_animation_node_bg, 1); + draw_sprite_stretched_ext(THEME.ui_panel_bg, 0, 0, key_y - ui(10), bar_show_w, ui(20), COLORS.panel_animation_node_bg, 1); key_y += ui(22); dope_sheet_y_max += ui(28); @@ -1537,12 +1568,12 @@ function Panel_Animation() : PanelContent() constructor { } #endregion - if(keyframe_boxing) { + if(keyframe_boxing) { #region draw_sprite_stretched_points(THEME.ui_selection, 0, keyframe_box_sx, keyframe_box_sy, msx, msy); if(mouse_release(mb_left)) keyframe_boxing = false; - } + } #endregion #region draw keys for( var i = 0; i < ds_list_size(anim_properties); i++ ) { @@ -1723,6 +1754,8 @@ function Panel_Animation() : PanelContent() constructor { draw_surface_safe(dope_sheet_surface, bar_x, ui(8)); draw_sprite_stretched(THEME.ui_panel_bg_cover, 1, bar_x, ui(8), bar_w, dope_sheet_h); + + if(node_ordering != noone) drawDopesheetLabelNode(node_ordering, mx - node_ordering_dx, my - node_ordering_dy, -1, -1, -1, false); } #endregion function drawAnimationControl() { #region diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index b53064c81..1c275aab8 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -19,6 +19,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { avoid_label : true, preview_scale : 100, + highlight : false, } bg_color = c_black; @@ -577,6 +578,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { function drawNodes() { #region if(selection_block-- > 0) return; //print("==== DRAW NODES ===="); + display_parameter.highlight = (!ds_list_empty(nodes_select_list) || node_focus != noone) * PREF_MAP[? "connection_line_highlight"]; var gr_x = graph_x * graph_s; var gr_y = graph_y * graph_s; @@ -603,6 +605,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { if(pHOVER) for(var i = 0; i < ds_list_size(nodes_list); i++) { var _node = nodes_list[| i]; + _node.branch_drawing = false; if(_node.pointIn(gr_x, gr_y, mx, my, graph_s)) node_hovering = _node; } @@ -620,250 +623,253 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { #endregion printIf(log, "Hover time: " + string(current_time - t)); t = current_time; - if(mouse_on_graph && pHOVER) { - if(NODE_DROPPER_TARGET != noone && node_hovering) { - node_hovering.draw_droppable = true; - if(mouse_press(mb_left, NODE_DROPPER_TARGET_CAN)) { - NODE_DROPPER_TARGET.expression += node_hovering.internalName; - NODE_DROPPER_TARGET.expressionUpdate(); - } - } else if(mouse_press(mb_left, pFOCUS) && !key_mod_press(ALT)) { - if(key_mod_press(SHIFT)) { - if(ds_list_empty(nodes_select_list) && node_focus) - ds_list_add(nodes_select_list, node_focus); - if(node_focus != node_hovering) - ds_list_add(nodes_select_list, node_hovering); - } else { - var _prevFocus = node_focus; - if(node_hovering != noone || value_focus == noone) - node_focus = node_hovering; - - if(node_focus) { - if(instanceof(node_focus) == "Node_Frame") { - var fx0 = (node_focus.x + graph_x) * graph_s; - var fy0 = (node_focus.y + graph_y) * graph_s; - var fx1 = fx0 + node_focus.w * graph_s; - var fy1 = fy0 + node_focus.h * graph_s; - - ds_list_clear(nodes_select_list); - - if(!key_mod_press(CTRL)) - for(var i = 0; i < ds_list_size(nodes_list); i++) { //select content - var _node = nodes_list[| i]; - if(instanceof(_node) == "Node_Frame") continue; - var _x = (_node.x + graph_x) * graph_s; - var _y = (_node.y + graph_y) * graph_s; - var _w = _node.w * graph_s; - var _h = _node.h * graph_s; - - if(rectangle_inside_rectangle(fx0, fy0, fx1, fy1, _x, _y, _x + _w, _y + _h)) - ds_list_add(nodes_select_list, _node); - } - ds_list_add(nodes_select_list, node_focus); - } else if(DOUBLE_CLICK) { - PANEL_PREVIEW.setNodePreview(node_focus); - } else { - if(_prevFocus != node_focus) - bringNodeToFront(node_focus); - - var hover_selected = false; - for( var i = 0; i < ds_list_size(nodes_select_list); i++ ) { - if(nodes_select_list[| i] == node_focus) { - hover_selected = true; - break; - } - } - if(!hover_selected) - ds_list_clear(nodes_select_list); - } + #region selection + if(mouse_on_graph && pHOVER) { + if(NODE_DROPPER_TARGET != noone && node_hovering) { + node_hovering.draw_droppable = true; + if(mouse_press(mb_left, NODE_DROPPER_TARGET_CAN)) { + NODE_DROPPER_TARGET.expression += node_hovering.internalName; + NODE_DROPPER_TARGET.expressionUpdate(); + } + } else if(mouse_press(mb_left, pFOCUS)) { + if(key_mod_press(SHIFT)) { + if(ds_list_empty(nodes_select_list) && node_focus) + ds_list_add(nodes_select_list, node_focus); + if(node_focus != node_hovering) + ds_list_add(nodes_select_list, node_hovering); } else { - if(value_focus == noone) - ds_list_clear(nodes_select_list); + var _prevFocus = node_focus; + if(node_hovering != noone || value_focus == noone) + node_focus = node_hovering; + + if(node_focus) { + if(instanceof(node_focus) == "Node_Frame") { + var fx0 = (node_focus.x + graph_x) * graph_s; + var fy0 = (node_focus.y + graph_y) * graph_s; + var fx1 = fx0 + node_focus.w * graph_s; + var fy1 = fy0 + node_focus.h * graph_s; + + ds_list_clear(nodes_select_list); + + if(!key_mod_press(CTRL)) + for(var i = 0; i < ds_list_size(nodes_list); i++) { //select content + var _node = nodes_list[| i]; + if(instanceof(_node) == "Node_Frame") continue; + var _x = (_node.x + graph_x) * graph_s; + var _y = (_node.y + graph_y) * graph_s; + var _w = _node.w * graph_s; + var _h = _node.h * graph_s; + + if(rectangle_inside_rectangle(fx0, fy0, fx1, fy1, _x, _y, _x + _w, _y + _h)) + ds_list_add(nodes_select_list, _node); + } + ds_list_add(nodes_select_list, node_focus); + } else if(DOUBLE_CLICK) { + PANEL_PREVIEW.setNodePreview(node_focus); + } else { + if(_prevFocus != node_focus) + bringNodeToFront(node_focus); + + var hover_selected = false; + for( var i = 0; i < ds_list_size(nodes_select_list); i++ ) { + if(nodes_select_list[| i] == node_focus) { + hover_selected = true; + break; + } + } + if(!hover_selected) + ds_list_clear(nodes_select_list); + } + } else { + if(value_focus == noone) + ds_list_clear(nodes_select_list); - if(DOUBLE_CLICK && !PANEL_INSPECTOR.locked) - PANEL_INSPECTOR.inspecting = noone; + if(DOUBLE_CLICK && !PANEL_INSPECTOR.locked) + PANEL_INSPECTOR.inspecting = noone; + } } } - } - if(mouse_press(mb_right, pFOCUS)) { #region - node_hover = node_hovering; - if(node_hover) { - var menu = []; - array_push(menu, - menuItem(__txtx("panel_graph_send_to_preview", "Send to preview"), function() { - setCurrentPreview(node_hover); - })); - array_push(menu, - menuItem(__txtx("panel_graph_preview_window", "Send to preview window"), function() { - create_preview_window(node_hover); - }, noone, ["Graph", "Preview window"])); - array_push(menu, - menuItem(__txtx("panel_graph_inspector_panel", "Send to new inspector"), function() { - var pan = panelAdd("Panel_Inspector", true); - pan.destroy_on_click_out = false; - pan.content.setInspecting(node_hover); - pan.content.locked = true; - })); - - if(DEMO) { + if(mouse_press(mb_right, pFOCUS)) { #region + node_hover = node_hovering; + if(node_hover) { + var menu = []; array_push(menu, - menuItem(__txtx("panel_graph_send_to_export", "Send to export"), function() { - setCurrentExport(node_hover); - }, noone, ["Graph", "Export"])); - } + menuItem(__txtx("panel_graph_send_to_preview", "Send to preview"), function() { + setCurrentPreview(node_hover); + })); + array_push(menu, + menuItem(__txtx("panel_graph_preview_window", "Send to preview window"), function() { + create_preview_window(node_hover); + }, noone, ["Graph", "Preview window"])); + array_push(menu, + menuItem(__txtx("panel_graph_inspector_panel", "Send to new inspector"), function() { + var pan = panelAdd("Panel_Inspector", true); + pan.destroy_on_click_out = false; + pan.content.setInspecting(node_hover); + pan.content.locked = true; + })); + + if(DEMO) { + array_push(menu, + menuItem(__txtx("panel_graph_send_to_export", "Send to export"), function() { + setCurrentExport(node_hover); + }, noone, ["Graph", "Export"])); + } - array_push(menu, - menuItem(__txtx("panel_graph_toggle_preview", "Toggle node preview"), function() { - setTriggerPreview(); - }, noone, ["Graph", "Toggle preview"])); - array_push(menu, - menuItem(__txtx("panel_graph_toggle_render", "Toggle node render"), function() { - setTriggerRender(); - }, noone, ["Graph", "Toggle render"])); + array_push(menu, + menuItem(__txtx("panel_graph_toggle_preview", "Toggle node preview"), function() { + setTriggerPreview(); + }, noone, ["Graph", "Toggle preview"])); + array_push(menu, + menuItem(__txtx("panel_graph_toggle_render", "Toggle node render"), function() { + setTriggerRender(); + }, noone, ["Graph", "Toggle render"])); + + if(struct_has(node_hover, "nodes")) { + array_push(menu, -1); + + array_push(menu, + menuItem(__txtx("panel_graph_enter_group", "Open group"), function() { + PANEL_GRAPH.addContext(node_hover); + }, THEME.group)); + array_push(menu, + menuItem(__txtx("panel_graph_enter_group_new_tab", "Open group in new tab"), function() { + var graph = new Panel_Graph(project); + panel.setContent(graph, true); + + for( var i = 0; i < ds_list_size(node_context); i++ ) + graph.addContext(node_context[| i]); + graph.addContext(node_hover); + + setFocus(panel); + }, THEME.group)); + array_push(menu, + menuItem(__txt("Ungroup"), function() { + doUngroup(); + }, THEME.group, ["Graph", "Ungroup"])); + } + + if(node_hover.group != noone) { + array_push(menu, + menuItem(__txt("Set as group tool"), function() { + node_hover.setTool(!node_hover.isTool); + })); + } - if(struct_has(node_hover, "nodes")) { array_push(menu, -1); array_push(menu, - menuItem(__txtx("panel_graph_enter_group", "Open group"), function() { - PANEL_GRAPH.addContext(node_hover); - }, THEME.group)); + menuItem(__txtx("panel_graph_delete_and_merge_connection", "Delete and merge connection"), function() { + doDelete(true); + }, THEME.cross, ["Graph", "Delete (merge)"])); array_push(menu, - menuItem(__txtx("panel_graph_enter_group_new_tab", "Open group in new tab"), function() { - var graph = new Panel_Graph(project); - panel.setContent(graph, true); - - for( var i = 0; i < ds_list_size(node_context); i++ ) - graph.addContext(node_context[| i]); - graph.addContext(node_hover); - - setFocus(panel); - }, THEME.group)); + menuItem(__txtx("panel_graph_delete_and_cut_connection", "Delete and cut connection"), function() { + doDelete(false); + }, THEME.cross, ["Graph", "Delete (break)"])); array_push(menu, - menuItem(__txt("Ungroup"), function() { - doUngroup(); - }, THEME.group, ["Graph", "Ungroup"])); - } - - if(node_hover.group != noone) { + menuItem(__txt("Duplicate"), function() { + doDuplicate(); + }, THEME.duplicate, ["Graph", "Duplicate"])); array_push(menu, - menuItem(__txt("Set as group tool"), function() { - node_hover.setTool(!node_hover.isTool); - })); - } + menuItem(__txt("Copy"), function() { + doCopy(); + }, THEME.copy, ["Graph", "Copy"])); - array_push(menu, -1); - - array_push(menu, - menuItem(__txtx("panel_graph_delete_and_merge_connection", "Delete and merge connection"), function() { - doDelete(true); - }, THEME.cross, ["Graph", "Delete (merge)"])); - array_push(menu, - menuItem(__txtx("panel_graph_delete_and_cut_connection", "Delete and cut connection"), function() { - doDelete(false); - }, THEME.cross, ["Graph", "Delete (break)"])); - array_push(menu, - menuItem(__txt("Duplicate"), function() { - doDuplicate(); - }, THEME.duplicate, ["Graph", "Duplicate"])); - array_push(menu, - menuItem(__txt("Copy"), function() { - doCopy(); - }, THEME.copy, ["Graph", "Copy"])); - - array_push(menu, -1); - array_push(menu, menuItem(__txtx("panel_graph_add_transform", "Add transform"), doTransform, noone, ["Graph", "Transform node"])); - array_push(menu, menuItem(__txtx("panel_graph_canvas", "Canvas"), - function(_dat) { - return submenuCall(_dat, [ - menuItem(__txtx("panel_graph_copy_to_canvas", "Copy to canvas"), function() { - setCurrentCanvas(node_hover); - }, noone, ["Graph", "Canvas"]), - menuItem(__txtx("panel_graph_overlay_canvas", "Overlay canvas"), function() { - setCurrentCanvasBlend(node_hover); - }, noone, ["Graph", "Canvas blend"]) - ]); - }).setIsShelf() - ); - - if(ds_list_size(nodes_select_list) >= 2) { array_push(menu, -1); - array_push(menu, - menuItem(__txtx("panel_graph_align_nodes", "Align nodes"), function(_dat) { + array_push(menu, menuItem(__txtx("panel_graph_add_transform", "Add transform"), doTransform, noone, ["Graph", "Transform node"])); + array_push(menu, menuItem(__txtx("panel_graph_canvas", "Canvas"), + function(_dat) { return submenuCall(_dat, [ - menuItemGroup(__txtx("horizontal", "Horizontal"), [ - [ [THEME.inspector_surface_halign, 0], function() { node_halign(nodes_select_list, fa_left); } ], - [ [THEME.inspector_surface_halign, 1], function() { node_halign(nodes_select_list, fa_center); } ], - [ [THEME.inspector_surface_halign, 2], function() { node_halign(nodes_select_list, fa_right); } ], - ]), - menuItemGroup(__txtx("vertical", "Vertical"), [ - [ [THEME.inspector_surface_valign, 0], function() { node_valign(nodes_select_list, fa_top); } ], - [ [THEME.inspector_surface_valign, 1], function() { node_valign(nodes_select_list, fa_middle); } ], - [ [THEME.inspector_surface_valign, 2], function() { node_valign(nodes_select_list, fa_bottom); } ], - ]), - menuItemGroup(__txtx("distribute", "Distribute"), [ - [ [THEME.obj_distribute_h, 0], function() { node_hdistribute(nodes_select_list); } ], - [ [THEME.obj_distribute_v, 0], function() { node_vdistribute(nodes_select_list); } ], - ]), + menuItem(__txtx("panel_graph_copy_to_canvas", "Copy to canvas"), function() { + setCurrentCanvas(node_hover); + }, noone, ["Graph", "Canvas"]), + menuItem(__txtx("panel_graph_overlay_canvas", "Overlay canvas"), function() { + setCurrentCanvasBlend(node_hover); + }, noone, ["Graph", "Canvas blend"]) ]); - }).setIsShelf()); - array_push(menu, - menuItem(__txtx("panel_graph_blend_nodes", "Blend nodes"), function() { - doBlend(); - }, noone, ["Graph", "Blend"])); - array_push(menu, - menuItem(__txtx("panel_graph_compose_nodes", "Compose nodes"), function() { - doCompose(); - }, noone, ["Graph", "Compose"])); - array_push(menu, - menuItem(__txtx("panel_graph_array_from_nodes", "Array from nodes"), function() { - doArray(); - }, noone, ["Graph", "Array"])); + }).setIsShelf() + ); + + if(ds_list_size(nodes_select_list) >= 2) { + array_push(menu, -1); + array_push(menu, + menuItem(__txtx("panel_graph_align_nodes", "Align nodes"), function(_dat) { + return submenuCall(_dat, [ + menuItemGroup(__txtx("horizontal", "Horizontal"), [ + [ [THEME.inspector_surface_halign, 0], function() { node_halign(nodes_select_list, fa_left); } ], + [ [THEME.inspector_surface_halign, 1], function() { node_halign(nodes_select_list, fa_center); } ], + [ [THEME.inspector_surface_halign, 2], function() { node_halign(nodes_select_list, fa_right); } ], + ]), + menuItemGroup(__txtx("vertical", "Vertical"), [ + [ [THEME.inspector_surface_valign, 0], function() { node_valign(nodes_select_list, fa_top); } ], + [ [THEME.inspector_surface_valign, 1], function() { node_valign(nodes_select_list, fa_middle); } ], + [ [THEME.inspector_surface_valign, 2], function() { node_valign(nodes_select_list, fa_bottom); } ], + ]), + menuItemGroup(__txtx("distribute", "Distribute"), [ + [ [THEME.obj_distribute_h, 0], function() { node_hdistribute(nodes_select_list); } ], + [ [THEME.obj_distribute_v, 0], function() { node_vdistribute(nodes_select_list); } ], + ]), + ]); + }).setIsShelf()); + array_push(menu, + menuItem(__txtx("panel_graph_blend_nodes", "Blend nodes"), function() { + doBlend(); + }, noone, ["Graph", "Blend"])); + array_push(menu, + menuItem(__txtx("panel_graph_compose_nodes", "Compose nodes"), function() { + doCompose(); + }, noone, ["Graph", "Compose"])); + array_push(menu, + menuItem(__txtx("panel_graph_array_from_nodes", "Array from nodes"), function() { + doArray(); + }, noone, ["Graph", "Array"])); - array_push(menu, - menuItem(__txtx("panel_graph_group_nodes", "Group nodes"), function() { - doGroup(); - }, THEME.group, ["Graph", "Group"])); + array_push(menu, + menuItem(__txtx("panel_graph_group_nodes", "Group nodes"), function() { + doGroup(); + }, THEME.group, ["Graph", "Group"])); + array_push(menu, + menuItem(__txtx("panel_graph_frame_nodes", "Frame nodes"), function() { + doFrame(); + }, noone, ["Graph", "Frame"])); + } + + menuCall("graph_node_selected_multiple_menu",,, menu ); + } else { + var menu = []; + array_push(menu, - menuItem(__txtx("panel_graph_frame_nodes", "Frame nodes"), function() { - doFrame(); - }, noone, ["Graph", "Frame"])); + menuItem(__txt("Copy"), function() { + doCopy(); + }, THEME.copy, ["Graph", "Copy"]).setActive(node_focus != noone || ds_list_size(nodes_select_list)) + ); + + array_push(menu, + menuItem(__txt("Paste"), function() { + doPaste(); + }, THEME.paste, ["Graph", "Paste"]).setActive(clipboard_get_text() != "") + ); + + callAddDialog(); + menuCall("graph_node_selected_menu", o_dialog_add_node.dialog_x - ui(8), o_dialog_add_node.dialog_y + ui(4), menu, fa_right ); + setFocus(o_dialog_add_node.id, "Dialog"); } - - menuCall("graph_node_selected_multiple_menu",,, menu ); - } else { - var menu = []; - - array_push(menu, - menuItem(__txt("Copy"), function() { - doCopy(); - }, THEME.copy, ["Graph", "Copy"]).setActive(node_focus != noone || ds_list_size(nodes_select_list)) - ); - - array_push(menu, - menuItem(__txt("Paste"), function() { - doPaste(); - }, THEME.paste, ["Graph", "Paste"]).setActive(clipboard_get_text() != "") - ); - - callAddDialog(); - menuCall("graph_node_selected_menu", o_dialog_add_node.dialog_x - ui(8), o_dialog_add_node.dialog_y + ui(4), menu, fa_right ); - setFocus(o_dialog_add_node.id, "Dialog"); - } - } #endregion - } + } #endregion + } + #endregion printIf(log, "Node selection time: " + string(current_time - t)); t = current_time; - if(node_focus) - node_focus.drawActive(gr_x, gr_y, graph_s); - - for(var i = 0; i < ds_list_size(nodes_select_list); i++) { - var _node = nodes_select_list[| i]; - if(!_node) continue; - _node.drawActive(gr_x, gr_y, graph_s); - } + #region draw active + if(node_focus) node_focus.drawActive(gr_x, gr_y, graph_s); + + for(var i = 0; i < ds_list_size(nodes_select_list); i++) { + var _node = nodes_select_list[| i]; + if(!_node) continue; + _node.drawActive(gr_x, gr_y, graph_s); + } + #endregion printIf(log, "Draw active: " + string(current_time - t)); t = current_time; var aa = PREF_MAP[? "connection_line_aa"]; @@ -942,7 +948,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { if(mouse_press(mb_left)) node_dragging = noone; - if(node_dragging) { + if(node_dragging && !key_mod_press(ALT)) { node_focus = node_dragging; if(ds_list_size(nodes_select_list) == 0) { // move single node diff --git a/scripts/panel_graph_connection_settings/panel_graph_connection_settings.gml b/scripts/panel_graph_connection_settings/panel_graph_connection_settings.gml index 07936e5a9..9d657b5b8 100644 --- a/scripts/panel_graph_connection_settings/panel_graph_connection_settings.gml +++ b/scripts/panel_graph_connection_settings/panel_graph_connection_settings.gml @@ -46,6 +46,13 @@ function Panel_Graph_Connection_Setting() : Panel_Linear_Setting() constructor { __txtx("pref_connection_highlight_fade", "Fade connection"), function() { return PREF_MAP[? "connection_line_highlight_fade"] }, ], + [ + new checkBox(function() { + PREF_MAP[? "connection_line_highlight_all"] = !PREF_MAP[? "connection_line_highlight_all"]; + }), + __txtx("pref_connection_highlight_all", "Highlight all"), + function() { return PREF_MAP[? "connection_line_highlight_all"] }, + ], ]; setHeight(); diff --git a/scripts/preferences/preferences.gml b/scripts/preferences/preferences.gml index a42d2f8f2..5382d4ba3 100644 --- a/scripts/preferences/preferences.gml +++ b/scripts/preferences/preferences.gml @@ -29,7 +29,8 @@ PREF_MAP[? "connection_line_aa"] = 2; PREF_MAP[? "connection_line_transition"] = true; PREF_MAP[? "connection_line_highlight"] = 0; - PREF_MAP[? "connection_line_highlight_fade"] = 0.75; + PREF_MAP[? "connection_line_highlight_fade"] = 0.75; + PREF_MAP[? "connection_line_highlight_all"] = false; PREF_MAP[? "curve_connection_line"] = 1; PREF_MAP[? "default_surface_side"] = 32; diff --git a/scripts/project_data/project_data.gml b/scripts/project_data/project_data.gml new file mode 100644 index 000000000..8acbb1806 --- /dev/null +++ b/scripts/project_data/project_data.gml @@ -0,0 +1,84 @@ +#region global + globalvar PROJECTS, PROJECT; +#endregion + +#region project + function Project() constructor { + active = true; /// @is {bool} + + path = ""; /// @is {string} + version = SAVE_VERSION; /// @is {number} + seed = irandom_range(100000, 999999); /// @is {number} + + modified = false; /// @is {bool} + readonly = false; /// @is {bool} + + nodes = ds_list_create(); + nodeMap = ds_map_create(); + nodeNameMap = ds_map_create(); + nodeTopo = ds_list_create(); + + animator = new AnimationManager(); + + globalNode = new Node_Global(); + + previewGrid = { #region + show : false, + snap : false, + size : [ 16, 16 ], + opacity : 0.5, + color : COLORS.panel_preview_grid, + } #endregion + + graphGrid = { #region + show : true, + snap : true, + size : 32, + opacity : 0.05, + color : c_white, + } #endregion + + addons = {}; + + onion_skin = { #region + enabled: false, + range: [ -1, 1 ], + step: 1, + color: [ c_red, c_blue ], + alpha: 0.5, + on_top: true, + }; #endregion + + attributes = { #region + surface_dimension: [ 32, 32 ], + palette: [ c_black, c_white ] + } #endregion + + attributeEditor = [ #region + [ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; return true; }) ], + [ "Palette", "palette", new buttonPalette(function(pal) { attributes.palette = pal; return true; }) ], + ]; #endregion + + timelines = new timelineItemGroup(); + + static cleanup = function() { #region + if(!ds_map_empty(nodeMap)) + array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { + var _node = nodeMap[? _key]; + _node.active = false; + _node.cleanUp(); + }); + + ds_list_destroy(nodes); + ds_map_destroy(nodeMap); + ds_map_destroy(nodeNameMap); + + gc_collect(); + } #endregion + } + + function __initProject() { + PROJECT = new Project(); + PROJECTS = [ PROJECT ]; + } +#endregion \ No newline at end of file diff --git a/scripts/project_data/project_data.yy b/scripts/project_data/project_data.yy new file mode 100644 index 000000000..19df4abdb --- /dev/null +++ b/scripts/project_data/project_data.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "project_data", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "startup scripts", + "path": "folders/main/startup scripts.yy", + }, +} \ No newline at end of file diff --git a/scripts/save_function/save_function.gml b/scripts/save_function/save_function.gml index 13c908bf3..4254116e8 100644 --- a/scripts/save_function/save_function.gml +++ b/scripts/save_function/save_function.gml @@ -40,6 +40,8 @@ function save_serialize(project = PROJECT, _outMap = false) { _map.graphGrid = project.graphGrid; _map.attributes = project.attributes; + _map.timelines = project.timelines.serialize(); + var prev = PANEL_PREVIEW.getNodePreviewSurface(); if(!is_surface(prev)) _map.preview = ""; else _map.preview = surface_encode(surface_size_lim(prev, 128, 128)); diff --git a/scripts/timeline_data/timeline_data.gml b/scripts/timeline_data/timeline_data.gml new file mode 100644 index 000000000..a4487e601 --- /dev/null +++ b/scripts/timeline_data/timeline_data.gml @@ -0,0 +1,83 @@ +function timelineItem() constructor { + color = c_white; + parent = noone; + + static removeSelf = function() { + if(parent == noone) return; + array_remove(parent.contents, self); + + return self; + } + + static serialize = function() {} + + static deserialize = function(_map) { + switch(_map.type) { + case "Node" : return new timelineItemNode(noone).deserialize(_map); + case "Folder" : return new timelineItemGroup(noone).deserialize(_map); + } + + return self; + } +} + +function timelineItemNode(node) : timelineItem() constructor { + self.node = node; + + static serialize = function() { + var _map = {}; + + _map.type = "Node"; + _map.color = color; + _map.node_id = node.node_id; + + return _map; + } + + static deserialize = function(_map) { + color = _map.color; + var _node_id = _map.node_id; + + node = PROJECT.nodeMap[? _node_id]; + node.timeline_item = self; + + return self; + } +} + +function timelineItemGroup() : timelineItem() constructor { + contents = []; + + static addItem = function(_item) { + array_push(contents, _item); + _item.parent = self; + + return self; + } + + static serialize = function() { + var _map = {}; + + _map.type = "Folder"; + _map.color = color; + + var _content = array_create(array_length(contents)); + for( var i = 0, n = array_length(contents); i < n; i++ ) + _content[i] = contents[i].serialize(); + _map.contents = _content; + + return _map; + } + + static deserialize = function(_map) { + color = _map.color; + + contents = array_create(array_length(_map.contents)); + for( var i = 0, n = array_length(_map.contents); i < n; i++ ) { + contents[i] = new timelineItem().deserialize(_map.contents[i]); + contents[i].parent = self; + } + + return self; + } +} \ No newline at end of file diff --git a/scripts/timeline_data/timeline_data.yy b/scripts/timeline_data/timeline_data.yy new file mode 100644 index 000000000..75d77e978 --- /dev/null +++ b/scripts/timeline_data/timeline_data.yy @@ -0,0 +1,11 @@ +{ + "resourceType": "GMScript", + "resourceVersion": "1.0", + "name": "timeline_data", + "isCompatibility": false, + "isDnD": false, + "parent": { + "name": "startup scripts", + "path": "folders/main/startup scripts.yy", + }, +} \ No newline at end of file