From af65d007b37f8343e386f674e0d82ea552e3869a Mon Sep 17 00:00:00 2001 From: Tanasart Date: Tue, 3 Sep 2024 16:49:51 +0700 Subject: [PATCH] undo --- scripts/event_recorder/event_recorder.gml | 133 ++++++------------ scripts/nodeValue_drawer/nodeValue_drawer.gml | 5 +- scripts/node_keyframe/node_keyframe.gml | 16 +-- scripts/node_path/node_path.gml | 6 +- scripts/node_path_3d/node_path_3d.gml | 6 +- scripts/node_path_smooth/node_path_smooth.gml | 4 +- scripts/node_value/node_value.gml | 4 +- scripts/panel_animation/panel_animation.gml | 6 +- scripts/panel_history/panel_history.gml | 5 +- scripts/panel_inspector/panel_inspector.gml | 18 +-- 10 files changed, 78 insertions(+), 125 deletions(-) diff --git a/scripts/event_recorder/event_recorder.gml b/scripts/event_recorder/event_recorder.gml index 3df2b531d..8ccc4c073 100644 --- a/scripts/event_recorder/event_recorder.gml +++ b/scripts/event_recorder/event_recorder.gml @@ -8,9 +8,9 @@ REDO_STACK = ds_stack_create(); enum ACTION_TYPE { var_modify, - list_modify, - list_insert, - list_delete, + array_modify, + array_insert, + array_delete, node_added, node_delete, @@ -51,29 +51,30 @@ function Action(_type, _object, _data, _trigger = 0) constructor { if(is_struct(obj)) { _n = variable_struct_get(obj, data[1]); variable_struct_set(obj, data[1], data[0]); + } else if(object_exists(obj)) { _n = variable_instance_get(obj, data[1]); variable_instance_set(obj, data[1], data[0]); } + data[0] = _n; break; - case ACTION_TYPE.list_insert : - if(!ds_exists(obj, ds_type_list)) return; - - ds_list_delete(obj, data[1]); + case ACTION_TYPE.array_insert : + if(!is_array(obj)) return; + array_delete(obj, data[1], 1); break; - case ACTION_TYPE.list_modify : - if(!ds_exists(obj, ds_type_list)) return; + case ACTION_TYPE.array_modify : + if(!is_array(obj)) return; _n = data[0]; - obj[| data[1]] = data[0]; + obj[data[1]] = data[0]; data[0] = _n; break; - case ACTION_TYPE.list_delete : - if(!ds_exists(obj, ds_type_list)) return; - ds_list_insert(obj, data[1], data[0]); + case ACTION_TYPE.array_delete : + if(!is_array(obj)) return; + array_insert(obj, data[1], data[0]); break; case ACTION_TYPE.node_added : @@ -85,7 +86,6 @@ function Action(_type, _object, _data, _trigger = 0) constructor { break; case ACTION_TYPE.junction_connect : - if(obj.is_dummy) { data[0].setFrom(noone); if(obj.dummy_undo != -1) obj.dummy_undo(data[0]); @@ -165,28 +165,30 @@ function Action(_type, _object, _data, _trigger = 0) constructor { if(is_struct(obj)) { _n = variable_struct_get(obj, data[1]); variable_struct_set(obj, data[1], data[0]); + } else if(object_exists(obj)) { _n = variable_instance_get(obj, data[1]); variable_instance_set(obj, data[1], data[0]); } + data[0] = _n; break; - case ACTION_TYPE.list_insert : - if(!ds_exists(obj, ds_type_list)) return; - ds_list_insert(obj, data[1], data[0]); + case ACTION_TYPE.array_insert : + if(!is_array(obj)) return; + array_insert(obj, data[1], data[0]); break; - case ACTION_TYPE.list_modify : - if(!ds_exists(obj, ds_type_list)) return; + case ACTION_TYPE.array_modify : + if(!is_array(obj)) return; _n = data[0]; - obj[| data[1]] = data[0]; + obj[data[1]] = data[0]; data[0] = _n; break; - case ACTION_TYPE.list_delete : - if(!ds_exists(obj, ds_type_list)) return; - ds_list_delete(obj, data[1]); + case ACTION_TYPE.array_delete : + if(!is_array(obj)) return; + array_delete(obj, data[1], 1); break; case ACTION_TYPE.node_added : @@ -250,75 +252,26 @@ function Action(_type, _object, _data, _trigger = 0) constructor { } static toString = function() { - var ss = ""; + switch(type) { - case ACTION_TYPE.var_modify : - if(array_length(data) > 2) - ss = $"modify {data[2]}"; - else - ss = $"modify {data[1]}"; - break; - - case ACTION_TYPE.list_insert : - if(array_length(data) > 2) - ss = data[2]; - else - ss = $"insert {data[1]} to list {obj}"; - break; - - case ACTION_TYPE.list_modify : - ss = $"modify {data[1]} of list {obj}"; - break; - - case ACTION_TYPE.list_delete : - ss = $"delete {data[1]} from list {obj}"; - break; - - case ACTION_TYPE.node_added : - ss = $"add {obj.name} node"; - break; - - case ACTION_TYPE.node_delete : - ss = $"deleted {obj.name} node"; - break; - - case ACTION_TYPE.junction_connect : - ss = $"connect {obj.name}"; - break; - - case ACTION_TYPE.junction_disconnect : - ss = $"disconnect {obj.name}"; - break; - - case ACTION_TYPE.group_added : - ss = $"add {obj.name} to group"; - break; - - case ACTION_TYPE.group_removed : - ss = $"remove {obj.name} from group"; - break; - - case ACTION_TYPE.group : - ss = $"group {array_length(data.content)} nodes"; - break; - - case ACTION_TYPE.ungroup : - ss = $"ungroup {obj.name} node"; - break; - - case ACTION_TYPE.collection_loaded : - ss = $"load {filename_name(data)}"; - break; - - case ACTION_TYPE.struct_modify : - ss = $"modify {struct_try_get(obj, "name", "value")}"; - break; - - case ACTION_TYPE.custom : - ss = struct_try_get(data, "tooltip", "action"); - break; + case ACTION_TYPE.var_modify : return $"Modify '{array_length(data) > 2? data[2] : data[1]}'"; + case ACTION_TYPE.array_insert : return array_length(data) > 2? data[2] : $"Insert {data[1]} to array {obj}"; + case ACTION_TYPE.array_modify : return $"Modify '{data[1]}' of array '{obj}'"; + case ACTION_TYPE.array_delete : return $"Delete '{data[1]}' from array '{obj}'"; + case ACTION_TYPE.node_added : return $"Add '{obj.name}' node"; + case ACTION_TYPE.node_delete : return $"Deleted '{obj.name}' node"; + case ACTION_TYPE.junction_connect : return $"Connect '{obj.name}'"; + case ACTION_TYPE.junction_disconnect : return $"Disconnect '{obj.name}'"; + case ACTION_TYPE.group_added : return $"Add '{obj.name}' to group"; + case ACTION_TYPE.group_removed : return $"Remove '{obj.name}' from group"; + case ACTION_TYPE.group : return $"Group {array_length(data.content)} nodes"; + case ACTION_TYPE.ungroup : return $"Ungroup '{obj.name}' node"; + case ACTION_TYPE.collection_loaded : return $"Load '{filename_name(data)}'"; + case ACTION_TYPE.struct_modify : return $"Modify struct value '{struct_try_get(obj, "name", "value")}'"; + case ACTION_TYPE.custom : return struct_try_get(data, "tooltip", "action"); } - return ss; + + return ""; } static destroy = function() { diff --git a/scripts/nodeValue_drawer/nodeValue_drawer.gml b/scripts/nodeValue_drawer/nodeValue_drawer.gml index bc6b9af64..004f8a535 100644 --- a/scripts/nodeValue_drawer/nodeValue_drawer.gml +++ b/scripts/nodeValue_drawer/nodeValue_drawer.gml @@ -46,7 +46,7 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc cHov = true; if(anim_hold != noone) - jun.setAnim(anim_hold); + jun.setAnim(anim_hold, true); draw_sprite_ui_uniform(THEME.animate_clock, index, butx, lb_y, 1, index == 2? COLORS._main_accent : c_white, 1); TOOLTIP = jun.hasJunctionFrom()? __txtx("panel_inspector_remove_link", "Remove link") : __txtx("panel_inspector_toggle_anim", "Toggle animation"); @@ -55,8 +55,7 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc if(jun.value_from != noone) jun.removeFrom(); else { - recordAction(ACTION_TYPE.var_modify, jun.animator, [ jun.is_anim, "is_anim", _name + " animation" ]); - jun.setAnim(!jun.is_anim); + jun.setAnim(!jun.is_anim, true); anim_hold = jun.is_anim; } } diff --git a/scripts/node_keyframe/node_keyframe.gml b/scripts/node_keyframe/node_keyframe.gml index 278afad46..6b5eb7f18 100644 --- a/scripts/node_keyframe/node_keyframe.gml +++ b/scripts/node_keyframe/node_keyframe.gml @@ -472,7 +472,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { updateKeyMap(); data.undo = !data.undo; - }, { overKey : values[i], index : i, undo : true }); + }, { overKey : values[i], index : i, undo : true, tooltip : $"Set {prop.name} value" }); mergeAction(act); } @@ -489,7 +489,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { setKeyTime(data.key, data.time, false); data.time = _prevTime; - }, { key : _key, time : _prevTime }, onUndo); + }, { key : _key, time : _prevTime, tooltip : $"Set {prop.name} value" }, onUndo); array_insert(values, i, _key); if(_replace) updateKeyMap(); @@ -501,7 +501,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { setKeyTime(data.key, data.time, false); data.time = _prevTime; - }, { key : _key, time : _prevTime }, onUndo); + }, { key : _key, time : _prevTime, tooltip : $"Set {prop.name} value" }, onUndo); array_push(values, _key); if(_replace) updateKeyMap(); @@ -543,7 +543,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(isEqual(values[0].value, _val)) return false; - if(_record) recordAction(ACTION_TYPE.var_modify, values[0], [ values[0].value, "value", prop.name ], onUndo); + if(_record) recordAction_variable_change(values[0], "value", values[0].value, prop.name, onUndo); values[0].value = _val; return true; @@ -552,7 +552,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(array_length(values) == 0) { // Should not be called normally var k = new valueKey(_time, _val, self, ease_in, ease_out); array_push(values, k); - if(_record) recordAction(ACTION_TYPE.list_insert, values, [ k, array_length(values) - 1, $"add {prop.name} keyframe" ], onUndo); + if(_record) recordAction(ACTION_TYPE.array_insert, values, [ k, array_length(values) - 1, $"add {prop.name} keyframe" ], onUndo); return true; } @@ -562,7 +562,7 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { if(!global.FLAG.keyframe_override) return false; if(_key.value != _val) { - if(_record) recordAction(ACTION_TYPE.var_modify, _key, [ _key.value, "value", prop.name ], onUndo); + if(_record) recordAction_variable_change(_key, "value", _key.value, prop.name, onUndo); _key.value = _val; return true; } @@ -570,14 +570,14 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor { } else if(_key.time > _time) { var k = new valueKey(_time, _val, self, ease_in, ease_out); array_insert(values, i, k); - if(_record) recordAction(ACTION_TYPE.list_insert, values, [k, i, $"add {prop.name} keyframe" ], onUndo); + if(_record) recordAction(ACTION_TYPE.array_insert, values, [k, i, $"add {prop.name} keyframe" ], onUndo); updateKeyMap(); return true; } } var k = new valueKey(_time, _val, self, ease_in, ease_out); - if(_record) recordAction(ACTION_TYPE.list_insert, values, [ k, array_length(values), $"add {prop.name} keyframe" ], onUndo); + if(_record) recordAction(ACTION_TYPE.array_insert, values, [ k, array_length(values), $"add {prop.name} keyframe" ], onUndo); array_push(values, k); updateKeyMap(); return true; diff --git a/scripts/node_path/node_path.gml b/scripts/node_path/node_path.gml index fd680ac23..05a153280 100644 --- a/scripts/node_path/node_path.gml +++ b/scripts/node_path/node_path.gml @@ -110,7 +110,7 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { newInput(index, nodeValue_Path_Anchor("Anchor", self, newAnchor( _x, _y, _dxx, _dxy, _dyx, _dyy ))); if(rec) { - recordAction(ACTION_TYPE.list_insert, inputs, [ inputs[index], index, $"add path anchor point {index}" ]); + recordAction(ACTION_TYPE.array_insert, inputs, [ inputs[index], index, $"add path anchor point {index}" ]); resetDisplayList(); } @@ -764,7 +764,7 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { if(mouse_press(mb_left, active)) { var _indx = input_fix_len + anchor_hover; - recordAction(ACTION_TYPE.list_delete, inputs, [ inputs[_indx], _indx, "remove path anchor point" ]); + recordAction(ACTION_TYPE.array_delete, inputs, [ inputs[_indx], _indx, "remove path anchor point" ]); array_delete(inputs, _indx, 1); resetDisplayList(); @@ -813,7 +813,7 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { ind = input_fix_len + _line_hover + 1; } - recordAction(ACTION_TYPE.list_insert, inputs, [ inputs[ind], ind, $"add path anchor point {ind}" ]); + recordAction(ACTION_TYPE.array_insert, inputs, [ inputs[ind], ind, $"add path anchor point {ind}" ]); resetDisplayList(); UNDO_HOLDING = true; diff --git a/scripts/node_path_3d/node_path_3d.gml b/scripts/node_path_3d/node_path_3d.gml index 8e74bcfc7..f01f906e4 100644 --- a/scripts/node_path_3d/node_path_3d.gml +++ b/scripts/node_path_3d/node_path_3d.gml @@ -118,7 +118,7 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor if(!rec) return inputs[index]; - recordAction(ACTION_TYPE.list_insert, inputs, [ inputs[index], index, $"add path anchor point {index}" ]); + recordAction(ACTION_TYPE.array_insert, inputs, [ inputs[index], index, $"add path anchor point {index}" ]); resetDisplayList(); return inputs[index]; @@ -390,7 +390,7 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor if(mouse_press(mb_left, active)) { var _indx = input_fix_len + anchor_hover; - recordAction(ACTION_TYPE.list_delete, inputs, [ inputs[_indx], _indx, "remove path anchor point" ]); + recordAction(ACTION_TYPE.array_delete, inputs, [ inputs[_indx], _indx, "remove path anchor point" ]); array_delete(inputs, _indx, 1); resetDisplayList(); @@ -456,7 +456,7 @@ function Node_Path_3D(_x, _y, _group = noone) : Node(_x, _y, _group) constructor ind = input_fix_len + _line_hover + 1; } - recordAction(ACTION_TYPE.list_insert, inputs, [ inputs[ind], ind, $"add path anchor point {ind}" ]); + recordAction(ACTION_TYPE.array_insert, inputs, [ inputs[ind], ind, $"add path anchor point {ind}" ]); resetDisplayList(); UNDO_HOLDING = true; diff --git a/scripts/node_path_smooth/node_path_smooth.gml b/scripts/node_path_smooth/node_path_smooth.gml index ec27fbaef..e38c6a5a3 100644 --- a/scripts/node_path_smooth/node_path_smooth.gml +++ b/scripts/node_path_smooth/node_path_smooth.gml @@ -59,7 +59,7 @@ function Node_Path_Smooth(_x, _y, _group = noone) : Node(_x, _y, _group) constru newInput(index, nodeValue_Vec2("Anchor", self, [ _x, _y ])); - recordAction(ACTION_TYPE.list_insert, inputs, [ inputs[index], index, "add path anchor point" ]); + recordAction(ACTION_TYPE.array_insert, inputs, [ inputs[index], index, "add path anchor point" ]); resetDisplayList(); return inputs[index]; @@ -122,7 +122,7 @@ function Node_Path_Smooth(_x, _y, _group = noone) : Node(_x, _y, _group) constru array_insert(inputs, input_fix_len + _line_hover + 1, anc); } } else { - recordAction(ACTION_TYPE.list_delete, inputs, [ inputs[input_fix_len + _anchor_hover], input_fix_len + _anchor_hover, "remove path anchor point" ]); + recordAction(ACTION_TYPE.array_delete, inputs, [ inputs[input_fix_len + _anchor_hover], input_fix_len + _anchor_hover, "remove path anchor point" ]); array_delete(inputs, input_fix_len + _anchor_hover, 1); resetDisplayList(); } diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index ee0f9fe95..d5a4e7bcb 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -464,7 +464,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru recordAction(ACTION_TYPE.custom, function(data) { setAnim(data.is_anim); data.is_anim = !data.is_anim; - }, { anim: is_anim }); + }, { is_anim, tooltip : $"Toggle '{name}' animation" }); } is_anim = anim; @@ -557,7 +557,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru editWidget = noone; switch(display_type) { case VALUE_DISPLAY.button : - var _onClick = struct_has(display_data, "onClick")? method(node, display_data.onClick) : function() /*=>*/ { setAnim(true); setValueDirect(true); }; + var _onClick = struct_has(display_data, "onClick")? method(node, display_data.onClick) : function() /*=>*/ { setAnim(true, true); setValueDirect(true); }; editWidget = button(_onClick).setText(struct_try_get(display_data, "name", "Trigger")); runInUI = struct_try_get(display_data, "UI", false); diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index 37348d36f..c2246305f 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -724,7 +724,7 @@ function Panel_Animation() : PanelContent() constructor { var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; draw_line_width(bar_line_x, 0, bar_line_x, bar_h, 2); - var bar_line_x = timeline_shift; + var bar_line_x = 0 * timeline_scale + timeline_shift; draw_line_width(bar_line_x, 0, bar_line_x, bar_h, 2); draw_set_alpha(1); @@ -1283,7 +1283,7 @@ function Panel_Animation() : PanelContent() constructor { var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; draw_line_width(bar_line_x, 0, bar_line_x, _gh, 2); - var bar_line_x = timeline_shift; + var bar_line_x = 0 * timeline_scale + timeline_shift; draw_line_width(bar_line_x, 0, bar_line_x, _gh, 2); draw_set_alpha(1); @@ -1969,7 +1969,7 @@ function Panel_Animation() : PanelContent() constructor { var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; draw_line_width(bar_line_x, ui(16), bar_line_x, dope_sheet_h, 2); - var bar_line_x = timeline_shift; + var bar_line_x = 0 * timeline_scale + timeline_shift; draw_line_width(bar_line_x, ui(16), bar_line_x, dope_sheet_h, 2); draw_set_alpha(1); diff --git a/scripts/panel_history/panel_history.gml b/scripts/panel_history/panel_history.gml index 04ac56e5f..ee354f052 100644 --- a/scripts/panel_history/panel_history.gml +++ b/scripts/panel_history/panel_history.gml @@ -42,12 +42,13 @@ function Panel_History() : PanelContent() constructor { if((ds_list_size(redo_list) != ds_stack_size(REDO_STACK)) || (ds_list_size(undo_list) != ds_stack_size(UNDO_STACK))) refreshList(); - draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text); + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text); var lh = line_get_height() + ui(8); var _h = 0, hh; var yy = _y + ui(8); + var ww = sc_history.surface_w; var lw = sc_history.surface_w - ui(32 + 2); var red = ds_list_size(redo_list); var amo = ds_list_size(redo_list) + ds_list_size(undo_list) + 1; @@ -79,7 +80,7 @@ function Panel_History() : PanelContent() constructor { hh = amoDisp * lh; BLEND_OVERRIDE; - if(pHOVER && sc_history.hover && point_in_rectangle(_m[0], _m[1], ui(32), yy - ui(4), lw, yy + hh + ui(4) - 1)) { + if(pHOVER && sc_history.hover && point_in_rectangle(_m[0], _m[1], ui(32), yy - ui(4), ww, yy + hh + ui(4) - 1)) { sc_history.hover_content = true; draw_sprite_stretched_ext(THEME.node_bg, 0, ui(32), yy - ui(2), lw, hh + ui(4), COLORS._main_icon_light, 1); _hover = i; diff --git a/scripts/panel_inspector/panel_inspector.gml b/scripts/panel_inspector/panel_inspector.gml index 19b439f20..c424cf301 100644 --- a/scripts/panel_inspector/panel_inspector.gml +++ b/scripts/panel_inspector/panel_inspector.gml @@ -219,14 +219,14 @@ function Panel_Inspector() : PanelContent() constructor { nodeCollapseAll(inspectings[i]); } - function junction_reset() { if(__dialog_junction == noone) return; __dialog_junction.resetValue(); } - function junction_add() { if(__dialog_junction == noone) return; __dialog_junction.setAnim(true); } - function junction_remove() { if(__dialog_junction == noone) return; __dialog_junction.setAnim(false); } - function junction_axis_combine() { if(__dialog_junction == noone) return; __dialog_junction.sep_axis = false; } - function junction_axis_separate() { if(__dialog_junction == noone) return; __dialog_junction.sep_axis = true; } - function junction_use_expression() { if(__dialog_junction == noone) return; __dialog_junction.expUse = true; } - function junction_disable_expression() { if(__dialog_junction == noone) return; __dialog_junction.expUse = false; } - function junction_extract_single() { if(__dialog_junction == noone) return; __dialog_junction.extractNode(); } + function junction_reset() { if(__dialog_junction == noone) return; __dialog_junction.resetValue(); } + function junction_add() { if(__dialog_junction == noone) return; __dialog_junction.setAnim(true, true); } + function junction_remove() { if(__dialog_junction == noone) return; __dialog_junction.setAnim(false, true); } + function junction_axis_combine() { if(__dialog_junction == noone) return; __dialog_junction.sep_axis = false; } + function junction_axis_separate() { if(__dialog_junction == noone) return; __dialog_junction.sep_axis = true; } + function junction_use_expression() { if(__dialog_junction == noone) return; __dialog_junction.expUse = true; } + function junction_disable_expression() { if(__dialog_junction == noone) return; __dialog_junction.expUse = false; } + function junction_extract_single() { if(__dialog_junction == noone) return; __dialog_junction.extractNode(); } function junction_bypass_toggle() { if(__dialog_junction == noone || __dialog_junction.bypass_junc == noone) return; __dialog_junction.bypass_junc.visible = !__dialog_junction.bypass_junc.visible; @@ -929,7 +929,7 @@ function Panel_Inspector() : PanelContent() constructor { draw_sprite_stretched_ext(THEME.prop_selecting, 0, ui(4), _selY, contentPane.surface_w - ui(8), _selH, COLORS._main_accent, 1); if(anim_toggling) { - jun.setAnim(!jun.is_anim); + jun.setAnim(!jun.is_anim, true); anim_toggling = false; }