diff --git a/datafiles/data/Theme.zip b/datafiles/data/Theme.zip index cb841f13b..8444451ce 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 86e4fe0cb..589e70670 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -38,7 +38,7 @@ LATEST_VERSION = 11700; VERSION = 11760; SAVE_VERSION = 11700; - VERSION_STRING = "1.17.6.001"; + VERSION_STRING = "1.17.6.002"; BUILD_NUMBER = 11760; globalvar HOTKEYS, HOTKEY_CONTEXT; diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index 1a90ee233..6c38313d3 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -33,7 +33,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor inputs[| 11] = nodeValue("Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1 ) .setDisplay(VALUE_DISPLAY.slider); - inputs[| 12] = nodeValue("Frames animation", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ); + inputs[| 12] = nodeValue("Frames animation", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true ); inputs[| 13] = nodeValue("Animation speed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1 ); @@ -128,10 +128,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } else if(point_in_rectangle(_msx, _msy, _sx, _sy, _sx + _ssw, _sy + _ssh)) { _del_a = 0; - if(mouse_press(mb_left, _focus)) { - if(_anim) PROJECT.animator.setFrame(i); - else preview_index = i; - } + if(mouse_press(mb_left, _focus)) + setFrame(i); } if(_del_a != noone) { @@ -161,7 +159,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _bx = _x1 + _aw / 2 - _bs / 2; var _by = _y + _h / 2 - _bs / 2; - if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, _m, _focus, _hover, "", THEME.add_16, 0, COLORS._main_value_positive) == 2) { + if(buttonInstant(noone, _bx, _by, _bs, _bs, _m, _focus, _hover, "", THEME.add_16, 0, [ COLORS._main_icon, COLORS._main_value_positive ]) == 2) { attributes.frames++; refreshFrames(); update(); @@ -387,6 +385,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor selection_tool_after = noone; #endregion + static setFrame = function(frame) { + var _anim = getInputData(12); + if(_anim) PROJECT.animator.setFrame(frame); + else preview_index = frame; + } + function setToolColor(color) { CURRENT_COLOR = color; } static drawTools = function(_mx, _my, xx, yy, tool_size, hover, focus) { #region @@ -1125,29 +1129,76 @@ function timelineItemNode_Canvas(node) : timelineItemNode(node) constructor { if(!is_instanceof(node, Node_Canvas)) return; if(!node.attributes.show_timeline) return; + } + + static drawDopesheetOver = function(_x, _y, _s, _msx, _msy, _hover, _focus) { + if(!is_instanceof(node, Node_Canvas)) return; + if(!node.attributes.show_timeline) return; + var _surfs = node.output_surface; var _surf, _rx, _ry; + var _rx0, _ry0; + var _h = h - 2; + + _ry = _h / 2 + _y; + _ry0 = _y; + + var _chv = _hover && _msy > _ry0 && _msy <= _ry0 + h; + var _hov = false; for (var i = 0, n = array_length(_surfs); i < n; i++) { _surf = _surfs[i]; if(!surface_exists(_surf)) continue; - _rx = _x + (i + 1) * _s; - _ry = h / 2 + _y; + _rx = _x + (i + 1) * _s; + _rx0 = _rx - _h / 2; var _sw = surface_get_width_safe(_surf); var _sh = surface_get_height_safe(_surf); - var _ss = h / max(_sw, _sh); + var _ss = _h / max(_sw, _sh); - draw_surface_ext(_surf, _rx - _sw * _ss / 2, _ry - _sh * _ss / 2, _ss, _ss, 0, c_white, .5); + draw_sprite_stretched_ext(THEME.menu_button_mask, 0, _rx0, _ry0, _h, _h, CDEF.main_dkblack); + + if(i == node.preview_index) { + draw_surface_ext(_surf, _rx - _sw * _ss / 2, _ry - _sh * _ss / 2, _ss, _ss, 0, c_white, 1); + draw_sprite_stretched_ext(THEME.menu_button_mask, 1, _rx0, _ry0, _h, _h, COLORS._main_accent); + + } else { + draw_surface_ext(_surf, _rx - _sw * _ss / 2, _ry - _sh * _ss / 2, _ss, _ss, 0, c_white, 0.1); + draw_sprite_stretched_ext(THEME.menu_button_mask, 1, _rx0, _ry0, _h, _h, COLORS._main_icon, 0.3); + } + + if(_hover && point_in_rectangle(_msx, _msy, _rx0, _ry0, _rx0 + _h, _ry0 + _h)) { + draw_sprite_stretched_add(THEME.menu_button_mask, 1, _rx0, _ry0, _h, _h, c_white, 0.3); + _hov = true; + + if(mouse_press(mb_left, _focus)) + node.setFrame(i); + } } - } - - static drawDopesheetOver = function(_x, _y, _s, _msx, _msy) { - if(!is_instanceof(node, Node_Canvas)) return; - if(!node.attributes.show_timeline) return; - drawDopesheetOutput(_x, _y, _s, _msx, _msy); + if(!_hov && _chv) { + var _fr = round((_msx - _x) / _s); + if(_fr < 1 || _fr > TOTAL_FRAMES) return _hov; + + _rx = _x + _fr * _s; + _rx0 = _rx - _h / 2; + + draw_sprite_stretched_ext(THEME.menu_button_mask, 0, _rx0, _ry0, _h, _h, CDEF.main_dkblack); + draw_sprite_stretched_ext(THEME.menu_button_mask, 1, _rx0, _ry0, _h, _h, COLORS._main_value_positive, 0.75); + + if(mouse_press(mb_left, _focus)) { + node.attributes.frames = _fr; + node.refreshFrames(); + node.update(); + + node.setFrame(_fr - 1); + } + + return true; + } + + return _hov; } static onSerialize = function(_map) { diff --git a/scripts/node_canvas_group/node_canvas_group.gml b/scripts/node_canvas_group/node_canvas_group.gml index 8978d27d7..f4c126161 100644 --- a/scripts/node_canvas_group/node_canvas_group.gml +++ b/scripts/node_canvas_group/node_canvas_group.gml @@ -2,6 +2,9 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con name = "Canvas Group"; color = COLORS.node_blend_canvas; + timeline_item_group = new timelineItemGroup_Canvas(self); + PROJECT.timelines.addItem(timeline_item_group); + modifiable = false; inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF ) @@ -84,7 +87,7 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con group_input_display_list = [ 0, ["Layers", false], layer_renderer, - ["Frames", false], frame_renderer, + ["Frames", true], frame_renderer, ["Inputs", false], ]; @@ -148,10 +151,18 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con node.modifiable = false; node.modify_parent = self; - if(is_instanceof(node, Node_Canvas)) array_push(canvases, node); - else if(is_instanceof(node, Node_Composite)) composite = node; - + if(is_instanceof(node, Node_Canvas)) { + array_push(canvases, node); + node.timeline_item.removeSelf(); + timeline_item_group.addItem(node.timeline_item); + + } else if(is_instanceof(node, Node_Composite)) { + composite = node; + composite.canvas_group = self; + } + refreshLayer(); + onLayerChanged(); } static layerAdd = function() { @@ -172,6 +183,7 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con _b += 32; var _canvas = nodeBuild("Node_Canvas", _l, _b); + _canvas.setDisplayName($"Layer {array_length(canvases)}"); _canvas.inputs[| 12].setValue(true); composite.dummy_input.setFrom(_canvas.outputs[| 0]); @@ -189,11 +201,36 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con if(!nod) return; nod.destroy(); + onLayerChanged(); + } + + static onLayerChanged = function() { + if(composite == noone) return; + + var imageAmo = composite.getInputAmount(); + var _canvas_tm = []; + var _grp_cont = timeline_item_group.contents; + + for(var i = 0; i < imageAmo; i++) { + var _ind = composite.input_fix_len + i * composite.data_length; + var _inp = composite.inputs[| _ind]; + var _junc = _inp.value_from? _inp.value_from.node : noone; + + if(_junc == noone) continue; + if(!struct_has(layers, _junc.node_id)) continue; + + var _jun_layer = layers[$ _junc.node_id]; + var _junc_canvas = _jun_layer.canvas; + + array_remove(_grp_cont, _junc_canvas.timeline_item); + array_insert(_grp_cont, 0, _junc_canvas.timeline_item); + } } if(NODE_NEW_MANUAL) { var _canvas = nodeBuild("Node_Canvas", x - 160, y); _canvas.inputs[| 12].setValue(true); + _canvas.setDisplayName($"Background"); var _compose = nodeBuild("Node_Composite", x, y); _compose.dummy_input.setFrom(_canvas.outputs[| 0]); @@ -237,6 +274,11 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con rightTools = canvas_sel.rightTools; drawTools = canvas_sel.drawTools; } + + if(timeline_item_group) { + timeline_item_group.name = getDisplayName(); + timeline_item_group.color = getColor(); + } } static update = function() { @@ -251,4 +293,21 @@ function Node_Canvas_Group(_x, _y, _group) : Node_Collection(_x, _y, _group) con } sortIO(); -} \ No newline at end of file +} + +function timelineItemGroup_Canvas(node = noone) : timelineItemGroup() constructor { + self.node = node; + + static onSerialize = function(_map) { + _map.node_id = is_struct(node)? node.node_id : -4; + } + + static onDeserialize = function(_map) { + var _node_id = _map.node_id; + + if(ds_map_exists(PROJECT.nodeMap, _node_id)) { + node = PROJECT.nodeMap[? _node_id]; + node.timeline_item_group = self; + } + } +} diff --git a/scripts/node_composite/node_composite.gml b/scripts/node_composite/node_composite.gml index ba7351428..e7954462d 100644 --- a/scripts/node_composite/node_composite.gml +++ b/scripts/node_composite/node_composite.gml @@ -34,6 +34,8 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) hold_select = true; layer_dragging = noone; layer_remove = -1; + + canvas_group = noone; canvas_draw = noone; renaming = noone; @@ -353,6 +355,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) } layer_dragging = noone; + if(canvas_group) canvas_group.onLayerChanged(); } layer_height = max(ui(16), _h); diff --git a/scripts/node_image_animated/node_image_animated.gml b/scripts/node_image_animated/node_image_animated.gml index f96aa864d..7ee891c67 100644 --- a/scripts/node_image_animated/node_image_animated.gml +++ b/scripts/node_image_animated/node_image_animated.gml @@ -280,7 +280,7 @@ function timelineItemNode_Image_Animated(node) : timelineItemNode(node) construc } } - static drawDopesheetOver = function(_x, _y, _s, _msx, _msy) { + static drawDopesheetOver = function(_x, _y, _s, _msx, _msy, _hover, _focus) { if(!is_instanceof(node, Node_Image_Animated)) return; if(!node.attributes.show_timeline) return; diff --git a/scripts/node_image_gif/node_image_gif.gml b/scripts/node_image_gif/node_image_gif.gml index 0bc6eeae8..cb505ef7a 100644 --- a/scripts/node_image_gif/node_image_gif.gml +++ b/scripts/node_image_gif/node_image_gif.gml @@ -258,7 +258,7 @@ function timelineItemNode_Image_gif(node) : timelineItemNode(node) constructor { } } - static drawDopesheetOver = function(_x, _y, _s, _msx, _msy) { + static drawDopesheetOver = function(_x, _y, _s, _msx, _msy, _hover, _focus) { if(!is_instanceof(node, Node_Image_gif)) return; if(!node.attributes.show_timeline) return; diff --git a/scripts/node_sequence_anim/node_sequence_anim.gml b/scripts/node_sequence_anim/node_sequence_anim.gml index 4f3f1cba9..787bda1a8 100644 --- a/scripts/node_sequence_anim/node_sequence_anim.gml +++ b/scripts/node_sequence_anim/node_sequence_anim.gml @@ -163,7 +163,7 @@ function timelineItemNode_Sequence_Anim(node) : timelineItemNode(node) construct } } - static drawDopesheetOver = function(_x, _y, _s, _msx, _msy) { + static drawDopesheetOver = function(_x, _y, _s, _msx, _msy, _hover, _focus) { if(!is_instanceof(node, Node_Sequence_Anim)) return; if(!node.attributes.show_timeline) return; diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index 7b11f6a3e..92e6a22fb 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -572,7 +572,6 @@ function Panel_Animation() : PanelContent() constructor { function getTimelineContent() { #region timeline_contents = []; - getTimelineContentFolder(PROJECT.timelines); } #endregion @@ -1430,7 +1429,8 @@ function Panel_Animation() : PanelContent() constructor { var _hov = pHOVER && (msy > 0 && msy < dope_sheet_h); var _foc = pFOCUS; - var _res = _item.item.drawLabel(_item, _itx, _ity, _itw, msx, msy, _hov, _foc, item_dragging, hovering_folder, node_name_type, alpha); + var pd = ui(4); + var _res = _item.item.drawLabel(_item, _itx + pd, _ity, _itw - pd * 2, msx, msy, _hov, _foc, item_dragging, hovering_folder, node_name_type, alpha); if(_res == 1) { if(mouse_press(mb_left, _foc)) { @@ -2027,14 +2027,16 @@ function Panel_Animation() : PanelContent() constructor { var cf = string(CURRENT_FRAME + 1); var tx = string_width(cf) + ui(4); - draw_rectangle(bar_line_x - tx / 2, PANEL_PAD, bar_line_x + tx / 2, hh, false); + draw_sprite_stretched_ext(THEME.menu_button_mask, 0, bar_line_x - tx / 2, 0, tx, hh + PANEL_PAD, cc, 1); draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text_on_accent); draw_text_add(bar_line_x, PANEL_PAD, cf); for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { var _cont = timeline_contents[i]; - _cont.item.drawDopesheetOver(timeline_shift, _cont.y, timeline_scale, msx, msy); + var _hov = _cont.item.drawDopesheetOver(timeline_shift, _cont.y, timeline_scale, msx, msy, pHOVER, pFOCUS); + if(is_undefined(_hov)) continue; + if(_hov) keyframe_boxable = false; } #endregion @@ -2119,7 +2121,7 @@ function Panel_Animation() : PanelContent() constructor { _drawDopesheetLabel(); - if(mouse_press(mb_right, pFOCUS)) { #region context menu + if(keyframe_boxable && mouse_press(mb_right, pFOCUS)) { #region context menu if(point_in_rectangle(mx, my, bar_x, ui(8), bar_x + dope_sheet_w, ui(8) + dope_sheet_h)) { if(array_empty(keyframe_selecting)) menuCall("animation_keyframe_empty_menu",,, keyframe_menu_empty); diff --git a/scripts/timeline_data/timeline_data.gml b/scripts/timeline_data/timeline_data.gml index 3f74e7cba..adae5ebc2 100644 --- a/scripts/timeline_data/timeline_data.gml +++ b/scripts/timeline_data/timeline_data.gml @@ -14,7 +14,7 @@ function timelineItem() constructor { static drawLabel = function(_x, _y, _w, _msx, _msy) {} static drawDopesheet = function(_x, _y, _s, _msx, _msy) {} - static drawDopesheetOver = function(_x, _y, _s, _msx, _msy) {} + static drawDopesheetOver = function(_x, _y, _s, _msx, _msy, _hover, _focus) {} static removeSelf = function() { if(parent == noone) return; @@ -23,14 +23,17 @@ function timelineItem() constructor { return self; } + static onSerialize = function(_map) {} static serialize = function() {} + static onDeserialize = function(_map) {} static deserialize = function(_map) { switch(_map.type) { case "Folder" : return new timelineItemGroup().deserialize(_map); case "Node" : return new timelineItemNode(noone).deserialize(_map); + case "timelineItemGroup_Canvas" : return new timelineItemGroup_Canvas().deserialize(_map); case "timelineItemNode_Canvas" : return new timelineItemNode_Canvas(noone).deserialize(_map); case "timelineItemNode_Image_Animated" : return new timelineItemNode_Image_Animated(noone).deserialize(_map); case "timelineItemNode_Sequence_Anim" : return new timelineItemNode_Sequence_Anim(noone).deserialize(_map); @@ -57,14 +60,16 @@ function timelineItemNode(node) : timelineItem() constructor { if(col == -1) for( var i = array_length(cxt) - 1; i >= 0; i-- ) { var _context = cxt[i]; - if(_context.item.getColor() == -1) continue; - col = _context.item.getColor(); + var _c = _context.item.getColor(); + if(_c == -1) continue; + + col = _c; break; } - if(col == -1) col = CDEF.main_grey; + if(col == -1) col = merge_color(CDEF.main_ltgrey, CDEF.main_white, 0.3); color_cur = col; - var cc = colorMultiply(col, COLORS.panel_animation_dope_bg); + var cc = colorMultiply(col, COLORS.panel_animation_dope_bg); if(hover && point_in_rectangle(_msx, _msy, _x + ui(20), _y, _x + _w, _y + lh - 1)) { cc = colorMultiply(col, COLORS.panel_animation_dope_bg_hover); @@ -72,16 +77,15 @@ function timelineItemNode(node) : timelineItem() constructor { } color_dsp = cc; - draw_sprite_stretched_ext(THEME.timeline_folder, 0, _x, _y, _w, lh, cc, alpha); - //draw_sprite_stretched_ext(THEME.timeline_node, 1, _x, _y, _w, lh, COLORS.panel_animation_node_outline, 1); - + draw_sprite_stretched_ext(THEME.menu_button_mask, 0, _x, _y, _w, lh, cc, alpha); + // draw_sprite_stretched_add(THEME.menu_button_mask, 1, _x, _y, _w, lh, c_white, 0.1); + var tx = lx + lw - ui(7); if(buttonInstant(THEME.button_hide, tx - ui(9), _y + ui(1), ui(18), ui(18), [ _msx, _msy ], focus, hover, __txtx("panel_animation_goto", "Go to node"), THEME.animate_node_go, 0, col == -1? CDEF.main_grey : col) == 2) graphFocusNode(node); - if(_sel) - draw_sprite_stretched_ext(THEME.timeline_node, 1, _x, _y + 1, _w, lh - 2, COLORS._main_accent, 1); + if(_sel) draw_sprite_stretched_ext(THEME.menu_button_mask, 1, _x, _y, _w, lh, COLORS._main_accent, 1); var aa = 0.75; if(hover && point_in_rectangle(_msx, _msy, lx, _y, lx + ui(20), _y + lh)) { @@ -111,7 +115,7 @@ function timelineItemNode(node) : timelineItem() constructor { return res; } - static drawDopesheetOutput = function(_x, _y, _s, _msx, _msy) { + static drawDopesheetOutput = function(_x, _y, _s, _msx, _msy) { return; var _surf = node.outputs[| 0].getValue(); if(!is_surface(_surf)) return; @@ -132,7 +136,6 @@ function timelineItemNode(node) : timelineItem() constructor { static setColor = function(color) { node.attributes.color = color; } static getColor = function() { return node.attributes.color; } - static onSerialize = function(_map) {} static serialize = function() { var _map = {}; @@ -144,11 +147,11 @@ function timelineItemNode(node) : timelineItem() constructor { return _map; } - static onDeserialize = function(_map) {} static deserialize = function(_map) { show = struct_try_get(_map, "show", true); var _node_id = _map.node_id; + if(_node_id == 0) { node = PROJECT.globalNode; node.timeline_item = self; @@ -158,12 +161,13 @@ function timelineItemNode(node) : timelineItem() constructor { } onDeserialize(_map); + return self; } } function timelineItemGroup() : timelineItem() constructor { - name = ""; + name = ""; renaming = false; tb_name = new textBox(TEXTBOX_INPUT.text, function(val) { name = val; renaming = false; }); contents = []; @@ -197,20 +201,21 @@ function timelineItemGroup() : timelineItem() constructor { if(col == -1) col = CDEF.main_grey; color_cur = col; - var bnd = hig? merge_color(c_white, COLORS.panel_animation_dope_bg, 0.8) : COLORS.panel_animation_dope_bg; + var bnd = hig? merge_color(c_white, COLORS.panel_animation_dope_bg, .9) : COLORS.panel_animation_dope_bg; var cc = colorMultiply(col, bnd); if(hover && point_in_rectangle(_msx, _msy, _x + ui(20), _y, _x + _w, _y + lh - 1)) { - bnd = hig? merge_color(c_white, COLORS.panel_animation_dope_bg_hover, 0.8) : COLORS.panel_animation_dope_bg_hover; + bnd = hig? merge_color(c_white, COLORS.panel_animation_dope_bg_hover, .9) : COLORS.panel_animation_dope_bg_hover; cc = colorMultiply(col, bnd); res = 1; } color_dsp = cc; - draw_sprite_stretched_ext(THEME.timeline_folder, 0, _x, _y, _w, lh, cc, alpha); + draw_sprite_stretched_ext(THEME.menu_button_mask, 0, _x, _y, _w, lh, cc, alpha); + // draw_sprite_stretched_add(THEME.menu_button_mask, 1, _x, _y, _w, lh, c_white, 0.1); if(fdHover == self) - draw_sprite_stretched_ext(THEME.timeline_folder, 1, _x, _y, _w, lh, col == -1? COLORS._main_accent : col, 1); + draw_sprite_stretched_ext(THEME.menu_button_mask, 1, _x, _y + 1, _w, lh - 2, col == -1? COLORS._main_accent : col, 1); var aa = 0.75; if(hover && point_in_rectangle(_msx, _msy, lx, _y, lx + ui(20), _y + lh)) { @@ -262,6 +267,7 @@ function timelineItemGroup() : timelineItem() constructor { for( var i = 0, n = array_length(contents); i < n; i++ ) _content[i] = contents[i].serialize(); _map.contents = _content; + onSerialize(_map); return _map; } @@ -276,6 +282,7 @@ function timelineItemGroup() : timelineItem() constructor { contents[i] = new timelineItem().deserialize(_map.contents[i]); contents[i].parent = self; } + onDeserialize(_map); return self; }