diff --git a/objects/_p_dialog/Destroy_0.gml b/objects/_p_dialog/Destroy_0.gml index a69c66beb..719188541 100644 --- a/objects/_p_dialog/Destroy_0.gml +++ b/objects/_p_dialog/Destroy_0.gml @@ -7,5 +7,4 @@ ds_list_remove(DIALOGS, self); if(parent) array_remove(parent.children, id); -if(!passthrough) - MOUSE_BLOCK = true; \ No newline at end of file +if(!passthrough) MOUSE_BLOCK = true; \ No newline at end of file diff --git a/objects/addon_key_displayer/Create_0.gml b/objects/addon_key_displayer/Create_0.gml index 403459033..a70c203a0 100644 --- a/objects/addon_key_displayer/Create_0.gml +++ b/objects/addon_key_displayer/Create_0.gml @@ -12,8 +12,8 @@ event_inherited(); show_graph = false; menu = [ - menuItemAction("Toggle double click bar", function() /*=>*/ { show_doubleclick = !show_doubleclick; }), - menuItemAction("Toggle graph", function() /*=>*/ { show_graph = !show_graph; }), + menuItem("Toggle double click bar", function() /*=>*/ { show_doubleclick = !show_doubleclick; }), + menuItem("Toggle graph", function() /*=>*/ { show_graph = !show_graph; }), ]; extra_keys = [ diff --git a/objects/o_dialog_add_node/Create_0.gml b/objects/o_dialog_add_node/Create_0.gml index 9cdd5aaae..89b3f71bb 100644 --- a/objects/o_dialog_add_node/Create_0.gml +++ b/objects/o_dialog_add_node/Create_0.gml @@ -78,7 +78,7 @@ event_inherited(); node_menu_selecting = node; var fav = array_exists(global.FAV_NODES, node.node); var menu = [ - menuItemAction(fav? __txtx("add_node_remove_favourite", "Remove from favourite") : __txtx("add_node_add_favourite", "Add to favourite"), trigger_favourite, THEME.star) + menuItem(fav? __txtx("add_node_remove_favourite", "Remove from favourite") : __txtx("add_node_add_favourite", "Add to favourite"), trigger_favourite, THEME.star) ]; menuCall("add_node_window_manu",,, menu,, node_menu_selecting); diff --git a/objects/o_dialog_color_selector/Create_0.gml b/objects/o_dialog_color_selector/Create_0.gml index b1b2efbb6..52e74c72b 100644 --- a/objects/o_dialog_color_selector/Create_0.gml +++ b/objects/o_dialog_color_selector/Create_0.gml @@ -101,10 +101,10 @@ event_inherited(); hovering = pal; menuCall("palette_window_preset_menu",,, [ - menuItemAction(__txtx("palette_editor_set_default", "Set as default"), function() { + menuItem(__txtx("palette_editor_set_default", "Set as default"), function() { PROJECT.setPalette(array_clone(hovering.palette)); }), - menuItemAction(__txtx("palette_editor_delete", "Delete palette"), function() { + menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { file_delete(hovering.path); __initPalette(); }), diff --git a/objects/o_dialog_gradient/Create_0.gml b/objects/o_dialog_gradient/Create_0.gml index 5bf5ac424..47630b5c6 100644 --- a/objects/o_dialog_gradient/Create_0.gml +++ b/objects/o_dialog_gradient/Create_0.gml @@ -138,7 +138,7 @@ event_inherited(); if(mouse_press(mb_right, interactable && sFOCUS)) { hovering_name = _gradient.path; menuCall("gradient_window_preset_menu",,, [ - menuItemAction(__txtx("gradient_editor_delete", "Delete gradient"), function() { + menuItem(__txtx("gradient_editor_delete", "Delete gradient"), function() { file_delete(hovering_name); __initGradient(); }) @@ -227,7 +227,7 @@ event_inherited(); hovering = pal; menuCall("palette_window_preset_menu",,, [ - menuItemAction(__txtx("gradient_set_palette", "Convert to Gradient"), function() { + menuItem(__txtx("gradient_set_palette", "Convert to Gradient"), function() { var _p = hovering.palette; if(array_length(_p) < 2) return; diff --git a/objects/o_dialog_gradient/Draw_64.gml b/objects/o_dialog_gradient/Draw_64.gml index d190f0139..1d7969790 100644 --- a/objects/o_dialog_gradient/Draw_64.gml +++ b/objects/o_dialog_gradient/Draw_64.gml @@ -100,11 +100,11 @@ if !ready exit; if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("gradient_editor_key_blend", "Key blending"), THEME.grad_blend) == 2) { menuCall("gradient_window_blend_menu", bx + ui(32), by, [ - menuItemAction(__txtx("gradient_editor_blend_hard", "Solid"), function() { gradient.type = 1; onApply(gradient); }), - menuItemAction(__txtx("gradient_editor_blend_RGB", "RGB"), function() { gradient.type = 0; onApply(gradient); }), - menuItemAction(__txtx("gradient_editor_blend_sRGB", "sRGB"), function() { gradient.type = 4; onApply(gradient); }), - menuItemAction(__txtx("gradient_editor_blend_HSV", "HSV"), function() { gradient.type = 2; onApply(gradient); }), - menuItemAction(__txtx("gradient_editor_blend_OKLAB", "OKLAB"), function() { gradient.type = 3; onApply(gradient); }), + menuItem(__txtx("gradient_editor_blend_hard", "Solid"), function() { gradient.type = 1; onApply(gradient); }), + menuItem(__txtx("gradient_editor_blend_RGB", "RGB"), function() { gradient.type = 0; onApply(gradient); }), + menuItem(__txtx("gradient_editor_blend_sRGB", "sRGB"), function() { gradient.type = 4; onApply(gradient); }), + menuItem(__txtx("gradient_editor_blend_HSV", "HSV"), function() { gradient.type = 2; onApply(gradient); }), + menuItem(__txtx("gradient_editor_blend_OKLAB", "OKLAB"), function() { gradient.type = 3; onApply(gradient); }), ],, gradient); } bx -= ui(32); diff --git a/objects/o_dialog_image_array_edit/Create_0.gml b/objects/o_dialog_image_array_edit/Create_0.gml index 6c61ca316..4e8c11725 100644 --- a/objects/o_dialog_image_array_edit/Create_0.gml +++ b/objects/o_dialog_image_array_edit/Create_0.gml @@ -112,7 +112,7 @@ event_inherited(); if(menu > -1) { menuCall("image_array_edit_menu",,, [ - menuItemAction(__txt("Remove"), function() { + menuItem(__txt("Remove"), function() { var arr = target.getValue(); array_delete(arr, menuOn, 1); diff --git a/objects/o_dialog_menubox/Create_0.gml b/objects/o_dialog_menubox/Create_0.gml index f3408523d..d1e04febd 100644 --- a/objects/o_dialog_menubox/Create_0.gml +++ b/objects/o_dialog_menubox/Create_0.gml @@ -10,7 +10,8 @@ event_inherited(); menu_id = ""; alarm[0] = -1; menu = 1; - hght = ui(36); + font = f_p1; + hght = line_get_height(font, 12); tooltips = []; show_icon = false; context = noone; @@ -20,6 +21,7 @@ event_inherited(); setFocus(self.id); + item_selecting = noone; remove_parents = true; selecting_menu = noone; hk_editing = noone; @@ -39,7 +41,7 @@ event_inherited(); instance_destroy(children[i]); children = []; - draw_set_text(f_p0, fa_center, fa_center, COLORS._main_text); + draw_set_text(font, fa_center, fa_center, COLORS._main_text); for(var i = 0; i < array_length(menu); i++) { var _menuItem = menu[i]; if(_menuItem == -1) { @@ -54,7 +56,7 @@ event_inherited(); continue; } - draw_set_font(f_p0); + draw_set_font(font); var ww = string_width(_menuItem.name) + ui(64); if(instanceof(_menuItem) == "MenuItemGroup") { @@ -67,7 +69,7 @@ event_inherited(); if(_menuItem.hotkey != noone) { var _key = find_hotkey(_menuItem.hotkey[0], _menuItem.hotkey[1]); if(_key) { - draw_set_font(f_p1); + draw_set_font(font); var ss = key_get_name(_key.key, _key.modi); ww += string_width(ss) + ui(16); } diff --git a/objects/o_dialog_menubox/Destroy_0.gml b/objects/o_dialog_menubox/Destroy_0.gml new file mode 100644 index 000000000..f1bae6e1c --- /dev/null +++ b/objects/o_dialog_menubox/Destroy_0.gml @@ -0,0 +1,4 @@ +event_inherited(); + +for( var i = 0, n = array_length(children); i < n; i++ ) + instance_destroy(children[i]); \ No newline at end of file diff --git a/objects/o_dialog_menubox/Draw_64.gml b/objects/o_dialog_menubox/Draw_64.gml index 4da39bffd..e26adca2a 100644 --- a/objects/o_dialog_menubox/Draw_64.gml +++ b/objects/o_dialog_menubox/Draw_64.gml @@ -5,6 +5,10 @@ if(!ready) exit; var yy = dialog_y; var _lclick = sFOCUS && (!mouse_init_inside && mouse_release(mb_left)) || (keyboard_check_pressed(vk_enter) && hk_editing == noone); var _rclick = sFOCUS && (!mouse_init_inside && mouse_release(mb_right)); + if(!mouse_init_inside && mouse_press(mb_right) && item_selecting) { + instance_destroy(item_selecting); + item_selecting = noone; + } draw_sprite_stretched(THEME.s_box_r2_clr, 0, dialog_x, dialog_y, dialog_w, dialog_h); @@ -23,8 +27,8 @@ if(!ready) exit; _menuItem = _menuItem.shiftMenu; if(_menuItem == -1) { - var bx = dialog_x + ui(8); - var bw = dialog_w - ui(16); + var bx = dialog_x + ui(16); + var bw = dialog_w - ui(32); draw_set_color(CDEF.main_mdblack); draw_line_width(bx, yy + ui(3), bx + bw, yy + ui(3), 2); yy += ui(8); @@ -50,9 +54,9 @@ if(!ready) exit; draw_sprite_stretched_ext(THEME.textbox, 3, dialog_x, yy, dialog_w, _h, _hc, _ha); - if(is_instanceof(_menuItem, MenuItem) && _menuItem.active && _hovering_ch) { + if(is_instanceof(_menuItem, MenuItem) && _hovering_ch) { - if(_lclick) { + if(_menuItem.active && _lclick) { var _dat = { _x: dialog_x, x: dialog_x + dialog_w, @@ -72,7 +76,7 @@ if(!ready) exit; if(_key && _rclick) { var _dat = { - _x: dialog_x, + _x: mouse_mx + ui(4), x: mouse_mx + ui(4), y: mouse_my + ui(4), depth: depth, @@ -83,19 +87,21 @@ if(!ready) exit; }; selecting_menu = _menuItem; - var _loadKey = $"{_key.context}.{_key.name}"; + var _loadKey = string_to_var($"{_key.context}.{_key.name}"); var context_menu_settings = [ _loadKey, - menuItemAction("Edit hotkey", function() /*=>*/ { + menuItem("Edit hotkey", function() /*=>*/ { hk_editing = selecting_menu; keyboard_lastchar = hk_editing.hoykeyObject.key; }), ]; with(o_dialog_menubox) { if(!remove_parents) instance_destroy(); } - var _menu = submenuCall(_dat, context_menu_settings); - _menu.remove_parents = false; + + item_selecting = submenuCall(_dat, context_menu_settings); + item_selecting.remove_parents = false; + array_push(children, item_selecting.id); } } } else if(cc != c_white) @@ -103,7 +109,7 @@ if(!ready) exit; if(is_instanceof(_menuItem, MenuItemGroup)) { var _submenus = _menuItem.group; - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_set_text(font, fa_center, fa_center, COLORS._main_text_sub); draw_set_alpha(_menuItem.active * 0.75 + 0.25); draw_text(dialog_x + dialog_w / 2, yy + hght / 2, label); draw_set_alpha(1); @@ -166,7 +172,7 @@ if(!ready) exit; if(_menuItem.spr != noone) { var spr = is_array(_menuItem.spr)? _menuItem.spr[0] : _menuItem.spr; var ind = is_array(_menuItem.spr)? _menuItem.spr[1] : 0; - draw_sprite_ui(spr, ind, dialog_x + ui(24), yy + hght / 2,,,, COLORS._main_icon, _menuItem.active * 0.5 + 0.25); + draw_sprite_ui(spr, ind, dialog_x + ui(24), yy + hght / 2, .8, .8, 0, COLORS._main_icon, _menuItem.active * 0.5 + 0.25); } if(_menuItem.toggle != noone) { @@ -175,19 +181,21 @@ if(!ready) exit; } var tx = dialog_x + show_icon * ui(32) + ui(16); - draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + draw_set_text(font, fa_left, fa_center, COLORS._main_text); draw_set_alpha(_menuItem.active * 0.75 + 0.25); draw_text(tx, yy + hght / 2, label); draw_set_alpha(1); + var _hx = dialog_x + dialog_w - ui(16); + var _hy = yy + hght / 2 + ui(2); + if(_menuItem.isShelf) { draw_sprite_ui_uniform(THEME.arrow, 0, dialog_x + dialog_w - ui(20), yy + hght / 2, 1, COLORS._main_icon); - - } else if(_key) { - var _hx = dialog_x + dialog_w - ui(16); - var _hy = yy + hght / 2 + ui(2); - - draw_set_font(f_p1); + _hx -= ui(24); + } + + if(_key) { + draw_set_font(font); var _ktxt = key_get_name(_key.key, _key.modi); var _tw = string_width(_ktxt); @@ -199,11 +207,11 @@ if(!ready) exit; var _bh = _th + ui(3); if(hk_editing == _menuItem) { - draw_set_text(f_p1, fa_right, fa_center, COLORS._main_accent); + draw_set_text(font, fa_right, fa_center, COLORS._main_accent); draw_sprite_stretched_ext(THEME.ui_panel, 1, _bx, _by, _bw, _bh, COLORS._main_text_accent); } else if(_ktxt != "") { - draw_set_text(f_p1, fa_right, fa_center, COLORS._main_text_sub); + draw_set_text(font, fa_right, fa_center, COLORS._main_text_sub); draw_sprite_stretched_ext(THEME.ui_panel, 1, _bx, _by, _bw, _bh, CDEF.main_dkgrey); } @@ -217,11 +225,12 @@ if(!ready) exit; if(hk_editing != noone) { if(keyboard_check_pressed(vk_enter)) hk_editing = noone; - else if(keyboard_check_pressed(vk_escape)) - hk_editing = noone; else hotkey_editing(hk_editing.hoykeyObject); + if(keyboard_check_pressed(vk_escape)) + hk_editing = noone; + } else if(sFOCUS) { if(keyboard_check_pressed(vk_up)) { selecting--; diff --git a/objects/o_dialog_menubox/Step_1.gml b/objects/o_dialog_menubox/Step_1.gml index ead79718a..fb4773559 100644 --- a/objects/o_dialog_menubox/Step_1.gml +++ b/objects/o_dialog_menubox/Step_1.gml @@ -9,5 +9,4 @@ for( var i = 0, n = array_length(children); i < n; i++ ) { } _hovering_ch = hov; -if((mouse_check_button_pressed(mb_left)) && !hov) - instance_destroy(); \ No newline at end of file +if(!hov && mouse_press(mb_left)) instance_destroy(); \ No newline at end of file diff --git a/objects/o_dialog_menubox/o_dialog_menubox.yy b/objects/o_dialog_menubox/o_dialog_menubox.yy index a80094e56..49a445f6a 100644 --- a/objects/o_dialog_menubox/o_dialog_menubox.yy +++ b/objects/o_dialog_menubox/o_dialog_menubox.yy @@ -3,6 +3,7 @@ "%Name":"o_dialog_menubox", "eventList":[ {"$GMEvent":"","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",}, + {"$GMEvent":"","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":1,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",}, {"$GMEvent":"","%Name":"","collisionObjectId":null,"eventNum":1,"eventType":3,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",}, {"$GMEvent":"","%Name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",}, ], diff --git a/objects/o_dialog_palette/Create_0.gml b/objects/o_dialog_palette/Create_0.gml index efd386d6f..04a24d7be 100644 --- a/objects/o_dialog_palette/Create_0.gml +++ b/objects/o_dialog_palette/Create_0.gml @@ -122,10 +122,10 @@ event_inherited(); hovering = pal; menuCall("palette_window_preset_menu",,, [ - menuItemAction(__txtx("palette_editor_set_default", "Set as default"), function() { + menuItem(__txtx("palette_editor_set_default", "Set as default"), function() { PROJECT.setPalette(array_clone(hovering.palette)); }), - menuItemAction(__txtx("palette_editor_delete", "Delete palette"), function() { + menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { file_delete(hovering.path); __initPalette(); }), diff --git a/objects/o_dialog_palette/Draw_64.gml b/objects/o_dialog_palette/Draw_64.gml index bfe3ede12..6ecf0b2ca 100644 --- a/objects/o_dialog_palette/Draw_64.gml +++ b/objects/o_dialog_palette/Draw_64.gml @@ -87,12 +87,12 @@ if palette == 0 exit; if(b) mouse_draggable = false; if(b == 2) { menuCall("palette_window_sort_menu", bx + ui(32), by, [ - menuItemAction(__txtx("palette_editor_sort_brighter", "Brighter"), function() { sortPalette(__sortBright); }), - menuItemAction(__txtx("palette_editor_sort_darker", "Darker"), function() { sortPalette(__sortDark); }), + menuItem(__txtx("palette_editor_sort_brighter", "Brighter"), function() { sortPalette(__sortBright); }), + menuItem(__txtx("palette_editor_sort_darker", "Darker"), function() { sortPalette(__sortDark); }), -1, - menuItemAction(__txtx("palette_editor_sort_hue", "Hue"), function() { sortPalette(__sortHue); }), - menuItemAction(__txtx("palette_editor_sort_sat", "Saturation"), function() { sortPalette(__sortSat); }), - menuItemAction(__txtx("palette_editor_sort_val", "Value"), function() { sortPalette(__sortVal); }), + menuItem(__txtx("palette_editor_sort_hue", "Hue"), function() { sortPalette(__sortHue); }), + menuItem(__txtx("palette_editor_sort_sat", "Saturation"), function() { sortPalette(__sortSat); }), + menuItem(__txtx("palette_editor_sort_val", "Value"), function() { sortPalette(__sortVal); }), ],, palette); } bx -= ui(32); diff --git a/objects/o_dialog_preset/Create_0.gml b/objects/o_dialog_preset/Create_0.gml index 18dbf4eae..b2d06bbee 100644 --- a/objects/o_dialog_preset/Create_0.gml +++ b/objects/o_dialog_preset/Create_0.gml @@ -13,6 +13,8 @@ event_inherited(); adding = false; add_txt = ""; tb_add = new textBox(TEXTBOX_INPUT.text, function(txt) /*=>*/ { add_txt = txt; newPresetFromNode(txt); adding = false; }); + + selecting_path = ""; #endregion #region content @@ -52,13 +54,8 @@ event_inherited(); } if(mouse_click(mb_right, sFOCUS)) { - var dia = menuCall("preset_window_menu",,, [ - menuItemAction(__txt("Delete"), function() { - file_delete(o_dialog_menubox.path); - __initPresets(); - }), - ],, preset); - dia.path = preset.path; + selecting_path = preset.path; + var dia = menuCall("preset_window_menu",,, [ menuItem(__txt("Delete"), function() { file_delete(selecting_path); __initPresets(); }), ]); } } diff --git a/scripts/addon_function/addon_function.gml b/scripts/addon_function/addon_function.gml index 7c4db2107..37c50bd9c 100644 --- a/scripts/addon_function/addon_function.gml +++ b/scripts/addon_function/addon_function.gml @@ -41,7 +41,7 @@ function addonContextItem(_addon, _name, _function) constructor { self._name = _name; self._function = _function; - menu_item = menuItemAction(_name, function(_data) { + menu_item = menuItem(_name, function(_data) { lua_call(_addon.thread, self._function, lua_byref(_data.context, true)); })//.setColor(COLORS._main_accent); } @@ -50,7 +50,7 @@ function addonContextSubMenu(_name, _content) constructor { self.name = _name; self.content = _content; - menu_item = menuItemAction(name, function(_dat) { + menu_item = menuItem(name, function(_dat) { return submenuCall(_dat, content); })//.setColor(COLORS._main_accent) .setIsShelf(); diff --git a/scripts/contextMenu_controller/contextMenu_controller.gml b/scripts/contextMenu_controller/contextMenu_controller.gml index 87e4cf634..0788db504 100644 --- a/scripts/contextMenu_controller/contextMenu_controller.gml +++ b/scripts/contextMenu_controller/contextMenu_controller.gml @@ -33,7 +33,9 @@ function pieMenuCall(menu_id = "", _x = mouse_mx, _y = mouse_my, menu = [], cont return dia; } -function submenuCall(_data, menu = []) { +function submenuCall(_data = undefined, menu = []) { + if(is_undefined(_data)) return menuCall("",,, menu); + var dia = instance_create_depth(_data.x - ui(4), _data.y, _data.depth - 1, o_dialog_menubox); dia.context = _data.context; dia.setMenu(menu); @@ -41,7 +43,6 @@ function submenuCall(_data, menu = []) { if(_data.x - ui(4) + dia.dialog_w > WIN_W - ui(2)) dia.dialog_x = _data._x - dia.dialog_w + ui(4); - return dia; } diff --git a/scripts/function_register/function_register.gml b/scripts/function_register/function_register.gml index 585a5c9d8..02ff47cd0 100644 --- a/scripts/function_register/function_register.gml +++ b/scripts/function_register/function_register.gml @@ -11,27 +11,63 @@ } function __fnInit() { - globalvar CMD_FUNCTIONS, ACTION_MAP; + globalvar CMD_FUNCTIONS, ACTION_MAP, MENU_ITEMS, FUNCTIONS; + + FUNCTIONS = {}; CMD_FUNCTIONS = {}; ACTION_MAP = {}; + MENU_ITEMS = {}; __fnInit_Global(); + __fnInit_Panels(); __fnInit_Preview(); __fnInit_Inspector(); __fnInit_Animation(); __fnInit_Graph(); __fnInit_Collection(); + __fnInit_Presets(); + __fnInit_Notification(); + __fnInit_Preview_Window(); } + #endregion -function registerFunction(_context, _name, _key, _mod, _action, _args = []) { +function registerFunction(_context, _name, _key, _mod, _action) { return new functionOnject(_context, _name, _key, _mod, _action); } + +function functionOnject(_context, _name, _key, _mod, _action) constructor { addHotkey(_context, _name, _key, _mod, _action); - var _fnName = _context == ""? _name : $"{_context} {_name}"; - _fnName = string_to_var(_fnName); + context = _context; + name = _name; + dkey = _key; + dmod = _mod; + action = _action; + hide = false; + + fnName = _context == ""? _name : $"{_context} {_name}"; + fnName = string_to_var(fnName); - CMD_FUNCTIONS[$ _fnName] = { _action, _args }; - ACTION_MAP[$ _action] = [ _context, _name ]; + FUNCTIONS[$ fnName] = self; + CMD_FUNCTIONS[$ fnName] = { action: _action, args: [] }; + ACTION_MAP[$ _action] = [ _context, _name ]; + + static setArg = function(_args = []) { + CMD_FUNCTIONS[$ fnName] = { action, args: _args }; + return self; + } + + static setMenu = function(_id, _spr = noone, shelf = false) { + var men = menuItemAction(__txt(name), action, _spr); + if(shelf) men.setIsShelf(); + MENU_ITEMS[$ _id] = men; + + return self; + } + + static hidePalette = function() { + hide = true; + return self; + } } function callStatusFunction(name) { diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 6f1659574..076b05c38 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -178,62 +178,6 @@ DEF_SURFACE_RESET(); #endregion -#region functions - function global_fullscreen() { CALL("fullscreen"); winMan_setFullscreen(!window_is_fullscreen); } - function global_project_close() { CALL("close_project"); PANEL_GRAPH.close(); } - function global_project_close_all() { CALL("close_project_all"); for( var i = array_length(PROJECTS) - 1; i >= 0; i-- ) closeProject(PROJECTS[i]); } - function global_theme_reload() { CALL("reload_theme"); loadGraphic(PREFERENCES.theme); resetPanel(); } - - function global_render_all() { CALL("render_all"); RENDER_ALL_REORDER } - function global_export_all() { - for (var i = 0, n = array_length(PROJECT.allNodes); i < n; i++) { - var node = PROJECT.allNodes[i]; - - if(!node.active) continue; - if(instanceof(node) != "Node_Export") continue; - - node.doInspectorAction(); - } - } - - function __fnInit_Global() { - registerFunction("", "New file", "N", MOD_KEY.ctrl, NEW); - - if(!DEMO) { - registerFunction("", "Save", "S", MOD_KEY.ctrl, SAVE); - registerFunction("", "Save as", "S", MOD_KEY.ctrl | MOD_KEY.shift, SAVE_AS); - registerFunction("", "Save at", "", MOD_KEY.none, SAVE_AT, [ ARG("project", function() { return PROJECT; }, true), ARG("path", ""), ARG("log", "save at ") ]); - registerFunction("", "Save all", "S", MOD_KEY.ctrl | MOD_KEY.alt, SAVE_ALL); - registerFunction("", "Open", "O", MOD_KEY.ctrl, LOAD); - registerFunction("", "Open Safe", "", MOD_KEY.none, LOAD_SAFE); - registerFunction("", "Open at", "", MOD_KEY.none, LOAD_AT, [ ARG("path", ""), ARG("readonly", false), ARG("override", false) ]); - registerFunction("", "Append", "", MOD_KEY.none, APPEND, [ ARG("path", ""), ARG("context", function() { return PANEL_GRAPH.getCurrentContext(); }, true) ]); - - registerFunction("", "Import .zip", "", MOD_KEY.none, __IMPORT_ZIP); - registerFunction("", "Export .zip", "", MOD_KEY.none, __EXPORT_ZIP); - } - - registerFunction("", "Undo", "Z", MOD_KEY.ctrl, UNDO); - registerFunction("", "Redo", "Z", MOD_KEY.ctrl | MOD_KEY.shift, REDO); - - registerFunction("", "Full panel", "`", MOD_KEY.none, set_focus_fullscreen); - registerFunction("", "Reset layout", vk_f10, MOD_KEY.ctrl, resetPanel); - - registerFunction("", "Open notification", vk_f12, MOD_KEY.none, function() /*=>*/ { dialogPanelCall(new Panel_Notification()); }); - - registerFunction("", "Fullscreen", vk_f11, MOD_KEY.none, global_fullscreen); - registerFunction("", "Render all", vk_f5, MOD_KEY.none, global_render_all); - registerFunction("", "Export all", "", MOD_KEY.none, global_export_all); - - registerFunction("", "Close file", "Q", MOD_KEY.ctrl, global_project_close); - registerFunction("", "Close all files", "", MOD_KEY.none, global_project_close_all); - registerFunction("", "Close program", vk_f4, MOD_KEY.alt, window_close); - registerFunction("", "Close project", "", MOD_KEY.none, closeProject, [ ARG("project", function() { return PROJECT; }, true) ]); - registerFunction("", "Reload theme", vk_f10, MOD_KEY.ctrl | MOD_KEY.shift, global_theme_reload); - } - -#endregion - #region debug global.FLAG = { render : 0, diff --git a/scripts/panel_animation/panel_animation.gml b/scripts/panel_animation/panel_animation.gml index 9f2719833..5c239e99a 100644 --- a/scripts/panel_animation/panel_animation.gml +++ b/scripts/panel_animation/panel_animation.gml @@ -1,2668 +1,2668 @@ #region funtion calls - function __fnInit_Animation() { - registerFunction("", "Play/Pause", vk_space, MOD_KEY.none, panel_animation_play_pause); - registerFunction("", "Resume/Pause", vk_space, MOD_KEY.shift, panel_animation_resume); - - registerFunction("", "First frame", vk_home, MOD_KEY.none, panel_animation_first_frame); - registerFunction("", "Last frame", vk_end, MOD_KEY.none, panel_animation_last_frame); - registerFunction("", "Next frame", vk_right, MOD_KEY.none, panel_animation_next_frame); - registerFunction("", "Previous frame", vk_left, MOD_KEY.none, panel_animation_prev_frame); - - registerFunction("Animation", "Delete keys", vk_delete, MOD_KEY.none, panel_animation_delete_key); - registerFunction("Animation", "Duplicate", "D", MOD_KEY.ctrl, panel_animation_duplicate); - registerFunction("Animation", "Copy", "C", MOD_KEY.ctrl, panel_animation_copy); - registerFunction("Animation", "Paste", "V", MOD_KEY.ctrl, panel_animation_paste); - registerFunction("Animation", "Collapse Toggle", "C", MOD_KEY.none, panel_animation_collapseToggle); - registerFunction("Animation", "Toggle Nodes", "H", MOD_KEY.none, panel_animation_show_nodes); - - registerFunction("Animation", "Settings", "S", MOD_KEY.ctrl | MOD_KEY.shift, panel_animation_settings); - registerFunction("Animation", "Scaler", "", MOD_KEY.none, panel_animation_scale); - - registerFunction("Animation", "Edit Keyframe Value","", MOD_KEY.none, panel_animation_edit_keyframe_value); - registerFunction("Animation", "Lock Keyframe Y", "", MOD_KEY.none, panel_animation_edit_keyframe_lock_y); - registerFunction("Animation", "Stagger", "", MOD_KEY.none, panel_animation_edit_keyframe_stagger); - registerFunction("Animation", "Driver", "", MOD_KEY.none, panel_animation_keyframe_driver); - - registerFunction("Animation", "New Folder", "", MOD_KEY.none, panel_animation_dopesheet_new_folder); - registerFunction("Animation", "Dopesheet Expand", "", MOD_KEY.none, panel_animation_dopesheet_expand); - registerFunction("Animation", "Dopesheet Collapse", "", MOD_KEY.none, panel_animation_dopesheet_collapse); - - registerFunction("Animation", "Rename Group", "", MOD_KEY.none, panel_animation_group_rename); - registerFunction("Animation", "Remove Group", "", MOD_KEY.none, panel_animation_group_remove); - registerFunction("Animation", "Separate Axis", "", MOD_KEY.none, panel_animation_separate_axis); - registerFunction("Animation", "Combine Axis", "", MOD_KEY.none, panel_animation_combine_axis); - - registerFunction("Animation", "Set Range Start", "", MOD_KEY.none, panel_animation_range_set_start); - registerFunction("Animation", "Set Range End", "", MOD_KEY.none, panel_animation_range_set_end); - registerFunction("Animation", "Reset Range", "", MOD_KEY.none, panel_animation_range_reset); - } - - function panel_animation_settings() { var dia = dialogPanelCall(new Panel_Animation_Setting()); dia.anchor = ANCHOR.none; } - function panel_animation_scale() { dialogPanelCall(new Panel_Animation_Scaler()); } - - function panel_animation_play_pause() { CALL("play_pause"); if(IS_RENDERING) return; if(IS_PLAYING) PROJECT.animator.pause() else PROJECT.animator.play(); } - function panel_animation_resume() { CALL("resume_pause"); if(IS_RENDERING) return; if(PROJECT.animator.is_playing) PROJECT.animator.pause() else PROJECT.animator.resume(); } - - function panel_animation_first_frame() { CALL("first_frame"); if(IS_RENDERING) return; PROJECT.animator.firstFrame(); } - function panel_animation_last_frame() { CALL("last_frame"); if(IS_RENDERING) return; PROJECT.animator.lastFrame(); } - function panel_animation_next_frame() { CALL("next_frame"); if(IS_RENDERING) return; PROJECT.animator.setFrame(min(PROJECT.animator.real_frame + 1, TOTAL_FRAMES - 1)); } - function panel_animation_prev_frame() { CALL("previous_frame"); if(IS_RENDERING) return; PROJECT.animator.setFrame(max(PROJECT.animator.real_frame - 1, 0)); } - - function panel_animation_collapseToggle(){ CALL("animation_collapse_toggle"); PANEL_ANIMATION.collapseToggle(); } - function panel_animation_delete_key() { CALL("animation_delete_key"); PANEL_ANIMATION.deleteKeys(); } - function panel_animation_duplicate() { CALL("animation_duplicate"); PANEL_ANIMATION.doDuplicate(); } - function panel_animation_copy() { CALL("animation_copy"); PANEL_ANIMATION.doCopy(); } - function panel_animation_paste() { CALL("animation_paste"); PANEL_ANIMATION.doPaste(PANEL_ANIMATION.value_focusing); } - function panel_animation_show_nodes() { CALL("animation_toggle_nodes"); PANEL_ANIMATION.show_nodes = !PANEL_ANIMATION.show_nodes; } - - function panel_animation_edit_keyframe_value() { CALL("animation_edit_keyframe_value"); PANEL_ANIMATION.edit_keyframe_value(); } - function panel_animation_edit_keyframe_lock_y() { CALL("animation_edit_lock_keyframe_y"); PANEL_ANIMATION.edit_keyframe_lock_y(); } - function panel_animation_edit_keyframe_stagger() { CALL("animation_stagger"); PANEL_ANIMATION.edit_keyframe_stagger(); } - function panel_animation_keyframe_driver() { CALL("animation_driver"); PANEL_ANIMATION.edit_keyframe_driver(); } - - function panel_animation_dopesheet_new_folder() { CALL("animation_new_folder"); PANEL_ANIMATION.dopesheet_new_folder(); } - function panel_animation_dopesheet_expand() { CALL("animation_dopesheet_expand"); PANEL_ANIMATION.dopesheet_expand(); } - function panel_animation_dopesheet_collapse() { CALL("animation_dopesheet_collapse"); PANEL_ANIMATION.dopesheet_collapse(); } - - function panel_animation_group_rename() { CALL("animation_rename_group"); PANEL_ANIMATION.group_rename(); } - function panel_animation_group_remove() { CALL("animation_remove_group"); PANEL_ANIMATION.group_remove(); } - function panel_animation_separate_axis() { CALL("animation_separate_axis"); PANEL_ANIMATION.separate_axis(); } - function panel_animation_combine_axis() { CALL("animation_combine_axis"); PANEL_ANIMATION.combine_axis(); } - - function panel_animation_range_set_start() { CALL("animation_range_set_start"); PANEL_ANIMATION.range_set_start(); } - function panel_animation_range_set_end() { CALL("animation_range_set_end"); PANEL_ANIMATION.range_set_end(); } - function panel_animation_range_reset() { CALL("animation_range_reset"); PANEL_ANIMATION.range_reset(); } + function __fnInit_Animation() { + registerFunction("", "Play/Pause", vk_space, MOD_KEY.none, panel_animation_play_pause ).setMenu("play_pause", ) + registerFunction("", "Resume/Pause", vk_space, MOD_KEY.shift, panel_animation_resume ).setMenu("resume_pause", ) + + registerFunction("", "First frame", vk_home, MOD_KEY.none, panel_animation_first_frame ).setMenu("first_frame", ) + registerFunction("", "Last frame", vk_end, MOD_KEY.none, panel_animation_last_frame ).setMenu("last_frame", ) + registerFunction("", "Next frame", vk_right, MOD_KEY.none, panel_animation_next_frame ).setMenu("next_frame", ) + registerFunction("", "Previous frame", vk_left, MOD_KEY.none, panel_animation_prev_frame ).setMenu("previous_frame", ) + + registerFunction("Animation", "Delete keys", vk_delete, MOD_KEY.none, panel_animation_delete_key ).setMenu("animation_delete_keys", ) + registerFunction("Animation", "Duplicate", "D", MOD_KEY.ctrl, panel_animation_duplicate ).setMenu("animation_duplicate", THEME.duplicate) + registerFunction("Animation", "Copy", "C", MOD_KEY.ctrl, panel_animation_copy ).setMenu("animation_copy", THEME.copy) + registerFunction("Animation", "Paste", "V", MOD_KEY.ctrl, panel_animation_paste ).setMenu("animation_paste", THEME.paste) + registerFunction("Animation", "Collapse Toggle", "C", MOD_KEY.none, panel_animation_collapseToggle ).setMenu("animation_collapse_toggle", ) + registerFunction("Animation", "Toggle Nodes", "H", MOD_KEY.none, panel_animation_show_nodes ).setMenu("animation_toggle_nodes", ) + + registerFunction("Animation", "Settings", "S", MOD_KEY.ctrl | MOD_KEY.shift, panel_animation_settings ).setMenu("animation_settings", THEME.animation_setting ) + registerFunction("Animation", "Scaler", "", MOD_KEY.none, panel_animation_scale ).setMenu("animation_scaler", THEME.animation_timing ) + + registerFunction("Animation", "Edit Keyframe Value","", MOD_KEY.none, panel_animation_edit_keyframe_value ).setMenu("animation_edit_keyframe_value", ) + registerFunction("Animation", "Lock Keyframe Y", "", MOD_KEY.none, panel_animation_edit_keyframe_lock_y ).setMenu("animation_lock_keyframe_y", ) + registerFunction("Animation", "Stagger", "", MOD_KEY.none, panel_animation_edit_keyframe_stagger ).setMenu("animation_stagger", ) + registerFunction("Animation", "Driver", "", MOD_KEY.none, panel_animation_keyframe_driver ).setMenu("animation_driver", ) + + registerFunction("Animation", "New Folder", "", MOD_KEY.none, panel_animation_dopesheet_new_folder ).setMenu("animation_new_folder", THEME.folder_content) + registerFunction("Animation", "Dopesheet Expand", "", MOD_KEY.none, panel_animation_dopesheet_expand ).setMenu("animation_dopesheet_expand", ) + registerFunction("Animation", "Dopesheet Collapse", "", MOD_KEY.none, panel_animation_dopesheet_collapse ).setMenu("animation_dopesheet_collapse", ) + + registerFunction("Animation", "Rename Group", "", MOD_KEY.none, panel_animation_group_rename ).setMenu("animation_rename_group", THEME.cross) + registerFunction("Animation", "Remove Group", "", MOD_KEY.none, panel_animation_group_remove ).setMenu("animation_remove_group", ) + registerFunction("Animation", "Separate Axis", "", MOD_KEY.none, panel_animation_separate_axis ).setMenu("animation_separate_axis", ) + registerFunction("Animation", "Combine Axis", "", MOD_KEY.none, panel_animation_combine_axis ).setMenu("animation_combine_axis", ) + + registerFunction("Animation", "Set Range Start", "", MOD_KEY.none, panel_animation_range_set_start ).setMenu("animation_set_range_start", [ THEME.frame_range, 0 ]) + registerFunction("Animation", "Set Range End", "", MOD_KEY.none, panel_animation_range_set_end ).setMenu("animation_set_range_end", [ THEME.frame_range, 1 ]) + registerFunction("Animation", "Reset Range", "", MOD_KEY.none, panel_animation_range_reset ).setMenu("animation_reset_range", ) + } + + function panel_animation_settings() { var dia = dialogPanelCall(new Panel_Animation_Setting()); dia.anchor = ANCHOR.none; } + function panel_animation_scale() { dialogPanelCall(new Panel_Animation_Scaler()); } + + function panel_animation_play_pause() { CALL("play_pause"); if(IS_RENDERING) return; if(IS_PLAYING) PROJECT.animator.pause() else PROJECT.animator.play(); } + function panel_animation_resume() { CALL("resume_pause"); if(IS_RENDERING) return; if(PROJECT.animator.is_playing) PROJECT.animator.pause() else PROJECT.animator.resume(); } + + function panel_animation_first_frame() { CALL("first_frame"); if(IS_RENDERING) return; PROJECT.animator.firstFrame(); } + function panel_animation_last_frame() { CALL("last_frame"); if(IS_RENDERING) return; PROJECT.animator.lastFrame(); } + function panel_animation_next_frame() { CALL("next_frame"); if(IS_RENDERING) return; PROJECT.animator.setFrame(min(PROJECT.animator.real_frame + 1, TOTAL_FRAMES - 1)); } + function panel_animation_prev_frame() { CALL("previous_frame"); if(IS_RENDERING) return; PROJECT.animator.setFrame(max(PROJECT.animator.real_frame - 1, 0)); } + + function panel_animation_collapseToggle() { CALL("animation_collapse_toggle"); PANEL_ANIMATION.collapseToggle(); } + function panel_animation_delete_key() { CALL("animation_delete_key"); PANEL_ANIMATION.deleteKeys(); } + function panel_animation_duplicate() { CALL("animation_duplicate"); PANEL_ANIMATION.doDuplicate(); } + function panel_animation_copy() { CALL("animation_copy"); PANEL_ANIMATION.doCopy(); } + function panel_animation_paste() { CALL("animation_paste"); PANEL_ANIMATION.doPaste(PANEL_ANIMATION.value_focusing); } + function panel_animation_show_nodes() { CALL("animation_toggle_nodes"); PANEL_ANIMATION.show_nodes = !PANEL_ANIMATION.show_nodes; } + + function panel_animation_edit_keyframe_value() { CALL("animation_edit_keyframe_value"); PANEL_ANIMATION.edit_keyframe_value(); } + function panel_animation_edit_keyframe_lock_y() { CALL("animation_edit_lock_keyframe_y"); PANEL_ANIMATION.edit_keyframe_lock_y(); } + function panel_animation_edit_keyframe_stagger() { CALL("animation_stagger"); PANEL_ANIMATION.edit_keyframe_stagger(); } + function panel_animation_keyframe_driver() { CALL("animation_driver"); PANEL_ANIMATION.edit_keyframe_driver(); } + + function panel_animation_dopesheet_new_folder() { CALL("animation_new_folder"); PANEL_ANIMATION.dopesheet_new_folder(); } + function panel_animation_dopesheet_expand() { CALL("animation_dopesheet_expand"); PANEL_ANIMATION.dopesheet_expand(); } + function panel_animation_dopesheet_collapse() { CALL("animation_dopesheet_collapse"); PANEL_ANIMATION.dopesheet_collapse(); } + + function panel_animation_group_rename() { CALL("animation_rename_group"); PANEL_ANIMATION.group_rename(); } + function panel_animation_group_remove() { CALL("animation_remove_group"); PANEL_ANIMATION.group_remove(); } + function panel_animation_separate_axis() { CALL("animation_separate_axis"); PANEL_ANIMATION.separate_axis(); } + function panel_animation_combine_axis() { CALL("animation_combine_axis"); PANEL_ANIMATION.combine_axis(); } + + function panel_animation_range_set_start() { CALL("animation_range_set_start"); PANEL_ANIMATION.range_set_start(); } + function panel_animation_range_set_end() { CALL("animation_range_set_end"); PANEL_ANIMATION.range_set_end(); } + function panel_animation_range_reset() { CALL("animation_range_reset"); PANEL_ANIMATION.range_reset(); } #endregion enum KEYFRAME_DRAG_TYPE { - move, - ease_in, - ease_out, - ease_both + move, + ease_in, + ease_out, + ease_both } function Panel_Animation() : PanelContent() constructor { - title = __txt("Animation"); - context_str = "Animation"; - icon = THEME.panel_animation_icon; - - #region ---- dimension ---- - timeline_h = ui(28); - min_w = ui(40); - min_h = ui(48); - tool_width = ui(224); - #endregion - - static initSize = function() { - timeline_w = w - tool_width - ui(80); - timeline_surface = surface_create_valid(timeline_w, timeline_h); - timeline_mask = surface_create_valid(timeline_w, timeline_h); - - dope_sheet_w = w - tool_width; - dope_sheet_h = h - timeline_h - ui(20); - dope_sheet_surface = surface_create_valid(dope_sheet_w, 1); - dope_sheet_mask = surface_create_valid(dope_sheet_w, 1); - - dope_sheet_name_mask = surface_create_valid(tool_width, 1); - dope_sheet_name_surface = surface_create_valid(tool_width, 1); - } - initSize(); - - #region ---- position ---- - dope_sheet_y = 0; - dope_sheet_y_to = 0; - dope_sheet_y_max = 0; - is_scrolling = false; - - dopesheet_dragging = noone; - dopesheet_drag_mx = 0; - #endregion - - #region ---- timeline ---- - timeline_scubbing = false; - timeline_scub_st = 0; - timeline_scale = 20; - timeline_separate = 5; - timeline_sep_line = 1; - _scrub_frame = -1; - - timeline_shift = 0; - timeline_shift_to = 0; - timeline_dragging = false; - timeline_drag_sx = 0; - timeline_drag_sy = 0; - timeline_drag_mx = 0; - timeline_drag_my = 0; - timeline_draggable = true; - - timeline_stretch = 0; - timeline_stretch_sx = 0; - timeline_stretch_mx = 0; - - timeline_show_time = -1; - timeline_preview = noone; - - timeline_contents = []; - - scroll_s = sprite_get_width(THEME.ui_scrollbar); - scroll_w = scroll_s; - - #endregion - - #region ---- keyframes ---- - keyframe_dragging = noone; - keyframe_drag_type = -1; - keyframe_dragout = false; - keyframe_drag_mx = 0; - keyframe_drag_my = 0; - keyframe_selecting = []; - - keyframe_boxable = true; - keyframe_boxing = false; - keyframe_box_sx = -1; - keyframe_box_sy = -1; - - keyframe_graph_surface = noone; - _graph_key_hover = noone; - _graph_key_hover_index = noone; - _graph_key_hover_x = noone; - _graph_key_hover_y = noone; - graph_key_hover = noone; - graph_key_hover_index = noone; - - graph_key_drag = noone; - graph_key_drag_index = noone; - - graph_key_mx = 0; - graph_key_my = 0; - graph_key_sx = 0; - graph_key_sy = 0; - #endregion - - #region ---- values ---- - value_hovering = noone; - value_focusing = noone; - #endregion - - #region ---- display ---- - show_node_outside_context = true; - show_nodes = true; - - tooltip_loop_prop = noone; - tooltip_loop_type = new tooltipSelector(__txtx("panel_animation_looping_mode", "Looping mode"), global.junctionEndName); - #endregion - - #region ---- item hover ---- - _item_dragging = noone; - item_dragging = noone; - item_dragging_mx = noone; - item_dragging_my = noone; - item_dragging_dx = noone; - item_dragging_dy = noone; - - hovering_folder = noone; - hovering_order = noone; - - node_name_type = 0; - node_name_tooltip = new tooltipSelector("Name Display", [ - __txtx("panel_animation_name_full", "Full name"), - __txtx("panel_animation_name_type", "Node type"), - __txtx("panel_animation_name_only", "Node name"), - ]); - #endregion - - #region ---- stagger ---- - stagger_mode = 0; - stagger_index = 0; - #endregion - - #region ---- tools ---- - tool_width_drag = false; - tool_width_start = 0; - tool_width_mx = 0; - #endregion - - on_end_dragging_anim = noone; - onion_dragging = noone; - prev_cache = array_create(TOTAL_FRAMES); - copy_clipboard = ds_list_create(); - - __collapse = false; - function collapseToggle() { - PANEL_ANIMATION.__collapse = !PANEL_ANIMATION.__collapse; - - for( var i = 0, n = array_length(PANEL_ANIMATION.timeline_contents); i < n; i++ ) - PANEL_ANIMATION.timeline_contents[i].item.show = PANEL_ANIMATION.__collapse; - } - - #region ++++ control_buttons ++++ - tooltip_toggle_nodes = new tooltipHotkey(__txtx("panel_animation_show_node", "Toggle node label"), "Animation", "Toggle nodes"); - tooltip_resume = new tooltipHotkey(__txt("Resume"), "", "Resume/Pause"); - tooltip_pause = new tooltipHotkey(__txt("Pause"), "", "Resume/Pause"); - tooltip_fr_first = new tooltipHotkey(__txtx("panel_animation_go_to_first_frame", "Go to first frame"), "", "First frame"); - tooltip_fr_last = new tooltipHotkey(__txtx("panel_animation_go_to_last_frame", "Go to last frame"), "", "Last frame"); - tooltip_fr_prev = new tooltipHotkey(__txtx("panel_animation_previous_frame", "Previous frame"), "", "Previous frame"); - tooltip_fr_next = new tooltipHotkey(__txtx("panel_animation_next_frame", "Next frame"), "", "Next frame"); - - control_buttons = [ - [ - function() { return __txt("Stop"); }, - function() { return 4; }, - function() { return PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_icon; }, - function() { PROJECT.animator.stop(); } - ], - [ - function() { return PROJECT.animator.is_playing? tooltip_pause : tooltip_resume; }, - function() { return !PROJECT.animator.is_playing; }, - function() { return PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_icon; }, - function() { if(PROJECT.animator.is_playing) PROJECT.animator.pause(); else PROJECT.animator.resume(); } - ], - [ - function() { return tooltip_fr_first; }, - function() { return 3; }, - function() { return COLORS._main_icon; }, - function() { PROJECT.animator.firstFrame(); } - ], - [ - function() { return tooltip_fr_last; }, - function() { return 2; }, - function() { return COLORS._main_icon; }, - function() { PROJECT.animator.lastFrame(); } - ], - [ - function() { return tooltip_fr_prev; }, - function() { return 5; }, - function() { return COLORS._main_icon; }, - function() { PROJECT.animator.setFrame(PROJECT.animator.real_frame - 1); } - ], - [ - function() { return tooltip_fr_next; }, - function() { return 6; }, - function() { return COLORS._main_icon; }, - function() { PROJECT.animator.setFrame(PROJECT.animator.real_frame + 1); } - ], - ]; - #endregion - - #region ++++ context menu ++++ - - #region actions - function edit_keyframe_value() { if(array_empty(keyframe_selecting)) return; editKeyFrame(keyframe_selecting[0]); } - - function edit_keyframe_lock_y() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_y_lock = !k.ease_y_lock; - } - } - - function edit_keyframe_stagger() { stagger_mode = 1; } - function edit_keyframe_driver() { dialogPanelCall(new Panel_Keyframe_Driver(keyframe_selecting[0]), mouse_mx + ui(8), mouse_my + ui(8)); } - - function dopesheet_new_folder() { var _dir = new timelineItemGroup(); PROJECT.timelines.addItem(_dir); } - function dopesheet_expand() { for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) timeline_contents[i].item.show = true; } - function dopesheet_collapse() { for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) timeline_contents[i].item.show = false; } - - function group_rename() { context_selecting_item.item.rename(); } - function group_remove() { context_selecting_item.item.destroy(); } - - function separate_axis() { context_selecting_prop.sep_axis = true; } - function combine_axis() { context_selecting_prop.sep_axis = false; } - - function range_set_start() { if(FRAME_RANGE == noone) FRAME_RANGE = [ __selecting_frame, TOTAL_FRAMES ]; else FRAME_RANGE[0] = __selecting_frame; } - function range_set_end() { if(FRAME_RANGE == noone) FRAME_RANGE = [ 0, __selecting_frame ]; else FRAME_RANGE[1] = __selecting_frame; } - function range_reset() { FRAME_RANGE = noone; } - #endregion - - keyframe_menu = [ - - menuItemAction(__txtx("panel_animation_keyframe_edit", "Edit Value..."), panel_animation_edit_keyframe_value), - menuItemAction(__txtx("panel_animation_lock_y", "Lock/Unlock Y easing"), panel_animation_edit_keyframe_lock_y), - - menuItemGroup(__txtx("panel_animation_ease_in", "Ease in"), [ - [ [THEME.timeline_ease, 0], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = CURVE_TYPE.linear; - k.ease_in = [0, 1]; - } - }, __txtx("panel_animation_ease_linear", "Linear") ], - [ [THEME.timeline_ease, 1], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = CURVE_TYPE.bezier; - k.ease_in = [1, 1]; - } - }, __txtx("panel_animation_ease_smooth", "Smooth") ], - [ [THEME.timeline_ease, 2], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = CURVE_TYPE.bezier; - k.ease_in = [1, 2]; - } - }, __txtx("panel_animation_ease_overshoot", "Overshoot") ], - [ [THEME.timeline_ease, 3], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = CURVE_TYPE.bezier; - k.ease_in = [0, 0]; - } - }, __txtx("panel_animation_ease_sharp", "Sharp") ], - [ [THEME.timeline_ease, 4], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = CURVE_TYPE.cut; - k.ease_in = [0, 0]; - } - }, __txtx("panel_animation_ease_hold", "Hold") ], - ]), - menuItemGroup(__txtx("panel_animation_ease_out", "Ease out"), [ - [ [THEME.timeline_ease, 0], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_out_type = CURVE_TYPE.linear; - k.ease_out = [0, 0]; - } - }, __txtx("panel_animation_ease_linear", "Linear") ], - [ [THEME.timeline_ease, 1], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_out_type = CURVE_TYPE.bezier; - k.ease_out = [1, 0]; - } - }, __txtx("panel_animation_ease_smooth", "Smooth") ], - [ [THEME.timeline_ease, 2], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_out_type = CURVE_TYPE.bezier; - k.ease_out = [1, -1]; - } - }, __txtx("panel_animation_ease_overshoot", "Overshoot") ], - [ [THEME.timeline_ease, 3], function() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_out_type = CURVE_TYPE.bezier; - k.ease_out = [0, 1]; - } - }, __txtx("panel_animation_ease_sharp", "Sharp") ], - ]), - -1, - menuItemGroup(__txt("Align"), [ - [ [THEME.object_halign, 0], function() { alignKeys(fa_left); } ], - [ [THEME.object_halign, 1], function() { alignKeys(fa_center); } ], - [ [THEME.object_halign, 2], function() { alignKeys(fa_right); } ], - ]), - menuItemAction(__txtx("panel_animation_stagger", "Stagger"), panel_animation_edit_keyframe_stagger), - menuItemAction(__txtx("panel_driver", "Driver..."), panel_animation_keyframe_driver), - -1, - menuItemAction(__txt("Delete"), panel_animation_delete_key), - menuItemAction(__txt("Duplicate"), panel_animation_duplicate, THEME.duplicate), - menuItemAction(__txt("Copy"), panel_animation_copy, THEME.copy), - menuItemAction(__txt("Paste"), panel_animation_paste, THEME.paste), - ]; - - keyframe_menu_empty = [ - menuItemAction(__txt("Paste"), panel_animation_paste, THEME.paste), - ]; - - context_selecting_item = noone; - context_selecting_prop = noone; - - name_menu_empty = [ - menuItemAction(__txt("New folder"), panel_animation_dopesheet_new_folder, THEME.folder_content), - -1, - menuItemAction(__txt("Expand all"), panel_animation_dopesheet_expand), - menuItemAction(__txt("Collapse all"), panel_animation_dopesheet_collapse), - ]; - - var _clrs = COLORS.labels; - var _item = array_create(array_length(_clrs)); - - function setSelectingItemColor(color) { if(context_selecting_item == noone) return; context_selecting_item.item.setColor(color); } - - for( var i = 0, n = array_length(_clrs); i < n; i++ ) { - _item[i] = [ - [ THEME.timeline_color, i > 0, _clrs[i] ], - function(_data) { setSelectingItemColor(_data.color); }, "", { color: i == 0? -1 : _clrs[i] } - ]; - } - - array_push(_item, [ - [ THEME.timeline_color, 2 ], - function(_data) /*=>*/ { colorSelectorCall(context_selecting_item? context_selecting_item.item.getColor() : c_white, setSelectingItemColor); } - ]); - - var clr = menuItemGroup(__txt("Color"), _item); - clr.spacing = ui(24); - - name_menu_item = [ - clr, - -1, - name_menu_empty[0], - name_menu_empty[2], - name_menu_empty[3], - ]; - - name_menu_group = [ - clr, - menuItemAction(__txt("Rename"), panel_animation_group_rename), - menuItemAction(__txt("Delete"), panel_animation_group_remove, THEME.cross), - -1, - name_menu_empty[0] - ]; - - name_menu_prop_sep = [ - menuItemAction(__txtx("panel_inspector_axis_separate", "Separate axis"), panel_animation_separate_axis), - -1, - name_menu_empty[2], - name_menu_empty[3], - ]; - - name_menu_prop_join = [ - menuItemAction(__txtx("panel_inspector_axis_combine", "Combine axis"), panel_animation_combine_axis), - -1, - name_menu_empty[2], - name_menu_empty[3], - ]; - - #endregion ++++ context menu ++++ - - function deleteKeys() { - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.anim.removeKey(k); - } - - keyframe_selecting = []; - } - - function alignKeys(halign = fa_left) { - if(array_empty(keyframe_selecting)) return; - - var tt = 0; - - switch(halign) { - case fa_left : - tt = 9999; - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) - tt = min(tt, keyframe_selecting[i].time); - break; - case fa_center : - tt = 0; - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) - tt += keyframe_selecting[i].time; - tt = round(tt / array_length(keyframe_selecting)); - break; - case fa_right : - tt = -9999; - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) - tt = max(tt, keyframe_selecting[i].time); - break; - } - - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.anim.setKeyTime(k, tt,, true); - } - } - - function arrangeKeys() { - //keyframe_selecting = l; - } - - function staggerKeys(_index, _stag) { - var modified = false; - var t = keyframe_selecting[_index].time; - - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - var _t = t + abs(i - _index) * _stag; - - modified |= k.anim.setKeyTime(k, _t); - } - - if(modified) UNDO_HOLDING = true; - } - - function onFocusBegin() { PANEL_ANIMATION = self; } - - function surfaceVerify() { - if(w - tool_width > 1) { - timeline_mask = surface_verify(timeline_mask, timeline_w, timeline_h); - timeline_surface = surface_verify(timeline_surface, timeline_w, timeline_h); - } - - dope_sheet_w = timeline_w; - dope_sheet_h = h - timeline_h - ui(24); - if(dope_sheet_h > ui(8)) { - dope_sheet_mask = surface_verify(dope_sheet_mask, dope_sheet_w, dope_sheet_h); - dope_sheet_surface = surface_verify(dope_sheet_surface, dope_sheet_w, dope_sheet_h); - - dope_sheet_name_mask = surface_verify(dope_sheet_name_mask, tool_width, dope_sheet_h); - dope_sheet_name_surface = surface_verify(dope_sheet_name_surface, tool_width, dope_sheet_h); - } - } - - function onResize() { - initSize(); - - surfaceVerify(); - resetTimelineMask(); - } - - function resetTimelineMask() { - timeline_mask = surface_verify(timeline_mask, timeline_w, timeline_h); - - surface_set_target(timeline_mask); - draw_clear(c_black); - gpu_set_blendmode(bm_subtract); - draw_sprite_stretched(THEME.ui_panel_bg, 0, 0, 0, timeline_w, timeline_h); - gpu_set_blendmode(bm_normal); - surface_reset_target(); - - if(dope_sheet_h > 8) { - gpu_set_blendmode(bm_subtract); - - surface_set_target(dope_sheet_mask); - draw_clear(c_black); - draw_sprite_stretched(THEME.ui_panel_bg, 0, 0, 0, dope_sheet_w, dope_sheet_h); - surface_reset_target(); - - surface_set_target(dope_sheet_name_mask); - draw_clear(c_black); - draw_sprite_stretched(THEME.ui_panel_bg, 0, 0, 0, tool_width, dope_sheet_h); - surface_reset_target(); - - gpu_set_blendmode(bm_normal); - } - } - resetTimelineMask(); - - function getTimelineContentFolder(folder, _context = [], _depth = 0, _show = true) { #region - var ind = 0; - - for( var i = 0, n = array_length(folder.contents); i < n; i++ ) { - var _cont = folder.contents[i]; - if(!_cont.active) continue; - - var _content = { - item: _cont, - parent: _cont.parent, - index: ind, - contexts: _context, - y: 0, - h: 0, - depth: _depth, - show: _show, - }; - - if(is_instanceof(_cont, timelineItemGroup)) { - _content.type = "folder"; - array_push(timeline_contents, _content); - - var _context_folder = array_create(array_length(_context) + 1); - for( var j = 0, m = array_length(_context); j < m; j++ ) - _context_folder[j] = _context[j]; - _context_folder[m] = _content; - - if(item_dragging == noone || item_dragging.item != _cont) - getTimelineContentFolder(_cont, _context_folder, _depth + 1, _show && _cont.show); - } else if(is_instanceof(_cont, timelineItemNode)) { - var _node = _cont.node; - if(!is_struct(_node)) continue; - - var _anim = []; - var _prop = []; - - for( var j = 0, m = array_length(_node.inputs); j < m; j++ ) { - var prop = _node.inputs[j]; - if(!prop.isTimelineVisible()) continue; - - var anim = prop.sep_axis? prop.animators : [ prop.animator ]; - if(prop.sep_axis) array_append(_anim, prop.animators); - else array_push(_anim, prop.animator); - - array_push(_prop, { prop, animators: anim, y: 0 }); - } - - _content.type = "node"; - _content.node = _node; - _content.props = _prop; - _content.animators = _anim; - - array_push(timeline_contents, _content); - } - - if(item_dragging == noone || item_dragging.item != _cont) ind++; - } - } #endregion - - function getTimelineContent() { #region - timeline_contents = []; - getTimelineContentFolder(PROJECT.timelines); - } #endregion - - function drawTimeline() { #region // Draw summary - var bar_x = tool_width + ui(16); - var bar_y = h - timeline_h - ui(10); - var bar_w = timeline_w; - var bar_h = timeline_h; - var bar_total_w = TOTAL_FRAMES * timeline_scale; - var inspecting = PANEL_INSPECTOR.getInspecting(); - - resetTimelineMask(); - timeline_surface = surface_verify(timeline_surface, timeline_w, timeline_h); - - surface_set_target(timeline_surface); - draw_clear_alpha(COLORS.panel_bg_clear, 0); - - #region bg - draw_sprite_stretched(THEME.ui_panel_bg, 1, 0, 0, bar_w, bar_h); - draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, bar_w, bar_h, COLORS.panel_animation_timeline_blend, 1); - #endregion - - #region cache - if(inspecting && inspecting.use_cache) { - for(var i = 0; i < TOTAL_FRAMES; i++) { - if(i >= array_length(inspecting.cache_result)) - break; - - var x0 = (i + 0) * timeline_scale + timeline_shift; - var x1 = (i + 1) * timeline_scale + timeline_shift; - - draw_set_color(inspecting.getAnimationCacheExist(i)? c_lime : c_red); - draw_set_alpha(0.05); - draw_rectangle(x0, 0, x1, bar_h, false); - draw_set_alpha(1); - } - } - #endregion - - #region lines - if(inspecting) - inspecting.drawAnimationTimeline(timeline_shift, bar_w, bar_h, timeline_scale); - - var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; - - for(var i = timeline_separate; i <= _fr; i += timeline_separate) { - var bar_line_x = i * timeline_scale + timeline_shift; - - if(i > TOTAL_FRAMES) draw_set_alpha(0.5); - - draw_set_color(COLORS.panel_animation_frame_divider); - draw_line(bar_line_x, ui(12), bar_line_x, bar_h - PANEL_PAD); - - draw_set_text(f_p2, fa_center, fa_bottom, COLORS._main_text_sub); - draw_text_add(bar_line_x, ui(16), string(i)); - } - - draw_set_alpha(1); - - var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; - draw_set_color(COLORS.panel_animation_end_line); - draw_set_alpha(0.5); - draw_line_width(bar_line_x, 0, bar_line_x, bar_h, 2); - draw_set_alpha(1.0); - - if(FRAME_RANGE != noone) { - var _fr_x0 = FRAME_RANGE[0] * timeline_scale + timeline_shift - 6; - var _fr_x1 = FRAME_RANGE[1] * timeline_scale + timeline_shift + 2; - - if(PROJECT.animator.is_simulating) - draw_sprite_stretched_ext(THEME.ui_selection_range_sim_hori, 0, _fr_x0, 0, _fr_x1 - _fr_x0, bar_h, COLORS.panel_animation_range_sim, 1); - else - draw_sprite_stretched_ext(THEME.ui_selection_range_hori, 0, _fr_x0, 0, _fr_x1 - _fr_x0, bar_h, COLORS.panel_animation_range, 1); - } - - var bar_line_x = (CURRENT_FRAME + 1) * timeline_scale + timeline_shift; - var cc = PROJECT.animator.is_playing? COLORS._main_value_positive : COLORS._main_accent; - draw_set_color(cc); - draw_line(bar_line_x, ui(15), bar_line_x, bar_h - PANEL_PAD); - - draw_set_text(f_p2, fa_center, fa_bottom, cc); - draw_text_add(bar_line_x, ui(16), string(CURRENT_FRAME + 1)); - #endregion - - #region summary \\\ Set X for all keyframes - var index = 0; - var key_y = ui(12) + (bar_h - ui(12)) / 2; - - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - if(_cont.type != "node") continue; - - var _anims = _cont.animators; - - for( var j = 0, m = array_length(_anims); j < m; j++ ) { - var _anim = _anims[j]; - - for(var k = 0; k < array_length(_anim.values); k++) { - var _keyframe = _anim.values[k]; - - var t = (_keyframe.time + 1) * timeline_scale + timeline_shift; - _keyframe.dopesheet_x = t; - - draw_sprite_ui_uniform(THEME.timeline_keyframe, 0, t, key_y, 1, COLORS.panel_animation_keyframe_hide); - } - } - } - #endregion - - #region pan zoom - timeline_shift = lerp_float(timeline_shift, timeline_shift_to, 4); - - if(timeline_scubbing) { - var rfrm = (mx - bar_x - timeline_shift) / timeline_scale - 1; - PROJECT.animator.setFrame(clamp(rfrm, 0, TOTAL_FRAMES - 1), !key_mod_press(ALT)); - timeline_show_time = CURRENT_FRAME; - - if(timeline_show_time != _scrub_frame) { - _scrub_frame = timeline_show_time; - } - - if(mouse_release(mb_left)) - timeline_scubbing = false; - } - - if(timeline_dragging) { - timeline_shift_to = clamp(timeline_drag_sx + mx - timeline_drag_mx, -max(bar_total_w - bar_w + 32, 0), 0); - timeline_shift = timeline_shift_to; - dope_sheet_y_to = clamp(timeline_drag_sy + my - timeline_drag_my, -dope_sheet_y_max, 0); - - if(mouse_release(mb_middle)) - timeline_dragging = false; - } - #endregion - - gpu_set_blendmode(bm_subtract); - draw_surface_safe(timeline_mask); - gpu_set_blendmode(bm_normal); - surface_reset_target(); - - draw_surface_safe(timeline_surface, bar_x, bar_y); - - #region mouse interact - var bar_line_w = TOTAL_FRAMES * timeline_scale + timeline_shift; - var bar_int_x = min(bar_x + bar_w, bar_x + bar_line_w); - - if(pHOVER && point_in_rectangle(mx, my, bar_x, 16, bar_x + bar_w, bar_y - 8)) { - var sca = timeline_scale; - - if(mouse_wheel_down()) timeline_scale = max(timeline_scale - 1 * SCROLL_SPEED, 1); - if(mouse_wheel_up()) timeline_scale = min(timeline_scale + 1 * SCROLL_SPEED, 24); - - timeline_separate = 5; - timeline_sep_line = 1; - - if(timeline_scale <= 1) { timeline_separate = 50; timeline_sep_line = 10; } - else if(timeline_scale <= 3) { timeline_separate = 20; timeline_sep_line = 5; } - else if(timeline_scale <= 10) { timeline_separate = 10; timeline_sep_line = 2; } - - if(sca != timeline_scale) { - var mfb = (mx - bar_x - timeline_shift) / timeline_scale; - var mfa = (mx - bar_x - timeline_shift) / ui(sca); - - timeline_shift_to = clamp(timeline_shift_to - (mfa - mfb) * timeline_scale, -max(bar_total_w - bar_w + 32, 0), 0); - timeline_shift = timeline_shift_to; - } - - if(mx < bar_int_x && mouse_press(mb_middle, pFOCUS)) { - timeline_dragging = true; - - timeline_drag_sx = timeline_shift; - timeline_drag_sy = dope_sheet_y_to; - timeline_drag_mx = mx; - timeline_drag_my = my; - } - } - - if(pHOVER && point_in_rectangle(mx, my, bar_x, bar_y, bar_x + bar_w, bar_y + bar_h)) { //preview - if(mouse_wheel_down()) timeline_shift_to = clamp(timeline_shift_to - 64 * SCROLL_SPEED, -max(bar_total_w - bar_w + 32, 0), 0); - if(mouse_wheel_up()) timeline_shift_to = clamp(timeline_shift_to + 64 * SCROLL_SPEED, -max(bar_total_w - bar_w + 32, 0), 0); - - if(mx < bar_int_x && mouse_press(mb_left, pFOCUS)) { - timeline_scubbing = true; - timeline_scub_st = CURRENT_FRAME; - _scrub_frame = timeline_scub_st; - } - - if(mouse_press(mb_right, pFOCUS)) { - __selecting_frame = clamp(round((mx - bar_x - timeline_shift) / timeline_scale), 0, TOTAL_FRAMES - 1); - - menuCall("animation_summary_menu",,, [ - menuItemAction(__txtx("panel_animation_range_start", "Set start"), panel_animation_range_set_start, [ THEME.frame_range, 0 ]), - menuItemAction(__txtx("panel_animation_range_end", "Set end"), panel_animation_range_set_end, [ THEME.frame_range, 1 ]), - menuItemAction(__txtx("panel_animation_range_reset", "Reset range"), panel_animation_range_reset), - ]); - } - } - - if(pHOVER && point_in_rectangle(mx, my, bar_x, 8, bar_x + bar_w, 8 + 16)) { //top bar - if(mx < bar_int_x && mouse_press(mb_left, pFOCUS) && timeline_draggable) { - timeline_scubbing = true; - timeline_scub_st = CURRENT_FRAME; - _scrub_frame = timeline_scub_st; - } - } - - timeline_draggable = true; - #endregion - } #endregion - - function __drawDopesheetGraphLine(animator, key_y, msx, msy, _gy_val_min = 999999, _gy_val_max = -999999) { - var bar_total_w = TOTAL_FRAMES * timeline_scale; - var bar_show_w = timeline_shift + bar_total_w; - var hovering = noone; - - var _gh = animator.prop.graph_h - ui(16); - var _gy0 = key_y + ui(8); - var _gy1 = _gy0 + _gh; - - var amo = array_length(animator.values); - - #region get range - var _prevDelt = [ 0, 0 ]; - - for(var k = 0; k < amo; k++) { - var key = animator.values[k]; - var key_val = key.value; - - var _minn = _gy_val_min; - var _maxx = _gy_val_max; - - if(is_array(key_val)) { - for( var ki = 0; ki < array_length(key_val); ki++ ) { - _minn = min(_minn, key_val[ki]); - _maxx = max(_maxx, key_val[ki]); - } - } else { - _minn = min(_minn, key_val); - _maxx = max(_maxx, key_val); - } - - _minn += _prevDelt[0]; - _maxx += _prevDelt[1]; - _prevDelt = [ 0, 0 ]; - - switch(key.drivers.type) { - case DRIVER_TYPE.linear : - var nk = k + 1 < amo? animator.values[k + 1].time : TOTAL_FRAMES; - - var spd = key.drivers.speed * (nk - key.time); - _minn += min(spd, 0); - _maxx += max(spd, 0); - _prevDelt = [ min(spd, 0), max(spd, 0) ]; - break; - case DRIVER_TYPE.wiggle : - case DRIVER_TYPE.sine : - _minn -= abs(key.drivers.amplitude); - _maxx += abs(key.drivers.amplitude); - _prevDelt = [ -key.drivers.amplitude, key.drivers.amplitude ]; - break; - } - - _gy_val_min = min(_minn, _gy_val_min); - _gy_val_max = max(_maxx, _gy_val_max); - } - #endregion - - var valArray = is_array(animator.values[0].value); - var ox = 0; - var nx = 0; - var ny = noone; - - var oly = 0; - var nly = 0; - var _kv, _kn; - var sy; - - var _oy = animator.values[0].value; - if(!valArray) _oy = [ _oy ]; - - var oy = array_create(array_length(_oy)); - for( var ki = 0; ki < array_length(_oy); ki++ ) - oy[ki] = value_map(_oy[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - - for(var k = 0; k < amo - 1; k++) { // draw line in between - var key = animator.values[k]; - var t = key.dopesheet_x; - var key_next = animator.values[k + 1]; - var dx = key_next.time - key.time; - - if(key.drivers.type) { // driver - nx = (key.time + 1) * timeline_scale + timeline_shift; - - for( var _time = key.time; _time <= key_next.time; _time++ ) { - var rat = (_time - key.time) / (key_next.time - key.time); - var _lrp = animator.interpolate(key, key_next, rat); - - _kv = animator.processDriver(_time, key, animator.lerpValue(key, key_next, _lrp), rat); - - if(!valArray) _kv = [ _kv ]; - - for( var ki = 0; ki < array_length(_kv); ki++ ) { - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); - __draw_set_color(cc); - - ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - - if(_time == key.time) draw_line(nx, oy[ki], nx, ny[ki]); - else draw_line(ox, oy[ki], nx, ny[ki]); - - oy[ki] = ny[ki]; - } - - ox = nx; - nx += timeline_scale; - } - } else if(key.ease_out_type == CURVE_TYPE.linear && key_next.ease_in_type == CURVE_TYPE.linear) { //linear draw - nx = (key_next.time + 1) * timeline_scale + timeline_shift; - - _kv = key.value; - _kn = key_next.value; - - if(!valArray) { - _kv = [ _kv ]; - _kn = [ _kn ]; - } - - for( var ki = 0; ki < array_length(_kv); ki++ ) { - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); - __draw_set_color(cc); - - ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - - if(array_length(oy) > ki) draw_line(t, oy[ki], t, ny[ki]); - oy[ki] = ny[ki]; - - ny[ki] = value_map(_kn[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - draw_line(t, oy[ki], nx, ny[ki]); - oy[ki] = ny[ki]; - } - - ox = nx; - } else { //bezier easing - var _step = 1 / dx; - for( var _r = 0; _r <= 1; _r += _step ) { - nx = t + _r * dx * timeline_scale; - nly = animator.interpolate(key, key_next, _r); - - _kv = key.value; - _kn = key_next.value; - - if(!valArray) { - _kv = [ _kv ]; - _kn = [ _kn ]; - } - - for( var ki = 0; ki < array_length(_kv); ki++ ) { - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); - __draw_set_color(cc); - - ny[ki] = value_map(lerp(_kv[ki], _kn[ki], nly), _gy_val_min, _gy_val_max, _gy1, _gy0); - - if(array_length(oy) > ki) draw_line(ox, oy[ki], nx, ny[ki]); - - oy[ki] = ny[ki]; - } - - ox = nx; - oly = nly; - } - } - } // draw line in between - - if(animator.prop.show_graph && array_length(animator.values) > 0) { // draw line outside keyframe range - var key_first = animator.values[0]; - var t_first = (key_first.time + 1) * timeline_scale + timeline_shift; - - _kv = key_first.value; - if(!valArray) _kv = [ _kv ]; - - for( var ki = 0; ki < array_length(_kv); ki++ ) { - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); - __draw_set_color(cc); - - sy = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - draw_line(0, sy, t_first, sy); - - if(array_length(animator.values) == 1) oy[ki] = sy; - } - - var key_last = animator.values[array_length(animator.values) - 1]; - var t_last = (key_last.time + 1) * timeline_scale + timeline_shift; - - if(key_last.time < TOTAL_FRAMES) { - if(key_last.drivers.type) { - nx = t_last; - - for( var _time = key_last.time; _time < TOTAL_FRAMES; _time++ ) { - _kv = animator.processDriver(_time, key_last); - if(!valArray) _kv = [ _kv ]; - - for( var ki = 0; ki < array_length(_kv); ki++ ) { - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); - __draw_set_color(cc); - - ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - if(_time == key_last.time) - draw_line(t_last, oy[ki], t_last, ny[ki]); - else - draw_line(ox, oy[ki], nx, ny[ki]); - - oy[ki] = ny[ki]; - } - - ox = nx; - nx += timeline_scale; - } - } else { - _kv = key_last.value; - if(!valArray) _kv = [ _kv ]; - - for( var ki = 0; ki < array_length(_kv); ki++ ) { - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); - __draw_set_color(cc); - - ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); - draw_line(t_last, oy[ki], t_last, ny[ki]); - draw_line(t_last, ny[ki], bar_show_w, ny[ki]); - } - } - } - } // draw line outside keyframe range - - #region // draw key - - for(var i = 0; i < amo; i++) { - var key = animator.values[i]; - var px = key.dopesheet_x; - - var v = key.value; - if(!valArray) v = [ v ]; - - var ei = key.ease_in; - var eo = key.ease_out; - - var ix = px - ei[0] * timeline_scale * 2; - var ox = px + eo[0] * timeline_scale * 2; - - for (var j = 0, m = array_length(v); j < m; j++) { - var py = value_map(v[j], _gy_val_min, _gy_val_max, _gy1, _gy0); - var iy = py + (1 - ei[1]) * timeline_scale * 2; - var oy = py - ( eo[1]) * timeline_scale * 2; - - var cc = COLORS.panel_animation_graph_line; - if(valArray) cc = array_safe_get(COLORS.axis, j, cc); - else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); - - if(ei[0] != 0) { - var _hv = (graph_key_hover == key && ( graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_in || graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_both)) || - (graph_key_drag == key && ( graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_in || graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_both)); - - draw_set_color(_hv? COLORS._main_accent : cc); - draw_line(ix, iy, px, py); - draw_circle(ix, iy, 3, false); - - if(point_in_circle(msx, msy, ix, iy, 4)) { - _graph_key_hover = key; - _graph_key_hover_index = KEYFRAME_DRAG_TYPE.ease_in; - - _graph_key_hover_x = px; - _graph_key_hover_y = py; - } - } - - if(eo[0] != 0) { - var _hv = (graph_key_hover == key && (graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_out || graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_both)) || - (graph_key_drag == key && (graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_out || graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_both)); - - draw_set_color(_hv? COLORS._main_accent : cc); - draw_line(px, py, ox, oy); - draw_circle(ox, oy, 3, false); - - if(point_in_circle(msx, msy, ox, oy, 4)) { - _graph_key_hover = key; - _graph_key_hover_index = KEYFRAME_DRAG_TYPE.ease_out; - - _graph_key_hover_x = px; - _graph_key_hover_y = py; - } - } - - var _hv = (graph_key_hover == key && graph_key_hover_index == KEYFRAME_DRAG_TYPE.move) || - (graph_key_drag == key && graph_key_drag_index == KEYFRAME_DRAG_TYPE.move); - - draw_set_color(_hv? COLORS._main_accent : cc); - draw_circle(px, py, 4, false); - - if(point_in_circle(msx, msy, px, py, 5)) { - _graph_key_hover = key; - _graph_key_hover_index = KEYFRAME_DRAG_TYPE.move; - - _graph_key_hover_x = px; - _graph_key_hover_y = py; - } - } - - } - #endregion // draw key - } - - function _drawDopesheetGraph(prop, key_y, msx, msy) { - var bar_total_w = TOTAL_FRAMES * timeline_scale; - var bar_show_w = timeline_shift + bar_total_w; - - if(prop.type == VALUE_TYPE.color) { // draw color - - var _gy0 = key_y - ui(4); - var _gy1 = key_y + ui(4); - - var amo = array_length(prop.animator.values); - var _prevKey = prop.animator.values[0]; - - draw_set_color(_prevKey.value); - draw_rectangle(0, _gy0, _prevKey.dopesheet_x, _gy1, 0); - - var ox, nx, oc, nc; - - for(var k = 0; k < amo - 1; k++) { - var key = prop.animator.values[k]; - var key_next = prop.animator.values[k + 1]; - var dx = key_next.time - key.time; - var _step = 1 / dx; - - for( var _r = 0; _r <= 1; _r += _step ) { - nx = key.dopesheet_x + _r * dx * timeline_scale; - var lrp = prop.animator.interpolate(key, key_next, _r); - nc = merge_color(key.value, key_next.value, lrp); - - if(_r > 0) draw_rectangle_color(ox, _gy0, nx, _gy1, oc, nc, nc, oc, 0); - - ox = nx; - oc = nc; - } - } - - key_next = prop.animator.values[array_length(prop.animator.values) - 1]; - if(key_next.time < TOTAL_FRAMES) { - draw_set_color(key_next.value); - draw_rectangle(key_next.dopesheet_x, _gy0, bar_show_w, _gy1, 0); - } - return; - } - - var bar_x = tool_width + ui(16); - var bar_y = h - timeline_h - ui(10); - var bar_w = timeline_w; - var bar_h = timeline_h; - var bar_total_w = TOTAL_FRAMES * timeline_scale; - - var _gh = prop.graph_h; - var _gy0 = key_y + ui(8); - var _gy1 = _gy0 + _gh; - - if(point_in_rectangle(msx, msy, 0, _gy0, w, _gy1)) - keyframe_boxable = false; - - var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; - var _mmx = msx - 0; - var _mmy = msy - _gy0; - - keyframe_graph_surface = surface_verify(keyframe_graph_surface, w, _gh); - surface_set_target(keyframe_graph_surface); - draw_clear(COLORS.panel_animation_timeline_top); - - for(var i = timeline_sep_line; i <= _fr; i += timeline_sep_line) { - var bar_line_x = i * timeline_scale + timeline_shift; - - draw_set_color(COLORS.panel_animation_frame_divider); - draw_set_alpha((i % timeline_separate == 0? 1 : 0.1) * ((i <= TOTAL_FRAMES) * 0.5 + 0.5) * 0.3); - draw_line(bar_line_x, 0, bar_line_x, _gh - PANEL_PAD); - } - draw_set_alpha(1); - - var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; - draw_set_color(COLORS.panel_animation_end_line); - draw_set_alpha(0.5); - draw_line_width(bar_line_x, 0, bar_line_x, _gh, 2); - draw_set_alpha(1); - - if(prop.sep_axis) { // draw number graphs - var _min = 999999; - var _max = -999999; - - for( var i = 0, n = array_length(prop.animators); i < n; i++ ) { - if(!prop.show_graphs[i]) continue; - - var animator = prop.animators[i]; - for(var k = 0; k < array_length(animator.values); k++) { - var key_val = animator.values[k].value; - if(is_array(key_val)) { - for( var ki = 0; ki < array_length(key_val); ki++ ) { - _min = min(_min, key_val[ki]); - _max = max(_max, key_val[ki]); - } - } else { - _min = min(_min, key_val); - _max = max(_max, key_val); - } - } - } - - for( var i = 0, n = array_length(prop.animators); i < n; i++ ) { - if(!prop.show_graphs[i]) continue; - - __drawDopesheetGraphLine(prop.animators[i], 0, _mmx, _mmy, _min, _max); - } - } else - __drawDopesheetGraphLine(prop.animator, 0, _mmx, _mmy); - surface_reset_target(); - - draw_surface(keyframe_graph_surface, 0, _gy0); - - } - - function editKeyFrame(keyframe, _x = mouse_mx + ui(8), _y = mouse_my + ui(8)) { - var _prop = keyframe.anim.prop; - var _wid = _prop.editWidget; - __keyframe_editing = keyframe; - - switch(_prop.type) { - case VALUE_TYPE.color : - switch(_prop.display_type) { - case VALUE_DISPLAY.palette : - var dialog = dialogCall(o_dialog_palette, WIN_W / 2, WIN_H / 2); - dialog.setDefault(keyframe.value); - dialog.onApply = function(val) { __keyframe_editing.value = val; }; - dialog.drop_target = _wid; - break; - - default : - var dialog = dialogCall(o_dialog_color_selector, WIN_W / 2, WIN_H / 2); - dialog.setDefault(keyframe.value); - dialog.selector.onApply = function(val) { __keyframe_editing.value = val; }; - dialog.onApply = function(val) { __keyframe_editing.value = val; }; - dialog.drop_target = _wid; - } - break; - - case VALUE_TYPE.gradient : - var dialog = dialogCall(o_dialog_gradient, WIN_W / 2, WIN_H / 2); - dialog.setDefault(keyframe.value.clone()); - dialog.onApply = function(val) { __keyframe_editing.value = val; }; - dialog.drop_target = _wid; - break; - - default : - dialogCall(o_dialog_value_editor, _x, _y).setKey(keyframe); - } - } - - function _drawDopesheetAnimatorKeysBG(animator, msx, msy) { #region - var prop_dope_y = animator.y; - var key_hover = noone; - var key_list = animator.values; - - if((animator.prop.on_end == KEYFRAME_END.loop || animator.prop.on_end == KEYFRAME_END.ping) && array_length(key_list) > 1) { - var keyframe_s = animator.prop.loop_range == -1? key_list[0].time : key_list[array_length(key_list) - 1 - animator.prop.loop_range].time; - var keyframe_e = key_list[array_length(key_list) - 1].time; - - var ks_x = (keyframe_s + 1) * timeline_scale + timeline_shift; - var ke_x = (keyframe_e + 1) * timeline_scale + timeline_shift; - - draw_set_color(COLORS.panel_animation_loop_line); - draw_set_alpha(0.2); - draw_line_width(ks_x, prop_dope_y - 1, ke_x, prop_dope_y - 1, 4); - draw_set_alpha(1); - } - - for( var k = 0, n = array_length(key_list); k < n; k++ ) { //draw easing - var key = key_list[k]; - var t = key.dopesheet_x; - - if(key.ease_in_type == CURVE_TYPE.bezier) { - draw_set_color(COLORS.panel_animation_keyframe_ease_line); - var _tx = t - key.ease_in[0] * timeline_scale * 2; - draw_line_width(_tx, prop_dope_y - 1, t, prop_dope_y - 1, 2); - - if(pHOVER && point_in_circle(msx, msy, _tx, prop_dope_y, ui(6))) { - key_hover = key; - draw_sprite_ui_uniform(THEME.timeline_key_ease, 0, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_selected); - if(mouse_press(mb_left, pFOCUS) && !key_mod_press(SHIFT)) { - keyframe_dragging = animator.values[k]; - keyframe_drag_type = KEYFRAME_DRAG_TYPE.ease_in; - } - } else - draw_sprite_ui_uniform(THEME.timeline_key_ease, 0, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_unselected); - } - - if(key.ease_out_type == CURVE_TYPE.bezier) { - draw_set_color(COLORS.panel_animation_keyframe_ease_line); - var _tx = t + key.ease_out[0] * timeline_scale * 2; - draw_line_width(t, prop_dope_y - 1, _tx, prop_dope_y - 1, 2); - - if(pHOVER && point_in_circle(msx, msy, _tx, prop_dope_y, ui(6))) { - key_hover = key; - draw_sprite_ui_uniform(THEME.timeline_key_ease, 1, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_selected); - if(mouse_press(mb_left, pFOCUS) && !key_mod_press(SHIFT)) { - keyframe_dragging = animator.values[k]; - keyframe_drag_type = KEYFRAME_DRAG_TYPE.ease_out; - } - } else - draw_sprite_ui_uniform(THEME.timeline_key_ease, 1, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_unselected); - } - } - - return key_hover; - } #endregion - - __keyframe_editing = noone; - - function _drawDopesheetAnimatorKeys(_cont, animator, msx, msy) { #region - var _node = _cont.node; - var prop_y = animator.y; - var node_y = _cont.y; - var anim_set = true; - var key_hover = noone; - - for(var k = 0; k < array_length(animator.values); k++) { - var keyframe = animator.values[k]; - var t = keyframe.dopesheet_x; - - for( var j = 0, n = array_length(_cont.contexts); j < n; j++ ) { - var _cxt = _cont.contexts[j]; - if(!_cxt.show) continue; - draw_sprite_ui_uniform(THEME.timeline_key_empty, 0, t, _cxt.y + ui(10), 1, COLORS._main_icon); - } - - if(!_cont.show) continue; - draw_sprite_ui_uniform(THEME.timeline_key_empty, 0, t, node_y + ui(10), 1, COLORS._main_icon); - - if(!_cont.item.show) continue; - - var cc = COLORS.panel_animation_keyframe_unselected; - if(on_end_dragging_anim == animator.prop && msx < t && anim_set) { - if(k == 0) - animator.prop.loop_range = -1; - else - animator.prop.loop_range = array_length(animator.values) - k; - anim_set = false; - } - - if(pHOVER && point_in_circle(msx, msy, t, prop_y, ui(8))) { - cc = COLORS.panel_animation_keyframe_selected; - key_hover = keyframe; - if(!instance_exists(o_dialog_menubox)) - TOOLTIP = [ keyframe.value, animator.prop.type ]; - - if(pFOCUS && !key_mod_press(SHIFT)) { - if(DOUBLE_CLICK) { - keyframe_dragging = keyframe; - keyframe_drag_type = KEYFRAME_DRAG_TYPE.ease_both; - keyframe_dragout = false; - keyframe_drag_mx = mx; - keyframe_drag_my = my; - - } else if(mouse_press(mb_left)) { - if(key_mod_press(CTRL)) { - editKeyFrame(keyframe); - - } else { - keyframe_dragging = keyframe; - keyframe_drag_type = KEYFRAME_DRAG_TYPE.move; - keyframe_drag_mx = mx; - keyframe_drag_my = my; - } - } - } - } - - if(stagger_mode == 1 && array_exists(keyframe_selecting, keyframe)) - cc = key_hover == keyframe? COLORS.panel_animation_keyframe_selected : COLORS._main_accent; - - var ind = keyframe.getDrawIndex(); - draw_sprite_ui_uniform(THEME.timeline_keyframe, ind, t, prop_y, 1, cc); - - if(array_exists(keyframe_selecting, keyframe)) - draw_sprite_ui_uniform(THEME.timeline_keyframe_selecting, ind, t, prop_y, 1, COLORS._main_accent); - - if(keyframe_boxing) { - var box_x0 = min(keyframe_box_sx, msx); - var box_x1 = max(keyframe_box_sx, msx); - var box_y0 = min(keyframe_box_sy, msy); - var box_y1 = max(keyframe_box_sy, msy); - - if(pHOVER && !point_in_rectangle(t, prop_y, box_x0, box_y0, box_x1, box_y1) && array_exists(keyframe_selecting, keyframe)) - array_remove(keyframe_selecting, keyframe); - if(pHOVER && point_in_rectangle(t, prop_y, box_x0, box_y0, box_x1, box_y1) && !array_exists(keyframe_selecting, keyframe)) - array_push(keyframe_selecting, keyframe); - } - } - - return key_hover; - } #endregion - - function __drawDopesheetLabelAnimator(_item, _node, animator, msx, msy) { #region - var prop = animator.prop; - var aa = _node.group == PANEL_GRAPH.getCurrentContext()? 1 : 0.9; - var tx = tool_width; - var ty = animator.y - 1; - - var hov = item_dragging == noone && pHOVER && point_in_rectangle(msx, msy, 0, ty - ui(8), w - ui(64), ty + ui(8)); - - //// DRAW NAME - var cc = prop.sep_axis? COLORS.axis[animator.index] : COLORS._main_text_sub; - if(hov) cc = COLORS._main_text_accent; - - draw_set_color(CDEF.main_mdblack); - draw_rectangle(ui(32), ty - ui(8), tool_width, ty + ui(8), false); - - draw_set_color(cc); - - var _title_x = ui(32); - if(!show_nodes) { - var _txt = animator.prop.node.getDisplayName(); - - draw_set_alpha(aa * 0.5); - draw_text_add(_title_x, ty - 2, _txt); - _title_x += string_width(_txt) + ui(4); - } - - var _txt = animator.getName(); - draw_set_alpha(aa); - draw_text_add(_title_x, ty - 2, _txt); - draw_set_alpha(1); - _title_x += string_width(_txt) + ui(4); - - if(hov) { - value_hovering = prop; - if(mouse_click(mb_left, pFOCUS)) - value_focusing = prop; - - if(mouse_press(mb_right, pFOCUS)) { - context_selecting_prop = prop; - context_selecting_item = _item; - } - } - - var _gx = ui(20); - var _gy = ty; - if(hov) - if(buttonInstant(noone, _gx - ui(10), _gy - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.animate_prop_go, 0, [COLORS._main_icon, COLORS._main_icon_on_inner], 0.75) == 2) { - graphFocusNode(_node); - PANEL_INSPECTOR.highlightProp(prop); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - var _tool_a = 0.5 + hov * 0.5; - - var _on_end_disp = prop.on_end || hov; - var _tool_x0 = tool_width - ui(20 + 16 * (3 + _on_end_disp * 1.5) + 12); - var _tool_x1 = tool_width; - draw_set_color(c_white); - BLEND_SUBTRACT - draw_rectangle(_tool_x0, ty - ui(8), _tool_x1, ty + ui(8), false); - BLEND_NORMAL - - var _graph_show = prop.sep_axis? prop.show_graphs[animator.index] : prop.show_graph; - - if(_graph_show) { - var _y1 = ty + ui(10) + prop.graph_h + ui(8); - var c1 = colorMultiply(_item.item.color_cur, COLORS.panel_animation_dope_key_bg_hover); - draw_set_color(c1); - draw_rectangle(0, ty + ui(10), tx, _y1, false); - } - - var c0 = colorMultiply(_item.item.color_cur, COLORS.panel_animation_dope_key_bg); - draw_set_color(c0); - draw_rectangle(0, ty - ui(10), tx, ty + ui(10), false); - - #region keyframe control - tx = tool_width - ui(20 + 16 * 3); - if(buttonInstant(noone, tx - ui(10), ty - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.prop_keyframe, 0, [COLORS._main_icon, COLORS._main_icon_on_inner], _tool_a) == 2) { - var _t = -1; - for(var k = 0; k < array_length(animator.values); k++) { - var _key = animator.values[k]; - if(_key.time < CURRENT_FRAME) - _t = _key.time; - } - if(_t > -1) PROJECT.animator.setFrame(_t); - } - - tx = tool_width - ui(20 + 16 * 1); - if(buttonInstant(noone, tx - ui(10), ty - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.prop_keyframe, 2, [COLORS._main_icon, COLORS._main_icon_on_inner], _tool_a) == 2) { - for(var k = 0; k < array_length(animator.values); k++) { - var _key = animator.values[k]; - if(_key.time > CURRENT_FRAME) { - PROJECT.animator.setFrame(_key.time); - break; - } - } - } - #endregion - - #region add keyframe - tx = tool_width - ui(20 + 16 * 2); - if(buttonInstant(noone, tx - ui(10), ty - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.prop_keyframe, 1, [COLORS._main_accent, COLORS._main_icon_on_inner], _tool_a) == 2) { - var _add = false; - for(var k = 0; k < array_length(animator.values); k++) { - var _key = animator.values[k]; - if(_key.time == CURRENT_FRAME) { - if(array_length(animator.values) > 1) - array_delete(animator.values, k, 1); - _add = true; - break; - } else if(_key.time > CURRENT_FRAME) { - array_insert(animator.values, k, new valueKey(CURRENT_FRAME, variable_clone(animator.getValue()), animator)); - _add = true; - break; - } - } - if(!_add) array_push(animator.values, new valueKey(CURRENT_FRAME, variable_clone(animator.getValue(, false)), animator)); - } - #endregion - - if(isGraphable(prop)) { - tx = tool_width - ui(16); - if(pHOVER && point_in_rectangle(msx, msy, tx - ui(9), ty - ui(10), tx + ui(10), ty + ui(8))) { - draw_sprite_ui_uniform(THEME.timeline_graph, 1, tx, ty, 1, COLORS._main_icon_on_inner, _tool_a); - TOOLTIP = _graph_show? __txtx("panel_animation_hide_graph", "Hide graph") : __txtx("panel_animation_show_graph", "Show graph"); - - if(mouse_press(mb_left, pFOCUS)) { - if(prop.sep_axis) prop.show_graphs[animator.index] = !_graph_show; - else prop.show_graph = !_graph_show; - } - } else - draw_sprite_ui_uniform(THEME.timeline_graph, 1, tx, ty, 1, _graph_show? COLORS._main_accent : COLORS._main_icon, _graph_show? 1 : _tool_a); - } - - tx = tool_width - ui(20 + 16 * 4.5); - - if(pHOVER && point_in_rectangle(msx, msy, tx - ui(10), ty - ui(9), tx + ui(10), ty + ui(8))) { - draw_sprite_ui_uniform(THEME.prop_on_end, prop.on_end, tx, ty, 1, COLORS._main_icon_on_inner, _on_end_disp); - - if(tooltip_loop_prop != prop) - tooltip_loop_type.arrow_pos = noone; - tooltip_loop_prop = prop; - tooltip_loop_type.index = prop.on_end; - TOOLTIP = tooltip_loop_type; - - if(mouse_release(mb_left, pFOCUS)) - prop.on_end = safe_mod(prop.on_end + 1, sprite_get_number(THEME.prop_on_end)); - if(mouse_press(mb_left, pFOCUS)) - on_end_dragging_anim = prop; - } else - draw_sprite_ui_uniform(THEME.prop_on_end, prop.on_end, tx, ty, 1, on_end_dragging_anim == prop? COLORS._main_accent : COLORS._main_icon, _on_end_disp); - - draw_set_alpha(1); - } #endregion - - function __drawDopesheetLabelItem(_item, _x, _y, msx = -1, msy = -1, alpha = 1) { #region - var _itx = _x; - var _ity = _y; - var _itw = tool_width; - var _hov = pHOVER && (msy > 0 && msy < dope_sheet_h); - var _foc = pFOCUS; - - 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)) { - _item_dragging = _item; - item_dragging_mx = msx; - item_dragging_my = msy; - - item_dragging_dx = msx - _x; - item_dragging_dy = msy - _y; - } - - if(mouse_press(mb_right, _foc)) - context_selecting_item = _item; - } - } #endregion - - function _drawDopesheetLabel() { #region - surface_set_target(dope_sheet_name_surface); - draw_clear_alpha(COLORS.panel_bg_clear_inner, 0); - var msx = mx - ui(8); - var msy = my - ui(8); - - draw_set_text(f_p2, fa_left, fa_center); - - value_hovering = noone; - if(mouse_click(mb_left, pFOCUS)) - value_focusing = noone; - - if(mouse_press(mb_right, pFOCUS)) { - context_selecting_item = noone; - context_selecting_prop = noone; - } - - #region draw - hovering_folder = PROJECT.timelines; - hovering_order = 0; - - var last_y = 0; - var last_i = 0; - - if(item_dragging != noone) - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - if(!_cont.show) continue; - - var _y = _cont.y; - var _h = _cont.h; - - if(_y + _h < 0) continue; - if(_y > h) break; - - if(item_dragging != noone && item_dragging.item == _cont.item) continue; - - if(_cont.type == "folder") { - if(msy > _y && msy <= _y + _h) { - hovering_folder = _cont.item; - hovering_order = -1; - } - } else if(_cont.type == "node") { - if(msy > _y && msy <= _y + _h / 2) { - hovering_folder = _cont.parent; - hovering_order = _cont.index; - } else if(msy > _y + _h / 2 && msy <= _y + _h) { - hovering_folder = _cont.parent; - hovering_order = _cont.index + 1; - } - } - - last_y = _y + _h; - if(_cont.parent == PROJECT.timelines) - last_i = _cont.index + 1; - } - - if(msy > last_y) { - hovering_folder = PROJECT.timelines; - hovering_order = last_i; - } - - var _itx = -1, _ity, _itw; - - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - if(!_cont.show) continue; - - var _y = _cont.y; - var _h = _cont.h; - - if(_y + _h < 0) continue; - if(_y > h) break; - - if(item_dragging != noone && item_dragging.item == _cont.item) { - _itx = _cont.depth * ui(20); - _ity = _cont.y; - _itw = tool_width - _cont.depth * ui(20); - continue; - } - - if(show_nodes) __drawDopesheetLabelItem(_cont, 0, _cont.y, msx, msy); - - if(_cont.type == "node" && _cont.item.show) - for( var j = 0; j < array_length(_cont.animators); j++ ) - __drawDopesheetLabelAnimator(_cont, _cont.node, _cont.animators[j], msx, msy); - } - - if(_itx != -1) { - draw_set_color(COLORS._main_accent); - draw_line_width(_itx, _ity, _itx + _itw, _ity, 2); - } - - if(_item_dragging != noone) { - if(point_distance(msx, msy, item_dragging_mx, item_dragging_my) > 4) { - item_dragging = _item_dragging; - _item_dragging = noone; - } - } - - if(item_dragging != noone) { - item_dragging.item.removeSelf(); - if(hovering_order == -1) - array_insert(hovering_folder.contents, 0, item_dragging.item); - else { - var _ind = min(array_length(hovering_folder.contents), hovering_order); - array_insert(hovering_folder.contents, _ind, item_dragging.item); - } - - item_dragging.item.parent = hovering_folder; - } - - if(mouse_release(mb_left)) { - _item_dragging = noone; - item_dragging = noone; - } - #endregion - - gpu_set_blendmode(bm_subtract); - draw_surface_safe(dope_sheet_name_mask); - gpu_set_blendmode(bm_normal); - surface_reset_target(); - } #endregion - - function drawDopesheet() { #region - var bar_x = tool_width + ui(16); - var bar_y = h - timeline_h - ui(10); - var bar_w = timeline_w; - var bar_h = timeline_h; - var bar_total_w = TOTAL_FRAMES * timeline_scale; - - surfaceVerify(); - - #region scroll - dope_sheet_y = lerp_float(dope_sheet_y, dope_sheet_y_to, 4); - - if(pHOVER && point_in_rectangle(mx, my, ui(8), ui(8), bar_x, ui(8) + dope_sheet_h)) { - if(mouse_wheel_down()) dope_sheet_y_to = clamp(dope_sheet_y_to - ui(32) * SCROLL_SPEED, -dope_sheet_y_max, 0); - if(mouse_wheel_up()) dope_sheet_y_to = clamp(dope_sheet_y_to + ui(32) * SCROLL_SPEED, -dope_sheet_y_max, 0); - } - - var scr_x = bar_x + dope_sheet_w + ui(4); - var scr_y = ui(8); - var scr_s = dope_sheet_h; - var scr_prog = -dope_sheet_y / dope_sheet_y_max; - var scr_size = dope_sheet_h / (dope_sheet_h + dope_sheet_y_max); - - var scr_scale_s = scr_s * scr_size; - var scr_prog_s = scr_prog * (scr_s - scr_scale_s); - - var scr_w = scroll_w; - var scr_h = scr_s; - var s_bar_w = scroll_w; - var s_bar_h = scr_scale_s; - var s_bar_x = scr_x; - var s_bar_y = scr_y + scr_prog_s; - - if(is_scrolling) { - if(scr_s - scr_scale_s != 0) - dope_sheet_y_to = clamp((my - scr_y - scr_scale_s / 2) / (scr_s - scr_scale_s), 0, 1) * -dope_sheet_y_max; - - if(mouse_release(mb_left)) is_scrolling = false; - } - - if(pHOVER && point_in_rectangle(mx, my, scr_x - ui(2), scr_y - ui(2), scr_x + scr_w + ui(2), scr_y + scr_h + ui(2))) { - draw_sprite_stretched_ext(THEME.ui_scrollbar, 0, s_bar_x, s_bar_y, s_bar_w, s_bar_h, COLORS.scrollbar_hover, 1); - if(mouse_click(mb_left, pFOCUS)) - is_scrolling = true; - } else { - draw_sprite_stretched_ext(THEME.ui_scrollbar, 0, s_bar_x, s_bar_y, s_bar_w, s_bar_h, COLORS.scrollbar_idle, 1); - } - - var _p = PEN_USE && (is_scrolling || point_in_rectangle(mx, my, scr_x - ui(2), scr_y - ui(2), scr_x + scr_w + ui(2), scr_y + scr_h + ui(2))); - scroll_w = lerp_float(scroll_w, _p? 12 : scroll_s, 5); - #endregion - - surface_set_target(dope_sheet_surface); - draw_clear_alpha(COLORS.panel_bg_clear, 1); - var msx = mx - bar_x; - var msy = my - ui(8); - - #region bg \\\\ set X, Y for Node and Prop - var bar_show_w = timeline_shift + bar_total_w; - - var _bg_w = min(bar_total_w + PANEL_PAD, bar_w); - draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, bar_w, dope_sheet_h, COLORS.panel_animation_timeline_blend, 1); - - dope_sheet_y_max = 0; - var key_y = ui(22) + dope_sheet_y; - var c0, c1; - - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - _cont.y = key_y; - _cont.h = 0; - _cont.item.drawDopesheet(timeline_shift, _cont.y, timeline_scale, msx, msy); - - if(!_cont.show) - continue; - if(item_dragging != noone && item_dragging.item == _cont.item) - continue; - - var _expand = _cont.type == "node" && _cont.item.show; - - var _ks = key_y; - if(_cont.item.color_dsp > -1) { - draw_set_color(_cont.item.color_dsp); - draw_rectangle(0, _ks - 1, bar_show_w, _ks + ui(20), false); - } - - if(_cont.item.color_cur > -1) { - c0 = colorMultiply(_cont.item.color_cur, COLORS.panel_animation_dope_key_bg); - c1 = colorMultiply(_cont.item.color_cur, COLORS.panel_animation_dope_key_bg_hover); - } else { - c0 = COLORS.panel_animation_dope_key_bg; - c1 = COLORS.panel_animation_dope_key_bg_hover; - } - - key_y += ui(20) * show_nodes + _expand * ui(10); - _cont.h += ui(20) * show_nodes; - _ks = key_y - ui(10); - - if(_expand) { - for( var j = 0; j < array_length(_cont.props); j++ ) { - var prop = _cont.props[j]; - var _prop = prop.prop; - prop.y = key_y; - - for( var k = 0; k < array_length(prop.animators); k++ ) { - prop.animators[k].y = key_y; - - if(_cont.item.color_cur > -1) { - draw_set_color(c0); - draw_rectangle(0, key_y - ui(10), bar_show_w, key_y + ui(10), false); - - if(_prop == value_focusing) draw_sprite_stretched_ext(THEME.s_box_r2, 0, 0, key_y - ui(8), bar_show_w, ui(16), c1); - else if(_prop == value_hovering) draw_sprite_stretched_ext(THEME.s_box_r2, 0, 0, key_y - ui(8), bar_show_w, ui(16), c1, .9); - } - - if(k) prop.y = key_y; - key_y += ui(18); - _cont.h += ui(18); - } - - var _graph_show = _prop.sep_axis? array_any(_prop.show_graphs, function(v) /*=>*/ {return v == true}) : _prop.show_graph; - - if(_graph_show && _prop.type != VALUE_TYPE.color) { - if(_cont.item.color_cur > -1) { - draw_set_color(c1); - draw_rectangle(0, key_y - ui(10), bar_show_w, key_y + _prop.graph_h - ui(2), false); - } - - var _gr_h = _prop.graph_h; - key_y += _gr_h + ui(8); - _cont.h += _gr_h + ui(8); - } - } - } - - key_y -= _expand * ui(10); - dope_sheet_y_max += _cont.h; - } - - dope_sheet_y_max = max(0, dope_sheet_y_max - dope_sheet_h + ui(48)); - - var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; - - for(var i = timeline_sep_line; i <= _fr; i += timeline_sep_line) { - var bar_line_x = i * timeline_scale + timeline_shift; - - draw_set_color(COLORS.panel_animation_frame_divider); - draw_set_alpha((i % timeline_separate == 0? 1 : 0.1) * ((i <= TOTAL_FRAMES) * 0.5 + 0.5)); - draw_line(bar_line_x, ui(16), bar_line_x, dope_sheet_h - PANEL_PAD); - } - draw_set_alpha(1); - - var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; - draw_set_color(COLORS.panel_animation_end_line); - draw_set_alpha(0.5); - draw_line_width(bar_line_x, ui(16), bar_line_x, dope_sheet_h, 2); - draw_set_alpha(1); - #endregion - - draw_set_text(f_p2, fa_left, fa_top); - - #region draw graph, easing line - var key_hover = noone; - _graph_key_hover = noone; - _graph_key_hover_index = noone; - _graph_key_hover_x = 0; - _graph_key_hover_y = 0; - - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - - if(!_cont.show) continue; - if(_cont.type != "node") continue; - - if(_cont.item.show) - for( var j = 0, m = array_length(_cont.props); j < m; j++ ) { - var prop = _cont.props[j]; - var _dy = prop.y; - var _prop = prop.prop; - - if(isGraphable(_prop)) { - var _graph_show = _prop.sep_axis? array_any(_prop.show_graphs, function(v) /*=>*/ {return v == true}) : _prop.show_graph; - if(_graph_show) _drawDopesheetGraph(_prop, _dy, msx, msy); - } - - for( var k = 0; k < array_length(prop.animators); k++ ) { - var key = _drawDopesheetAnimatorKeysBG(prop.animators[k], msx, msy); - _dy = prop.animators[k].y; - if(key != noone) key_hover = key; - } - } - } - - graph_key_hover = _graph_key_hover; - graph_key_hover_index = _graph_key_hover_index; - - if(graph_key_drag != noone) { - var bar_x = tool_width + ui(16); - var k = graph_key_drag; - - if(graph_key_drag_index == KEYFRAME_DRAG_TYPE.move) { - var tt = round((mx - bar_x - timeline_shift) / timeline_scale) - 1; - tt = max(tt, 0); - - var sh = tt - k.time; - var kt = k.time + sh; - var edited = k.anim.setKeyTime(k, kt, false, true) - if(edited) UNDO_HOLDING = true; - - if(mouse_release(mb_left)) - k.anim.setKeyTime(k, k.time, true, true); - - } else { - var _dir = point_direction(graph_key_sx, graph_key_sy, msx, msy); - var _dis = point_distance( graph_key_sx, graph_key_sy, msx, msy); - - var _dx = lengthdir_x(_dis, _dir) / timeline_scale / 2; - var _dy = lengthdir_y(_dis, _dir) / 32; - if(_dx < 0) _dy = -_dy; - - _dx = clamp(abs(_dx), 0, 1); - if(_dx > 0.1) keyframe_dragout = true; - else { _dx = 0; _dy = 0; } - - var _in = k.ease_in; - var _ot = k.ease_out; - - switch(graph_key_drag_index) { - case KEYFRAME_DRAG_TYPE.ease_in : - k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - k.ease_in[0] = _dx; - // k.ease_in[1] = _dy + 1; - - break; - case KEYFRAME_DRAG_TYPE.ease_out : - k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - k.ease_out[0] = _dx; - // k.ease_out[1] = -_dy; - - break; - case KEYFRAME_DRAG_TYPE.ease_both : - - k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - - k.ease_in[0] = _dx; - // k.ease_in[1] = _dy + 1; - - k.ease_out[0] = _dx; - // k.ease_out[1] = -_dy; - break; - } - - if(mouse_release(mb_left)) { - recordAction(ACTION_TYPE.var_modify, k, [_in, "ease_in"]); - recordAction(ACTION_TYPE.var_modify, k, [_ot, "ease_out"]); - } - } - - if(mouse_release(mb_left)) { - graph_key_drag = noone; - UNDO_HOLDING = false; - } - - } else if(graph_key_hover != noone) { - - if(DOUBLE_CLICK) { - graph_key_drag = _graph_key_hover; - graph_key_drag_index = KEYFRAME_DRAG_TYPE.ease_both; - graph_key_mx = msx; - graph_key_my = msy; - graph_key_sx = _graph_key_hover_x; - graph_key_sy = _graph_key_hover_y; - keyframe_dragout = false; - - } else if(mouse_press(mb_left)) { - graph_key_drag = _graph_key_hover; - graph_key_drag_index = _graph_key_hover_index; - graph_key_mx = msx; - graph_key_my = msy; - graph_key_sx = _graph_key_hover_x; - graph_key_sy = _graph_key_hover_y; - } - - } - #endregion - - #region drag key - if(keyframe_dragging) { - if(keyframe_drag_type == KEYFRAME_DRAG_TYPE.move) { - var tt = round((mx - bar_x - timeline_shift) / timeline_scale) - 1; - tt = max(tt, 0); - var sh = tt - keyframe_dragging.time; - var edited = false; - - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - var kt = k.time + sh; - - if(k.anim.setKeyTime(k, kt, false, true)) - edited = true; - } - - if(edited) UNDO_HOLDING = true; - timeline_show_time = floor(tt); - - if(mouse_release(mb_left) || mouse_press(mb_left)) { - keyframe_dragging = noone; - UNDO_HOLDING = false; - - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.anim.setKeyTime(k, k.time, true, true); - } - } - } else { - var dx = abs((keyframe_dragging.time + 1) - (mx - bar_x - timeline_shift) / timeline_scale) / 2; - dx = clamp(dx, 0, 1); - if(dx > 0.2) keyframe_dragout = true; - - var dy = -(my - keyframe_drag_my) / 32; - - var _in = keyframe_dragging.ease_in; - var _ot = keyframe_dragging.ease_out; - - switch(keyframe_drag_type) { - case KEYFRAME_DRAG_TYPE.ease_in : - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - - k.ease_in[0] = dx; - if(!k.ease_y_lock) - k.ease_in[1] = dy; - } - - break; - case KEYFRAME_DRAG_TYPE.ease_out : - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - - k.ease_out[0] = dx; - if(!k.ease_y_lock) - k.ease_out[1] = dy; - } - break; - case KEYFRAME_DRAG_TYPE.ease_both : - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var k = keyframe_selecting[i]; - k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; - - k.ease_in[0] = dx; - if(!k.ease_y_lock) - k.ease_in[1] = dy; - - k.ease_out[0] = dx; - if(!k.ease_y_lock) - k.ease_out[1] = dy; - } - break; - } - - if(mouse_release(mb_left)) { - recordAction(ACTION_TYPE.var_modify, keyframe_dragging, [_in, "ease_in"]); - recordAction(ACTION_TYPE.var_modify, keyframe_dragging, [_ot, "ease_out"]); - - keyframe_dragging = noone; - UNDO_HOLDING = false; - } - } - } - #endregion - - #region on end dragging - if(on_end_dragging_anim != noone) { - if(mouse_release(mb_left)) - on_end_dragging_anim = false; - } - #endregion - - if(keyframe_boxing) { #region - draw_sprite_stretched_points_clamp(THEME.ui_selection, 0, keyframe_box_sx, keyframe_box_sy, msx, msy, COLORS._main_accent); - - if(mouse_release(mb_left)) - keyframe_boxing = false; - } #endregion - - #region ======= draw keys ======= - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - if(_cont.type != "node") continue; - - for( var j = 0, m = array_length(_cont.animators); j < m; j++ ) { - var _anim = _cont.animators[j]; - - var key = _drawDopesheetAnimatorKeys(_cont, _anim, msx, msy); - if(key != noone) key_hover = key; - } - } - #endregion - - if(pHOVER && point_in_rectangle(msx, msy, 0, ui(18), dope_sheet_w, dope_sheet_h)) { #region selection & stagger - if(mouse_press(mb_right, pFOCUS) && key_hover == noone) - keyframe_selecting = []; - - if(mouse_press(mb_left, pFOCUS)) { - if(key_hover == noone) { - keyframe_selecting = []; - } else if(key_mod_press(SHIFT)) { - if(array_exists(keyframe_selecting, key_hover)) - array_remove(keyframe_selecting, key_hover); - else - array_push(keyframe_selecting, key_hover) - } else { - if(!array_exists(keyframe_selecting, key_hover)) - keyframe_selecting = [ key_hover ]; - } - - if(stagger_mode == 1) { - if(key_hover == noone || !array_exists(keyframe_selecting, key_hover)) - stagger_mode = 0; - else { - arrangeKeys(); - stagger_index = array_find(keyframe_selecting, key_hover); - stagger_mode = 2; - } - } else if(stagger_mode == 2) { - stagger_mode = 0; - UNDO_HOLDING = false; - } else if(key_hover == noone && keyframe_boxable) { - keyframe_boxing = true; - keyframe_box_sx = msx; - keyframe_box_sy = msy; - } - } - - keyframe_boxable = true; - - if(stagger_mode == 2) { - var ts = keyframe_selecting[stagger_index].time; - var tm = round((mx - bar_x - timeline_shift) / timeline_scale) - 1; - tm = max(tm, 0); - - var stg = tm - ts; - staggerKeys(stagger_index, stg); - } - } #endregion - - #region overlay - var hh = ui(20); - - var bar_line_x = (CURRENT_FRAME + 1) * timeline_scale + timeline_shift; - var cc = PROJECT.animator.is_playing? COLORS._main_value_positive : COLORS._main_accent; - - draw_set_color(cc); - draw_line(bar_line_x, PANEL_PAD, bar_line_x, dope_sheet_h); - - var _phover = pHOVER && msy > hh; - for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { - var _cont = timeline_contents[i]; - if(!_cont.show) continue; - - 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; - } - - draw_set_color(COLORS.panel_animation_timeline_top); - draw_rectangle(0, 0, bar_w, hh, false); - - var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; - - for(var i = timeline_separate; i <= _fr; i += timeline_separate) { - var ln_x = i * timeline_scale + timeline_shift; - - if(i > TOTAL_FRAMES) draw_set_alpha(0.5); - - draw_set_color(COLORS.panel_animation_frame_divider); - draw_line(ln_x, 0, ln_x, hh); - - draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text_sub); - draw_text_add(ln_x, PANEL_PAD, i); - } - - draw_set_alpha(1); - - var end_x = TOTAL_FRAMES * timeline_scale + timeline_shift; - draw_set_color(COLORS.panel_animation_end_line); - draw_line_width(end_x, 0, end_x, ui(20), 2); - - if(PROJECT.onion_skin.enabled) { //ONION SKIN - var rang = PROJECT.onion_skin.range; - var colr = PROJECT.onion_skin.color; - - var fr = CURRENT_FRAME + 1; - var tx = fr * timeline_scale + timeline_shift; - var sx = (fr + rang[0]) * timeline_scale + timeline_shift; - var ex = (fr + rang[1]) * timeline_scale + timeline_shift; - var y0 = PANEL_PAD; - var y1 = hh; - var yc = (y0 + y1) / 2; - - draw_sprite_stretched_ext(THEME.timeline_onion_skin, 0, sx, y0, tx - sx, y1 - y0, colr[0], 1); - draw_sprite_stretched_ext(THEME.timeline_onion_skin, 1, tx, y0, ex - tx, y1 - y0, colr[1], 1); - - var _sx = (fr + rang[0]) * timeline_scale + timeline_shift - ui(8); - var _ex = (fr + rang[1]) * timeline_scale + timeline_shift + ui(8); - - if(point_in_circle(msx, msy, _sx, yc, ui(8))) { - draw_sprite_ext(THEME.arrow, 2, _sx, yc, 1, 1, 0, colr[0], 1); - - if(mouse_press(mb_left, pFOCUS)) - onion_dragging = 0; - timeline_draggable = false; - } else - draw_sprite_ext(THEME.arrow, 2, _sx, yc, 1, 1, 0, colr[0], 0.5); - - if(point_in_circle(msx, msy, _ex, yc, ui(8))) { - draw_sprite_ext(THEME.arrow, 0, _ex, yc, 1, 1, 0, colr[1], 1); - - if(mouse_press(mb_left, pFOCUS)) - onion_dragging = 1; - timeline_draggable = false; - } else - draw_sprite_ext(THEME.arrow, 0, _ex, yc, 1, 1, 0, colr[1], 0.5); - - if(onion_dragging != noone) { - if(onion_dragging == 0) { - var mf = round((msx - timeline_shift + ui(8)) / timeline_scale) - fr; - mf = min(mf, 0); - - if(PROJECT.onion_skin.range[0] != mf) { - PROJECT.onion_skin.range[0] = mf; - } - } else if(onion_dragging == 1) { - var mf = round((msx - timeline_shift - ui(8)) / timeline_scale) - fr; - mf = max(mf, 0); - - if(PROJECT.onion_skin.range[1] != mf) { - PROJECT.onion_skin.range[1] = mf; - } - } - - if(mouse_release(mb_left)) - onion_dragging = noone; - } - } - - draw_set_font(f_p2); - var cf = string(CURRENT_FRAME + 1); - var tx = string_width(cf) + ui(4); - draw_sprite_stretched_ext(THEME.s_box_r2, 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); - - #endregion - - #region stretch - var stx = timeline_shift + bar_total_w + ui(24); - var sty = ui(10); - - if(timeline_stretch == 1) { - var len = round((mx - bar_x - timeline_shift) / timeline_scale) - 2; - len = max(1, len); - TOOLTIP = __txtx("panel_animation_length", "Animation length") + " " + string(len); - TOTAL_FRAMES = len; - - if(mouse_release(mb_left)) - timeline_stretch = 0; - - draw_sprite_ui(THEME.animation_stretch, 0, stx, sty, 1, 1, 0, COLORS.panel_animation_end_line, 1); - - } else if(timeline_stretch == 2) { - var len = round((mx - bar_x - timeline_shift) / timeline_scale) - 2; - len = max(1, len); - TOOLTIP = __txtx("panel_animation_length", "Animation length") + " " + string(len); - var _len = TOTAL_FRAMES; - TOTAL_FRAMES = len; - - if(_len != len) { - for (var m = 0, n = array_length(PROJECT.allNodes); m < n; m++) { - var _node = PROJECT.allNodes[m]; - if(!_node || !_node.active) continue; - - for(var i = 0; i < array_length(_node.inputs); i++) { - var in = _node.inputs[i]; - if(!in.is_anim) continue; - - for(var j = 0; j < array_length(in.animator.values); j++) { - var t = in.animator.values[j]; - t.time = t.ratio * (len - 1); - } - - for( var k = 0; k < array_length(in.animators); k++ ) - for(var j = 0; j < array_length(in.animators[k].values); j++) { - var t = in.animators[k].values[j]; - t.time = t.ratio * (len - 1); - } - } - } - } - - if(mouse_release(mb_left)) - timeline_stretch = 0; - - draw_sprite_ui(THEME.animation_stretch, 1, stx, sty, 1, 1, 0, COLORS.panel_animation_end_line, 1); - - } else { - if(!IS_PLAYING && pHOVER && point_in_circle(msx, msy, stx, sty, sty)) { - if(key_mod_press(CTRL)) { - draw_sprite_ui(THEME.animation_stretch, 1, stx, sty, 1, 1, 0, COLORS._main_icon, 1); - TOOLTIP = __txtx("panel_animation_stretch", "Stretch animation"); - if(mouse_press(mb_left, pFOCUS)) { - timeline_stretch = 2; - timeline_stretch_mx = msx; - timeline_stretch_sx = TOTAL_FRAMES; - } - } else { - draw_sprite_ui(THEME.animation_stretch, 0, stx, sty, 1, 1, 0, COLORS._main_icon, 1); - TOOLTIP = __txtx("panel_animation_adjust_length", "Adjust animation length"); - if(mouse_press(mb_left, pFOCUS)) { - timeline_stretch = 1; - timeline_stretch_mx = msx; - timeline_stretch_sx = TOTAL_FRAMES; - } - } - } else - draw_sprite_ui(THEME.animation_stretch, 0, stx, sty, 1, 1, 0, COLORS._main_icon, 0.5); - } - #endregion - - gpu_set_blendmode(bm_subtract); - draw_surface_safe(dope_sheet_mask); - gpu_set_blendmode(bm_normal); - surface_reset_target(); - - _drawDopesheetLabel(); - - 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); - else menuCall("animation_keyframe_menu",,, keyframe_menu,, keyframe_selecting); - - } else if(point_in_rectangle(mx, my, ui(8), ui(8), ui(8) + tool_width, ui(8) + dope_sheet_h)) { - - if(context_selecting_prop != noone) { - if(context_selecting_prop.sepable) - menuCall("animation_name_empty_menu",,, context_selecting_prop.sep_axis? name_menu_prop_join : name_menu_prop_sep); - else - menuCall("animation_name_empty_menu",,, name_menu_empty); - } - - else if(context_selecting_item == noone) - menuCall("animation_name_empty_menu",,, name_menu_empty); - - else if(is_instanceof(context_selecting_item.item, timelineItemNode)) - menuCall("animation_name_empty_menu",,, name_menu_item); - - else if(is_instanceof(context_selecting_item.item, timelineItemGroup)) - menuCall("animation_name_empty_menu",,, name_menu_group); - } - } #endregion - - draw_sprite_stretched(THEME.ui_panel_bg, 1, ui(8), ui(8), tool_width, dope_sheet_h); - draw_surface_safe(dope_sheet_name_surface, ui(8), ui(8)); - - draw_sprite_stretched(THEME.ui_panel_bg, 1, bar_x, ui(8), bar_w, dope_sheet_h); //base BG - 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(item_dragging != noone) __drawDopesheetLabelItem(item_dragging, mx - item_dragging_dx, my - item_dragging_dy,,, 0.5); - } #endregion - - function drawAnimationControl() { #region - var mini = w < ui(348); - - var amo = array_length(control_buttons); - var col = floor((w - ui(8)) / ui(36)); - var row = ceil(amo / col); - if(col < 1) return; - - var bx = tool_width / 2 - ui(36) * amo / 2 + ui(8); - var by = h - ui(40); - - for( var i = 0; i < row; i++ ) { - var colAmo = min(amo - i * col, col); - if(mini) bx = w / 2 - ui(36) * colAmo / 2; - - for( var j = 0; j < colAmo; j++ ) { - var ind = i * col + j; - if(ind >= amo) return; - var but = control_buttons[ind]; - var txt = but[0](); - var ind = but[1](); - var cc = IS_RENDERING? COLORS._main_icon_dark : but[2](); - var fnc = but[3]; - - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS && !IS_RENDERING, pHOVER && !IS_RENDERING, txt, THEME.sequence_control, ind, cc) == 2) - fnc(); - - bx += ui(36); - } - - by -= ui(36); - } - - if(mini) { - var y0 = ui(8); - var y1 = by + ui(36) - ui(8); - var cy = (y0 + y1) / 2; - - if(y1 - y0 < 12) return; - - draw_sprite_stretched(THEME.ui_panel_bg, 1, ui(8), y0, w - ui(16), y1 - y0); - - var pw = w - ui(16); - var px = ui(8) + pw * (CURRENT_FRAME / TOTAL_FRAMES); - draw_set_color(COLORS._main_accent); - draw_line(px, y0, px, y1); - - if(point_in_rectangle(mx, my, ui(8), y0, w - ui(16), y1)) { - if(mouse_click(mb_left, pFOCUS)) { - var rfrm = (mx - ui(8)) / (w - ui(16)) * TOTAL_FRAMES; - PROJECT.animator.setFrame(clamp(rfrm, 0, TOTAL_FRAMES - 1)); - } - } - - var txt = string(CURRENT_FRAME + 1) + "/" + string(TOTAL_FRAMES); - - if(y1 - y0 < ui(40)) { - draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text_sub); - draw_text_add(ui(16), cy, __txt("Frame")); - draw_set_text(f_p1, fa_right, fa_center, PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_text_sub); - draw_text_add(w - ui(16), cy, txt); - } else { - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); - draw_text_add(w / 2, cy - ui(12), __txt("Frame")); - - draw_set_text(f_h5, fa_center, fa_center, PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_text_sub); - draw_text_add(w / 2, cy + ui(6), txt); - } - return; - } - - by += ui(36); - bx = w - ui(44); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_animation_animation_settings", "Animation settings"), THEME.animation_setting, 2) == 2) - dialogPanelCall(new Panel_Animation_Setting(), x + bx + ui(32), y + by - ui(8), { anchor: ANCHOR.right | ANCHOR.bottom }); - - by -= ui(40); if(by < 8) return; - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_animation_scale_animation", "Scale animation"), THEME.animation_timing, 2) == 2) - dialogPanelCall(new Panel_Animation_Scaler(), x + bx + ui(32), y + by - ui(8), { anchor: ANCHOR.right | ANCHOR.bottom }); - - var max_y = by - ui(28); - if(by < ui(28)) return; - by = ui(8); - - var txt = __txt("New folder"); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.folder_content) == 2) { - var _dir = new timelineItemGroup(); - PROJECT.timelines.addItem(_dir); - } - - by += ui(32); if(by > max_y) return; - node_name_tooltip.index = node_name_type; - - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, node_name_tooltip, THEME.node_name_type, node_name_type) == 2) - node_name_type = (node_name_type + 1) % 3; - - by += ui(32); if(by > max_y) return; - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, tooltip_toggle_nodes, THEME.junc_visible, show_nodes) == 2) - show_nodes = !show_nodes; - - by += ui(32); if(by > max_y) return; - txt = __txtx("panel_animation_keyframe_override", "Override Keyframe"); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.keyframe_override, global.FLAG.keyframe_override) == 2) - global.FLAG.keyframe_override = !global.FLAG.keyframe_override; - - by += ui(32); if(by > max_y) return; - txt = __txt("Onion skin"); - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.onion_skin,, PROJECT.onion_skin.enabled? c_white : COLORS._main_icon) == 2) - PROJECT.onion_skin.enabled = !PROJECT.onion_skin.enabled; - } #endregion - - function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<< - draw_clear_alpha(COLORS.panel_bg_clear, 0); - if(!PROJECT.active) return; - - if(tool_width_drag) { - CURSOR = cr_size_we; - - tool_width = tool_width_start + (mx - tool_width_mx); - tool_width = clamp(tool_width, ui(224), w - ui(128)); - onResize(); - - if(mouse_release(mb_left)) - tool_width_drag = false; - } - - getTimelineContent(); - if(w >= ui(348)) { - drawTimeline(); - - if(dope_sheet_h > 8) { - drawDopesheet(); - - if(pHOVER && point_in_rectangle(mx, my, tool_width + ui(8), ui(8), tool_width + ui(12), ui(8) + dope_sheet_h)) { - CURSOR = cr_size_we; - if(mouse_press(mb_left, pFOCUS)) { - tool_width_drag = true; - tool_width_start = tool_width; - tool_width_mx = mx; - } - } - } - } - drawAnimationControl(); - - if(timeline_show_time > -1) { - TOOLTIP = $"{__txt("Frame")} {timeline_show_time + 1}/{TOTAL_FRAMES}"; - timeline_show_time = -1; - } - } #endregion - - function doDuplicate() { #region - if(array_empty(keyframe_selecting)) return; - - var clones = []; - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { - var cl = keyframe_selecting[i].cloneAnimator(,, false); - if(cl == noone) continue; - array_push(clones, cl); - } - - if(array_empty(clones)) return; - - keyframe_selecting = clones; - keyframe_dragging = keyframe_selecting[0]; - keyframe_drag_type = KEYFRAME_DRAG_TYPE.move; - keyframe_drag_mx = mx; - keyframe_drag_my = my; - } #endregion - - function doCopy() { #region - ds_list_clear(copy_clipboard); - for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) - ds_list_add(copy_clipboard, keyframe_selecting[i]); - } #endregion - - function doPaste(val = noone) { #region - if(ds_list_empty(copy_clipboard)) return; - - var shf = 0; - var minx = TOTAL_FRAMES + 2; - for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) - minx = min(minx, copy_clipboard[| i].time); - shf = CURRENT_FRAME - minx; - - var multiVal = false; - var _val = noone; - - for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) { - if(_val != noone && _val != copy_clipboard[| i].anim) { - multiVal = true; - break; - } - _val = copy_clipboard[| i].anim; - } - - if(multiVal && val != noone) { - var nodeTo = val.node; - for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) { - var propFrom = copy_clipboard[| i].anim.prop; - var propTo = noone; - - for( var j = 0; j < array_length(nodeTo.inputs); j++ ) { - if(nodeTo.inputs[j].name == propFrom.name) { - propTo = nodeTo.inputs[j].animator; - copy_clipboard[| i].cloneAnimator(shf, propTo); - break; - } - } - } - } else { - for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) - copy_clipboard[| i].cloneAnimator(shf, (multiVal || val == noone)? noone : val.animator); - } - } #endregion + title = __txt("Animation"); + context_str = "Animation"; + icon = THEME.panel_animation_icon; + + #region ---- dimension ---- + timeline_h = ui(28); + min_w = ui(40); + min_h = ui(48); + tool_width = ui(224); + #endregion + + static initSize = function() { + timeline_w = w - tool_width - ui(80); + timeline_surface = surface_create_valid(timeline_w, timeline_h); + timeline_mask = surface_create_valid(timeline_w, timeline_h); + + dope_sheet_w = w - tool_width; + dope_sheet_h = h - timeline_h - ui(20); + dope_sheet_surface = surface_create_valid(dope_sheet_w, 1); + dope_sheet_mask = surface_create_valid(dope_sheet_w, 1); + + dope_sheet_name_mask = surface_create_valid(tool_width, 1); + dope_sheet_name_surface = surface_create_valid(tool_width, 1); + } + initSize(); + + #region ---- position ---- + dope_sheet_y = 0; + dope_sheet_y_to = 0; + dope_sheet_y_max = 0; + is_scrolling = false; + + dopesheet_dragging = noone; + dopesheet_drag_mx = 0; + #endregion + + #region ---- timeline ---- + timeline_scubbing = false; + timeline_scub_st = 0; + timeline_scale = 20; + timeline_separate = 5; + timeline_sep_line = 1; + _scrub_frame = -1; + + timeline_shift = 0; + timeline_shift_to = 0; + timeline_dragging = false; + timeline_drag_sx = 0; + timeline_drag_sy = 0; + timeline_drag_mx = 0; + timeline_drag_my = 0; + timeline_draggable = true; + + timeline_stretch = 0; + timeline_stretch_sx = 0; + timeline_stretch_mx = 0; + + timeline_show_time = -1; + timeline_preview = noone; + + timeline_contents = []; + + scroll_s = sprite_get_width(THEME.ui_scrollbar); + scroll_w = scroll_s; + + #endregion + + #region ---- keyframes ---- + keyframe_dragging = noone; + keyframe_drag_type = -1; + keyframe_dragout = false; + keyframe_drag_mx = 0; + keyframe_drag_my = 0; + keyframe_selecting = []; + + keyframe_boxable = true; + keyframe_boxing = false; + keyframe_box_sx = -1; + keyframe_box_sy = -1; + + keyframe_graph_surface = noone; + _graph_key_hover = noone; + _graph_key_hover_index = noone; + _graph_key_hover_x = noone; + _graph_key_hover_y = noone; + graph_key_hover = noone; + graph_key_hover_index = noone; + + graph_key_drag = noone; + graph_key_drag_index = noone; + + graph_key_mx = 0; + graph_key_my = 0; + graph_key_sx = 0; + graph_key_sy = 0; + #endregion + + #region ---- values ---- + value_hovering = noone; + value_focusing = noone; + #endregion + + #region ---- display ---- + show_node_outside_context = true; + show_nodes = true; + + tooltip_loop_prop = noone; + tooltip_loop_type = new tooltipSelector(__txtx("panel_animation_looping_mode", "Looping mode"), global.junctionEndName); + #endregion + + #region ---- item hover ---- + _item_dragging = noone; + item_dragging = noone; + item_dragging_mx = noone; + item_dragging_my = noone; + item_dragging_dx = noone; + item_dragging_dy = noone; + + hovering_folder = noone; + hovering_order = noone; + + node_name_type = 0; + node_name_tooltip = new tooltipSelector("Name Display", [ + __txtx("panel_animation_name_full", "Full name"), + __txtx("panel_animation_name_type", "Node type"), + __txtx("panel_animation_name_only", "Node name"), + ]); + #endregion + + #region ---- stagger ---- + stagger_mode = 0; + stagger_index = 0; + #endregion + + #region ---- tools ---- + tool_width_drag = false; + tool_width_start = 0; + tool_width_mx = 0; + #endregion + + on_end_dragging_anim = noone; + onion_dragging = noone; + prev_cache = array_create(TOTAL_FRAMES); + copy_clipboard = ds_list_create(); + + __collapse = false; + function collapseToggle() { + PANEL_ANIMATION.__collapse = !PANEL_ANIMATION.__collapse; + + for( var i = 0, n = array_length(PANEL_ANIMATION.timeline_contents); i < n; i++ ) + PANEL_ANIMATION.timeline_contents[i].item.show = PANEL_ANIMATION.__collapse; + } + + #region ++++ control_buttons ++++ + tooltip_toggle_nodes = new tooltipHotkey(__txtx("panel_animation_show_node", "Toggle node label"), "Animation", "Toggle nodes"); + tooltip_resume = new tooltipHotkey(__txt("Resume"), "", "Resume/Pause"); + tooltip_pause = new tooltipHotkey(__txt("Pause"), "", "Resume/Pause"); + tooltip_fr_first = new tooltipHotkey(__txtx("panel_animation_go_to_first_frame", "Go to first frame"), "", "First frame"); + tooltip_fr_last = new tooltipHotkey(__txtx("panel_animation_go_to_last_frame", "Go to last frame"), "", "Last frame"); + tooltip_fr_prev = new tooltipHotkey(__txtx("panel_animation_previous_frame", "Previous frame"), "", "Previous frame"); + tooltip_fr_next = new tooltipHotkey(__txtx("panel_animation_next_frame", "Next frame"), "", "Next frame"); + + control_buttons = [ + [ + function() { return __txt("Stop"); }, + function() { return 4; }, + function() { return PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_icon; }, + function() { PROJECT.animator.stop(); } + ], + [ + function() { return PROJECT.animator.is_playing? tooltip_pause : tooltip_resume; }, + function() { return !PROJECT.animator.is_playing; }, + function() { return PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_icon; }, + function() { if(PROJECT.animator.is_playing) PROJECT.animator.pause(); else PROJECT.animator.resume(); } + ], + [ + function() { return tooltip_fr_first; }, + function() { return 3; }, + function() { return COLORS._main_icon; }, + function() { PROJECT.animator.firstFrame(); } + ], + [ + function() { return tooltip_fr_last; }, + function() { return 2; }, + function() { return COLORS._main_icon; }, + function() { PROJECT.animator.lastFrame(); } + ], + [ + function() { return tooltip_fr_prev; }, + function() { return 5; }, + function() { return COLORS._main_icon; }, + function() { PROJECT.animator.setFrame(PROJECT.animator.real_frame - 1); } + ], + [ + function() { return tooltip_fr_next; }, + function() { return 6; }, + function() { return COLORS._main_icon; }, + function() { PROJECT.animator.setFrame(PROJECT.animator.real_frame + 1); } + ], + ]; + #endregion + + #region ++++ context menu ++++ + + #region actions + function edit_keyframe_value() { if(array_empty(keyframe_selecting)) return; editKeyFrame(keyframe_selecting[0]); } + + function edit_keyframe_lock_y() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_y_lock = !k.ease_y_lock; + } + } + + function edit_keyframe_stagger() { stagger_mode = 1; } + function edit_keyframe_driver() { dialogPanelCall(new Panel_Keyframe_Driver(keyframe_selecting[0]), mouse_mx + ui(8), mouse_my + ui(8)); } + + function dopesheet_new_folder() { var _dir = new timelineItemGroup(); PROJECT.timelines.addItem(_dir); } + function dopesheet_expand() { for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) timeline_contents[i].item.show = true; } + function dopesheet_collapse() { for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) timeline_contents[i].item.show = false; } + + function group_rename() { context_selecting_item.item.rename(); } + function group_remove() { context_selecting_item.item.destroy(); } + + function separate_axis() { context_selecting_prop.sep_axis = true; } + function combine_axis() { context_selecting_prop.sep_axis = false; } + + function range_set_start() { if(FRAME_RANGE == noone) FRAME_RANGE = [ __selecting_frame, TOTAL_FRAMES ]; else FRAME_RANGE[0] = __selecting_frame; } + function range_set_end() { if(FRAME_RANGE == noone) FRAME_RANGE = [ 0, __selecting_frame ]; else FRAME_RANGE[1] = __selecting_frame; } + function range_reset() { FRAME_RANGE = noone; } + #endregion + + keyframe_menu = [ + + MENU_ITEMS.animation_edit_keyframe_value, + MENU_ITEMS.animation_lock_keyframe_y, + + menuItemGroup(__txtx("panel_animation_ease_in", "Ease in"), [ + [ [THEME.timeline_ease, 0], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = CURVE_TYPE.linear; + k.ease_in = [0, 1]; + } + }, __txtx("panel_animation_ease_linear", "Linear") ], + [ [THEME.timeline_ease, 1], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = CURVE_TYPE.bezier; + k.ease_in = [1, 1]; + } + }, __txtx("panel_animation_ease_smooth", "Smooth") ], + [ [THEME.timeline_ease, 2], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = CURVE_TYPE.bezier; + k.ease_in = [1, 2]; + } + }, __txtx("panel_animation_ease_overshoot", "Overshoot") ], + [ [THEME.timeline_ease, 3], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = CURVE_TYPE.bezier; + k.ease_in = [0, 0]; + } + }, __txtx("panel_animation_ease_sharp", "Sharp") ], + [ [THEME.timeline_ease, 4], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = CURVE_TYPE.cut; + k.ease_in = [0, 0]; + } + }, __txtx("panel_animation_ease_hold", "Hold") ], + ]), + + menuItemGroup(__txtx("panel_animation_ease_out", "Ease out"), [ + [ [THEME.timeline_ease, 0], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_out_type = CURVE_TYPE.linear; + k.ease_out = [0, 0]; + } + }, __txtx("panel_animation_ease_linear", "Linear") ], + [ [THEME.timeline_ease, 1], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_out_type = CURVE_TYPE.bezier; + k.ease_out = [1, 0]; + } + }, __txtx("panel_animation_ease_smooth", "Smooth") ], + [ [THEME.timeline_ease, 2], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_out_type = CURVE_TYPE.bezier; + k.ease_out = [1, -1]; + } + }, __txtx("panel_animation_ease_overshoot", "Overshoot") ], + [ [THEME.timeline_ease, 3], function() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_out_type = CURVE_TYPE.bezier; + k.ease_out = [0, 1]; + } + }, __txtx("panel_animation_ease_sharp", "Sharp") ], + ]), + -1, + menuItemGroup(__txt("Align"), [ + [ [THEME.object_halign, 0], function() { alignKeys(fa_left); } ], + [ [THEME.object_halign, 1], function() { alignKeys(fa_center); } ], + [ [THEME.object_halign, 2], function() { alignKeys(fa_right); } ], + ]), + MENU_ITEMS.animation_stagger, + MENU_ITEMS.animation_driver, + -1, + MENU_ITEMS.animation_delete_keys, + MENU_ITEMS.animation_duplicate, + MENU_ITEMS.animation_copy, + MENU_ITEMS.animation_paste, + ]; + + keyframe_menu_empty = [ + MENU_ITEMS.animation_paste, + ]; + + context_selecting_item = noone; + context_selecting_prop = noone; + + name_menu_empty = [ + MENU_ITEMS.animation_new_folder, + -1, + MENU_ITEMS.animation_dopesheet_expand, + MENU_ITEMS.animation_dopesheet_collapse, + ]; + + var _clrs = COLORS.labels; + var _item = array_create(array_length(_clrs)); + + function setSelectingItemColor(color) { if(context_selecting_item == noone) return; context_selecting_item.item.setColor(color); } + + for( var i = 0, n = array_length(_clrs); i < n; i++ ) { + _item[i] = [ + [ THEME.timeline_color, i > 0, _clrs[i] ], + function(_data) { setSelectingItemColor(_data.color); }, "", { color: i == 0? -1 : _clrs[i] } + ]; + } + + array_push(_item, [ + [ THEME.timeline_color, 2 ], + function(_data) /*=>*/ { colorSelectorCall(context_selecting_item? context_selecting_item.item.getColor() : c_white, setSelectingItemColor); } + ]); + + var clr = menuItemGroup(__txt("Color"), _item); + clr.spacing = ui(24); + + name_menu_item = [ + clr, + -1, + name_menu_empty[0], + name_menu_empty[2], + name_menu_empty[3], + ]; + + name_menu_group = [ + clr, + MENU_ITEMS.animation_rename_group, + MENU_ITEMS.animation_remove_group, + -1, + name_menu_empty[0] + ]; + + name_menu_prop_sep = [ + MENU_ITEMS.animation_separate_axis, + -1, + name_menu_empty[2], + name_menu_empty[3], + ]; + + name_menu_prop_join = [ + MENU_ITEMS.animation_combine_axis, + -1, + name_menu_empty[2], + name_menu_empty[3], + ]; + + #endregion ++++ context menu ++++ + + function deleteKeys() { + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.anim.removeKey(k); + } + + keyframe_selecting = []; + } + + function alignKeys(halign = fa_left) { + if(array_empty(keyframe_selecting)) return; + + var tt = 0; + + switch(halign) { + case fa_left : + tt = 9999; + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) + tt = min(tt, keyframe_selecting[i].time); + break; + case fa_center : + tt = 0; + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) + tt += keyframe_selecting[i].time; + tt = round(tt / array_length(keyframe_selecting)); + break; + case fa_right : + tt = -9999; + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) + tt = max(tt, keyframe_selecting[i].time); + break; + } + + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.anim.setKeyTime(k, tt,, true); + } + } + + function arrangeKeys() { + //keyframe_selecting = l; + } + + function staggerKeys(_index, _stag) { + var modified = false; + var t = keyframe_selecting[_index].time; + + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + var _t = t + abs(i - _index) * _stag; + + modified |= k.anim.setKeyTime(k, _t); + } + + if(modified) UNDO_HOLDING = true; + } + + function onFocusBegin() { PANEL_ANIMATION = self; } + + function surfaceVerify() { + if(w - tool_width > 1) { + timeline_mask = surface_verify(timeline_mask, timeline_w, timeline_h); + timeline_surface = surface_verify(timeline_surface, timeline_w, timeline_h); + } + + dope_sheet_w = timeline_w; + dope_sheet_h = h - timeline_h - ui(24); + if(dope_sheet_h > ui(8)) { + dope_sheet_mask = surface_verify(dope_sheet_mask, dope_sheet_w, dope_sheet_h); + dope_sheet_surface = surface_verify(dope_sheet_surface, dope_sheet_w, dope_sheet_h); + + dope_sheet_name_mask = surface_verify(dope_sheet_name_mask, tool_width, dope_sheet_h); + dope_sheet_name_surface = surface_verify(dope_sheet_name_surface, tool_width, dope_sheet_h); + } + } + + function onResize() { + initSize(); + + surfaceVerify(); + resetTimelineMask(); + } + + function resetTimelineMask() { + timeline_mask = surface_verify(timeline_mask, timeline_w, timeline_h); + + surface_set_target(timeline_mask); + draw_clear(c_black); + gpu_set_blendmode(bm_subtract); + draw_sprite_stretched(THEME.ui_panel_bg, 0, 0, 0, timeline_w, timeline_h); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + + if(dope_sheet_h > 8) { + gpu_set_blendmode(bm_subtract); + + surface_set_target(dope_sheet_mask); + draw_clear(c_black); + draw_sprite_stretched(THEME.ui_panel_bg, 0, 0, 0, dope_sheet_w, dope_sheet_h); + surface_reset_target(); + + surface_set_target(dope_sheet_name_mask); + draw_clear(c_black); + draw_sprite_stretched(THEME.ui_panel_bg, 0, 0, 0, tool_width, dope_sheet_h); + surface_reset_target(); + + gpu_set_blendmode(bm_normal); + } + } + resetTimelineMask(); + + function getTimelineContentFolder(folder, _context = [], _depth = 0, _show = true) { #region + var ind = 0; + + for( var i = 0, n = array_length(folder.contents); i < n; i++ ) { + var _cont = folder.contents[i]; + if(!_cont.active) continue; + + var _content = { + item: _cont, + parent: _cont.parent, + index: ind, + contexts: _context, + y: 0, + h: 0, + depth: _depth, + show: _show, + }; + + if(is_instanceof(_cont, timelineItemGroup)) { + _content.type = "folder"; + array_push(timeline_contents, _content); + + var _context_folder = array_create(array_length(_context) + 1); + for( var j = 0, m = array_length(_context); j < m; j++ ) + _context_folder[j] = _context[j]; + _context_folder[m] = _content; + + if(item_dragging == noone || item_dragging.item != _cont) + getTimelineContentFolder(_cont, _context_folder, _depth + 1, _show && _cont.show); + } else if(is_instanceof(_cont, timelineItemNode)) { + var _node = _cont.node; + if(!is_struct(_node)) continue; + + var _anim = []; + var _prop = []; + + for( var j = 0, m = array_length(_node.inputs); j < m; j++ ) { + var prop = _node.inputs[j]; + if(!prop.isTimelineVisible()) continue; + + var anim = prop.sep_axis? prop.animators : [ prop.animator ]; + if(prop.sep_axis) array_append(_anim, prop.animators); + else array_push(_anim, prop.animator); + + array_push(_prop, { prop, animators: anim, y: 0 }); + } + + _content.type = "node"; + _content.node = _node; + _content.props = _prop; + _content.animators = _anim; + + array_push(timeline_contents, _content); + } + + if(item_dragging == noone || item_dragging.item != _cont) ind++; + } + } #endregion + + function getTimelineContent() { #region + timeline_contents = []; + getTimelineContentFolder(PROJECT.timelines); + } #endregion + + function drawTimeline() { #region // Draw summary + var bar_x = tool_width + ui(16); + var bar_y = h - timeline_h - ui(10); + var bar_w = timeline_w; + var bar_h = timeline_h; + var bar_total_w = TOTAL_FRAMES * timeline_scale; + var inspecting = PANEL_INSPECTOR.getInspecting(); + + resetTimelineMask(); + timeline_surface = surface_verify(timeline_surface, timeline_w, timeline_h); + + surface_set_target(timeline_surface); + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + #region bg + draw_sprite_stretched(THEME.ui_panel_bg, 1, 0, 0, bar_w, bar_h); + draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, bar_w, bar_h, COLORS.panel_animation_timeline_blend, 1); + #endregion + + #region cache + if(inspecting && inspecting.use_cache) { + for(var i = 0; i < TOTAL_FRAMES; i++) { + if(i >= array_length(inspecting.cache_result)) + break; + + var x0 = (i + 0) * timeline_scale + timeline_shift; + var x1 = (i + 1) * timeline_scale + timeline_shift; + + draw_set_color(inspecting.getAnimationCacheExist(i)? c_lime : c_red); + draw_set_alpha(0.05); + draw_rectangle(x0, 0, x1, bar_h, false); + draw_set_alpha(1); + } + } + #endregion + + #region lines + if(inspecting) + inspecting.drawAnimationTimeline(timeline_shift, bar_w, bar_h, timeline_scale); + + var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; + + for(var i = timeline_separate; i <= _fr; i += timeline_separate) { + var bar_line_x = i * timeline_scale + timeline_shift; + + if(i > TOTAL_FRAMES) draw_set_alpha(0.5); + + draw_set_color(COLORS.panel_animation_frame_divider); + draw_line(bar_line_x, ui(12), bar_line_x, bar_h - PANEL_PAD); + + draw_set_text(f_p2, fa_center, fa_bottom, COLORS._main_text_sub); + draw_text_add(bar_line_x, ui(16), string(i)); + } + + draw_set_alpha(1); + + var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; + draw_set_color(COLORS.panel_animation_end_line); + draw_set_alpha(0.5); + draw_line_width(bar_line_x, 0, bar_line_x, bar_h, 2); + draw_set_alpha(1.0); + + if(FRAME_RANGE != noone) { + var _fr_x0 = FRAME_RANGE[0] * timeline_scale + timeline_shift - 6; + var _fr_x1 = FRAME_RANGE[1] * timeline_scale + timeline_shift + 2; + + if(PROJECT.animator.is_simulating) + draw_sprite_stretched_ext(THEME.ui_selection_range_sim_hori, 0, _fr_x0, 0, _fr_x1 - _fr_x0, bar_h, COLORS.panel_animation_range_sim, 1); + else + draw_sprite_stretched_ext(THEME.ui_selection_range_hori, 0, _fr_x0, 0, _fr_x1 - _fr_x0, bar_h, COLORS.panel_animation_range, 1); + } + + var bar_line_x = (CURRENT_FRAME + 1) * timeline_scale + timeline_shift; + var cc = PROJECT.animator.is_playing? COLORS._main_value_positive : COLORS._main_accent; + draw_set_color(cc); + draw_line(bar_line_x, ui(15), bar_line_x, bar_h - PANEL_PAD); + + draw_set_text(f_p2, fa_center, fa_bottom, cc); + draw_text_add(bar_line_x, ui(16), string(CURRENT_FRAME + 1)); + #endregion + + #region summary \\\ Set X for all keyframes + var index = 0; + var key_y = ui(12) + (bar_h - ui(12)) / 2; + + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + if(_cont.type != "node") continue; + + var _anims = _cont.animators; + + for( var j = 0, m = array_length(_anims); j < m; j++ ) { + var _anim = _anims[j]; + + for(var k = 0; k < array_length(_anim.values); k++) { + var _keyframe = _anim.values[k]; + + var t = (_keyframe.time + 1) * timeline_scale + timeline_shift; + _keyframe.dopesheet_x = t; + + draw_sprite_ui_uniform(THEME.timeline_keyframe, 0, t, key_y, 1, COLORS.panel_animation_keyframe_hide); + } + } + } + #endregion + + #region pan zoom + timeline_shift = lerp_float(timeline_shift, timeline_shift_to, 4); + + if(timeline_scubbing) { + var rfrm = (mx - bar_x - timeline_shift) / timeline_scale - 1; + PROJECT.animator.setFrame(clamp(rfrm, 0, TOTAL_FRAMES - 1), !key_mod_press(ALT)); + timeline_show_time = CURRENT_FRAME; + + if(timeline_show_time != _scrub_frame) { + _scrub_frame = timeline_show_time; + } + + if(mouse_release(mb_left)) + timeline_scubbing = false; + } + + if(timeline_dragging) { + timeline_shift_to = clamp(timeline_drag_sx + mx - timeline_drag_mx, -max(bar_total_w - bar_w + 32, 0), 0); + timeline_shift = timeline_shift_to; + dope_sheet_y_to = clamp(timeline_drag_sy + my - timeline_drag_my, -dope_sheet_y_max, 0); + + if(mouse_release(mb_middle)) + timeline_dragging = false; + } + #endregion + + gpu_set_blendmode(bm_subtract); + draw_surface_safe(timeline_mask); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + + draw_surface_safe(timeline_surface, bar_x, bar_y); + + #region mouse interact + var bar_line_w = TOTAL_FRAMES * timeline_scale + timeline_shift; + var bar_int_x = min(bar_x + bar_w, bar_x + bar_line_w); + + if(pHOVER && point_in_rectangle(mx, my, bar_x, 16, bar_x + bar_w, bar_y - 8)) { + var sca = timeline_scale; + + if(mouse_wheel_down()) timeline_scale = max(timeline_scale - 1 * SCROLL_SPEED, 1); + if(mouse_wheel_up()) timeline_scale = min(timeline_scale + 1 * SCROLL_SPEED, 24); + + timeline_separate = 5; + timeline_sep_line = 1; + + if(timeline_scale <= 1) { timeline_separate = 50; timeline_sep_line = 10; } + else if(timeline_scale <= 3) { timeline_separate = 20; timeline_sep_line = 5; } + else if(timeline_scale <= 10) { timeline_separate = 10; timeline_sep_line = 2; } + + if(sca != timeline_scale) { + var mfb = (mx - bar_x - timeline_shift) / timeline_scale; + var mfa = (mx - bar_x - timeline_shift) / ui(sca); + + timeline_shift_to = clamp(timeline_shift_to - (mfa - mfb) * timeline_scale, -max(bar_total_w - bar_w + 32, 0), 0); + timeline_shift = timeline_shift_to; + } + + if(mx < bar_int_x && mouse_press(mb_middle, pFOCUS)) { + timeline_dragging = true; + + timeline_drag_sx = timeline_shift; + timeline_drag_sy = dope_sheet_y_to; + timeline_drag_mx = mx; + timeline_drag_my = my; + } + } + + if(pHOVER && point_in_rectangle(mx, my, bar_x, bar_y, bar_x + bar_w, bar_y + bar_h)) { //preview + if(mouse_wheel_down()) timeline_shift_to = clamp(timeline_shift_to - 64 * SCROLL_SPEED, -max(bar_total_w - bar_w + 32, 0), 0); + if(mouse_wheel_up()) timeline_shift_to = clamp(timeline_shift_to + 64 * SCROLL_SPEED, -max(bar_total_w - bar_w + 32, 0), 0); + + if(mx < bar_int_x && mouse_press(mb_left, pFOCUS)) { + timeline_scubbing = true; + timeline_scub_st = CURRENT_FRAME; + _scrub_frame = timeline_scub_st; + } + if(mouse_press(mb_right, pFOCUS)) { + __selecting_frame = clamp(round((mx - bar_x - timeline_shift) / timeline_scale), 0, TOTAL_FRAMES - 1); + + menuCall("animation_summary_menu",,, [ + MENU_ITEMS.animation_set_range_start, + MENU_ITEMS.animation_set_range_end, + MENU_ITEMS.animation_reset_range, + ]); + } + } + + if(pHOVER && point_in_rectangle(mx, my, bar_x, 8, bar_x + bar_w, 8 + 16)) { //top bar + if(mx < bar_int_x && mouse_press(mb_left, pFOCUS) && timeline_draggable) { + timeline_scubbing = true; + timeline_scub_st = CURRENT_FRAME; + _scrub_frame = timeline_scub_st; + } + } + + timeline_draggable = true; + #endregion + } #endregion + + function __drawDopesheetGraphLine(animator, key_y, msx, msy, _gy_val_min = 999999, _gy_val_max = -999999) { + var bar_total_w = TOTAL_FRAMES * timeline_scale; + var bar_show_w = timeline_shift + bar_total_w; + var hovering = noone; + + var _gh = animator.prop.graph_h - ui(16); + var _gy0 = key_y + ui(8); + var _gy1 = _gy0 + _gh; + + var amo = array_length(animator.values); + + #region get range + var _prevDelt = [ 0, 0 ]; + + for(var k = 0; k < amo; k++) { + var key = animator.values[k]; + var key_val = key.value; + + var _minn = _gy_val_min; + var _maxx = _gy_val_max; + + if(is_array(key_val)) { + for( var ki = 0; ki < array_length(key_val); ki++ ) { + _minn = min(_minn, key_val[ki]); + _maxx = max(_maxx, key_val[ki]); + } + } else { + _minn = min(_minn, key_val); + _maxx = max(_maxx, key_val); + } + + _minn += _prevDelt[0]; + _maxx += _prevDelt[1]; + _prevDelt = [ 0, 0 ]; + + switch(key.drivers.type) { + case DRIVER_TYPE.linear : + var nk = k + 1 < amo? animator.values[k + 1].time : TOTAL_FRAMES; + + var spd = key.drivers.speed * (nk - key.time); + _minn += min(spd, 0); + _maxx += max(spd, 0); + _prevDelt = [ min(spd, 0), max(spd, 0) ]; + break; + case DRIVER_TYPE.wiggle : + case DRIVER_TYPE.sine : + _minn -= abs(key.drivers.amplitude); + _maxx += abs(key.drivers.amplitude); + _prevDelt = [ -key.drivers.amplitude, key.drivers.amplitude ]; + break; + } + + _gy_val_min = min(_minn, _gy_val_min); + _gy_val_max = max(_maxx, _gy_val_max); + } + #endregion + + var valArray = is_array(animator.values[0].value); + var ox = 0; + var nx = 0; + var ny = noone; + + var oly = 0; + var nly = 0; + var _kv, _kn; + var sy; + + var _oy = animator.values[0].value; + if(!valArray) _oy = [ _oy ]; + + var oy = array_create(array_length(_oy)); + for( var ki = 0; ki < array_length(_oy); ki++ ) + oy[ki] = value_map(_oy[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + + for(var k = 0; k < amo - 1; k++) { // draw line in between + var key = animator.values[k]; + var t = key.dopesheet_x; + var key_next = animator.values[k + 1]; + var dx = key_next.time - key.time; + + if(key.drivers.type) { // driver + nx = (key.time + 1) * timeline_scale + timeline_shift; + + for( var _time = key.time; _time <= key_next.time; _time++ ) { + var rat = (_time - key.time) / (key_next.time - key.time); + var _lrp = animator.interpolate(key, key_next, rat); + + _kv = animator.processDriver(_time, key, animator.lerpValue(key, key_next, _lrp), rat); + + if(!valArray) _kv = [ _kv ]; + + for( var ki = 0; ki < array_length(_kv); ki++ ) { + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); + __draw_set_color(cc); + + ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + + if(_time == key.time) draw_line(nx, oy[ki], nx, ny[ki]); + else draw_line(ox, oy[ki], nx, ny[ki]); + + oy[ki] = ny[ki]; + } + + ox = nx; + nx += timeline_scale; + } + } else if(key.ease_out_type == CURVE_TYPE.linear && key_next.ease_in_type == CURVE_TYPE.linear) { //linear draw + nx = (key_next.time + 1) * timeline_scale + timeline_shift; + + _kv = key.value; + _kn = key_next.value; + + if(!valArray) { + _kv = [ _kv ]; + _kn = [ _kn ]; + } + + for( var ki = 0; ki < array_length(_kv); ki++ ) { + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); + __draw_set_color(cc); + + ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + + if(array_length(oy) > ki) draw_line(t, oy[ki], t, ny[ki]); + oy[ki] = ny[ki]; + + ny[ki] = value_map(_kn[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + draw_line(t, oy[ki], nx, ny[ki]); + oy[ki] = ny[ki]; + } + + ox = nx; + } else { //bezier easing + var _step = 1 / dx; + for( var _r = 0; _r <= 1; _r += _step ) { + nx = t + _r * dx * timeline_scale; + nly = animator.interpolate(key, key_next, _r); + + _kv = key.value; + _kn = key_next.value; + + if(!valArray) { + _kv = [ _kv ]; + _kn = [ _kn ]; + } + + for( var ki = 0; ki < array_length(_kv); ki++ ) { + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); + __draw_set_color(cc); + + ny[ki] = value_map(lerp(_kv[ki], _kn[ki], nly), _gy_val_min, _gy_val_max, _gy1, _gy0); + + if(array_length(oy) > ki) draw_line(ox, oy[ki], nx, ny[ki]); + + oy[ki] = ny[ki]; + } + + ox = nx; + oly = nly; + } + } + } // draw line in between + + if(animator.prop.show_graph && array_length(animator.values) > 0) { // draw line outside keyframe range + var key_first = animator.values[0]; + var t_first = (key_first.time + 1) * timeline_scale + timeline_shift; + + _kv = key_first.value; + if(!valArray) _kv = [ _kv ]; + + for( var ki = 0; ki < array_length(_kv); ki++ ) { + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); + __draw_set_color(cc); + + sy = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + draw_line(0, sy, t_first, sy); + + if(array_length(animator.values) == 1) oy[ki] = sy; + } + + var key_last = animator.values[array_length(animator.values) - 1]; + var t_last = (key_last.time + 1) * timeline_scale + timeline_shift; + + if(key_last.time < TOTAL_FRAMES) { + if(key_last.drivers.type) { + nx = t_last; + + for( var _time = key_last.time; _time < TOTAL_FRAMES; _time++ ) { + _kv = animator.processDriver(_time, key_last); + if(!valArray) _kv = [ _kv ]; + + for( var ki = 0; ki < array_length(_kv); ki++ ) { + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); + __draw_set_color(cc); + + ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + if(_time == key_last.time) + draw_line(t_last, oy[ki], t_last, ny[ki]); + else + draw_line(ox, oy[ki], nx, ny[ki]); + + oy[ki] = ny[ki]; + } + + ox = nx; + nx += timeline_scale; + } + } else { + _kv = key_last.value; + if(!valArray) _kv = [ _kv ]; + + for( var ki = 0; ki < array_length(_kv); ki++ ) { + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, ki, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + cc = colorMultiplyRGB(cc, CDEF.main_ltgrey); + __draw_set_color(cc); + + ny[ki] = value_map(_kv[ki], _gy_val_min, _gy_val_max, _gy1, _gy0); + draw_line(t_last, oy[ki], t_last, ny[ki]); + draw_line(t_last, ny[ki], bar_show_w, ny[ki]); + } + } + } + } // draw line outside keyframe range + + #region // draw key + + for(var i = 0; i < amo; i++) { + var key = animator.values[i]; + var px = key.dopesheet_x; + + var v = key.value; + if(!valArray) v = [ v ]; + + var ei = key.ease_in; + var eo = key.ease_out; + + var ix = px - ei[0] * timeline_scale * 2; + var ox = px + eo[0] * timeline_scale * 2; + + for (var j = 0, m = array_length(v); j < m; j++) { + var py = value_map(v[j], _gy_val_min, _gy_val_max, _gy1, _gy0); + var iy = py + (1 - ei[1]) * timeline_scale * 2; + var oy = py - ( eo[1]) * timeline_scale * 2; + + var cc = COLORS.panel_animation_graph_line; + if(valArray) cc = array_safe_get(COLORS.axis, j, cc); + else if(animator.prop.sep_axis) cc = array_safe_get(COLORS.axis, animator.index, cc); + + if(ei[0] != 0) { + var _hv = (graph_key_hover == key && ( graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_in || graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_both)) || + (graph_key_drag == key && ( graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_in || graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_both)); + + draw_set_color(_hv? COLORS._main_accent : cc); + draw_line(ix, iy, px, py); + draw_circle(ix, iy, 3, false); + + if(point_in_circle(msx, msy, ix, iy, 4)) { + _graph_key_hover = key; + _graph_key_hover_index = KEYFRAME_DRAG_TYPE.ease_in; + + _graph_key_hover_x = px; + _graph_key_hover_y = py; + } + } + + if(eo[0] != 0) { + var _hv = (graph_key_hover == key && (graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_out || graph_key_hover_index == KEYFRAME_DRAG_TYPE.ease_both)) || + (graph_key_drag == key && (graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_out || graph_key_drag_index == KEYFRAME_DRAG_TYPE.ease_both)); + + draw_set_color(_hv? COLORS._main_accent : cc); + draw_line(px, py, ox, oy); + draw_circle(ox, oy, 3, false); + + if(point_in_circle(msx, msy, ox, oy, 4)) { + _graph_key_hover = key; + _graph_key_hover_index = KEYFRAME_DRAG_TYPE.ease_out; + + _graph_key_hover_x = px; + _graph_key_hover_y = py; + } + } + + var _hv = (graph_key_hover == key && graph_key_hover_index == KEYFRAME_DRAG_TYPE.move) || + (graph_key_drag == key && graph_key_drag_index == KEYFRAME_DRAG_TYPE.move); + + draw_set_color(_hv? COLORS._main_accent : cc); + draw_circle(px, py, 4, false); + + if(point_in_circle(msx, msy, px, py, 5)) { + _graph_key_hover = key; + _graph_key_hover_index = KEYFRAME_DRAG_TYPE.move; + + _graph_key_hover_x = px; + _graph_key_hover_y = py; + } + } + + } + #endregion // draw key + } + + function _drawDopesheetGraph(prop, key_y, msx, msy) { + var bar_total_w = TOTAL_FRAMES * timeline_scale; + var bar_show_w = timeline_shift + bar_total_w; + + if(prop.type == VALUE_TYPE.color) { // draw color + + var _gy0 = key_y - ui(4); + var _gy1 = key_y + ui(4); + + var amo = array_length(prop.animator.values); + var _prevKey = prop.animator.values[0]; + + draw_set_color(_prevKey.value); + draw_rectangle(0, _gy0, _prevKey.dopesheet_x, _gy1, 0); + + var ox, nx, oc, nc; + + for(var k = 0; k < amo - 1; k++) { + var key = prop.animator.values[k]; + var key_next = prop.animator.values[k + 1]; + var dx = key_next.time - key.time; + var _step = 1 / dx; + + for( var _r = 0; _r <= 1; _r += _step ) { + nx = key.dopesheet_x + _r * dx * timeline_scale; + var lrp = prop.animator.interpolate(key, key_next, _r); + nc = merge_color(key.value, key_next.value, lrp); + + if(_r > 0) draw_rectangle_color(ox, _gy0, nx, _gy1, oc, nc, nc, oc, 0); + + ox = nx; + oc = nc; + } + } + + key_next = prop.animator.values[array_length(prop.animator.values) - 1]; + if(key_next.time < TOTAL_FRAMES) { + draw_set_color(key_next.value); + draw_rectangle(key_next.dopesheet_x, _gy0, bar_show_w, _gy1, 0); + } + return; + } + + var bar_x = tool_width + ui(16); + var bar_y = h - timeline_h - ui(10); + var bar_w = timeline_w; + var bar_h = timeline_h; + var bar_total_w = TOTAL_FRAMES * timeline_scale; + + var _gh = prop.graph_h; + var _gy0 = key_y + ui(8); + var _gy1 = _gy0 + _gh; + + if(point_in_rectangle(msx, msy, 0, _gy0, w, _gy1)) + keyframe_boxable = false; + + var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; + var _mmx = msx - 0; + var _mmy = msy - _gy0; + + keyframe_graph_surface = surface_verify(keyframe_graph_surface, w, _gh); + surface_set_target(keyframe_graph_surface); + draw_clear(COLORS.panel_animation_timeline_top); + + for(var i = timeline_sep_line; i <= _fr; i += timeline_sep_line) { + var bar_line_x = i * timeline_scale + timeline_shift; + + draw_set_color(COLORS.panel_animation_frame_divider); + draw_set_alpha((i % timeline_separate == 0? 1 : 0.1) * ((i <= TOTAL_FRAMES) * 0.5 + 0.5) * 0.3); + draw_line(bar_line_x, 0, bar_line_x, _gh - PANEL_PAD); + } + draw_set_alpha(1); + + var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; + draw_set_color(COLORS.panel_animation_end_line); + draw_set_alpha(0.5); + draw_line_width(bar_line_x, 0, bar_line_x, _gh, 2); + draw_set_alpha(1); + + if(prop.sep_axis) { // draw number graphs + var _min = 999999; + var _max = -999999; + + for( var i = 0, n = array_length(prop.animators); i < n; i++ ) { + if(!prop.show_graphs[i]) continue; + + var animator = prop.animators[i]; + for(var k = 0; k < array_length(animator.values); k++) { + var key_val = animator.values[k].value; + if(is_array(key_val)) { + for( var ki = 0; ki < array_length(key_val); ki++ ) { + _min = min(_min, key_val[ki]); + _max = max(_max, key_val[ki]); + } + } else { + _min = min(_min, key_val); + _max = max(_max, key_val); + } + } + } + + for( var i = 0, n = array_length(prop.animators); i < n; i++ ) { + if(!prop.show_graphs[i]) continue; + + __drawDopesheetGraphLine(prop.animators[i], 0, _mmx, _mmy, _min, _max); + } + } else + __drawDopesheetGraphLine(prop.animator, 0, _mmx, _mmy); + surface_reset_target(); + + draw_surface(keyframe_graph_surface, 0, _gy0); + + } + + function editKeyFrame(keyframe, _x = mouse_mx + ui(8), _y = mouse_my + ui(8)) { + var _prop = keyframe.anim.prop; + var _wid = _prop.editWidget; + __keyframe_editing = keyframe; + + switch(_prop.type) { + case VALUE_TYPE.color : + switch(_prop.display_type) { + case VALUE_DISPLAY.palette : + var dialog = dialogCall(o_dialog_palette, WIN_W / 2, WIN_H / 2); + dialog.setDefault(keyframe.value); + dialog.onApply = function(val) { __keyframe_editing.value = val; }; + dialog.drop_target = _wid; + break; + + default : + var dialog = dialogCall(o_dialog_color_selector, WIN_W / 2, WIN_H / 2); + dialog.setDefault(keyframe.value); + dialog.selector.onApply = function(val) { __keyframe_editing.value = val; }; + dialog.onApply = function(val) { __keyframe_editing.value = val; }; + dialog.drop_target = _wid; + } + break; + + case VALUE_TYPE.gradient : + var dialog = dialogCall(o_dialog_gradient, WIN_W / 2, WIN_H / 2); + dialog.setDefault(keyframe.value.clone()); + dialog.onApply = function(val) { __keyframe_editing.value = val; }; + dialog.drop_target = _wid; + break; + + default : + dialogCall(o_dialog_value_editor, _x, _y).setKey(keyframe); + } + } + + function _drawDopesheetAnimatorKeysBG(animator, msx, msy) { #region + var prop_dope_y = animator.y; + var key_hover = noone; + var key_list = animator.values; + + if((animator.prop.on_end == KEYFRAME_END.loop || animator.prop.on_end == KEYFRAME_END.ping) && array_length(key_list) > 1) { + var keyframe_s = animator.prop.loop_range == -1? key_list[0].time : key_list[array_length(key_list) - 1 - animator.prop.loop_range].time; + var keyframe_e = key_list[array_length(key_list) - 1].time; + + var ks_x = (keyframe_s + 1) * timeline_scale + timeline_shift; + var ke_x = (keyframe_e + 1) * timeline_scale + timeline_shift; + + draw_set_color(COLORS.panel_animation_loop_line); + draw_set_alpha(0.2); + draw_line_width(ks_x, prop_dope_y - 1, ke_x, prop_dope_y - 1, 4); + draw_set_alpha(1); + } + + for( var k = 0, n = array_length(key_list); k < n; k++ ) { //draw easing + var key = key_list[k]; + var t = key.dopesheet_x; + + if(key.ease_in_type == CURVE_TYPE.bezier) { + draw_set_color(COLORS.panel_animation_keyframe_ease_line); + var _tx = t - key.ease_in[0] * timeline_scale * 2; + draw_line_width(_tx, prop_dope_y - 1, t, prop_dope_y - 1, 2); + + if(pHOVER && point_in_circle(msx, msy, _tx, prop_dope_y, ui(6))) { + key_hover = key; + draw_sprite_ui_uniform(THEME.timeline_key_ease, 0, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_selected); + if(mouse_press(mb_left, pFOCUS) && !key_mod_press(SHIFT)) { + keyframe_dragging = animator.values[k]; + keyframe_drag_type = KEYFRAME_DRAG_TYPE.ease_in; + } + } else + draw_sprite_ui_uniform(THEME.timeline_key_ease, 0, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_unselected); + } + + if(key.ease_out_type == CURVE_TYPE.bezier) { + draw_set_color(COLORS.panel_animation_keyframe_ease_line); + var _tx = t + key.ease_out[0] * timeline_scale * 2; + draw_line_width(t, prop_dope_y - 1, _tx, prop_dope_y - 1, 2); + + if(pHOVER && point_in_circle(msx, msy, _tx, prop_dope_y, ui(6))) { + key_hover = key; + draw_sprite_ui_uniform(THEME.timeline_key_ease, 1, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_selected); + if(mouse_press(mb_left, pFOCUS) && !key_mod_press(SHIFT)) { + keyframe_dragging = animator.values[k]; + keyframe_drag_type = KEYFRAME_DRAG_TYPE.ease_out; + } + } else + draw_sprite_ui_uniform(THEME.timeline_key_ease, 1, _tx, prop_dope_y, 1, COLORS.panel_animation_keyframe_unselected); + } + } + + return key_hover; + } #endregion + + __keyframe_editing = noone; + + function _drawDopesheetAnimatorKeys(_cont, animator, msx, msy) { #region + var _node = _cont.node; + var prop_y = animator.y; + var node_y = _cont.y; + var anim_set = true; + var key_hover = noone; + + for(var k = 0; k < array_length(animator.values); k++) { + var keyframe = animator.values[k]; + var t = keyframe.dopesheet_x; + + for( var j = 0, n = array_length(_cont.contexts); j < n; j++ ) { + var _cxt = _cont.contexts[j]; + if(!_cxt.show) continue; + draw_sprite_ui_uniform(THEME.timeline_key_empty, 0, t, _cxt.y + ui(10), 1, COLORS._main_icon); + } + + if(!_cont.show) continue; + draw_sprite_ui_uniform(THEME.timeline_key_empty, 0, t, node_y + ui(10), 1, COLORS._main_icon); + + if(!_cont.item.show) continue; + + var cc = COLORS.panel_animation_keyframe_unselected; + if(on_end_dragging_anim == animator.prop && msx < t && anim_set) { + if(k == 0) + animator.prop.loop_range = -1; + else + animator.prop.loop_range = array_length(animator.values) - k; + anim_set = false; + } + + if(pHOVER && point_in_circle(msx, msy, t, prop_y, ui(8))) { + cc = COLORS.panel_animation_keyframe_selected; + key_hover = keyframe; + if(!instance_exists(o_dialog_menubox)) + TOOLTIP = [ keyframe.value, animator.prop.type ]; + + if(pFOCUS && !key_mod_press(SHIFT)) { + if(DOUBLE_CLICK) { + keyframe_dragging = keyframe; + keyframe_drag_type = KEYFRAME_DRAG_TYPE.ease_both; + keyframe_dragout = false; + keyframe_drag_mx = mx; + keyframe_drag_my = my; + + } else if(mouse_press(mb_left)) { + if(key_mod_press(CTRL)) { + editKeyFrame(keyframe); + + } else { + keyframe_dragging = keyframe; + keyframe_drag_type = KEYFRAME_DRAG_TYPE.move; + keyframe_drag_mx = mx; + keyframe_drag_my = my; + } + } + } + } + + if(stagger_mode == 1 && array_exists(keyframe_selecting, keyframe)) + cc = key_hover == keyframe? COLORS.panel_animation_keyframe_selected : COLORS._main_accent; + + var ind = keyframe.getDrawIndex(); + draw_sprite_ui_uniform(THEME.timeline_keyframe, ind, t, prop_y, 1, cc); + + if(array_exists(keyframe_selecting, keyframe)) + draw_sprite_ui_uniform(THEME.timeline_keyframe_selecting, ind, t, prop_y, 1, COLORS._main_accent); + + if(keyframe_boxing) { + var box_x0 = min(keyframe_box_sx, msx); + var box_x1 = max(keyframe_box_sx, msx); + var box_y0 = min(keyframe_box_sy, msy); + var box_y1 = max(keyframe_box_sy, msy); + + if(pHOVER && !point_in_rectangle(t, prop_y, box_x0, box_y0, box_x1, box_y1) && array_exists(keyframe_selecting, keyframe)) + array_remove(keyframe_selecting, keyframe); + if(pHOVER && point_in_rectangle(t, prop_y, box_x0, box_y0, box_x1, box_y1) && !array_exists(keyframe_selecting, keyframe)) + array_push(keyframe_selecting, keyframe); + } + } + + return key_hover; + } #endregion + + function __drawDopesheetLabelAnimator(_item, _node, animator, msx, msy) { #region + var prop = animator.prop; + var aa = _node.group == PANEL_GRAPH.getCurrentContext()? 1 : 0.9; + var tx = tool_width; + var ty = animator.y - 1; + + var hov = item_dragging == noone && pHOVER && point_in_rectangle(msx, msy, 0, ty - ui(8), w - ui(64), ty + ui(8)); + + //// DRAW NAME + var cc = prop.sep_axis? COLORS.axis[animator.index] : COLORS._main_text_sub; + if(hov) cc = COLORS._main_text_accent; + + draw_set_color(CDEF.main_mdblack); + draw_rectangle(ui(32), ty - ui(8), tool_width, ty + ui(8), false); + + draw_set_color(cc); + + var _title_x = ui(32); + if(!show_nodes) { + var _txt = animator.prop.node.getDisplayName(); + + draw_set_alpha(aa * 0.5); + draw_text_add(_title_x, ty - 2, _txt); + _title_x += string_width(_txt) + ui(4); + } + + var _txt = animator.getName(); + draw_set_alpha(aa); + draw_text_add(_title_x, ty - 2, _txt); + draw_set_alpha(1); + _title_x += string_width(_txt) + ui(4); + + if(hov) { + value_hovering = prop; + if(mouse_click(mb_left, pFOCUS)) + value_focusing = prop; + + if(mouse_press(mb_right, pFOCUS)) { + context_selecting_prop = prop; + context_selecting_item = _item; + } + } + + var _gx = ui(20); + var _gy = ty; + if(hov) + if(buttonInstant(noone, _gx - ui(10), _gy - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.animate_prop_go, 0, [COLORS._main_icon, COLORS._main_icon_on_inner], 0.75) == 2) { + graphFocusNode(_node); + PANEL_INSPECTOR.highlightProp(prop); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + var _tool_a = 0.5 + hov * 0.5; + + var _on_end_disp = prop.on_end || hov; + var _tool_x0 = tool_width - ui(20 + 16 * (3 + _on_end_disp * 1.5) + 12); + var _tool_x1 = tool_width; + draw_set_color(c_white); + BLEND_SUBTRACT + draw_rectangle(_tool_x0, ty - ui(8), _tool_x1, ty + ui(8), false); + BLEND_NORMAL + + var _graph_show = prop.sep_axis? prop.show_graphs[animator.index] : prop.show_graph; + + if(_graph_show) { + var _y1 = ty + ui(10) + prop.graph_h + ui(8); + var c1 = colorMultiply(_item.item.color_cur, COLORS.panel_animation_dope_key_bg_hover); + draw_set_color(c1); + draw_rectangle(0, ty + ui(10), tx, _y1, false); + } + + var c0 = colorMultiply(_item.item.color_cur, COLORS.panel_animation_dope_key_bg); + draw_set_color(c0); + draw_rectangle(0, ty - ui(10), tx, ty + ui(10), false); + + #region keyframe control + tx = tool_width - ui(20 + 16 * 3); + if(buttonInstant(noone, tx - ui(10), ty - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.prop_keyframe, 0, [COLORS._main_icon, COLORS._main_icon_on_inner], _tool_a) == 2) { + var _t = -1; + for(var k = 0; k < array_length(animator.values); k++) { + var _key = animator.values[k]; + if(_key.time < CURRENT_FRAME) + _t = _key.time; + } + if(_t > -1) PROJECT.animator.setFrame(_t); + } + + tx = tool_width - ui(20 + 16 * 1); + if(buttonInstant(noone, tx - ui(10), ty - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.prop_keyframe, 2, [COLORS._main_icon, COLORS._main_icon_on_inner], _tool_a) == 2) { + for(var k = 0; k < array_length(animator.values); k++) { + var _key = animator.values[k]; + if(_key.time > CURRENT_FRAME) { + PROJECT.animator.setFrame(_key.time); + break; + } + } + } + #endregion + + #region add keyframe + tx = tool_width - ui(20 + 16 * 2); + if(buttonInstant(noone, tx - ui(10), ty - ui(9), ui(20), ui(17), [msx, msy], pFOCUS, pHOVER, "", THEME.prop_keyframe, 1, [COLORS._main_accent, COLORS._main_icon_on_inner], _tool_a) == 2) { + var _add = false; + for(var k = 0; k < array_length(animator.values); k++) { + var _key = animator.values[k]; + if(_key.time == CURRENT_FRAME) { + if(array_length(animator.values) > 1) + array_delete(animator.values, k, 1); + _add = true; + break; + } else if(_key.time > CURRENT_FRAME) { + array_insert(animator.values, k, new valueKey(CURRENT_FRAME, variable_clone(animator.getValue()), animator)); + _add = true; + break; + } + } + if(!_add) array_push(animator.values, new valueKey(CURRENT_FRAME, variable_clone(animator.getValue(, false)), animator)); + } + #endregion + + if(isGraphable(prop)) { + tx = tool_width - ui(16); + if(pHOVER && point_in_rectangle(msx, msy, tx - ui(9), ty - ui(10), tx + ui(10), ty + ui(8))) { + draw_sprite_ui_uniform(THEME.timeline_graph, 1, tx, ty, 1, COLORS._main_icon_on_inner, _tool_a); + TOOLTIP = _graph_show? __txtx("panel_animation_hide_graph", "Hide graph") : __txtx("panel_animation_show_graph", "Show graph"); + + if(mouse_press(mb_left, pFOCUS)) { + if(prop.sep_axis) prop.show_graphs[animator.index] = !_graph_show; + else prop.show_graph = !_graph_show; + } + } else + draw_sprite_ui_uniform(THEME.timeline_graph, 1, tx, ty, 1, _graph_show? COLORS._main_accent : COLORS._main_icon, _graph_show? 1 : _tool_a); + } + + tx = tool_width - ui(20 + 16 * 4.5); + + if(pHOVER && point_in_rectangle(msx, msy, tx - ui(10), ty - ui(9), tx + ui(10), ty + ui(8))) { + draw_sprite_ui_uniform(THEME.prop_on_end, prop.on_end, tx, ty, 1, COLORS._main_icon_on_inner, _on_end_disp); + + if(tooltip_loop_prop != prop) + tooltip_loop_type.arrow_pos = noone; + tooltip_loop_prop = prop; + tooltip_loop_type.index = prop.on_end; + TOOLTIP = tooltip_loop_type; + + if(mouse_release(mb_left, pFOCUS)) + prop.on_end = safe_mod(prop.on_end + 1, sprite_get_number(THEME.prop_on_end)); + if(mouse_press(mb_left, pFOCUS)) + on_end_dragging_anim = prop; + } else + draw_sprite_ui_uniform(THEME.prop_on_end, prop.on_end, tx, ty, 1, on_end_dragging_anim == prop? COLORS._main_accent : COLORS._main_icon, _on_end_disp); + + draw_set_alpha(1); + } #endregion + + function __drawDopesheetLabelItem(_item, _x, _y, msx = -1, msy = -1, alpha = 1) { #region + var _itx = _x; + var _ity = _y; + var _itw = tool_width; + var _hov = pHOVER && (msy > 0 && msy < dope_sheet_h); + var _foc = pFOCUS; + + 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)) { + _item_dragging = _item; + item_dragging_mx = msx; + item_dragging_my = msy; + + item_dragging_dx = msx - _x; + item_dragging_dy = msy - _y; + } + + if(mouse_press(mb_right, _foc)) + context_selecting_item = _item; + } + } #endregion + + function _drawDopesheetLabel() { #region + surface_set_target(dope_sheet_name_surface); + draw_clear_alpha(COLORS.panel_bg_clear_inner, 0); + var msx = mx - ui(8); + var msy = my - ui(8); + + draw_set_text(f_p2, fa_left, fa_center); + + value_hovering = noone; + if(mouse_click(mb_left, pFOCUS)) + value_focusing = noone; + + if(mouse_press(mb_right, pFOCUS)) { + context_selecting_item = noone; + context_selecting_prop = noone; + } + + #region draw + hovering_folder = PROJECT.timelines; + hovering_order = 0; + + var last_y = 0; + var last_i = 0; + + if(item_dragging != noone) + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + if(!_cont.show) continue; + + var _y = _cont.y; + var _h = _cont.h; + + if(_y + _h < 0) continue; + if(_y > h) break; + + if(item_dragging != noone && item_dragging.item == _cont.item) continue; + + if(_cont.type == "folder") { + if(msy > _y && msy <= _y + _h) { + hovering_folder = _cont.item; + hovering_order = -1; + } + } else if(_cont.type == "node") { + if(msy > _y && msy <= _y + _h / 2) { + hovering_folder = _cont.parent; + hovering_order = _cont.index; + } else if(msy > _y + _h / 2 && msy <= _y + _h) { + hovering_folder = _cont.parent; + hovering_order = _cont.index + 1; + } + } + + last_y = _y + _h; + if(_cont.parent == PROJECT.timelines) + last_i = _cont.index + 1; + } + + if(msy > last_y) { + hovering_folder = PROJECT.timelines; + hovering_order = last_i; + } + + var _itx = -1, _ity, _itw; + + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + if(!_cont.show) continue; + + var _y = _cont.y; + var _h = _cont.h; + + if(_y + _h < 0) continue; + if(_y > h) break; + + if(item_dragging != noone && item_dragging.item == _cont.item) { + _itx = _cont.depth * ui(20); + _ity = _cont.y; + _itw = tool_width - _cont.depth * ui(20); + continue; + } + + if(show_nodes) __drawDopesheetLabelItem(_cont, 0, _cont.y, msx, msy); + + if(_cont.type == "node" && _cont.item.show) + for( var j = 0; j < array_length(_cont.animators); j++ ) + __drawDopesheetLabelAnimator(_cont, _cont.node, _cont.animators[j], msx, msy); + } + + if(_itx != -1) { + draw_set_color(COLORS._main_accent); + draw_line_width(_itx, _ity, _itx + _itw, _ity, 2); + } + + if(_item_dragging != noone) { + if(point_distance(msx, msy, item_dragging_mx, item_dragging_my) > 4) { + item_dragging = _item_dragging; + _item_dragging = noone; + } + } + + if(item_dragging != noone) { + item_dragging.item.removeSelf(); + if(hovering_order == -1) + array_insert(hovering_folder.contents, 0, item_dragging.item); + else { + var _ind = min(array_length(hovering_folder.contents), hovering_order); + array_insert(hovering_folder.contents, _ind, item_dragging.item); + } + + item_dragging.item.parent = hovering_folder; + } + + if(mouse_release(mb_left)) { + _item_dragging = noone; + item_dragging = noone; + } + #endregion + + gpu_set_blendmode(bm_subtract); + draw_surface_safe(dope_sheet_name_mask); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + } #endregion + + function drawDopesheet() { #region + var bar_x = tool_width + ui(16); + var bar_y = h - timeline_h - ui(10); + var bar_w = timeline_w; + var bar_h = timeline_h; + var bar_total_w = TOTAL_FRAMES * timeline_scale; + + surfaceVerify(); + + #region scroll + dope_sheet_y = lerp_float(dope_sheet_y, dope_sheet_y_to, 4); + + if(pHOVER && point_in_rectangle(mx, my, ui(8), ui(8), bar_x, ui(8) + dope_sheet_h)) { + if(mouse_wheel_down()) dope_sheet_y_to = clamp(dope_sheet_y_to - ui(32) * SCROLL_SPEED, -dope_sheet_y_max, 0); + if(mouse_wheel_up()) dope_sheet_y_to = clamp(dope_sheet_y_to + ui(32) * SCROLL_SPEED, -dope_sheet_y_max, 0); + } + + var scr_x = bar_x + dope_sheet_w + ui(4); + var scr_y = ui(8); + var scr_s = dope_sheet_h; + var scr_prog = -dope_sheet_y / dope_sheet_y_max; + var scr_size = dope_sheet_h / (dope_sheet_h + dope_sheet_y_max); + + var scr_scale_s = scr_s * scr_size; + var scr_prog_s = scr_prog * (scr_s - scr_scale_s); + + var scr_w = scroll_w; + var scr_h = scr_s; + var s_bar_w = scroll_w; + var s_bar_h = scr_scale_s; + var s_bar_x = scr_x; + var s_bar_y = scr_y + scr_prog_s; + + if(is_scrolling) { + if(scr_s - scr_scale_s != 0) + dope_sheet_y_to = clamp((my - scr_y - scr_scale_s / 2) / (scr_s - scr_scale_s), 0, 1) * -dope_sheet_y_max; + + if(mouse_release(mb_left)) is_scrolling = false; + } + + if(pHOVER && point_in_rectangle(mx, my, scr_x - ui(2), scr_y - ui(2), scr_x + scr_w + ui(2), scr_y + scr_h + ui(2))) { + draw_sprite_stretched_ext(THEME.ui_scrollbar, 0, s_bar_x, s_bar_y, s_bar_w, s_bar_h, COLORS.scrollbar_hover, 1); + if(mouse_click(mb_left, pFOCUS)) + is_scrolling = true; + } else { + draw_sprite_stretched_ext(THEME.ui_scrollbar, 0, s_bar_x, s_bar_y, s_bar_w, s_bar_h, COLORS.scrollbar_idle, 1); + } + + var _p = PEN_USE && (is_scrolling || point_in_rectangle(mx, my, scr_x - ui(2), scr_y - ui(2), scr_x + scr_w + ui(2), scr_y + scr_h + ui(2))); + scroll_w = lerp_float(scroll_w, _p? 12 : scroll_s, 5); + #endregion + + surface_set_target(dope_sheet_surface); + draw_clear_alpha(COLORS.panel_bg_clear, 1); + var msx = mx - bar_x; + var msy = my - ui(8); + + #region bg \\\\ set X, Y for Node and Prop + var bar_show_w = timeline_shift + bar_total_w; + + var _bg_w = min(bar_total_w + PANEL_PAD, bar_w); + draw_sprite_stretched_ext(THEME.ui_panel_bg, 2, 0, 0, bar_w, dope_sheet_h, COLORS.panel_animation_timeline_blend, 1); + + dope_sheet_y_max = 0; + var key_y = ui(22) + dope_sheet_y; + var c0, c1; + + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + _cont.y = key_y; + _cont.h = 0; + _cont.item.drawDopesheet(timeline_shift, _cont.y, timeline_scale, msx, msy); + + if(!_cont.show) + continue; + if(item_dragging != noone && item_dragging.item == _cont.item) + continue; + + var _expand = _cont.type == "node" && _cont.item.show; + + var _ks = key_y; + if(_cont.item.color_dsp > -1) { + draw_set_color(_cont.item.color_dsp); + draw_rectangle(0, _ks - 1, bar_show_w, _ks + ui(20), false); + } + + if(_cont.item.color_cur > -1) { + c0 = colorMultiply(_cont.item.color_cur, COLORS.panel_animation_dope_key_bg); + c1 = colorMultiply(_cont.item.color_cur, COLORS.panel_animation_dope_key_bg_hover); + } else { + c0 = COLORS.panel_animation_dope_key_bg; + c1 = COLORS.panel_animation_dope_key_bg_hover; + } + + key_y += ui(20) * show_nodes + _expand * ui(10); + _cont.h += ui(20) * show_nodes; + _ks = key_y - ui(10); + + if(_expand) { + for( var j = 0; j < array_length(_cont.props); j++ ) { + var prop = _cont.props[j]; + var _prop = prop.prop; + prop.y = key_y; + + for( var k = 0; k < array_length(prop.animators); k++ ) { + prop.animators[k].y = key_y; + + if(_cont.item.color_cur > -1) { + draw_set_color(c0); + draw_rectangle(0, key_y - ui(10), bar_show_w, key_y + ui(10), false); + + if(_prop == value_focusing) draw_sprite_stretched_ext(THEME.s_box_r2, 0, 0, key_y - ui(8), bar_show_w, ui(16), c1); + else if(_prop == value_hovering) draw_sprite_stretched_ext(THEME.s_box_r2, 0, 0, key_y - ui(8), bar_show_w, ui(16), c1, .9); + } + + if(k) prop.y = key_y; + key_y += ui(18); + _cont.h += ui(18); + } + + var _graph_show = _prop.sep_axis? array_any(_prop.show_graphs, function(v) /*=>*/ {return v == true}) : _prop.show_graph; + + if(_graph_show && _prop.type != VALUE_TYPE.color) { + if(_cont.item.color_cur > -1) { + draw_set_color(c1); + draw_rectangle(0, key_y - ui(10), bar_show_w, key_y + _prop.graph_h - ui(2), false); + } + + var _gr_h = _prop.graph_h; + key_y += _gr_h + ui(8); + _cont.h += _gr_h + ui(8); + } + } + } + + key_y -= _expand * ui(10); + dope_sheet_y_max += _cont.h; + } + + dope_sheet_y_max = max(0, dope_sheet_y_max - dope_sheet_h + ui(48)); + + var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; + + for(var i = timeline_sep_line; i <= _fr; i += timeline_sep_line) { + var bar_line_x = i * timeline_scale + timeline_shift; + + draw_set_color(COLORS.panel_animation_frame_divider); + draw_set_alpha((i % timeline_separate == 0? 1 : 0.1) * ((i <= TOTAL_FRAMES) * 0.5 + 0.5)); + draw_line(bar_line_x, ui(16), bar_line_x, dope_sheet_h - PANEL_PAD); + } + draw_set_alpha(1); + + var bar_line_x = TOTAL_FRAMES * timeline_scale + timeline_shift; + draw_set_color(COLORS.panel_animation_end_line); + draw_set_alpha(0.5); + draw_line_width(bar_line_x, ui(16), bar_line_x, dope_sheet_h, 2); + draw_set_alpha(1); + #endregion + + draw_set_text(f_p2, fa_left, fa_top); + + #region draw graph, easing line + var key_hover = noone; + _graph_key_hover = noone; + _graph_key_hover_index = noone; + _graph_key_hover_x = 0; + _graph_key_hover_y = 0; + + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + + if(!_cont.show) continue; + if(_cont.type != "node") continue; + + if(_cont.item.show) + for( var j = 0, m = array_length(_cont.props); j < m; j++ ) { + var prop = _cont.props[j]; + var _dy = prop.y; + var _prop = prop.prop; + + if(isGraphable(_prop)) { + var _graph_show = _prop.sep_axis? array_any(_prop.show_graphs, function(v) /*=>*/ {return v == true}) : _prop.show_graph; + if(_graph_show) _drawDopesheetGraph(_prop, _dy, msx, msy); + } + + for( var k = 0; k < array_length(prop.animators); k++ ) { + var key = _drawDopesheetAnimatorKeysBG(prop.animators[k], msx, msy); + _dy = prop.animators[k].y; + if(key != noone) key_hover = key; + } + } + } + + graph_key_hover = _graph_key_hover; + graph_key_hover_index = _graph_key_hover_index; + + if(graph_key_drag != noone) { + var bar_x = tool_width + ui(16); + var k = graph_key_drag; + + if(graph_key_drag_index == KEYFRAME_DRAG_TYPE.move) { + var tt = round((mx - bar_x - timeline_shift) / timeline_scale) - 1; + tt = max(tt, 0); + + var sh = tt - k.time; + var kt = k.time + sh; + var edited = k.anim.setKeyTime(k, kt, false, true) + if(edited) UNDO_HOLDING = true; + + if(mouse_release(mb_left)) + k.anim.setKeyTime(k, k.time, true, true); + + } else { + var _dir = point_direction(graph_key_sx, graph_key_sy, msx, msy); + var _dis = point_distance( graph_key_sx, graph_key_sy, msx, msy); + + var _dx = lengthdir_x(_dis, _dir) / timeline_scale / 2; + var _dy = lengthdir_y(_dis, _dir) / 32; + if(_dx < 0) _dy = -_dy; + + _dx = clamp(abs(_dx), 0, 1); + if(_dx > 0.1) keyframe_dragout = true; + else { _dx = 0; _dy = 0; } + + var _in = k.ease_in; + var _ot = k.ease_out; + + switch(graph_key_drag_index) { + case KEYFRAME_DRAG_TYPE.ease_in : + k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + k.ease_in[0] = _dx; + // k.ease_in[1] = _dy + 1; + + break; + case KEYFRAME_DRAG_TYPE.ease_out : + k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + k.ease_out[0] = _dx; + // k.ease_out[1] = -_dy; + + break; + case KEYFRAME_DRAG_TYPE.ease_both : + + k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + + k.ease_in[0] = _dx; + // k.ease_in[1] = _dy + 1; + + k.ease_out[0] = _dx; + // k.ease_out[1] = -_dy; + break; + } + + if(mouse_release(mb_left)) { + recordAction(ACTION_TYPE.var_modify, k, [_in, "ease_in"]); + recordAction(ACTION_TYPE.var_modify, k, [_ot, "ease_out"]); + } + } + + if(mouse_release(mb_left)) { + graph_key_drag = noone; + UNDO_HOLDING = false; + } + + } else if(graph_key_hover != noone) { + + if(DOUBLE_CLICK) { + graph_key_drag = _graph_key_hover; + graph_key_drag_index = KEYFRAME_DRAG_TYPE.ease_both; + graph_key_mx = msx; + graph_key_my = msy; + graph_key_sx = _graph_key_hover_x; + graph_key_sy = _graph_key_hover_y; + keyframe_dragout = false; + + } else if(mouse_press(mb_left)) { + graph_key_drag = _graph_key_hover; + graph_key_drag_index = _graph_key_hover_index; + graph_key_mx = msx; + graph_key_my = msy; + graph_key_sx = _graph_key_hover_x; + graph_key_sy = _graph_key_hover_y; + } + + } + #endregion + + #region drag key + if(keyframe_dragging) { + if(keyframe_drag_type == KEYFRAME_DRAG_TYPE.move) { + var tt = round((mx - bar_x - timeline_shift) / timeline_scale) - 1; + tt = max(tt, 0); + var sh = tt - keyframe_dragging.time; + var edited = false; + + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + var kt = k.time + sh; + + if(k.anim.setKeyTime(k, kt, false, true)) + edited = true; + } + + if(edited) UNDO_HOLDING = true; + timeline_show_time = floor(tt); + + if(mouse_release(mb_left) || mouse_press(mb_left)) { + keyframe_dragging = noone; + UNDO_HOLDING = false; + + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.anim.setKeyTime(k, k.time, true, true); + } + } + } else { + var dx = abs((keyframe_dragging.time + 1) - (mx - bar_x - timeline_shift) / timeline_scale) / 2; + dx = clamp(dx, 0, 1); + if(dx > 0.2) keyframe_dragout = true; + + var dy = -(my - keyframe_drag_my) / 32; + + var _in = keyframe_dragging.ease_in; + var _ot = keyframe_dragging.ease_out; + + switch(keyframe_drag_type) { + case KEYFRAME_DRAG_TYPE.ease_in : + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + + k.ease_in[0] = dx; + if(!k.ease_y_lock) + k.ease_in[1] = dy; + } + + break; + case KEYFRAME_DRAG_TYPE.ease_out : + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + + k.ease_out[0] = dx; + if(!k.ease_y_lock) + k.ease_out[1] = dy; + } + break; + case KEYFRAME_DRAG_TYPE.ease_both : + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var k = keyframe_selecting[i]; + k.ease_in_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + k.ease_out_type = keyframe_dragout? CURVE_TYPE.bezier : CURVE_TYPE.linear; + + k.ease_in[0] = dx; + if(!k.ease_y_lock) + k.ease_in[1] = dy; + + k.ease_out[0] = dx; + if(!k.ease_y_lock) + k.ease_out[1] = dy; + } + break; + } + + if(mouse_release(mb_left)) { + recordAction(ACTION_TYPE.var_modify, keyframe_dragging, [_in, "ease_in"]); + recordAction(ACTION_TYPE.var_modify, keyframe_dragging, [_ot, "ease_out"]); + + keyframe_dragging = noone; + UNDO_HOLDING = false; + } + } + } + #endregion + + #region on end dragging + if(on_end_dragging_anim != noone) { + if(mouse_release(mb_left)) + on_end_dragging_anim = false; + } + #endregion + + if(keyframe_boxing) { #region + draw_sprite_stretched_points_clamp(THEME.ui_selection, 0, keyframe_box_sx, keyframe_box_sy, msx, msy, COLORS._main_accent); + + if(mouse_release(mb_left)) + keyframe_boxing = false; + } #endregion + + #region ======= draw keys ======= + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + if(_cont.type != "node") continue; + + for( var j = 0, m = array_length(_cont.animators); j < m; j++ ) { + var _anim = _cont.animators[j]; + + var key = _drawDopesheetAnimatorKeys(_cont, _anim, msx, msy); + if(key != noone) key_hover = key; + } + } + #endregion + + if(pHOVER && point_in_rectangle(msx, msy, 0, ui(18), dope_sheet_w, dope_sheet_h)) { #region selection & stagger + if(mouse_press(mb_right, pFOCUS) && key_hover == noone) + keyframe_selecting = []; + + if(mouse_press(mb_left, pFOCUS)) { + if(key_hover == noone) { + keyframe_selecting = []; + } else if(key_mod_press(SHIFT)) { + if(array_exists(keyframe_selecting, key_hover)) + array_remove(keyframe_selecting, key_hover); + else + array_push(keyframe_selecting, key_hover) + } else { + if(!array_exists(keyframe_selecting, key_hover)) + keyframe_selecting = [ key_hover ]; + } + + if(stagger_mode == 1) { + if(key_hover == noone || !array_exists(keyframe_selecting, key_hover)) + stagger_mode = 0; + else { + arrangeKeys(); + stagger_index = array_find(keyframe_selecting, key_hover); + stagger_mode = 2; + } + } else if(stagger_mode == 2) { + stagger_mode = 0; + UNDO_HOLDING = false; + } else if(key_hover == noone && keyframe_boxable) { + keyframe_boxing = true; + keyframe_box_sx = msx; + keyframe_box_sy = msy; + } + } + + keyframe_boxable = true; + + if(stagger_mode == 2) { + var ts = keyframe_selecting[stagger_index].time; + var tm = round((mx - bar_x - timeline_shift) / timeline_scale) - 1; + tm = max(tm, 0); + + var stg = tm - ts; + staggerKeys(stagger_index, stg); + } + } #endregion + + #region overlay + var hh = ui(20); + + var bar_line_x = (CURRENT_FRAME + 1) * timeline_scale + timeline_shift; + var cc = PROJECT.animator.is_playing? COLORS._main_value_positive : COLORS._main_accent; + + draw_set_color(cc); + draw_line(bar_line_x, PANEL_PAD, bar_line_x, dope_sheet_h); + + var _phover = pHOVER && msy > hh; + for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) { + var _cont = timeline_contents[i]; + if(!_cont.show) continue; + + 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; + } + + draw_set_color(COLORS.panel_animation_timeline_top); + draw_rectangle(0, 0, bar_w, hh, false); + + var _fr = ceil((bar_w / timeline_scale - timeline_shift) / timeline_separate) * timeline_separate; + + for(var i = timeline_separate; i <= _fr; i += timeline_separate) { + var ln_x = i * timeline_scale + timeline_shift; + + if(i > TOTAL_FRAMES) draw_set_alpha(0.5); + + draw_set_color(COLORS.panel_animation_frame_divider); + draw_line(ln_x, 0, ln_x, hh); + + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_text_sub); + draw_text_add(ln_x, PANEL_PAD, i); + } + + draw_set_alpha(1); + + var end_x = TOTAL_FRAMES * timeline_scale + timeline_shift; + draw_set_color(COLORS.panel_animation_end_line); + draw_line_width(end_x, 0, end_x, ui(20), 2); + + if(PROJECT.onion_skin.enabled) { //ONION SKIN + var rang = PROJECT.onion_skin.range; + var colr = PROJECT.onion_skin.color; + + var fr = CURRENT_FRAME + 1; + var tx = fr * timeline_scale + timeline_shift; + var sx = (fr + rang[0]) * timeline_scale + timeline_shift; + var ex = (fr + rang[1]) * timeline_scale + timeline_shift; + var y0 = PANEL_PAD; + var y1 = hh; + var yc = (y0 + y1) / 2; + + draw_sprite_stretched_ext(THEME.timeline_onion_skin, 0, sx, y0, tx - sx, y1 - y0, colr[0], 1); + draw_sprite_stretched_ext(THEME.timeline_onion_skin, 1, tx, y0, ex - tx, y1 - y0, colr[1], 1); + + var _sx = (fr + rang[0]) * timeline_scale + timeline_shift - ui(8); + var _ex = (fr + rang[1]) * timeline_scale + timeline_shift + ui(8); + + if(point_in_circle(msx, msy, _sx, yc, ui(8))) { + draw_sprite_ext(THEME.arrow, 2, _sx, yc, 1, 1, 0, colr[0], 1); + + if(mouse_press(mb_left, pFOCUS)) + onion_dragging = 0; + timeline_draggable = false; + } else + draw_sprite_ext(THEME.arrow, 2, _sx, yc, 1, 1, 0, colr[0], 0.5); + + if(point_in_circle(msx, msy, _ex, yc, ui(8))) { + draw_sprite_ext(THEME.arrow, 0, _ex, yc, 1, 1, 0, colr[1], 1); + + if(mouse_press(mb_left, pFOCUS)) + onion_dragging = 1; + timeline_draggable = false; + } else + draw_sprite_ext(THEME.arrow, 0, _ex, yc, 1, 1, 0, colr[1], 0.5); + + if(onion_dragging != noone) { + if(onion_dragging == 0) { + var mf = round((msx - timeline_shift + ui(8)) / timeline_scale) - fr; + mf = min(mf, 0); + + if(PROJECT.onion_skin.range[0] != mf) { + PROJECT.onion_skin.range[0] = mf; + } + } else if(onion_dragging == 1) { + var mf = round((msx - timeline_shift - ui(8)) / timeline_scale) - fr; + mf = max(mf, 0); + + if(PROJECT.onion_skin.range[1] != mf) { + PROJECT.onion_skin.range[1] = mf; + } + } + + if(mouse_release(mb_left)) + onion_dragging = noone; + } + } + + draw_set_font(f_p2); + var cf = string(CURRENT_FRAME + 1); + var tx = string_width(cf) + ui(4); + draw_sprite_stretched_ext(THEME.s_box_r2, 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); + + #endregion + + #region stretch + var stx = timeline_shift + bar_total_w + ui(24); + var sty = ui(10); + + if(timeline_stretch == 1) { + var len = round((mx - bar_x - timeline_shift) / timeline_scale) - 2; + len = max(1, len); + TOOLTIP = __txtx("panel_animation_length", "Animation length") + " " + string(len); + TOTAL_FRAMES = len; + + if(mouse_release(mb_left)) + timeline_stretch = 0; + + draw_sprite_ui(THEME.animation_stretch, 0, stx, sty, 1, 1, 0, COLORS.panel_animation_end_line, 1); + + } else if(timeline_stretch == 2) { + var len = round((mx - bar_x - timeline_shift) / timeline_scale) - 2; + len = max(1, len); + TOOLTIP = __txtx("panel_animation_length", "Animation length") + " " + string(len); + var _len = TOTAL_FRAMES; + TOTAL_FRAMES = len; + + if(_len != len) { + for (var m = 0, n = array_length(PROJECT.allNodes); m < n; m++) { + var _node = PROJECT.allNodes[m]; + if(!_node || !_node.active) continue; + + for(var i = 0; i < array_length(_node.inputs); i++) { + var in = _node.inputs[i]; + if(!in.is_anim) continue; + + for(var j = 0; j < array_length(in.animator.values); j++) { + var t = in.animator.values[j]; + t.time = t.ratio * (len - 1); + } + + for( var k = 0; k < array_length(in.animators); k++ ) + for(var j = 0; j < array_length(in.animators[k].values); j++) { + var t = in.animators[k].values[j]; + t.time = t.ratio * (len - 1); + } + } + } + } + + if(mouse_release(mb_left)) + timeline_stretch = 0; + + draw_sprite_ui(THEME.animation_stretch, 1, stx, sty, 1, 1, 0, COLORS.panel_animation_end_line, 1); + + } else { + if(!IS_PLAYING && pHOVER && point_in_circle(msx, msy, stx, sty, sty)) { + if(key_mod_press(CTRL)) { + draw_sprite_ui(THEME.animation_stretch, 1, stx, sty, 1, 1, 0, COLORS._main_icon, 1); + TOOLTIP = __txtx("panel_animation_stretch", "Stretch animation"); + if(mouse_press(mb_left, pFOCUS)) { + timeline_stretch = 2; + timeline_stretch_mx = msx; + timeline_stretch_sx = TOTAL_FRAMES; + } + } else { + draw_sprite_ui(THEME.animation_stretch, 0, stx, sty, 1, 1, 0, COLORS._main_icon, 1); + TOOLTIP = __txtx("panel_animation_adjust_length", "Adjust animation length"); + if(mouse_press(mb_left, pFOCUS)) { + timeline_stretch = 1; + timeline_stretch_mx = msx; + timeline_stretch_sx = TOTAL_FRAMES; + } + } + } else + draw_sprite_ui(THEME.animation_stretch, 0, stx, sty, 1, 1, 0, COLORS._main_icon, 0.5); + } + #endregion + + gpu_set_blendmode(bm_subtract); + draw_surface_safe(dope_sheet_mask); + gpu_set_blendmode(bm_normal); + surface_reset_target(); + + _drawDopesheetLabel(); + + 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); + else menuCall("animation_keyframe_menu",,, keyframe_menu,, keyframe_selecting); + + } else if(point_in_rectangle(mx, my, ui(8), ui(8), ui(8) + tool_width, ui(8) + dope_sheet_h)) { + + if(context_selecting_prop != noone) { + if(context_selecting_prop.sepable) + menuCall("animation_name_empty_menu",,, context_selecting_prop.sep_axis? name_menu_prop_join : name_menu_prop_sep); + else + menuCall("animation_name_empty_menu",,, name_menu_empty); + } + + else if(context_selecting_item == noone) + menuCall("animation_name_empty_menu",,, name_menu_empty); + + else if(is_instanceof(context_selecting_item.item, timelineItemNode)) + menuCall("animation_name_empty_menu",,, name_menu_item); + + else if(is_instanceof(context_selecting_item.item, timelineItemGroup)) + menuCall("animation_name_empty_menu",,, name_menu_group); + } + } #endregion + + draw_sprite_stretched(THEME.ui_panel_bg, 1, ui(8), ui(8), tool_width, dope_sheet_h); + draw_surface_safe(dope_sheet_name_surface, ui(8), ui(8)); + + draw_sprite_stretched(THEME.ui_panel_bg, 1, bar_x, ui(8), bar_w, dope_sheet_h); //base BG + 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(item_dragging != noone) __drawDopesheetLabelItem(item_dragging, mx - item_dragging_dx, my - item_dragging_dy,,, 0.5); + } #endregion + + function drawAnimationControl() { #region + var mini = w < ui(348); + + var amo = array_length(control_buttons); + var col = floor((w - ui(8)) / ui(36)); + var row = ceil(amo / col); + if(col < 1) return; + + var bx = tool_width / 2 - ui(36) * amo / 2 + ui(8); + var by = h - ui(40); + + for( var i = 0; i < row; i++ ) { + var colAmo = min(amo - i * col, col); + if(mini) bx = w / 2 - ui(36) * colAmo / 2; + + for( var j = 0; j < colAmo; j++ ) { + var ind = i * col + j; + if(ind >= amo) return; + var but = control_buttons[ind]; + var txt = but[0](); + var ind = but[1](); + var cc = IS_RENDERING? COLORS._main_icon_dark : but[2](); + var fnc = but[3]; + + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS && !IS_RENDERING, pHOVER && !IS_RENDERING, txt, THEME.sequence_control, ind, cc) == 2) + fnc(); + + bx += ui(36); + } + + by -= ui(36); + } + + if(mini) { + var y0 = ui(8); + var y1 = by + ui(36) - ui(8); + var cy = (y0 + y1) / 2; + + if(y1 - y0 < 12) return; + + draw_sprite_stretched(THEME.ui_panel_bg, 1, ui(8), y0, w - ui(16), y1 - y0); + + var pw = w - ui(16); + var px = ui(8) + pw * (CURRENT_FRAME / TOTAL_FRAMES); + draw_set_color(COLORS._main_accent); + draw_line(px, y0, px, y1); + + if(point_in_rectangle(mx, my, ui(8), y0, w - ui(16), y1)) { + if(mouse_click(mb_left, pFOCUS)) { + var rfrm = (mx - ui(8)) / (w - ui(16)) * TOTAL_FRAMES; + PROJECT.animator.setFrame(clamp(rfrm, 0, TOTAL_FRAMES - 1)); + } + } + + var txt = string(CURRENT_FRAME + 1) + "/" + string(TOTAL_FRAMES); + + if(y1 - y0 < ui(40)) { + draw_set_text(f_p1, fa_left, fa_center, COLORS._main_text_sub); + draw_text_add(ui(16), cy, __txt("Frame")); + draw_set_text(f_p1, fa_right, fa_center, PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_text_sub); + draw_text_add(w - ui(16), cy, txt); + } else { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text_add(w / 2, cy - ui(12), __txt("Frame")); + + draw_set_text(f_h5, fa_center, fa_center, PROJECT.animator.is_playing? COLORS._main_accent : COLORS._main_text_sub); + draw_text_add(w / 2, cy + ui(6), txt); + } + return; + } + + by += ui(36); + bx = w - ui(44); + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_animation_animation_settings", "Animation settings"), THEME.animation_setting, 2) == 2) + dialogPanelCall(new Panel_Animation_Setting(), x + bx + ui(32), y + by - ui(8), { anchor: ANCHOR.right | ANCHOR.bottom }); + + by -= ui(40); if(by < 8) return; + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_animation_scale_animation", "Scale animation"), THEME.animation_timing, 2) == 2) + dialogPanelCall(new Panel_Animation_Scaler(), x + bx + ui(32), y + by - ui(8), { anchor: ANCHOR.right | ANCHOR.bottom }); + + var max_y = by - ui(28); + if(by < ui(28)) return; + by = ui(8); + + var txt = __txt("New folder"); + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.folder_content) == 2) { + var _dir = new timelineItemGroup(); + PROJECT.timelines.addItem(_dir); + } + + by += ui(32); if(by > max_y) return; + node_name_tooltip.index = node_name_type; + + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, node_name_tooltip, THEME.node_name_type, node_name_type) == 2) + node_name_type = (node_name_type + 1) % 3; + + by += ui(32); if(by > max_y) return; + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, tooltip_toggle_nodes, THEME.junc_visible, show_nodes) == 2) + show_nodes = !show_nodes; + + by += ui(32); if(by > max_y) return; + txt = __txtx("panel_animation_keyframe_override", "Override Keyframe"); + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.keyframe_override, global.FLAG.keyframe_override) == 2) + global.FLAG.keyframe_override = !global.FLAG.keyframe_override; + + by += ui(32); if(by > max_y) return; + txt = __txt("Onion skin"); + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(28), [mx, my], pFOCUS, pHOVER, txt, THEME.onion_skin,, PROJECT.onion_skin.enabled? c_white : COLORS._main_icon) == 2) + PROJECT.onion_skin.enabled = !PROJECT.onion_skin.enabled; + } #endregion + + function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<< + draw_clear_alpha(COLORS.panel_bg_clear, 0); + if(!PROJECT.active) return; + + if(tool_width_drag) { + CURSOR = cr_size_we; + + tool_width = tool_width_start + (mx - tool_width_mx); + tool_width = clamp(tool_width, ui(224), w - ui(128)); + onResize(); + + if(mouse_release(mb_left)) + tool_width_drag = false; + } + + getTimelineContent(); + if(w >= ui(348)) { + drawTimeline(); + + if(dope_sheet_h > 8) { + drawDopesheet(); + + if(pHOVER && point_in_rectangle(mx, my, tool_width + ui(8), ui(8), tool_width + ui(12), ui(8) + dope_sheet_h)) { + CURSOR = cr_size_we; + if(mouse_press(mb_left, pFOCUS)) { + tool_width_drag = true; + tool_width_start = tool_width; + tool_width_mx = mx; + } + } + } + } + drawAnimationControl(); + + if(timeline_show_time > -1) { + TOOLTIP = $"{__txt("Frame")} {timeline_show_time + 1}/{TOTAL_FRAMES}"; + timeline_show_time = -1; + } + } #endregion + + function doDuplicate() { #region + if(array_empty(keyframe_selecting)) return; + + var clones = []; + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) { + var cl = keyframe_selecting[i].cloneAnimator(,, false); + if(cl == noone) continue; + array_push(clones, cl); + } + + if(array_empty(clones)) return; + + keyframe_selecting = clones; + keyframe_dragging = keyframe_selecting[0]; + keyframe_drag_type = KEYFRAME_DRAG_TYPE.move; + keyframe_drag_mx = mx; + keyframe_drag_my = my; + } #endregion + + function doCopy() { #region + ds_list_clear(copy_clipboard); + for( var i = 0, n = array_length(keyframe_selecting); i < n; i++ ) + ds_list_add(copy_clipboard, keyframe_selecting[i]); + } #endregion + + function doPaste(val = noone) { #region + if(ds_list_empty(copy_clipboard)) return; + + var shf = 0; + var minx = TOTAL_FRAMES + 2; + for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) + minx = min(minx, copy_clipboard[| i].time); + shf = CURRENT_FRAME - minx; + + var multiVal = false; + var _val = noone; + + for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) { + if(_val != noone && _val != copy_clipboard[| i].anim) { + multiVal = true; + break; + } + _val = copy_clipboard[| i].anim; + } + + if(multiVal && val != noone) { + var nodeTo = val.node; + for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) { + var propFrom = copy_clipboard[| i].anim.prop; + var propTo = noone; + + for( var j = 0; j < array_length(nodeTo.inputs); j++ ) { + if(nodeTo.inputs[j].name == propFrom.name) { + propTo = nodeTo.inputs[j].animator; + copy_clipboard[| i].cloneAnimator(shf, propTo); + break; + } + } + } + } else { + for( var i = 0; i < ds_list_size(copy_clipboard); i++ ) + copy_clipboard[| i].cloneAnimator(shf, (multiVal || val == noone)? noone : val.animator); + } + } #endregion } diff --git a/scripts/panel_collection/panel_collection.gml b/scripts/panel_collection/panel_collection.gml index 9641a8ff3..046d43b51 100644 --- a/scripts/panel_collection/panel_collection.gml +++ b/scripts/panel_collection/panel_collection.gml @@ -1,13 +1,13 @@ #region funtion calls function __fnInit_Collection() { - registerFunction("Collection", "Replace", "", MOD_KEY.none, panel_collection_replace); - registerFunction("Collection", "Edit Meta", "", MOD_KEY.none, panel_collection_edit_meta); - registerFunction("Collection", "Update Thumbnail", "", MOD_KEY.none, panel_collection_update_thumbnail); - registerFunction("Collection", "Delete Collection", "", MOD_KEY.none, panel_collection_delete_collection); + registerFunction("Collection", "Replace", "", MOD_KEY.none, panel_collection_replace ).setMenu("collection_replace") + registerFunction("Collection", "Edit Meta", "", MOD_KEY.none, panel_collection_edit_meta ).setMenu("collection_edit_meta") + registerFunction("Collection", "Update Thumbnail", "", MOD_KEY.none, panel_collection_update_thumbnail ).setMenu("collection_update_thumbnail") + registerFunction("Collection", "Delete Collection", "", MOD_KEY.none, panel_collection_delete_collection ).setMenu("collection_delete_collection") - registerFunction("Collection", "Upload To Steam", "", MOD_KEY.none, panel_collection_steam_file_upload); - registerFunction("Collection", "Update Steam", "", MOD_KEY.none, panel_collection_steam_file_update); - registerFunction("Collection", "Unsubscribe", "", MOD_KEY.none, panel_collection_steam_unsubscribe); + registerFunction("Collection", "Upload To Steam", "", MOD_KEY.none, panel_collection_steam_file_upload ).setMenu("collection_upload_to_steam") + registerFunction("Collection", "Update Steam", "", MOD_KEY.none, panel_collection_steam_file_update ).setMenu("collection_update_steam") + registerFunction("Collection", "Unsubscribe", "", MOD_KEY.none, panel_collection_steam_unsubscribe ).setMenu("collection_unsubscribe") } function panel_collection_replace() { CALL("collection_replace"); PANEL_COLLECTION.replace(); } @@ -163,11 +163,11 @@ function Panel_Collection() : PanelContent() constructor { if(meta == noone || !meta.steam) { contentMenu = [ - menuItemAction(__txtx("panel_collection_replace", "Replace with selected"), panel_collection_replace), - menuItemAction(__txtx("panel_collection_edit_meta", "Edit metadata") + "...", panel_collection_edit_meta), - menuItemAction(__txtx("panel_collection_update_thumbnail", "Update thumbnail"), panel_collection_update_thumbnail), + MENU_ITEMS.collection_replace, + MENU_ITEMS.collection_edit_meta, + MENU_ITEMS.collection_update_thumbnail, -1, - menuItemAction(__txt("Delete"), panel_collection_delete_collection) + MENU_ITEMS.collection_delete_collection, ]; if(STEAM_ENABLED) @@ -176,11 +176,11 @@ function Panel_Collection() : PanelContent() constructor { if(STEAM_ENABLED) { if(meta.steam == FILE_STEAM_TYPE.local) { - array_push(contentMenu, menuItemAction(__txtx("panel_collection_workshop_upload", "Upload to Steam Workshop") + "...", panel_collection_steam_file_upload)); + array_push(contentMenu, MENU_ITEMS.collection_upload_to_steam); } else { if(meta.author_steam_id == STEAM_USER_ID && meta.file_id != 0) - array_push(contentMenu, menuItemAction(__txtx("panel_collection_workshop_update", "Update Steam Workshop content") + "...", panel_collection_steam_file_update)); - array_push(contentMenu, menuItemAction(__txt("Unsubscribe"), panel_collection_steam_unsubscribe)); + array_push(contentMenu, MENU_ITEMS.collection_update_steam); + array_push(contentMenu, MENU_ITEMS.collection_unsubscribe); } } } diff --git a/scripts/panel_color/panel_color.gml b/scripts/panel_color/panel_color.gml index 972a38d64..5324a4850 100644 --- a/scripts/panel_color/panel_color.gml +++ b/scripts/panel_color/panel_color.gml @@ -327,15 +327,15 @@ function Panel_Color() : PanelContent() constructor { if(mouse_press(mb_right, pFOCUS)) { menuCall("color_window_menu",,, [ - menuItemAction(__txt("Hue"), function() { mode = 0; } ), - menuItemAction(__txt("Value"), function() { mode = 1; } ), - menuItemAction(__txt("Saturation"), function() { mode = 2; } ), + menuItem(__txt("Hue"), function() { mode = 0; } ), + menuItem(__txt("Value"), function() { mode = 1; } ), + menuItem(__txt("Saturation"), function() { mode = 2; } ), -1, - menuItemAction(__txt("Toggle Alpha"), function() { show_alpha = !show_alpha; }, noone, noone, function() /*=>*/ {return show_alpha} ), - menuItemAction(__txt("Toggle Palette"), function() { show_palette = !show_palette; }, noone, noone, function() /*=>*/ {return show_palette} ), - menuItemAction(__txt("Toggle Hex"), function() { show_hex = !show_hex; }, noone, noone, function() /*=>*/ {return show_hex} ), + menuItem(__txt("Toggle Alpha"), function() { show_alpha = !show_alpha; }, noone, noone, function() /*=>*/ {return show_alpha} ), + menuItem(__txt("Toggle Palette"), function() { show_palette = !show_palette; }, noone, noone, function() /*=>*/ {return show_palette} ), + menuItem(__txt("Toggle Hex"), function() { show_hex = !show_hex; }, noone, noone, function() /*=>*/ {return show_hex} ), -1, - menuItemAction(__txt("Discretize"), function() { discretize_pal = !discretize_pal; }, noone, noone, function() /*=>*/ {return discretize_pal} ), + menuItem(__txt("Discretize"), function() { discretize_pal = !discretize_pal; }, noone, noone, function() /*=>*/ {return discretize_pal} ), ]); } diff --git a/scripts/panel_file_explorer/panel_file_explorer.gml b/scripts/panel_file_explorer/panel_file_explorer.gml index 28fb70a12..0ca122943 100644 --- a/scripts/panel_file_explorer/panel_file_explorer.gml +++ b/scripts/panel_file_explorer/panel_file_explorer.gml @@ -207,29 +207,29 @@ function Panel_File_Explorer() : PanelContent() constructor { __menu_cnxt_selecting = noone; menu_file_image = [ - menuItemAction("Add as node", function() { + menuItem("Add as node", function() { var node = Node_create_Image_path(PANEL_GRAPH.graph_cx, PANEL_GRAPH.graph_cy, __menu_file_selecting.path); PANEL_PREVIEW.setNodePreview(node); PANEL_INSPECTOR.inspecting = node; }), - menuItemAction("Add as canvas", function() { + menuItem("Add as canvas", function() { var node = nodeBuild("Node_Canvas", PANEL_GRAPH.graph_cx, PANEL_GRAPH.graph_cy).loadImagePath(__menu_file_selecting.path); PANEL_PREVIEW.setNodePreview(node); PANEL_INSPECTOR.inspecting = node; }), - menuItemAction("Copy path", function() { clipboard_set_text(__menu_file_selecting.path); }, THEME.copy), + menuItem("Copy path", function() { clipboard_set_text(__menu_file_selecting.path); }, THEME.copy), ]; menu_file_project = [ - menuItemAction("Open", function() { LOAD_AT(__menu_file_selecting.path); }), + menuItem("Open", function() { LOAD_AT(__menu_file_selecting.path); }), - menuItemAction("Copy path", function() { clipboard_set_text(__menu_file_selecting.path); }, THEME.copy), + menuItem("Copy path", function() { clipboard_set_text(__menu_file_selecting.path); }, THEME.copy), ]; menu_general = [ - menuItemAction("New Canvas", function() { + menuItem("New Canvas", function() { var dia = dialogCall(o_dialog_file_name, mouse_mx + 8, mouse_my + 8); dia.onModify = function (txt) { var _s = surface_create(DEF_SURF_W, DEF_SURF_H); @@ -246,7 +246,7 @@ function Panel_File_Explorer() : PanelContent() constructor { dia.path = __menu_cnxt_selecting.path + "/"; }, THEME.new_file), - menuItemAction("New Folder", function() { + menuItem("New Folder", function() { var dia = dialogCall(o_dialog_file_name, mouse_mx + 8, mouse_my + 8); dia.name = "New Folder"; dia.onModify = function (txt) { @@ -257,7 +257,7 @@ function Panel_File_Explorer() : PanelContent() constructor { }, THEME.folder), -1, - menuItemAction("Refresh", function() { if(rootFile) rootFile.getContent() }), + menuItem("Refresh", function() { if(rootFile) rootFile.getContent() }), ]; #endregion diff --git a/scripts/panel_function/panel_function.gml b/scripts/panel_function/panel_function.gml index 5eb664a52..66acb9541 100644 --- a/scripts/panel_function/panel_function.gml +++ b/scripts/panel_function/panel_function.gml @@ -174,7 +174,6 @@ panelDisplayInit(); checkPanelValid(); - __initPanelHotkeys(); } #endregion function setPanel() { #region @@ -446,73 +445,75 @@ #region hotkey - function call_dialog_preference() { dialogCall(o_dialog_preference); } - function call_dialog_splash() { dialogCall(o_dialog_splash); } - function call_dialog_release_note() { dialogCall(o_dialog_release_note); } - function open_autosave_folder() { shellOpenExplorer(DIRECTORY + "autosave"); } + function call_dialog_preference() { dialogCall(o_dialog_preference); } + function call_dialog_splash() { dialogCall(o_dialog_splash); } + function call_dialog_release_note() { dialogCall(o_dialog_release_note); } + function open_autosave_folder() { shellOpenExplorer(DIRECTORY + "autosave"); } - function call_panel_addon() { dialogPanelCall(new Panel_Addon()); } - function call_panel_history() { dialogPanelCall(new Panel_History()); } + function call_panel_addon() { dialogPanelCall(new Panel_Addon()); } + function call_panel_history() { dialogPanelCall(new Panel_History()); } - function call_panel_Notification() { panelAdd("Panel_Notification", true); } - function call_panel_Collection() { panelAdd("Panel_Collection", true); } - function call_panel_Graph() { panelAdd("Panel_Graph", true); } + function call_panel_Notification() { panelAdd("Panel_Notification", true); } + function call_panel_Collection() { panelAdd("Panel_Collection", true); } + function call_panel_Graph() { panelAdd("Panel_Graph", true); } - function call_panel_Preview() { panelAdd("Panel_Preview", true); } - function call_panel_Preview_Histogram() { panelAdd("Panel_Preview_Histogram", true); } + function call_panel_Preview() { panelAdd("Panel_Preview", true); } + function call_panel_Preview_Histogram() { panelAdd("Panel_Preview_Histogram", true); } - function call_panel_Inspector() { panelAdd("Panel_Inspector", true); } - function call_panel_Workspace() { panelAdd("Panel_Workspace", true); } - function call_panel_Animation() { panelAdd("Panel_Animation", true); } - function call_panel_Node_Align() { panelAdd("Panel_Node_Align", true); } - function call_panel_Nodes() { panelAdd("Panel_Nodes", true); } - function call_panel_Tunnels() { panelAdd("Panel_Tunnels", true); } + function call_panel_Inspector() { panelAdd("Panel_Inspector", true); } + function call_panel_Workspace() { panelAdd("Panel_Workspace", true); } + function call_panel_Animation() { panelAdd("Panel_Animation", true); } + function call_panel_Node_Align() { panelAdd("Panel_Node_Align", true); } + function call_panel_Nodes() { panelAdd("Panel_Nodes", true); } + function call_panel_Tunnels() { panelAdd("Panel_Tunnels", true); } - function call_panel_Color() { panelAdd("Panel_Color", true); } - function call_panel_Palette() { panelAdd("Panel_Palette", true); } - function call_panel_Palette_Mixer() { panelAdd("Panel_Palette_Mixer", true); } - function call_panel_Gradient() { panelAdd("Panel_Gradient", true); } + function call_panel_Color() { panelAdd("Panel_Color", true); } + function call_panel_Palette() { panelAdd("Panel_Palette", true); } + function call_panel_Palette_Mixer() { panelAdd("Panel_Palette_Mixer", true); } + function call_panel_Gradient() { panelAdd("Panel_Gradient", true); } - function call_panel_Console() { panelAdd("Panel_Console", true); } - function call_panel_Globalvar() { panelAdd("Panel_Globalvar", true); } - function call_panel_File_Explorer() { panelAdd("Panel_File_Explorer", true); } + function call_panel_Console() { panelAdd("Panel_Console", true); } + function call_panel_Globalvar() { panelAdd("Panel_Globalvar", true); } + function call_panel_File_Explorer() { panelAdd("Panel_File_Explorer", true); } - function __initPanelHotkeys() { - registerFunction("", "Preference", "", MOD_KEY.none, call_dialog_preference); - registerFunction("", "Splash screen", "", MOD_KEY.none, call_dialog_splash); - registerFunction("", "Release note", "", MOD_KEY.none, call_dialog_release_note); - registerFunction("", "Autosave folder", "", MOD_KEY.none, open_autosave_folder); + function __fnInit_Panels() { + registerFunction("", "Preference", "", MOD_KEY.none, call_dialog_preference ).setMenu("preference", THEME.gear) + registerFunction("", "Splash screen", "", MOD_KEY.none, call_dialog_splash ).setMenu("splash_screen") + registerFunction("", "Release note", "", MOD_KEY.none, call_dialog_release_note ).setMenu("release_note") + registerFunction("", "Autosave folder", "", MOD_KEY.none, open_autosave_folder ).setMenu("autosave_folder", THEME.save_auto) + + registerFunction("", "Addons", "", MOD_KEY.none, call_panel_addon ).setMenu("addons") + registerFunction("", "History", "", MOD_KEY.none, call_panel_history ).setMenu("history") + + registerFunction("", "Notification Panel", vk_f12, MOD_KEY.none, call_panel_Notification ).setMenu("notification_panel") + registerFunction("", "Collections Panel", "", MOD_KEY.none, call_panel_Collection ).setMenu("collections_panel") + registerFunction("", "Graph Panel", "", MOD_KEY.none, call_panel_Graph ).setMenu("graph_panel") + registerFunction("", "Preview Panel", "", MOD_KEY.none, call_panel_Preview ).setMenu("preview_panel") + registerFunction("", "Preview Histogram", "", MOD_KEY.none, call_panel_Preview_Histogram ).setMenu("preview_histogram") + registerFunction("", "Inspector Panel", "", MOD_KEY.none, call_panel_Inspector ).setMenu("inspector_panel") + registerFunction("", "Workspace Panel", "", MOD_KEY.none, call_panel_Workspace ).setMenu("workspace_panel") + registerFunction("", "Animation Panel", "", MOD_KEY.none, call_panel_Animation ).setMenu("animation_panel") + + registerFunction("", "Align Panel", "", MOD_KEY.none, call_panel_Node_Align ).setMenu("align_panel") + registerFunction("", "Nodes Panel", "", MOD_KEY.none, call_panel_Nodes ).setMenu("nodes_panel") + registerFunction("", "Tunnels Panel", "", MOD_KEY.none, call_panel_Tunnels ).setMenu("tunnels_panel") + + registerFunction("", "Color Panel", "", MOD_KEY.none, call_panel_Color ).setMenu("color_panel") + registerFunction("", "Palettes Panel", "", MOD_KEY.none, call_panel_Palette ).setMenu("palettes_panel") + registerFunction("", "Palettes Mixer Panel", "", MOD_KEY.none, call_panel_Palette_Mixer ).setMenu("palettes_mixer_panel") + registerFunction("", "Gradients Panel", "", MOD_KEY.none, call_panel_Gradient ).setMenu("gradients_panel") + + registerFunction("", "Console Panel", "", MOD_KEY.none, call_panel_Console ).setMenu("console_panel") + registerFunction("", "Globalvar Panel", "", MOD_KEY.none, call_panel_Globalvar ).setMenu("globalvar_panel") + registerFunction("", "File Explorer Panel", "", MOD_KEY.none, call_panel_File_Explorer ).setMenu("file_explorer_panel") + - registerFunction("", "Recent files", "R", MOD_KEY.ctrl | MOD_KEY.shift, function() /*=>*/ { + registerFunction("", "Recent files", "R", MOD_KEY.ctrl | MOD_KEY.shift, function() /*=>*/ { var arr = []; for(var i = 0; i < min(10, ds_list_size(RECENT_FILES)); i++) array_push(arr, menuItemAction(RECENT_FILES[| i], function(_dat) { LOAD_PATH(_dat.name); })); return menuCall("Recent files",,, arr); - }); + }).setMenu("recent_files"); - registerFunction("", "Addons", "", MOD_KEY.none, call_panel_addon); - registerFunction("", "History", "", MOD_KEY.none, call_panel_history); - - registerFunction("", "Notification Panel", "", MOD_KEY.none, call_panel_Notification ); - registerFunction("", "Collections Panel", "", MOD_KEY.none, call_panel_Collection ); - registerFunction("", "Graph Panel", "", MOD_KEY.none, call_panel_Graph ); - registerFunction("", "Preview Panel", "", MOD_KEY.none, call_panel_Preview ); - registerFunction("", "Preview Histogram", "", MOD_KEY.none, call_panel_Preview_Histogram ); - registerFunction("", "Inspector Panel", "", MOD_KEY.none, call_panel_Inspector ); - registerFunction("", "Workspace Panel", "", MOD_KEY.none, call_panel_Workspace ); - registerFunction("", "Animation Panel", "", MOD_KEY.none, call_panel_Animation ); - - registerFunction("", "Align Panel", "", MOD_KEY.none, call_panel_Node_Align ); - registerFunction("", "Nodes Panel", "", MOD_KEY.none, call_panel_Nodes ); - registerFunction("", "Tunnels Panel", "", MOD_KEY.none, call_panel_Tunnels ); - - registerFunction("", "Color Panel", "", MOD_KEY.none, call_panel_Color ); - registerFunction("", "Palettes Panel", "", MOD_KEY.none, call_panel_Palette ); - registerFunction("", "Palettes Mixer Panel","", MOD_KEY.none, call_panel_Palette_Mixer ); - registerFunction("", "Gradients Panel", "", MOD_KEY.none, call_panel_Gradient ); - - registerFunction("", "Console Panel", "", MOD_KEY.none, call_panel_Console ); - registerFunction("", "Globalvar Panel", "", MOD_KEY.none, call_panel_Globalvar ); - registerFunction("", "File Explorer Panel", "", MOD_KEY.none, call_panel_File_Explorer ); } #endregion \ No newline at end of file diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index 9d83d0fb3..153a31ed6 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -1,3240 +1,3238 @@ #region // function calls - function panel_graph_add_node() { CALL("graph_add_node"); PANEL_GRAPH.callAddDialog(); } - function panel_graph_focus_content() { CALL("graph_focus_content"); PANEL_GRAPH.fullView(); } - function panel_graph_preview_focus() { CALL("graph_preview_focus"); PANEL_GRAPH.setCurrentPreview(); } - - function panel_graph_import_image() { CALL("graph_import_image"); PANEL_GRAPH.createNodeHotkey("Node_Image"); } - function panel_graph_import_image_array() { CALL("graph_import_image_array"); PANEL_GRAPH.createNodeHotkey("Node_Image_Sequence"); } - function panel_graph_add_number() { CALL("graph_add_number"); PANEL_GRAPH.createNodeHotkey("Node_Number"); } - function panel_graph_add_vec2() { CALL("graph_add_vec2"); PANEL_GRAPH.createNodeHotkey("Node_Vector2"); } - function panel_graph_add_vec3() { CALL("graph_add_vec3"); PANEL_GRAPH.createNodeHotkey("Node_Vector3"); } - function panel_graph_add_vec4() { CALL("graph_add_vec4"); PANEL_GRAPH.createNodeHotkey("Node_Vector4"); } - function panel_graph_add_display() { CALL("graph_add_disp"); PANEL_GRAPH.createNodeHotkey("Node_Display_Text"); } - - function panel_graph_add_math_add() { CALL("graph_add_math_add"); PANEL_GRAPH.createNodeHotkey(Node_create_Math, { query: "add" }); } - - function panel_graph_select_all() { CALL("graph_select_all"); PANEL_GRAPH.nodes_selecting = PANEL_GRAPH.nodes_list; } - function panel_graph_toggle_grid() { CALL("graph_toggle_grid"); PANEL_GRAPH.display_parameter.show_grid = !PANEL_GRAPH.display_parameter.show_grid; } - - function panel_graph_export() { CALL("graph_export"); PANEL_GRAPH.setCurrentExport(); } - - function panel_graph_add_transform() { CALL("graph_add_transform"); PANEL_GRAPH.doTransform(); } - function panel_graph_blend() { CALL("graph_blend"); PANEL_GRAPH.doBlend(); } - function panel_graph_compose() { CALL("graph_compose"); PANEL_GRAPH.doCompose(); } - function panel_graph_array() { CALL("graph_array"); PANEL_GRAPH.doArray(); } - function panel_graph_group() { CALL("graph_group"); PANEL_GRAPH.doGroup(); } - function panel_graph_ungroup() { CALL("graph_ungroup"); PANEL_GRAPH.doUngroup(); } - - function panel_graph_canvas() { CALL("graph_canvas"); PANEL_GRAPH.setCurrentCanvas(); } - function panel_graph_canvas_blend() { CALL("graph_canvas_blend"); PANEL_GRAPH.setCurrentCanvasBlend(); } - - function panel_graph_frame() { CALL("graph_frame"); PANEL_GRAPH.doFrame(); } - function panel_graph_delete_break() { CALL("graph_delete_break"); PANEL_GRAPH.doDelete(false); } - function panel_graph_delete_merge() { CALL("graph_delete_merge"); PANEL_GRAPH.doDelete(true); } - function panel_graph_duplicate() { CALL("graph_duplicate"); PANEL_GRAPH.doDuplicate(); } - function panel_graph_copy() { CALL("graph_copy"); PANEL_GRAPH.doCopy(); } - function panel_graph_paste() { CALL("graph_paste"); PANEL_GRAPH.doPaste(); } - - function panel_graph_auto_align() { CALL("graph_auto_align"); node_auto_align(PANEL_GRAPH.nodes_selecting); } - function panel_graph_search() { CALL("graph_search"); PANEL_GRAPH.toggleSearch(); } - function panel_graph_toggle_minimap() { CALL("graph_toggle_minimap"); PANEL_GRAPH.minimap_show = !PANEL_GRAPH.minimap_show; } - - function panel_graph_pan() { CALL("graph_pan"); if(PANEL_GRAPH.node_hovering || PANEL_GRAPH.value_focus) return; PANEL_GRAPH.graph_dragging_key = true; } - function panel_graph_zoom() { CALL("graph_zoom"); if(PANEL_GRAPH.node_hovering || PANEL_GRAPH.value_focus) return; PANEL_GRAPH.graph_zooming_key = true; } - - function panel_graph_send_to_preview() { CALL("graph_send_to_preview"); PANEL_GRAPH.send_to_preview(); } - function panel_graph_preview_window() { CALL("graph_preview_window"); create_preview_window(PANEL_GRAPH.getFocusingNode()); } - function panel_graph_inspector_panel() { CALL("graph_inspector_panel"); PANEL_GRAPH.inspector_panel(); } - function panel_graph_send_to_export() { CALL("graph_send_to_export"); PANEL_GRAPH.send_to_export(); } - function panel_graph_toggle_preview() { CALL("graph_toggle_preview"); PANEL_GRAPH.setTriggerPreview(); } - function panel_graph_toggle_render() { CALL("graph_toggle_render"); PANEL_GRAPH.setTriggerRender(); } - function panel_graph_toggle_parameter() { CALL("graph_toggle_parameter"); PANEL_GRAPH.setTriggerParameter(); } - function panel_graph_enter_group() { CALL("graph_enter_group"); PANEL_GRAPH.enter_group(); } - function panel_graph_hide_disconnected() { CALL("graph_hide_disconnected"); PANEL_GRAPH.hide_disconnected(); } - - function panel_graph_open_group_tab() { CALL("graph_open_group_tab"); PANEL_GRAPH.open_group_tab(); } - function panel_graph_set_as_tool() { CALL("graph_open_set_as_tool"); PANEL_GRAPH.set_as_tool(); } - - function panel_graph_doCopyProp() { CALL("graph_doCopyProp"); PANEL_GRAPH.doCopyProp(); } - function panel_graph_doPasteProp() { CALL("graph_doPasteProp"); PANEL_GRAPH.doPasteProp(); } - function panel_graph_createTunnel() { CALL("graph_createTunnel"); PANEL_GRAPH.createTunnel(); } + function panel_graph_add_node() { CALL("graph_add_node"); PANEL_GRAPH.callAddDialog(); } + function panel_graph_focus_content() { CALL("graph_focus_content"); PANEL_GRAPH.fullView(); } + function panel_graph_preview_focus() { CALL("graph_preview_focus"); PANEL_GRAPH.setCurrentPreview(); } + + function panel_graph_import_image() { CALL("graph_import_image"); PANEL_GRAPH.createNodeHotkey("Node_Image"); } + function panel_graph_import_image_array() { CALL("graph_import_image_array"); PANEL_GRAPH.createNodeHotkey("Node_Image_Sequence"); } + function panel_graph_add_number() { CALL("graph_add_number"); PANEL_GRAPH.createNodeHotkey("Node_Number"); } + function panel_graph_add_vec2() { CALL("graph_add_vec2"); PANEL_GRAPH.createNodeHotkey("Node_Vector2"); } + function panel_graph_add_vec3() { CALL("graph_add_vec3"); PANEL_GRAPH.createNodeHotkey("Node_Vector3"); } + function panel_graph_add_vec4() { CALL("graph_add_vec4"); PANEL_GRAPH.createNodeHotkey("Node_Vector4"); } + function panel_graph_add_display() { CALL("graph_add_disp"); PANEL_GRAPH.createNodeHotkey("Node_Display_Text"); } + + function panel_graph_add_math_add() { CALL("graph_add_math_add"); PANEL_GRAPH.createNodeHotkey(Node_create_Math, { query: "add" }); } + + function panel_graph_select_all() { CALL("graph_select_all"); PANEL_GRAPH.nodes_selecting = PANEL_GRAPH.nodes_list; } + function panel_graph_toggle_grid() { CALL("graph_toggle_grid"); PANEL_GRAPH.display_parameter.show_grid = !PANEL_GRAPH.display_parameter.show_grid; } + + function panel_graph_export() { CALL("graph_export"); PANEL_GRAPH.setCurrentExport(); } + + function panel_graph_add_transform() { CALL("graph_add_transform"); PANEL_GRAPH.doTransform(); } + function panel_graph_blend() { CALL("graph_blend"); PANEL_GRAPH.doBlend(); } + function panel_graph_compose() { CALL("graph_compose"); PANEL_GRAPH.doCompose(); } + function panel_graph_array() { CALL("graph_array"); PANEL_GRAPH.doArray(); } + function panel_graph_group() { CALL("graph_group"); PANEL_GRAPH.doGroup(); } + function panel_graph_ungroup() { CALL("graph_ungroup"); PANEL_GRAPH.doUngroup(); } + + function panel_graph_canvas_copy() { CALL("graph_canvas_copy"); PANEL_GRAPH.setCurrentCanvas(); } + function panel_graph_canvas_blend() { CALL("graph_canvas_blend"); PANEL_GRAPH.setCurrentCanvasBlend(); } + + function panel_graph_frame() { CALL("graph_frame"); PANEL_GRAPH.doFrame(); } + function panel_graph_delete_break() { CALL("graph_delete_break"); PANEL_GRAPH.doDelete(false); } + function panel_graph_delete_merge() { CALL("graph_delete_merge"); PANEL_GRAPH.doDelete(true); } + function panel_graph_duplicate() { CALL("graph_duplicate"); PANEL_GRAPH.doDuplicate(); } + function panel_graph_copy() { CALL("graph_copy"); PANEL_GRAPH.doCopy(); } + function panel_graph_paste() { CALL("graph_paste"); PANEL_GRAPH.doPaste(); } + + function panel_graph_auto_align() { CALL("graph_auto_align"); node_auto_align(PANEL_GRAPH.nodes_selecting); } + function panel_graph_search() { CALL("graph_search"); PANEL_GRAPH.toggleSearch(); } + function panel_graph_toggle_minimap() { CALL("graph_toggle_minimap"); PANEL_GRAPH.minimap_show = !PANEL_GRAPH.minimap_show; } + + function panel_graph_pan() { CALL("graph_pan"); if(PANEL_GRAPH.node_hovering || PANEL_GRAPH.value_focus) return; PANEL_GRAPH.graph_dragging_key = true;} + function panel_graph_zoom() { CALL("graph_zoom"); if(PANEL_GRAPH.node_hovering || PANEL_GRAPH.value_focus) return; PANEL_GRAPH.graph_zooming_key = true;} + + function panel_graph_send_to_preview() { CALL("graph_send_to_preview"); PANEL_GRAPH.send_to_preview(); } + function panel_graph_preview_window() { CALL("graph_preview_window"); create_preview_window(PANEL_GRAPH.getFocusingNode()); } + function panel_graph_inspector_panel() { CALL("graph_inspector_panel"); PANEL_GRAPH.inspector_panel(); } + function panel_graph_send_to_export() { CALL("graph_send_to_export"); PANEL_GRAPH.send_hover_to_export(); } + function panel_graph_toggle_preview() { CALL("graph_toggle_preview"); PANEL_GRAPH.setTriggerPreview(); } + function panel_graph_toggle_render() { CALL("graph_toggle_render"); PANEL_GRAPH.setTriggerRender(); } + function panel_graph_toggle_parameter() { CALL("graph_toggle_parameter"); PANEL_GRAPH.setTriggerParameter(); } + function panel_graph_enter_group() { CALL("graph_enter_group"); PANEL_GRAPH.enter_group(); } + function panel_graph_hide_disconnected() { CALL("graph_hide_disconnected"); PANEL_GRAPH.hide_disconnected(); } + + function panel_graph_open_group_tab() { CALL("graph_open_group_tab"); PANEL_GRAPH.open_group_tab(); } + function panel_graph_set_as_tool() { CALL("graph_open_set_as_tool"); PANEL_GRAPH.set_as_tool(); } + + function panel_graph_doCopyProp() { CALL("graph_doCopyProp"); PANEL_GRAPH.doCopyProp(); } + function panel_graph_doPasteProp() { CALL("graph_doPasteProp"); PANEL_GRAPH.doPasteProp(); } + function panel_graph_createTunnel() { CALL("graph_createTunnel"); PANEL_GRAPH.createTunnel(); } - function __fnInit_Graph() { - registerFunction("Graph", "Add Node", "A", MOD_KEY.none, panel_graph_add_node); - registerFunction("Graph", "Focus Content", "F", MOD_KEY.none, panel_graph_focus_content); - registerFunction("Graph", "Preview Focusing Node", "P", MOD_KEY.none, panel_graph_preview_focus); - - registerFunction("Graph", "Import Image", "I", MOD_KEY.none, panel_graph_import_image); - registerFunction("Graph", "Import Image Array", "I", MOD_KEY.shift, panel_graph_import_image_array); - registerFunction("Graph", "Add Number", "1", MOD_KEY.none, panel_graph_add_number); - registerFunction("Graph", "Add Vector2", "2", MOD_KEY.none, panel_graph_add_vec2); - registerFunction("Graph", "Add Vector3", "3", MOD_KEY.none, panel_graph_add_vec3); - registerFunction("Graph", "Add Vector4", "4", MOD_KEY.none, panel_graph_add_vec4); - registerFunction("Graph", "Add Display", "D", MOD_KEY.none, panel_graph_add_display); - registerFunction("Graph", "Transform Node", "T", MOD_KEY.ctrl, panel_graph_add_transform); - - registerFunction("Graph", "Select All", "A", MOD_KEY.ctrl, panel_graph_select_all); - registerFunction("Graph", "Toggle Grid", "G", MOD_KEY.none, panel_graph_toggle_grid); - - if(!DEMO) registerFunction("Graph", "Export", "E", MOD_KEY.ctrl, panel_graph_export); - - registerFunction("Graph", "Blend", "B", MOD_KEY.ctrl, panel_graph_blend); - registerFunction("Graph", "Compose", "B", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_compose); - registerFunction("Graph", "Array", "A", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_array); - registerFunction("Graph", "Group", "G", MOD_KEY.ctrl, panel_graph_group); - registerFunction("Graph", "Ungroup", "G", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_ungroup); - registerFunction("Graph", "Frame", "F", MOD_KEY.shift, panel_graph_frame); - - registerFunction("Graph", "Canvas", "C", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_canvas); - registerFunction("Graph", "Canvas Blend", "C", MOD_KEY.ctrl | MOD_KEY.alt, panel_graph_canvas_blend); - - - registerFunction("Graph", "Delete (break)", vk_delete, MOD_KEY.shift, panel_graph_delete_break); - registerFunction("Graph", "Delete (merge)", vk_delete, MOD_KEY.none, panel_graph_delete_merge); - - registerFunction("Graph", "Duplicate", "D", MOD_KEY.ctrl, panel_graph_duplicate); - registerFunction("Graph", "Copy", "C", MOD_KEY.ctrl, panel_graph_copy); - registerFunction("Graph", "Paste", "V", MOD_KEY.ctrl, panel_graph_paste); - - registerFunction("Graph", "Pan", "", MOD_KEY.ctrl, panel_graph_pan); - registerFunction("Graph", "Zoom", "", MOD_KEY.alt | MOD_KEY.ctrl, panel_graph_zoom); - - registerFunction("Graph", "Auto Align", "L", MOD_KEY.none, panel_graph_auto_align); - registerFunction("Graph", "Search", "F", MOD_KEY.ctrl, panel_graph_search); - registerFunction("Graph", "Toggle Minimap", "M", MOD_KEY.ctrl, panel_graph_toggle_minimap); - - registerFunction("Graph", "Preview Hovering Node", "", MOD_KEY.none, panel_graph_send_to_preview); - registerFunction("Graph", "Preview Window", "P", MOD_KEY.ctrl, panel_graph_preview_window); - registerFunction("Graph", "Inspect", "", MOD_KEY.none, panel_graph_inspector_panel); - if(!DEMO) registerFunction("Graph", "Export", "", MOD_KEY.none, panel_graph_send_to_export); - registerFunction("Graph", "Toggle Preview", "H", MOD_KEY.none, panel_graph_toggle_preview); - registerFunction("Graph", "Toggle Render", "R", MOD_KEY.none, panel_graph_toggle_render); - registerFunction("Graph", "Toggle Parameters", "M", MOD_KEY.none, panel_graph_toggle_parameter); - registerFunction("Graph", "Enter Group", "", MOD_KEY.none, panel_graph_enter_group); - registerFunction("Graph", "Hide Disconnected", "", MOD_KEY.none, panel_graph_hide_disconnected); - - registerFunction("Graph", "Open In New Tab", "", MOD_KEY.none, panel_graph_open_group_tab); - registerFunction("Graph", "Set As Tool", "", MOD_KEY.none, panel_graph_set_as_tool); - - registerFunction("Graph", "Copy Value", "", MOD_KEY.none, panel_graph_doCopyProp); - registerFunction("Graph", "Paste Value", "", MOD_KEY.none, panel_graph_doPasteProp); - registerFunction("Graph", "Create Tunnel", "", MOD_KEY.none, panel_graph_createTunnel); - } + function __fnInit_Graph() { + registerFunction("Graph", "Add Node", "A", MOD_KEY.none, panel_graph_add_node ).setMenu("graph_add_node") + registerFunction("Graph", "Focus Content", "F", MOD_KEY.none, panel_graph_focus_content ).setMenu("graph_focus_content") + registerFunction("Graph", "Preview Focusing Node", "P", MOD_KEY.none, panel_graph_preview_focus ).setMenu("graph_preview_focusing_node") + + registerFunction("Graph", "Import Image", "I", MOD_KEY.none, panel_graph_import_image ).setMenu("graph_import_image") + registerFunction("Graph", "Import Image Array", "I", MOD_KEY.shift, panel_graph_import_image_array ).setMenu("graph_import_image_array") + registerFunction("Graph", "Add Number", "1", MOD_KEY.none, panel_graph_add_number ).setMenu("graph_add_number") + registerFunction("Graph", "Add Vector2", "2", MOD_KEY.none, panel_graph_add_vec2 ).setMenu("graph_add_vector2") + registerFunction("Graph", "Add Vector3", "3", MOD_KEY.none, panel_graph_add_vec3 ).setMenu("graph_add_vector3") + registerFunction("Graph", "Add Vector4", "4", MOD_KEY.none, panel_graph_add_vec4 ).setMenu("graph_add_vector4") + registerFunction("Graph", "Add Display", "D", MOD_KEY.none, panel_graph_add_display ).setMenu("graph_add_display") + registerFunction("Graph", "Transform Node", "T", MOD_KEY.ctrl, panel_graph_add_transform ).setMenu("graph_transform_node") + + registerFunction("Graph", "Select All", "A", MOD_KEY.ctrl, panel_graph_select_all ).setMenu("graph_select_all") + registerFunction("Graph", "Toggle Grid", "G", MOD_KEY.none, panel_graph_toggle_grid ).setMenu("graph_toggle_grid") + + registerFunction("Graph", "Blend", "B", MOD_KEY.ctrl, panel_graph_blend ).setMenu("graph_blend") + registerFunction("Graph", "Compose", "B", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_compose ).setMenu("graph_compose") + registerFunction("Graph", "Array", "A", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_array ).setMenu("graph_array") + registerFunction("Graph", "Frame", "F", MOD_KEY.shift, panel_graph_frame ).setMenu("graph_frame") + + registerFunction("Graph", "Canvas", "", MOD_KEY.none, + function(_dat) { return submenuCall(_dat, [ MENU_ITEMS.graph_canvas_copy, MENU_ITEMS.graph_canvas_blend ]); } ).setMenu("graph_canvas",, true) + registerFunction("Graph", "Copy to Canvas", "C", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_canvas_copy ).setMenu("graph_canvas_copy") + registerFunction("Graph", "Blend Canvas", "C", MOD_KEY.ctrl | MOD_KEY.alt, panel_graph_canvas_blend ).setMenu("graph_canvas_blend") + + + registerFunction("Graph", "Delete (break)", vk_delete, MOD_KEY.shift, panel_graph_delete_break ).setMenu("graph_delete_break", THEME.cross) + registerFunction("Graph", "Delete (merge)", vk_delete, MOD_KEY.none, panel_graph_delete_merge ).setMenu("graph_delete_merge", THEME.cross) + + registerFunction("Graph", "Duplicate", "D", MOD_KEY.ctrl, panel_graph_duplicate ).setMenu("graph_duplicate", THEME.duplicate) + registerFunction("Graph", "Copy", "C", MOD_KEY.ctrl, panel_graph_copy ).setMenu("graph_copy", THEME.copy) + registerFunction("Graph", "Paste", "V", MOD_KEY.ctrl, panel_graph_paste ).setMenu("graph_paste", THEME.paste) + + registerFunction("Graph", "Pan", "", MOD_KEY.ctrl, panel_graph_pan ).setMenu("graph_pan") + registerFunction("Graph", "Zoom", "", MOD_KEY.alt | MOD_KEY.ctrl, panel_graph_zoom ).setMenu("graph_zoom") + + registerFunction("Graph", "Auto Align", "L", MOD_KEY.none, panel_graph_auto_align ).setMenu("graph_auto_align") + registerFunction("Graph", "Search", "F", MOD_KEY.ctrl, panel_graph_search ).setMenu("graph_search") + registerFunction("Graph", "Toggle Minimap", "M", MOD_KEY.ctrl, panel_graph_toggle_minimap ).setMenu("graph_toggle_minimap") + + registerFunction("Graph", "Send To Preview", "", MOD_KEY.none, panel_graph_send_to_preview ).setMenu("graph_preview_hovering_node") + registerFunction("Graph", "Send To Preview Window","P", MOD_KEY.ctrl, panel_graph_preview_window ).setMenu("graph_preview_window") + registerFunction("Graph", "Send To Inspector", "", MOD_KEY.none, panel_graph_inspector_panel ).setMenu("graph_inspect") + registerFunction("Graph", "Toggle Preview", "H", MOD_KEY.none, panel_graph_toggle_preview ).setMenu("graph_toggle_preview") + registerFunction("Graph", "Toggle Render", "R", MOD_KEY.none, panel_graph_toggle_render ).setMenu("graph_toggle_render") + registerFunction("Graph", "Toggle Parameters", "M", MOD_KEY.none, panel_graph_toggle_parameter ).setMenu("graph_toggle_parameters") + registerFunction("Graph", "Hide Disconnected", "", MOD_KEY.none, panel_graph_hide_disconnected ).setMenu("graph_hide_disconnected") + + registerFunction("Graph", "Enter Group", "", MOD_KEY.none, panel_graph_enter_group ).setMenu("graph_enter_group", THEME.group) + registerFunction("Graph", "Open Group In New Tab", "", MOD_KEY.none, panel_graph_open_group_tab ).setMenu("graph_open_in_new_tab", THEME.group) + registerFunction("Graph", "Group", "G", MOD_KEY.ctrl, panel_graph_group ).setMenu("graph_group", THEME.group) + registerFunction("Graph", "Ungroup", "G", MOD_KEY.ctrl | MOD_KEY.shift, panel_graph_ungroup ).setMenu("graph_ungroup", THEME.group) + registerFunction("Graph", "Set As Group Tool", "", MOD_KEY.none, panel_graph_set_as_tool ).setMenu("graph_set_as_tool") + + registerFunction("Graph", "Copy Value", "", MOD_KEY.none, panel_graph_doCopyProp ).setMenu("graph_copy_value") + registerFunction("Graph", "Paste Value", "", MOD_KEY.none, panel_graph_doPasteProp ).setMenu("graph_paste_value") + registerFunction("Graph", "Create Tunnel", "", MOD_KEY.none, panel_graph_createTunnel ).setMenu("graph_create_tunnel") + + if(!DEMO) { + registerFunction("Graph", "Export Selected", "E", MOD_KEY.ctrl, panel_graph_export ).setMenu("graph_export_selected") + registerFunction("Graph", "Export Hover", "", MOD_KEY.none, panel_graph_send_to_export ).setMenu("graph_export_hover") + } + } #endregion function connectionParameter() constructor { - log = false; - active = true; - - x = 0; - y = 0; - s = 0; - mx = 0; - my = 0; - aa = 0; - bg = 0; - - minx = 0; - miny = 0; - maxx = 0; - maxy = 0; - - max_layer = 0; - highlight = 0; - cur_layer = 1; - - static setPos = function(_x, _y, _s, _mx, _my) { - self.x = _x; - self.y = _y; - self.s = _s; - self.mx = _mx; - self.my = _my; - } + log = false; + active = true; + + x = 0; + y = 0; + s = 0; + mx = 0; + my = 0; + aa = 0; + bg = 0; + + minx = 0; + miny = 0; + maxx = 0; + maxy = 0; + + max_layer = 0; + highlight = 0; + cur_layer = 1; + + static setPos = function(_x, _y, _s, _mx, _my) { + self.x = _x; + self.y = _y; + self.s = _s; + self.mx = _mx; + self.my = _my; + } - static setBoundary = function(_minx, _miny, _maxx, _maxy) { - self.minx = _minx; - self.miny = _miny; - self.maxx = _maxx; - self.maxy = _maxy; - } + static setBoundary = function(_minx, _miny, _maxx, _maxy) { + self.minx = _minx; + self.miny = _miny; + self.maxx = _maxx; + self.maxy = _maxy; + } - static setProp = function(_max_layer, _highlight) { - self.max_layer = _max_layer; - self.highlight = _highlight; - } + static setProp = function(_max_layer, _highlight) { + self.max_layer = _max_layer; + self.highlight = _highlight; + } - static setDraw = function(_aa, _bg = c_black) { - self.aa = _aa; - self.bg = _bg; - } + static setDraw = function(_aa, _bg = c_black) { + self.aa = _aa; + self.bg = _bg; + } } //// ========== Graph Panel ========== - + function Panel_Graph(project = PROJECT) : PanelContent() constructor { - title = __txt("Graph"); - title_raw = ""; - context_str = "Graph"; - icon = THEME.panel_graph_icon; - - function setTitle() { - title_raw = project.path == ""? "New project" : filename_name_only(project.path); - title = title_raw + (project.modified? "*" : ""); - } - - static reset = function() { - onFocusBegin(); - resetContext(); - } - - #region // ---- display ---- - display_parameter = { - show_grid : true, - show_dimension : true, - show_compute : true, - - avoid_label : true, - preview_scale : 100, - highlight : false, - - show_control : false, - } - - connection_param = new connectionParameter(); - show_view_control = 1; - - bg_color = c_black; - - slider_width = 0; - #endregion - - #region // ---- position ---- - graph_x = 0; - graph_y = 0; - graph_cx = 0; - graph_cy = 0; - - graph_autopan = false; - graph_pan_x_to = 0; - graph_pan_y_to = 0; - - scale = [ 0.01, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.33, 0.50, 0.65, 0.80, 1, 1.2, 1.35, 1.5, 2.0 ]; - graph_s = 1; - graph_s_to = graph_s; - - graph_dragging_key = false; - graph_zooming_key = false; - - graph_draggable= true; - graph_dragging = false; - graph_drag_mx = 0; - graph_drag_my = 0; - graph_drag_sx = 0; - graph_drag_sy = 0; - - graph_zooming = false; - graph_zoom_mx = 0; - graph_zoom_my = 0; - graph_zoom_m = 0; - graph_zoom_s = 0; - - view_hovering = false; - view_pan_tool = false; - view_zoom_tool = false; - - drag_key = PREFERENCES.pan_mouse_key; - drag_locking = false; - #endregion - - #region // ---- mouse ---- - mouse_graph_x = 0; - mouse_graph_y = 0; - mouse_grid_x = 0; - mouse_grid_y = 0; - - mouse_create_x = undefined; - mouse_create_y = undefined; - mouse_create_sx = undefined; - mouse_create_sy = undefined; - - mouse_on_graph = false; - node_bg_hovering = false; - #endregion - - #region // ---- nodes ---- - node_context = []; - nodes_list = []; - - node_dragging = noone; - node_drag_mx = 0; - node_drag_my = 0; - node_drag_sx = 0; - node_drag_sy = 0; - node_drag_ox = 0; - node_drag_oy = 0; - - selection_block = 0; - nodes_selecting = []; - nodes_selecting_jun = []; - nodes_select_anchor = noone; - nodes_select_drag = 0; - nodes_select_frame = 0; - nodes_select_mx = 0; - nodes_select_my = 0; - - nodes_junction_d = noone; - nodes_junction_dx = 0; - nodes_junction_dy = 0; - - node_hovering = noone; - node_hover = noone; - - junction_hovering = noone; - add_node_draw_junc = false; - add_node_draw_x_fix = 0; - add_node_draw_y_fix = 0; - add_node_draw_x = 0; - add_node_draw_y = 0; - - connection_aa = 2; - connection_surface = surface_create(1, 1); - connection_surface_aa = surface_create(1, 1); - - connection_draw_mouse = noone; - connection_draw_target = noone; - - value_focus = noone; - _value_focus = noone; - value_dragging = noone; - value_draggings = []; - value_drag_from = noone; - - frame_hovering = noone; - _frame_hovering = noone; - #endregion - - #region // ---- minimap ---- - minimap_show = false; - minimap_w = ui(160); - minimap_h = ui(160); - minimap_surface = -1; - - minimap_panning = false; - minimap_dragging = false; - minimap_drag_sx = 0; - minimap_drag_sy = 0; - minimap_drag_mx = 0; - minimap_drag_my = 0; - #endregion - - #region // ---- context frame ---- - context_framing = false; - context_frame_progress = 0; - context_frame_direct = 0; - context_frame_sx = 0; context_frame_ex = 0; - context_frame_sy = 0; context_frame_ey = 0; - #endregion - - #region // ---- search ---- - is_searching = false; - search_string = ""; - search_index = 0; - search_result = []; - - tb_search = new textBox(TEXTBOX_INPUT.text, function(str) /*=>*/ { search_string = string(str); searchNodes(); }); - tb_search.align = fa_left; - tb_search.auto_update = true; - #endregion - - toolbar_height = ui(40); - - function toCenterNode(_arr = nodes_list) { - if(!project.active) return; - - graph_s = 1; - graph_s_to = 1; - - if(array_empty(_arr)) { - graph_x = round(w / 2 / graph_s); - graph_y = round(h / 2 / graph_s); - return; - } - - var minx = 99999; - var maxx = -99999; - var miny = 99999; - var maxy = -99999; - - for(var i = 0; i < array_length(_arr); i++) { - var _node = _arr[i]; - - if(!is_instanceof(_node, Node)) continue; - if(is_instanceof(_node, Node_Collection_Inline)) continue; - if(is_instanceof(_node, Node_Feedback_Inline)) continue; - if(!_node.active) continue; - - minx = min(minx, _node.x - 32); - maxx = max(maxx, _node.x + _node.w + 32); - - miny = min(miny, _node.y - 32); - maxy = max(maxy, _node.y + _node.h + 32); - } - - var cx = (minx + maxx) / 2; - var cy = (miny + maxy) / 2; - - graph_x = (w ) / 2 - cx; - graph_y = (h - toolbar_height) / 2 - cy; - - graph_x = round(graph_x * graph_s); - graph_y = round(graph_y * graph_s); - - // print($"{cx}, {cy} / {graph_x}, {graph_y}"); - } - - function initSize() { toCenterNode(); } - - #region // ++++ toolbars ++++ - tooltip_center = new tooltipHotkey(__txtx("panel_graph_center_to_nodes", "Center to nodes"), "Graph", "Focus content"); - tooltip_search = new tooltipHotkey(__txt("Search"), "Graph", "Search"); - tooltip_minimap = new tooltipHotkey(__txtx("panel_graph_toggle_minimap", "Toggle minimap"), "Graph", "Toggle Minimap"); - - toolbars_general = [ - [ - THEME.icon_preview_export, - function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("panel_graph_export_image", "Export graph as image")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Export_Image(self)); } - ], - [ - THEME.search_24, - function() /*=>*/ {return 0}, function() /*=>*/ {return tooltip_search}, - function(param) /*=>*/ { toggleSearch(); } - ], - [ - THEME.icon_center_canvas, - function() /*=>*/ {return 0}, function() /*=>*/ {return tooltip_center}, - function(param) /*=>*/ { toCenterNode(); } - ], - [ - THEME.icon_minimap, - function() /*=>*/ {return minimap_show}, function() /*=>*/ {return tooltip_minimap}, - function(param) /*=>*/ { minimap_show = !minimap_show; } - ], - [ - THEME.icon_curve_connection, - function() /*=>*/ {return PREFERENCES.curve_connection_line}, function() /*=>*/ {return __txtx("panel_graph_connection_line", "Connection render settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Connection_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - [ - THEME.icon_grid_setting, - function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("grid_title", "Grid settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - [ - THEME.icon_visibility, - function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("graph_visibility_title", "Visibility settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_View_Setting(self, display_parameter), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - ]; - - toolbars_halign = [ - [ THEME.object_halign, function() /*=>*/ {return 2}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_right); } ], - [ THEME.object_halign, function() /*=>*/ {return 1}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_center); } ], - [ THEME.object_halign, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_left); } ], - ]; - - toolbars_valign = [ - [ THEME.object_valign, function() /*=>*/ {return 2}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_bottom); } ], - [ THEME.object_valign, function() /*=>*/ {return 1}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_middle); } ], - [ THEME.object_valign, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_top); } ], - ]; - - toolbars_distrib = [ - [ THEME.obj_distribute_h, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_hdistribute(nodes_selecting); } ], - [ THEME.obj_distribute_v, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_vdistribute(nodes_selecting); } ], - ]; - - distribution_spacing = 0; - toolbars_distrib_space = [ - [ THEME.obj_distribute_h, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_hdistribute_dist(nodes_selecting, nodes_select_anchor, distribution_spacing); } ], - [ THEME.obj_distribute_v, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_vdistribute_dist(nodes_selecting, nodes_select_anchor, distribution_spacing); } ], - [ new textBox(TEXTBOX_INPUT.number, function(val) { distribution_spacing = value_snap(val, 4); } ).setPadding(4), function() /*=>*/ {return distribution_spacing} ], - ]; - - toolbars = [ toolbars_general ]; - #endregion - - //// =========== Get Set =========== - - function setCurrentPreview(_node = getFocusingNode()) { - if(!_node) return; - - PANEL_PREVIEW.setNodePreview(_node); - } + title = __txt("Graph"); + title_raw = ""; + context_str = "Graph"; + icon = THEME.panel_graph_icon; + + function setTitle() { + title_raw = project.path == ""? "New project" : filename_name_only(project.path); + title = title_raw + (project.modified? "*" : ""); + } + + static reset = function() { + onFocusBegin(); + resetContext(); + } + + #region // ---- display ---- + display_parameter = { + show_grid : true, + show_dimension : true, + show_compute : true, + + avoid_label : true, + preview_scale : 100, + highlight : false, + + show_control : false, + } + + connection_param = new connectionParameter(); + show_view_control = 1; + + bg_color = c_black; + + slider_width = 0; + #endregion + + #region // ---- position ---- + graph_x = 0; + graph_y = 0; + graph_cx = 0; + graph_cy = 0; + + graph_autopan = false; + graph_pan_x_to = 0; + graph_pan_y_to = 0; + + scale = [ 0.01, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.33, 0.50, 0.65, 0.80, 1, 1.2, 1.35, 1.5, 2.0 ]; + graph_s = 1; + graph_s_to = graph_s; + + graph_dragging_key = false; + graph_zooming_key = false; + + graph_draggable= true; + graph_dragging = false; + graph_drag_mx = 0; + graph_drag_my = 0; + graph_drag_sx = 0; + graph_drag_sy = 0; + + graph_zooming = false; + graph_zoom_mx = 0; + graph_zoom_my = 0; + graph_zoom_m = 0; + graph_zoom_s = 0; + + view_hovering = false; + view_pan_tool = false; + view_zoom_tool = false; + + drag_key = PREFERENCES.pan_mouse_key; + drag_locking = false; + #endregion + + #region // ---- mouse ---- + mouse_graph_x = 0; + mouse_graph_y = 0; + mouse_grid_x = 0; + mouse_grid_y = 0; + + mouse_create_x = undefined; + mouse_create_y = undefined; + mouse_create_sx = undefined; + mouse_create_sy = undefined; + + mouse_on_graph = false; + node_bg_hovering = false; + #endregion + + #region // ---- nodes ---- + node_context = []; + nodes_list = []; + + node_dragging = noone; + node_drag_mx = 0; + node_drag_my = 0; + node_drag_sx = 0; + node_drag_sy = 0; + node_drag_ox = 0; + node_drag_oy = 0; + + selection_block = 0; + nodes_selecting = []; + nodes_selecting_jun = []; + nodes_select_anchor = noone; + nodes_select_drag = 0; + nodes_select_frame = 0; + nodes_select_mx = 0; + nodes_select_my = 0; + + nodes_junction_d = noone; + nodes_junction_dx = 0; + nodes_junction_dy = 0; + + node_hovering = noone; + node_hover = noone; + + junction_hovering = noone; + add_node_draw_junc = false; + add_node_draw_x_fix = 0; + add_node_draw_y_fix = 0; + add_node_draw_x = 0; + add_node_draw_y = 0; + + connection_aa = 2; + connection_surface = surface_create(1, 1); + connection_surface_aa = surface_create(1, 1); + + connection_draw_mouse = noone; + connection_draw_target = noone; + + value_focus = noone; + _value_focus = noone; + value_dragging = noone; + value_draggings = []; + value_drag_from = noone; + + frame_hovering = noone; + _frame_hovering = noone; + #endregion + + #region // ---- minimap ---- + minimap_show = false; + minimap_w = ui(160); + minimap_h = ui(160); + minimap_surface = -1; + + minimap_panning = false; + minimap_dragging = false; + minimap_drag_sx = 0; + minimap_drag_sy = 0; + minimap_drag_mx = 0; + minimap_drag_my = 0; + #endregion + + #region // ---- context frame ---- + context_framing = false; + context_frame_progress = 0; + context_frame_direct = 0; + context_frame_sx = 0; context_frame_ex = 0; + context_frame_sy = 0; context_frame_ey = 0; + #endregion + + #region // ---- search ---- + is_searching = false; + search_string = ""; + search_index = 0; + search_result = []; + + tb_search = new textBox(TEXTBOX_INPUT.text, function(str) /*=>*/ { search_string = string(str); searchNodes(); }); + tb_search.align = fa_left; + tb_search.auto_update = true; + #endregion + + toolbar_height = ui(40); + + function toCenterNode(_arr = nodes_list) { + if(!project.active) return; + + graph_s = 1; + graph_s_to = 1; + + if(array_empty(_arr)) { + graph_x = round(w / 2 / graph_s); + graph_y = round(h / 2 / graph_s); + return; + } + + var minx = 99999; + var maxx = -99999; + var miny = 99999; + var maxy = -99999; + + for(var i = 0; i < array_length(_arr); i++) { + var _node = _arr[i]; + + if(!is_instanceof(_node, Node)) continue; + if(is_instanceof(_node, Node_Collection_Inline)) continue; + if(is_instanceof(_node, Node_Feedback_Inline)) continue; + if(!_node.active) continue; + + minx = min(minx, _node.x - 32); + maxx = max(maxx, _node.x + _node.w + 32); + + miny = min(miny, _node.y - 32); + maxy = max(maxy, _node.y + _node.h + 32); + } + + var cx = (minx + maxx) / 2; + var cy = (miny + maxy) / 2; + + graph_x = (w ) / 2 - cx; + graph_y = (h - toolbar_height) / 2 - cy; + + graph_x = round(graph_x * graph_s); + graph_y = round(graph_y * graph_s); + + // print($"{cx}, {cy} / {graph_x}, {graph_y}"); + } + + function initSize() { toCenterNode(); } + + #region // ++++ toolbars ++++ + tooltip_center = new tooltipHotkey(__txtx("panel_graph_center_to_nodes", "Center to nodes"), "Graph", "Focus content"); + tooltip_search = new tooltipHotkey(__txt("Search"), "Graph", "Search"); + tooltip_minimap = new tooltipHotkey(__txtx("panel_graph_toggle_minimap", "Toggle minimap"), "Graph", "Toggle Minimap"); + + toolbars_general = [ + [ + THEME.icon_preview_export, + function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("panel_graph_export_image", "Export graph as image")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Export_Image(self)); } + ], + [ + THEME.search_24, + function() /*=>*/ {return 0}, function() /*=>*/ {return tooltip_search}, + function(param) /*=>*/ { toggleSearch(); } + ], + [ + THEME.icon_center_canvas, + function() /*=>*/ {return 0}, function() /*=>*/ {return tooltip_center}, + function(param) /*=>*/ { toCenterNode(); } + ], + [ + THEME.icon_minimap, + function() /*=>*/ {return minimap_show}, function() /*=>*/ {return tooltip_minimap}, + function(param) /*=>*/ { minimap_show = !minimap_show; } + ], + [ + THEME.icon_curve_connection, + function() /*=>*/ {return PREFERENCES.curve_connection_line}, function() /*=>*/ {return __txtx("panel_graph_connection_line", "Connection render settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Connection_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + [ + THEME.icon_grid_setting, + function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("grid_title", "Grid settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + [ + THEME.icon_visibility, + function() /*=>*/ {return 0}, function() /*=>*/ {return __txtx("graph_visibility_title", "Visibility settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Graph_View_Setting(self, display_parameter), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + ]; + + toolbars_halign = [ + [ THEME.object_halign, function() /*=>*/ {return 2}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_right); } ], + [ THEME.object_halign, function() /*=>*/ {return 1}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_center); } ], + [ THEME.object_halign, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_halign(nodes_selecting, fa_left); } ], + ]; + + toolbars_valign = [ + [ THEME.object_valign, function() /*=>*/ {return 2}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_bottom); } ], + [ THEME.object_valign, function() /*=>*/ {return 1}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_middle); } ], + [ THEME.object_valign, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_valign(nodes_selecting, fa_top); } ], + ]; + + toolbars_distrib = [ + [ THEME.obj_distribute_h, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_hdistribute(nodes_selecting); } ], + [ THEME.obj_distribute_v, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_vdistribute(nodes_selecting); } ], + ]; + + distribution_spacing = 0; + toolbars_distrib_space = [ + [ THEME.obj_distribute_h, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_hdistribute_dist(nodes_selecting, nodes_select_anchor, distribution_spacing); } ], + [ THEME.obj_distribute_v, function() /*=>*/ {return 0}, function() /*=>*/ {return ""}, function(param) /*=>*/ { node_vdistribute_dist(nodes_selecting, nodes_select_anchor, distribution_spacing); } ], + [ new textBox(TEXTBOX_INPUT.number, function(val) { distribution_spacing = value_snap(val, 4); } ).setPadding(4), function() /*=>*/ {return distribution_spacing} ], + ]; + + toolbars = [ toolbars_general ]; + #endregion + + //// =========== Get Set =========== + + function setCurrentPreview(_node = getFocusingNode()) { + if(!_node) return; + + PANEL_PREVIEW.setNodePreview(_node); + } - function setCurrentExport(_node = getFocusingNode()) { - if(DEMO) return; - if(!_node) return; - - var _outp = -1; - var _path = -1; - - for( var i = 0; i < array_length(_node.outputs); i++ ) { - if(_node.outputs[i].type == VALUE_TYPE.path) - _path = _node.outputs[i]; - if(_node.outputs[i].type == VALUE_TYPE.surface && _outp == -1) - _outp = _node.outputs[i]; - } - - if(_outp == -1) return; - - var _export = nodeBuild("Node_Export", _node.x + _node.w + 64, _node.y); - if(_path != -1) - _export.inputs[1].setFrom(_path); - - _export.inputs[0].setFrom(_outp); - } + function setCurrentExport(_node = getFocusingNode()) { + if(DEMO) return; + if(!_node) return; + + var _outp = -1; + var _path = -1; + + for( var i = 0; i < array_length(_node.outputs); i++ ) { + if(_node.outputs[i].type == VALUE_TYPE.path) + _path = _node.outputs[i]; + if(_node.outputs[i].type == VALUE_TYPE.surface && _outp == -1) + _outp = _node.outputs[i]; + } + + if(_outp == -1) return; + + var _export = nodeBuild("Node_Export", _node.x + _node.w + 64, _node.y); + if(_path != -1) + _export.inputs[1].setFrom(_path); + + _export.inputs[0].setFrom(_outp); + } - function setTriggerPreview() { - __temp_show = false; - array_foreach(nodes_selecting, function(node, index) { - if(index == 0) __temp_show = !node.previewable; - node.previewable = __temp_show; - node.refreshNodeDisplay(); - }); - } + function setTriggerPreview() { + __temp_show = false; + array_foreach(nodes_selecting, function(node, index) { + if(index == 0) __temp_show = !node.previewable; + node.previewable = __temp_show; + node.refreshNodeDisplay(); + }); + } - function setTriggerParameter() { - __temp_show = false; - array_foreach(nodes_selecting, function(node, index) { - if(index == 0) __temp_show = !node.show_parameter; - node.show_parameter = __temp_show; - node.refreshNodeDisplay(); - }); - } + function setTriggerParameter() { + __temp_show = false; + array_foreach(nodes_selecting, function(node, index) { + if(index == 0) __temp_show = !node.show_parameter; + node.show_parameter = __temp_show; + node.refreshNodeDisplay(); + }); + } - function setTriggerRender() { - __temp_active = false; - array_foreach(nodes_selecting, function(node, index) { - if(index == 0) __temp_active = !node.renderActive; - node.renderActive = __temp_active; - }); - } + function setTriggerRender() { + __temp_active = false; + array_foreach(nodes_selecting, function(node, index) { + if(index == 0) __temp_active = !node.renderActive; + node.renderActive = __temp_active; + }); + } - function setCurrentCanvas(_node = getFocusingNode()) { - if(!_node) return; - - var _outp = -1; - var surf = -1; - - for( var i = 0; i < array_length(_node.outputs); i++ ) { - if(_node.outputs[i].type != VALUE_TYPE.surface) continue; - - _outp = _node.outputs[i]; - surf = _outp.getValue(); - break; - } - - if(_outp == -1) return; - if(!is_array(surf)) surf = [ surf ]; - - var _canvas = nodeBuild("Node_Canvas", _node.x + _node.w + 64, _node.y).skipDefault(); - var _dim = surface_get_dimension(surf[0]); - - _canvas.inputs[0].setValue(_dim); - _canvas.attributes.dimension = _dim; - _canvas.attributes.frames = array_length(surf); - _canvas.canvas_surface = surface_array_clone(surf); - - _canvas.apply_surfaces(); - } + function setCurrentCanvas(_node = getFocusingNode()) { + if(!_node) return; + + var _outp = -1; + var surf = -1; + + for( var i = 0; i < array_length(_node.outputs); i++ ) { + if(_node.outputs[i].type != VALUE_TYPE.surface) continue; + + _outp = _node.outputs[i]; + surf = _outp.getValue(); + break; + } + + if(_outp == -1) return; + if(!is_array(surf)) surf = [ surf ]; + + var _canvas = nodeBuild("Node_Canvas", _node.x + _node.w + 64, _node.y).skipDefault(); + var _dim = surface_get_dimension(surf[0]); + + _canvas.inputs[0].setValue(_dim); + _canvas.attributes.dimension = _dim; + _canvas.attributes.frames = array_length(surf); + _canvas.canvas_surface = surface_array_clone(surf); + + _canvas.apply_surfaces(); + } - function setCurrentCanvasBlend(_node = getFocusingNode()) { - if(!_node) return; - - var _outp = -1; - var surf = -1; - - for( var i = 0; i < array_length(_node.outputs); i++ ) { - if(_node.outputs[i].type == VALUE_TYPE.surface) { - _outp = _node.outputs[i]; - var _val = _node.outputs[i].getValue(); - if(is_array(_val)) - surf = _val[_node.preview_index]; - else - surf = _val; - break; - } - } - - if(_outp == -1) return; - - var _canvas = nodeBuild("Node_Canvas", _node.x, _node.y + _node.h + 64).skipDefault(); - - _canvas.inputs[0].setValue([surface_get_width_safe(surf), surface_get_height_safe(surf)]); - _canvas.inputs[5].setValue(true); - - var _blend = nodeBuild("Node_Blend", _node.x + _node.w + 64, _node.y).skipDefault(); - _blend.inputs[0].setFrom(_outp); - _blend.inputs[1].setFrom(_canvas.outputs[0]); - } - - function getFocusingNode() { return array_empty(nodes_selecting)? noone : nodes_selecting[0]; } - - //// =========== Menus =========== - - #region ++++++++++++ Actions ++++++++++++ - function send_to_preview() { setCurrentPreview(node_hover); } - - function inspector_panel() { - var pan = panelAdd("Panel_Inspector", true); - pan.destroy_on_click_out = false; - pan.content.setInspecting(node_hover); - pan.content.locked = true; - } - - function send_to_export() { setCurrentExport(node_hover); } - function enter_group() { PANEL_GRAPH.addContext(node_hover); } - function hide_disconnected() { hideDisconnected(); } - - - function open_group_tab(group = node_hover) { - if(group == noone) return; - - var graph = new Panel_Graph(project); - panel.setContent(graph, true); - - for( var i = 0; i < array_length(node_context); i++ ) - graph.addContext(node_context[i]); - graph.addContext(group); - - setFocus(panel); - } - - function set_as_tool() { - if(node_hover == noone) return; - node_hover.setTool(!node_hover.isTool); - } - #endregion - - menu_sent_to_preview = menuItemAction(__txtx("panel_graph_send_to_preview", "Send to preview"), panel_graph_send_to_preview); - menu_send_to_window = menuItemAction(__txtx("panel_graph_preview_window", "Send to preview window"), panel_graph_preview_window); - menu_sent_to_inspector = menuItemAction(__txtx("panel_graph_inspector_panel", "Send to new inspector"), panel_graph_inspector_panel); - menu_send_export = menuItemAction(__txtx("panel_graph_send_to_export", "Send to export"), panel_graph_send_to_export); - menu_toggle_preview = menuItemAction(__txtx("panel_graph_toggle_preview", "Toggle node preview"), panel_graph_toggle_preview); - menu_toggle_render = menuItemAction(__txtx("panel_graph_toggle_render", "Toggle node render"), panel_graph_toggle_render); - menu_toggle_param = menuItemAction(__txtx("panel_graph_toggle_parameter", "Toggle node parameters"), panel_graph_toggle_parameter); - menu_open_group = menuItemAction(__txtx("panel_graph_enter_group", "Open group"), panel_graph_enter_group, THEME.group); - menu_hide_disconnect = menuItemAction(__txtx("panel_graph_hide_disconnected", "Hide stray junctions"), panel_graph_hide_disconnected); - - menu_open_group_tab = menuItemAction(__txtx("panel_graph_enter_group_new_tab", "Open group in new tab"), panel_graph_open_group_tab, THEME.group); - menu_group_group = menuItemAction(__txt("Group"), panel_graph_group, THEME.group); - menu_group_ungroup = menuItemAction(__txt("Ungroup"), panel_graph_ungroup, THEME.group); - menu_group_tool = menuItemAction(__txt("Set as group tool"), panel_graph_set_as_tool); - - menu_node_delete_cut = menuItemAction(__txtx("panel_graph_delete_and_cut_connection", "Delete and cut connection"), panel_graph_delete_break, THEME.cross); - menu_node_delete_merge = menuItemAction(__txtx("panel_graph_delete_and_merge_connection", "Delete and merge connection"), panel_graph_delete_merge, THEME.cross); - menu_node_duplicate = menuItemAction(__txt("Duplicate"), panel_graph_duplicate, THEME.duplicate); - menu_node_copy = menuItemAction(__txt("Copy"), panel_graph_copy, THEME.copy); - - menu_node_transform = menuItemAction(__txtx("panel_graph_add_transform", "Add transform"), panel_graph_add_transform); - menu_node_canvas = menuItemAction(__txtx("panel_graph_canvas", "Canvas"), - function(_dat) { - return submenuCall(_dat, [ - menuItemAction(__txtx("panel_graph_copy_to_canvas", "Copy to canvas"), panel_graph_canvas), - menuItemAction(__txtx("panel_graph_overlay_canvas", "Overlay canvas"), panel_graph_canvas_blend) - ]); - }).setIsShelf(); - - menu_nodes_align = menuItemGroup(__txtx("panel_graph_align_nodes", "Align"), [ - [ [THEME.inspector_surface_halign, 0], function() { node_halign(nodes_selecting, fa_left); } ], - [ [THEME.inspector_surface_halign, 1], function() { node_halign(nodes_selecting, fa_center); } ], - [ [THEME.inspector_surface_halign, 2], function() { node_halign(nodes_selecting, fa_right); } ], - - [ [THEME.inspector_surface_valign, 0], function() { node_valign(nodes_selecting, fa_top); } ], - [ [THEME.inspector_surface_valign, 1], function() { node_valign(nodes_selecting, fa_middle); } ], - [ [THEME.inspector_surface_valign, 2], function() { node_valign(nodes_selecting, fa_bottom); } ], - - [ [THEME.obj_distribute_h, 0], function() { node_hdistribute(nodes_selecting); } ], - [ [THEME.obj_distribute_v, 0], function() { node_vdistribute(nodes_selecting); } ], - ]); - menu_nodes_blend = menuItemAction(__txtx("panel_graph_blend_nodes", "Blend nodes"), panel_graph_blend); - menu_nodes_compose = menuItemAction(__txtx("panel_graph_compose_nodes", "Compose nodes"), panel_graph_compose); - menu_nodes_array = menuItemAction(__txtx("panel_graph_array_from_nodes", "Array from nodes"), panel_graph_array); - menu_nodes_group = menuItemAction(__txtx("panel_graph_group_nodes", "Group nodes"), panel_graph_group); - menu_nodes_frame = menuItemAction(__txtx("panel_graph_frame_nodes", "Frame nodes"), panel_graph_frame); - - menu_node_copy_prop = menuItemAction(__txtx("panel_graph_copy_prop", "Copy all properties"), panel_graph_doCopyProp); - menu_node_paste_prop = menuItemAction(__txtx("panel_graph_paste_prop", "Paste all properties"), panel_graph_doPasteProp); - - menu_connection_tunnel = menuItemAction(__txtx("panel_graph_tunnel", "Create tunnels"), panel_graph_createTunnel); - - // node color - function setSelectingNodeColor(color) { - __temp_color = color; - - if(node_hover) node_hover.attributes.color = __temp_color; - array_foreach(nodes_selecting, function(node) { node.attributes.color = __temp_color; }); - } - - var _clrs = COLORS.labels; - var _item = array_create(array_length(_clrs)); + function setCurrentCanvasBlend(_node = getFocusingNode()) { + if(!_node) return; + + var _outp = -1; + var surf = -1; + + for( var i = 0; i < array_length(_node.outputs); i++ ) { + if(_node.outputs[i].type == VALUE_TYPE.surface) { + _outp = _node.outputs[i]; + var _val = _node.outputs[i].getValue(); + if(is_array(_val)) + surf = _val[_node.preview_index]; + else + surf = _val; + break; + } + } + + if(_outp == -1) return; + + var _canvas = nodeBuild("Node_Canvas", _node.x, _node.y + _node.h + 64).skipDefault(); + + _canvas.inputs[0].setValue([surface_get_width_safe(surf), surface_get_height_safe(surf)]); + _canvas.inputs[5].setValue(true); + + var _blend = nodeBuild("Node_Blend", _node.x + _node.w + 64, _node.y).skipDefault(); + _blend.inputs[0].setFrom(_outp); + _blend.inputs[1].setFrom(_canvas.outputs[0]); + } + + function getFocusingNode() { return array_empty(nodes_selecting)? noone : nodes_selecting[0]; } + + //// =========== Menus =========== + + #region ++++++++++++ Actions ++++++++++++ + function send_to_preview() { setCurrentPreview(node_hover); } + + function inspector_panel() { + var pan = panelAdd("Panel_Inspector", true); + pan.destroy_on_click_out = false; + pan.content.setInspecting(node_hover); + pan.content.locked = true; + } + + function send_hover_to_export() { setCurrentExport(node_hover); } + function enter_group() { PANEL_GRAPH.addContext(node_hover); } + function hide_disconnected() { hideDisconnected(); } + + + function open_group_tab(group = node_hover) { + if(group == noone) return; + + var graph = new Panel_Graph(project); + panel.setContent(graph, true); + + for( var i = 0; i < array_length(node_context); i++ ) + graph.addContext(node_context[i]); + graph.addContext(group); + + setFocus(panel); + } + + function set_as_tool() { + if(node_hover == noone) return; + node_hover.setTool(!node_hover.isTool); + } + #endregion + + menu_sent_to_preview = MENU_ITEMS.graph_preview_hovering_node; + menu_send_to_window = MENU_ITEMS.graph_preview_window; + menu_sent_to_inspector = MENU_ITEMS.graph_inspect; + menu_send_export = MENU_ITEMS.graph_export_hover; + menu_toggle_preview = MENU_ITEMS.graph_toggle_preview; + menu_toggle_render = MENU_ITEMS.graph_toggle_render; + menu_toggle_param = MENU_ITEMS.graph_toggle_parameters; + menu_hide_disconnect = MENU_ITEMS.graph_hide_disconnected; + + menu_open_group = MENU_ITEMS.graph_enter_group; + menu_open_group_tab = MENU_ITEMS.graph_open_in_new_tab; + menu_group_group = MENU_ITEMS.graph_group; + menu_group_ungroup = MENU_ITEMS.graph_ungroup; + menu_group_tool = MENU_ITEMS.graph_set_as_tool; + + menu_node_delete_cut = MENU_ITEMS.graph_delete_break; + menu_node_delete_merge = MENU_ITEMS.graph_delete_merge; + menu_node_duplicate = MENU_ITEMS.graph_duplicate; + menu_node_copy = MENU_ITEMS.graph_copy; + + menu_nodes_align = menuItemGroup(__txtx("panel_graph_align_nodes", "Align"), [ + [ [THEME.inspector_surface_halign, 0], function() { node_halign(nodes_selecting, fa_left); } ], + [ [THEME.inspector_surface_halign, 1], function() { node_halign(nodes_selecting, fa_center); } ], + [ [THEME.inspector_surface_halign, 2], function() { node_halign(nodes_selecting, fa_right); } ], + + [ [THEME.inspector_surface_valign, 0], function() { node_valign(nodes_selecting, fa_top); } ], + [ [THEME.inspector_surface_valign, 1], function() { node_valign(nodes_selecting, fa_middle); } ], + [ [THEME.inspector_surface_valign, 2], function() { node_valign(nodes_selecting, fa_bottom); } ], + + [ [THEME.obj_distribute_h, 0], function() { node_hdistribute(nodes_selecting); } ], + [ [THEME.obj_distribute_v, 0], function() { node_vdistribute(nodes_selecting); } ], + ]); + + menu_node_transform = MENU_ITEMS.graph_transform_node; + menu_nodes_blend = MENU_ITEMS.graph_blend; + menu_nodes_compose = MENU_ITEMS.graph_compose; + menu_nodes_array = MENU_ITEMS.graph_array; + menu_nodes_group = MENU_ITEMS.graph_group; + menu_nodes_frame = MENU_ITEMS.graph_frame; + menu_node_canvas = MENU_ITEMS.graph_canvas; + + menu_node_copy_prop = MENU_ITEMS.graph_copy_value; + menu_node_paste_prop = MENU_ITEMS.graph_paste_value; + + menu_connection_tunnel = MENU_ITEMS.graph_create_tunnel; + + // node color + function setSelectingNodeColor(color) { + __temp_color = color; + + if(node_hover) node_hover.attributes.color = __temp_color; + array_foreach(nodes_selecting, function(node) { node.attributes.color = __temp_color; }); + } + + var _clrs = COLORS.labels; + var _item = array_create(array_length(_clrs)); - for( var i = 0, n = array_length(_clrs); i < n; i++ ) { - _item[i] = [ - [ THEME.timeline_color, i > 0, _clrs[i] ], - function(_data) { - setSelectingNodeColor(_data.color); - }, "", { color: i == 0? -1 : _clrs[i] } - ]; - } + for( var i = 0, n = array_length(_clrs); i < n; i++ ) { + _item[i] = [ + [ THEME.timeline_color, i > 0, _clrs[i] ], + function(_data) { + setSelectingNodeColor(_data.color); + }, "", { color: i == 0? -1 : _clrs[i] } + ]; + } - array_push(_item, [ - [ THEME.timeline_color, 2 ], - function(_data) { - colorSelectorCall(node_hover? node_hover.attributes.color : c_white, setSelectingNodeColor); - } - ]); + array_push(_item, [ + [ THEME.timeline_color, 2 ], + function(_data) { + colorSelectorCall(node_hover? node_hover.attributes.color : c_white, setSelectingNodeColor); + } + ]); - menu_node_color = menuItemGroup(__txt("Node Color"), _item); - menu_node_color.spacing = ui(24); - - - // junction color - __junction_hovering = noone; - - function setSelectingJuncColor(color) { - if(__junction_hovering == noone) return; - __junction_hovering.setColor(color); - - for(var i = 0; i < array_length(nodes_selecting); i++) { - var _node = nodes_selecting[i]; - - for( var j = 0, m = array_length(_node.inputs); j < m; j++ ) { - var _input = _node.inputs[j]; - if(_input.value_from == noone) continue; - _input.setColor(color); - } - } - } - - var _clrs = COLORS.labels; - var _item = array_create(array_length(_clrs)); + menu_node_color = menuItemGroup(__txt("Node Color"), _item); + menu_node_color.spacing = ui(24); + + + // junction color + __junction_hovering = noone; + + function setSelectingJuncColor(color) { + if(__junction_hovering == noone) return; + __junction_hovering.setColor(color); + + for(var i = 0; i < array_length(nodes_selecting); i++) { + var _node = nodes_selecting[i]; + + for( var j = 0, m = array_length(_node.inputs); j < m; j++ ) { + var _input = _node.inputs[j]; + if(_input.value_from == noone) continue; + _input.setColor(color); + } + } + } + + var _clrs = COLORS.labels; + var _item = array_create(array_length(_clrs)); - for( var i = 0, n = array_length(_clrs); i < n; i++ ) { - _item[i] = [ - [ THEME.timeline_color, i > 0, _clrs[i] ], - function(_data) { - setSelectingJuncColor(_data.color); - }, "", { color: i == 0? -1 : _clrs[i] } - ]; - } + for( var i = 0, n = array_length(_clrs); i < n; i++ ) { + _item[i] = [ + [ THEME.timeline_color, i > 0, _clrs[i] ], + function(_data) { + setSelectingJuncColor(_data.color); + }, "", { color: i == 0? -1 : _clrs[i] } + ]; + } - array_push(_item, [ - [ THEME.timeline_color, 2 ], - function(_data) { - colorSelectorCall(__junction_hovering? __junction_hovering.color : c_white, setSelectingJuncColor); - } - ]); + array_push(_item, [ + [ THEME.timeline_color, 2 ], + function(_data) { + colorSelectorCall(__junction_hovering? __junction_hovering.color : c_white, setSelectingJuncColor); + } + ]); - menu_junc_color = menuItemGroup(__txt("Connection Color"), _item); - menu_junc_color.spacing = ui(24); - - - //// ============ Project ============ - - static setProject = function(project) { - self.project = project; - nodes_list = project.nodes; - - setTitle(); - run_in(2, function() /*=>*/ { - setSlideShow(0); - struct_override(display_parameter, project.graph_display_parameter); - }); - } - - //// ============ Views ============ - - function onFocusBegin() { // - PANEL_GRAPH = self; - PROJECT = project; - - nodes_select_drag = 0; - } - - function focusNode(_node) { // - if(_node == noone) { - nodes_selecting = []; - return; - } - - nodes_selecting = [ _node ]; - fullView(); - } - - function fullView() { - INLINE - toCenterNode(array_empty(nodes_selecting)? nodes_list : nodes_selecting); - } - - function dragGraph() { - if(graph_autopan) { - graph_x = lerp_float(graph_x, graph_pan_x_to, 32, 1); - graph_y = lerp_float(graph_y, graph_pan_y_to, 32, 1); - - if(graph_x == graph_pan_x_to && graph_y == graph_pan_y_to) - graph_autopan = false; - return; - } - - if(graph_dragging) { - if(!MOUSE_WRAPPING) { - var dx = mx - graph_drag_mx; - var dy = my - graph_drag_my; - - graph_x += dx / graph_s; - graph_y += dy / graph_s; - } - - graph_drag_mx = mx; - graph_drag_my = my; - setMouseWrap(); - - if(mouse_release(drag_key)) { - graph_dragging = false; - view_pan_tool = false; - } - } - - if(graph_zooming) { - if(!MOUSE_WRAPPING) { - var dy = -(my - graph_zoom_m) / 200; - - var _s = graph_s; - - graph_s_to = clamp(graph_s_to * (1 + dy), scale[0], scale[array_length(scale) - 1]); - graph_s = graph_s_to; - - if(_s != graph_s) { - var mb_x = (graph_zoom_mx - graph_x * _s) / _s; - var ma_x = (graph_zoom_mx - graph_x * graph_s) / graph_s; - var md_x = ma_x - mb_x; - graph_x += md_x; - - var mb_y = (graph_zoom_my - graph_y * _s) / _s; - var ma_y = (graph_zoom_my - graph_y * graph_s) / graph_s; - var md_y = ma_y - mb_y; - graph_y += md_y; - } - } - - graph_zoom_m = my; - setMouseWrap(); - - if(mouse_release(drag_key)) { - graph_zooming = false; - view_zoom_tool = false; - } - } - - if(mouse_on_graph && pFOCUS && graph_draggable) { - var _doDragging = false; - var _doZooming = false; - - if(mouse_press(PREFERENCES.pan_mouse_key)) { - _doDragging = true; - drag_key = PREFERENCES.pan_mouse_key; - - } else if(mouse_press(mb_left) && graph_dragging_key) { - _doDragging = true; - drag_key = mb_left; - - } else if(mouse_press(mb_left) && graph_zooming_key) { - _doZooming = true; - drag_key = mb_left; - } - - if(_doDragging) { - graph_dragging = true; - graph_drag_mx = mx; - graph_drag_my = my; - graph_drag_sx = graph_x; - graph_drag_sy = graph_y; - } - - if(_doZooming) { - graph_zooming = true; - graph_zoom_mx = mx; - graph_zoom_my = my; - graph_zoom_m = my; - graph_zoom_s = graph_s; - } - } - - if(mouse_on_graph && pHOVER && graph_draggable) { - var _s = graph_s; - if(mouse_wheel_down() && !key_mod_press_any()) { //zoom out - for( var i = 1, n = array_length(scale); i < n; i++ ) { - if(scale[i - 1] < graph_s_to && graph_s_to <= scale[i]) { - graph_s_to = scale[i - 1]; - break; - } - } - } - if(mouse_wheel_up() && !key_mod_press_any()) { // zoom in - for( var i = 1, n = array_length(scale); i < n; i++ ) { - if(scale[i - 1] <= graph_s_to && graph_s_to < scale[i]) { - graph_s_to = scale[i]; - break; - } - } - } - - graph_s = lerp_float(graph_s, graph_s_to, PREFERENCES.graph_zoom_smoooth); - - if(_s != graph_s) { - var mb_x = (mx - graph_x * _s) / _s; - var ma_x = (mx - graph_x * graph_s) / graph_s; - var md_x = ma_x - mb_x; - graph_x += md_x; - - var mb_y = (my - graph_y * _s) / _s; - var ma_y = (my - graph_y * graph_s) / graph_s; - var md_y = ma_y - mb_y; - graph_y += md_y; - } - } - - graph_draggable = true; - graph_x = round(graph_x); - graph_y = round(graph_y); - } - - function autoPanTo(_x, _y) { - graph_autopan = true; - graph_pan_x_to = _x; - graph_pan_y_to = _y; - } - - function setSlideShow(index, skip = false) { - var _targ = project.slideShowSet(index); - if(_targ == noone) return; - - setContext(_targ); - - var _gx = w / 2 / graph_s; - var _gy = h / 2 / graph_s; - - var _tx = _gx; - var _ty = _gy; - - switch(_targ.slide_anchor) { - case 0 : - _tx = _gx - _targ.x; - _ty = _gy - _targ.y; - break; - - case 1 : - _tx = 64 * graph_s - _targ.x; - _ty = 64 * graph_s - _targ.y; - break; - - } - - if(skip) { - graph_x = _tx; - graph_y = _ty; - - } else - autoPanTo(_tx, _ty, skip); - } - - //// =========== Context ========== - - - function getCurrentContext() { return array_empty(node_context)? noone : node_context[array_length(node_context) - 1]; } - - function getNodeList(cont = getCurrentContext()) { return cont == noone? project.nodes : cont.getNodeList(); } - - function setContext(context) { - if(context.group == getCurrentContext()) return; - - node_context = []; - nodes_list = project.nodes; - - var _ctxs = []; - var _ctx = context; - - while(_ctx.group != noone) { - array_insert(_ctxs, 0, _ctx.group); - _ctx = _ctx.group; - } - - for (var i = 0, n = array_length(_ctxs); i < n; i++) - addContext(_ctxs[i]); - } - - function resetContext() { - node_context = []; - nodes_list = project.nodes; - toCenterNode(); - } - - function addContext(node) { - var _node = node.getNodeBase(); - - nodes_list = _node.nodes; - array_push(node_context, _node); - - node_dragging = noone; - nodes_selecting = []; - selection_block = 1; - - setContextFrame(false, _node); - toCenterNode(); - } - - function setContextFrame(dirr, node) { - context_framing = true; - - context_frame_direct = dirr; - context_frame_progress = 0; - - context_frame_sx = w / 2 - 8; - context_frame_sy = h / 2 - 8; - context_frame_ex = context_frame_sx + 16; - context_frame_ey = context_frame_sy + 16; - - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - - context_frame_sx = gr_x + node.x * graph_s; - context_frame_sy = gr_y + node.y * graph_s; - context_frame_ex = context_frame_sx + node.w * graph_s; - context_frame_ey = context_frame_sy + node.h * graph_s; - } - - //// ============ Step ============ - - function stepBegin() { // - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - var m_x = (mx - gr_x) / graph_s; - var m_y = (my - gr_y) / graph_s; - mouse_graph_x = m_x; - mouse_graph_y = m_y; - - mouse_grid_x = round(m_x / project.graphGrid.size) * project.graphGrid.size; - mouse_grid_y = round(m_y / project.graphGrid.size) * project.graphGrid.size; - - setTitle(); - } - - //// ============ Draw ============ - - function drawGrid() { // - if(!display_parameter.show_grid) return; - var gls = project.graphGrid.size; - while(gls * graph_s < 8) gls *= 5; - - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - var gr_ls = gls * graph_s; - var xx = -gr_ls, xs = safe_mod(gr_x, gr_ls); - var yy = -gr_ls, ys = safe_mod(gr_y, gr_ls); - - draw_set_color(project.graphGrid.color); - var aa = 0.5; - if(graph_s < 0.25) - aa = 0.3; - var oa = project.graphGrid.opacity; - var ori = project.graphGrid.show_origin; - var hig = project.graphGrid.highlight; - - while(xx < w + gr_ls) { - draw_set_alpha( oa * aa * (1 + (round((xx + xs - gr_x) / gr_ls) % hig == 0) * 2) ); - draw_line(xx + xs, 0, xx + xs, h); - - if(ori && xx + xs - gr_x == 0) draw_line_width(xx + xs, 0, xx + xs, h, 3); - xx += gr_ls; - } - - while(yy < h + gr_ls) { - draw_set_alpha( oa * aa * (1 + (round((yy + ys - gr_y) / gr_ls) % hig == 0) * 2) ); - draw_line(0, yy + ys, w, yy + ys); - - if(ori && yy + ys - gr_y == 0) draw_line_width(0, yy + ys, w, yy + ys, 3); - yy += gr_ls; - } - draw_set_alpha(1); - } - - function drawViewControl() { // - if(h < ui(96)) return; - - view_hovering = false; - if(!show_view_control) return; - - var _side = show_view_control == 1? 1 : -1; - var _hab = pHOVER && !view_pan_tool && !view_zoom_tool; - - var d3_view_wz = ui(16); - - var _d3x = show_view_control == 1? - ui(8) + d3_view_wz : - w - ui(8) - d3_view_wz; - - var _d3y = ui(8) + d3_view_wz; - var _hv = false; - - if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { - _hv = true; - view_hovering = true; - - if(mouse_press(mb_left, pFOCUS)) { - drag_key = mb_left; - graph_dragging = true; - graph_drag_mx = mx; - graph_drag_my = my; - graph_drag_sx = graph_x; - graph_drag_sy = graph_y; - - view_pan_tool = true; - } - } - - if(view_pan_tool) - _hv = true; - - draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); - draw_sprite_ui(THEME.view_pan, 0, _d3x, _d3y, 1, 1, 0, view_pan_tool? COLORS._main_accent : COLORS._main_icon, 1); - - _d3x += (d3_view_wz + ui(4) + d3_view_wz) * _side; - _hv = false; - - if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { - _hv = true; - view_hovering = true; - - if(mouse_press(mb_left, pFOCUS)) { - drag_key = mb_left; - graph_zooming = true; - graph_zoom_mx = w / 2; - graph_zoom_my = h / 2; - graph_zoom_m = my; - graph_zoom_s = graph_s; - - view_zoom_tool = true; - } - } - - if(view_zoom_tool) - _hv = true; - - draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); - draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1); - - } - - function drawBasePreview() { // - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - var _hov = false; - - for(var i = 0; i < array_length(nodes_list); i++) { - var h = nodes_list[i].drawPreviewBackground(gr_x, gr_y, mx, my, graph_s); - _hov |= h; - } - - return _hov; - } - - function drawNodes() { // - if(selection_block-- > 0) return; - var _focus = pFOCUS && !view_hovering; - - display_parameter.highlight = - !array_empty(nodes_selecting) && ( - (PREFERENCES.connection_line_highlight == 1 && key_mod_press(ALT)) || - PREFERENCES.connection_line_highlight == 2 - ); - - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - - var log = false; - var t = get_timer(); - printIf(log, "============ Draw start ============"); - - _frame_hovering = frame_hovering; - frame_hovering = noone; - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - if(!display_parameter.show_control && _node.is_controller) continue; - - _node.cullCheck(gr_x, gr_y, graph_s, -32, -32, w + 32, h + 64); - _node.preDraw(gr_x, gr_y, graph_s, gr_x, gr_y); - } - printIf(log, $"Predraw time: {get_timer() - t}"); t = get_timer(); - - // draw frame - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - if(!display_parameter.show_control && _node.is_controller) continue; - - if(_node.drawNodeBG(gr_x, gr_y, mx, my, graph_s, display_parameter, self)) - frame_hovering = _node; - } - - printIf(log, $"Frame draw time: {get_timer() - t}"); t = get_timer(); - - // hover - node_hovering = noone; - if(pHOVER) - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - if(!display_parameter.show_control && _node.is_controller) continue; - - _node.branch_drawing = false; - - if(_node.pointIn(gr_x, gr_y, mx, my, graph_s)) - node_hovering = _node; - } - - if(node_hovering != noone) - _HOVERING_ELEMENT = node_hovering; - - if(DOUBLE_CLICK) { - // print($"Double click {node_hovering} || {_focus} || {instanceof(node_hovering)}"); - - if(node_hovering != noone && _focus && node_hovering.onDoubleClick != -1) - if(node_hovering.onDoubleClick(self)) { - DOUBLE_CLICK = false; - node_hovering = noone; - } - } - - if(node_hovering) node_hovering.onDrawHover(gr_x, gr_y, mx, my, graph_s); - - printIf(log, $"Hover time: {get_timer() - t}"); t = get_timer(); - - // ++++++++++++ interaction ++++++++++++ - if(mouse_on_graph && pHOVER) { - - // select - var _anc = nodes_select_anchor; - if(mouse_press(mb_left, _focus)) _anc = noone; - - 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, _focus)) { - if(key_mod_press(SHIFT)) { - if(node_hovering) { - if(array_exists(nodes_selecting, node_hovering)) - array_remove(nodes_selecting, node_hovering); - else - array_push(nodes_selecting, node_hovering); - } else - nodes_selecting = []; - - } else if(value_focus || node_hovering == noone) { - nodes_selecting = []; - - if(DOUBLE_CLICK && !PANEL_INSPECTOR.locked) - PANEL_INSPECTOR.inspecting = noone; - - } else { - if(is_instanceof(node_hovering, Node_Frame)) { - var fx0 = (node_hovering.x + graph_x) * graph_s; - var fy0 = (node_hovering.y + graph_y) * graph_s; - var fx1 = fx0 + node_hovering.w * graph_s; - var fy1 = fy0 + node_hovering.h * graph_s; - - nodes_selecting = [ node_hovering ]; - - if(!key_mod_press(CTRL)) - for(var i = 0; i < array_length(nodes_list); i++) { //select content - var _node = nodes_list[i]; - if(_node == node_hovering) continue; - if(!display_parameter.show_control && _node.is_controller) continue; - - if(!_node.selectable) 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(_w && _h && rectangle_inside_rectangle(fx0, fy0, fx1, fy1, _x, _y, _x + _w, _y + _h)) - array_push_unique(nodes_selecting, _node); - } - - } else if(DOUBLE_CLICK) { - PANEL_PREVIEW.setNodePreview(node_hovering); - - if(PREFERENCES.inspector_focus_on_double_click) { - if(PANEL_INSPECTOR.panel && struct_has(PANEL_INSPECTOR.panel, "switchContent")) - PANEL_INSPECTOR.panel.switchContent(PANEL_INSPECTOR); - } - - } else { - var hover_selected = false; - for( var i = 0; i < array_length(nodes_selecting); i++ ) { - if(nodes_selecting[i] != node_hovering) continue; - - hover_selected = true; - break; - } - - if(!hover_selected) - nodes_selecting = [ node_hovering ]; - - if(array_length(nodes_selecting) > 1) - _anc = nodes_select_anchor == node_hovering? noone : node_hovering; - } - - if(WIDGET_CURRENT) WIDGET_CURRENT.deactivate(); - array_foreach(nodes_selecting, function(node) { bringNodeToFront(node); }); - } - } - - nodes_select_anchor = _anc; - - - if(mouse_press(mb_right, _focus)) { // - node_hover = node_hovering; - - if(value_focus) { - // print($"Right click value focus {value_focus}"); - - __junction_hovering = value_focus; - - var menu = [ menu_junc_color ]; - - if(value_focus.connect_type == JUNCTION_CONNECT.output) { - var sep = false; - - for( var i = 0, n = array_length(value_focus.value_to); i < n; i++ ) { - if(!sep) { array_push(menu, -1); sep = true; } - - var _to = value_focus.value_to[i]; - var _lb = $"[{_to.node.display_name}] {_to.getName()}"; - array_push(menu, menuItemAction(_lb, function(data) /*=>*/ { data.params.juncTo.removeFrom(); }, THEME.cross, noone, noone, { juncTo: _to })); - } - - for( var i = 0, n = array_length(value_focus.value_to_loop); i < n; i++ ) { - if(!sep) { array_push(menu, -1); sep = true; } - - var _to = value_focus.value_to_loop[i]; - var _lb = $"[{_to.junc_in.node.display_name}] {_to.junc_in.getName()}"; - array_push(menu, menuItemAction(_lb, function(data) /*=>*/ { data.params.juncTo.destroy(); }, _to.icon_24, noone, noone, { juncTo: _to })); - } - } else { - var sep = false; - - if(value_focus.value_from) { - if(!sep) { array_push(menu, -1); sep = true; } - - var _jun = value_focus.value_from; - var _lb = $"[{_jun.node.display_name}] {_jun.getName()}"; - array_push(menu, menuItemAction(_lb, function(data) /*=>*/ { __junction_hovering.removeFrom(); }, THEME.cross)); - } - - if(value_focus.value_from_loop) { - if(!sep) { array_push(menu, -1); sep = true; } - - var _jun = value_focus.value_from_loop.junc_out; - var _lb = $"[{_jun.node.display_name}] {_jun.getName()}"; - array_push(menu, menuItemAction(_lb, function(data) /*=>*/ { __junction_hovering.removeFromLoop(); }, value_focus.value_from_loop.icon_24)); - } - } - - menuCall("graph_node_selected_menu",,, menu); - - } else if(node_hover && node_hover.draggable) { - // print($"Right click node hover {node_hover}"); - - var menu = []; - array_push(menu, menu_node_color, -1, menu_sent_to_preview, menu_send_to_window, menu_sent_to_inspector); - if(!DEMO) - array_push(menu, menu_send_export); - array_push(menu, -1, menu_toggle_preview, menu_toggle_render, menu_toggle_param, menu_hide_disconnect); - - if(is_instanceof(node_hover, Node_Collection)) - array_push(menu, -1, menu_open_group, menu_open_group_tab, menu_group_ungroup); - - if(node_hover.group != noone) - array_push(menu, menu_group_tool); - if(array_length(nodes_selecting) >= 2) - array_push(menu, -1, menu_nodes_group, menu_nodes_frame); - - array_push(menu, -1, menu_node_delete_merge, menu_node_delete_cut, menu_node_duplicate, menu_node_copy); - if(array_empty(nodes_selecting)) array_push(menu, menu_node_copy_prop, menu_node_paste_prop); - - array_push(menu, -1, menu_node_transform, menu_node_canvas); - - if(array_length(nodes_selecting) >= 2) - array_push(menu, -1, menu_nodes_align, menu_nodes_blend, menu_nodes_compose, menu_nodes_array); - - menuCall("graph_node_selected_multiple_menu",,, menu ); - - } else if(node_hover == noone) { - // print($"Right click not node hover"); - - var menu = []; - - __junction_hovering = junction_hovering; - if(junction_hovering != noone) - array_push(menu, menu_junc_color, menu_connection_tunnel, -1); - - array_push(menu, menuItemAction(__txt("Copy"), panel_graph_copy, THEME.copy).setActive(array_length(nodes_selecting))); - array_push(menu, menuItemAction(__txt("Paste"), panel_graph_paste, THEME.paste).setActive(clipboard_get_text() != "")); - - if(junction_hovering != noone) { - array_push(menu, -1); - - if(is_instanceof(junction_hovering, Node_Feedback_Inline)) { - var _jun = junction_hovering.junc_out; - array_push(menu, menuItemAction($"[{_jun.node.display_name}] {_jun.getName()}", function(data) /*=>*/ { __junction_hovering.destroy(); }, THEME.feedback)); - - } else { - var _jun = junction_hovering.value_from; - array_push(menu, menuItemAction($"[{_jun.node.display_name}] {_jun.getName()}", function(data) /*=>*/ { __junction_hovering.removeFrom(); }, THEME.cross)); - } - } - - var ctx = is_instanceof(frame_hovering, Node_Collection_Inline)? frame_hovering : getCurrentContext(); - var _diaAdd = callAddDialog(ctx); - - var _dia = menuCall("graph_node_selected_menu", o_dialog_add_node.dialog_x - ui(8), o_dialog_add_node.dialog_y + ui(4), menu, fa_right ); - _dia.passthrough = true; - setFocus(_diaAdd, "Dialog"); - } - } - - if(is_instanceof(frame_hovering, Node_Collection_Inline) && DOUBLE_CLICK && array_empty(nodes_selecting)) { // - nodes_selecting = [ frame_hovering ]; - - if(frame_hovering.onDoubleClick != -1) frame_hovering.onDoubleClick(self) - if(frame_hovering.previewable) PANEL_PREVIEW.setNodePreview(frame_hovering); - } - } - - printIf(log, $"Node selection time: {get_timer() - t}"); t = get_timer(); - - // draw active - for(var i = 0; i < array_length(nodes_selecting); i++) { - var _node = nodes_selecting[i]; - if(!_node) continue; - _node.drawActive(gr_x, gr_y, graph_s); - } - - if(nodes_select_anchor) nodes_select_anchor.active_draw_anchor = true; - - printIf(log, $"Draw active: {get_timer() - t}"); t = get_timer(); - - // draw connections - var aa = floor(min(8192 / w, 8192 / h, PREFERENCES.connection_line_aa)); - - connection_surface = surface_verify(connection_surface, w * aa, h * aa); - connection_surface_aa = surface_verify(connection_surface_aa, w, h); - surface_set_target(connection_surface); - DRAW_CLEAR - - var hov = noone; - var hoverable = !bool(node_dragging) && pHOVER; - var param = connection_param; - - param.active = hoverable; - param.setPos(gr_x, gr_y, graph_s, mx, my); - param.setBoundary(-64, -64, w + 64, h + 64); - param.setProp(array_length(nodes_list), display_parameter.highlight); - param.setDraw(aa, bg_color); - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - if(!display_parameter.show_control && _node.is_controller) continue; - - param.cur_layer = i + 1; - - var _hov = _node.drawConnections(param); - if(_hov != noone && is_struct(_hov)) hov = _hov; - } - - if(value_dragging && connection_draw_mouse != noone && !key_mod_press(SHIFT)) { - var _cmx = connection_draw_mouse[0]; - var _cmy = connection_draw_mouse[1]; - var _cmt = connection_draw_target; - - if(array_empty(value_draggings)) - value_dragging.drawConnectionMouse(param, _cmx, _cmy, _cmt); - else { - var _stIndex = array_find(value_draggings, value_dragging); - - for( var i = 0, n = array_length(value_draggings); i < n; i++ ) { - var _dmx = _cmx; - var _dmy = value_draggings[i].connect_type == JUNCTION_CONNECT.output? _cmy + (i - _stIndex) * 24 * graph_s : _cmy; - - value_draggings[i].drawConnectionMouse(param, _dmx, _dmy, _cmt); - } - } - } - - surface_reset_target(); - - gpu_set_texfilter(true); - surface_set_shader(connection_surface_aa, sh_downsample); - shader_set_f("down", aa); - shader_set_dim("dimension", connection_surface); - draw_surface_safe(connection_surface); - surface_reset_shader(); - gpu_set_texfilter(false); - - BLEND_ALPHA_MULP - draw_surface_safe(connection_surface_aa); - BLEND_NORMAL - - junction_hovering = node_hovering == noone? hov : noone; - - printIf(log, $"Draw connection: {get_timer() - t}"); t = get_timer(); - - // draw node - _value_focus = value_focus; - value_focus = noone; - - var t = get_timer(); - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - if(!display_parameter.show_control && _node.is_controller) continue; - nodes_list[i].drawNodeBehind(gr_x, gr_y, mx, my, graph_s); - } - - for( var i = 0, n = array_length(value_draggings); i < n; i++ ) - value_draggings[i].graph_selecting = true; - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - if(!display_parameter.show_control && _node.is_controller) continue; - if(is_instanceof(_node, Node_Frame)) continue; - try { - var val = _node.drawNode(gr_x, gr_y, mx, my, graph_s, display_parameter, self); - if(val) { - value_focus = val; - if(key_mod_press(SHIFT)) TOOLTIP = [ val.getValue(), val.type ]; - } - } catch(e) { - log_warning("NODE DRAW", exception_print(e)); - } - } - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - if(!display_parameter.show_control && _node.is_controller) continue; - if(!is_instanceof(nodes_list[i], Node_Frame)) - nodes_list[i].drawBadge(gr_x, gr_y, graph_s); - } - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - if(!display_parameter.show_control && _node.is_controller) continue; - nodes_list[i].drawNodeFG(gr_x, gr_y, mx, my, graph_s, display_parameter, self); - } - - if(PANEL_INSPECTOR && PANEL_INSPECTOR.prop_hover != noone) - value_focus = PANEL_INSPECTOR.prop_hover; - - printIf(log, $"Draw node: {get_timer() - t}"); t = get_timer(); - - // dragging - if(mouse_press(mb_left)) - node_dragging = noone; - - for(var i = 0; i < array_length(nodes_list); i++) - nodes_list[i].groupCheck(gr_x, gr_y, graph_s, mx, my); - - if(node_dragging && !key_mod_press(ALT)) { - var nx = node_drag_sx + (mouse_graph_x - node_drag_mx); - var ny = node_drag_sy + (mouse_graph_y - node_drag_my); - - if(!key_mod_press(CTRL) && project.graphGrid.snap) { - nx = round(nx / project.graphGrid.size) * project.graphGrid.size; - ny = round(ny / project.graphGrid.size) * project.graphGrid.size; - } - - if(node_drag_ox == -1 || node_drag_oy == -1) { - node_drag_ox = nx; - node_drag_oy = ny; - } else if(nx != node_drag_ox || ny != node_drag_oy) { - var dx = nx - node_drag_ox; - var dy = ny - node_drag_oy; - - for(var i = 0; i < array_length(nodes_selecting); i++) { - var _node = nodes_selecting[i]; - var _nx = _node.x + dx; - var _ny = _node.y + dy; - - if(!key_mod_press(CTRL) && project.graphGrid.snap) { - _nx = round(_nx / project.graphGrid.size) * project.graphGrid.size; - _ny = round(_ny / project.graphGrid.size) * project.graphGrid.size; - } - - _node.move(_nx, _ny, graph_s); - } - - node_drag_ox = nx; - node_drag_oy = ny; - } - - if(mouse_release(mb_left) && (nx != node_drag_sx || ny != node_drag_sy)) { - var shfx = node_drag_sx - nx; - var shfy = node_drag_sy - ny; - - UNDO_HOLDING = false; - for(var i = 0; i < array_length(nodes_selecting); i++) { - var _n = nodes_selecting[i]; - if(_n == noone) continue; - recordAction(ACTION_TYPE.var_modify, _n, [ _n.x + shfx, "x", "node x position" ]); - recordAction(ACTION_TYPE.var_modify, _n, [ _n.y + shfy, "y", "node y position" ]); - } - } - } - - if(mouse_release(mb_left)) - node_dragging = noone; - - printIf(log, $"Drag node time : {get_timer() - t}"); t = get_timer(); - - if(mouse_on_graph && _focus) { // - var _node = getFocusingNode(); - if(_node && _node.draggable && value_focus == noone) { - if(mouse_press(mb_left) && !key_mod_press(ALT)) { - node_dragging = _node; - node_drag_mx = mouse_graph_x; - node_drag_my = mouse_graph_y; - node_drag_sx = _node.x; - node_drag_sy = _node.y; - - node_drag_ox = -1; - node_drag_oy = -1; - } - } - - if(DOUBLE_CLICK && junction_hovering != noone) { - var _mx = round(mouse_graph_x / project.graphGrid.size) * project.graphGrid.size; - var _my = round(mouse_graph_y / project.graphGrid.size) * project.graphGrid.size; - - var _pin = nodeBuild("Node_Pin", _mx, _my).skipDefault(); - _pin.inputs[0].setFrom(junction_hovering.value_from); - junction_hovering.setFrom(_pin.outputs[0]); - } - } - - // draw selection frame - if(nodes_select_drag) { - if(point_distance(nodes_select_mx, nodes_select_my, mx, my) > 16) - nodes_select_drag = 2; - - if(nodes_select_drag == 2) { - draw_sprite_stretched_points_clamp(THEME.ui_selection, 0, nodes_select_mx, nodes_select_my, mx, my, COLORS._main_accent); - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - if(!display_parameter.show_control && _node.is_controller) continue; - if(!_node.selectable) continue; - if(is_instanceof(_node, Node_Frame) && !nodes_select_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; - - var _sel = _w && _h && rectangle_in_rectangle(_x, _y, _x + _w, _y + _h, nodes_select_mx, nodes_select_my, mx, my); - - if(!array_exists(nodes_selecting, _node) && _sel) - array_push(nodes_selecting, _node); - if(array_exists(nodes_selecting, _node) && !_sel) - array_remove(nodes_selecting, _node); - } - } - - if(mouse_release(mb_left)) - nodes_select_drag = 0; - } - - if(nodes_junction_d != noone) { - var shx = nodes_junction_dx + (mx - nodes_select_mx) / graph_s; - var shy = nodes_junction_dy + (my - nodes_select_my) / graph_s; - - shx = value_snap(shx, key_mod_press(CTRL)? 1 : 4); - shy = value_snap(shy, key_mod_press(CTRL)? 1 : 4); - - nodes_junction_d.draw_line_shift_x = shx; - nodes_junction_d.draw_line_shift_y = shy; - - if(mouse_release(mb_left)) - nodes_junction_d = noone; - } - - if(mouse_on_graph && !node_bg_hovering && mouse_press(mb_left, _focus) && !graph_dragging_key && !graph_zooming_key) { - if(is_instanceof(junction_hovering, NodeValue) && junction_hovering.draw_line_shift_hover) { - nodes_select_mx = mx; - nodes_select_my = my; - nodes_junction_d = junction_hovering; - nodes_junction_dx = junction_hovering.draw_line_shift_x; - nodes_junction_dy = junction_hovering.draw_line_shift_y; - - } else if(array_empty(nodes_selecting) && !value_focus && !drag_locking) { - nodes_select_drag = 1; - nodes_select_frame = frame_hovering == noone; - - nodes_select_mx = mx; - nodes_select_my = my; - } - drag_locking = false; - } - - - printIf(log, $"Draw selection frame : {get_timer() - t}"); t = get_timer(); - } - - function connectDraggingValueTo(target) { - var _connect = [ 0, noone, noone ]; - - if(is_instanceof(PANEL_INSPECTOR, Panel_Inspector) && PANEL_INSPECTOR.attribute_hovering != noone) { - PANEL_INSPECTOR.attribute_hovering(value_dragging); - - } else if(target != noone && target != value_dragging) { - - if(target.connect_type == value_dragging.connect_type) { - - if(value_dragging.connect_type == JUNCTION_CONNECT.input) { - if(target.value_from) { - value_dragging.setFrom(target.value_from); - target.removeFrom(); - } - - } else if(value_dragging.connect_type == JUNCTION_CONNECT.output) { - var _tos = target.getJunctionTo(); - - for (var i = 0, n = array_length(_tos); i < n; i++) - _tos[i].setFrom(value_dragging); - } - - } else { - var _addInput = target.value_from == noone && target.connect_type == JUNCTION_CONNECT.input && target.node.auto_input; - - if(value_dragging.connect_type == JUNCTION_CONNECT.input) { - if(array_empty(value_draggings)) - _connect = [ value_dragging.setFrom(target), value_dragging, target ]; - - else { - for( var i = 0, n = array_length(value_draggings); i < n; i++ ) - value_draggings[i].setFrom(target); - } - - } else if(_addInput && !array_empty(value_draggings)) { - for( var i = 0, n = array_length(value_draggings); i < n; i++ ) - target.node.addInput(value_draggings[i]); - - } else { - if(value_drag_from && target.value_from && value_drag_from.node == target.node) - value_drag_from.setFrom(target.value_from); - - if(array_empty(value_draggings)) - _connect = [ target.setFrom(value_dragging), target, value_dragging ]; - - else { - var _node = target.node; - var _indx = target.index; - - for( var i = 0, n = array_length(value_draggings); i < n; i++ ) { - _node.inputs[_indx].setFrom(value_draggings[i]); - if(++_indx > array_length(_node.inputs)) break; - } - } - - } - } - - } else { - if(value_dragging.connect_type == JUNCTION_CONNECT.input) - value_dragging.removeFrom(); - value_dragging.node.triggerRender(); - - if(value_focus != value_dragging) { - var ctx = is_instanceof(frame_hovering, Node_Collection_Inline)? frame_hovering : getCurrentContext(); - if(value_dragging.node.inline_context && !key_mod_press(SHIFT)) - ctx = value_dragging.node.inline_context; - - with(dialogCall(o_dialog_add_node, mouse_mx + 8, mouse_my + 8, { context: ctx })) { - node_target_x = other.mouse_grid_x; - node_target_y = other.mouse_grid_y; - node_target_x_raw = other.mouse_grid_x; - node_target_y_raw = other.mouse_grid_y; - node_called = other.value_dragging; - - alarm[0] = 1; - } - } - } - - if(_connect[0] == -7 && !is_instanceof(value_dragging.node, Node_Pin)) { - if(_connect[1].value_from_loop != noone) - _connect[1].value_from_loop.destroy(); - - var menu = [ - menuItemAction("Feedback", function(data) { - var junc_in = data.params.junc_in; - var junc_out = data.params.junc_out; - - var feed = nodeBuild("Node_Feedback_Inline", 0, 0).skipDefault(); - // feed.connectJunctions(junc_in, junc_out); - feed.attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; - feed.attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; - feed.scanJunc(); - - }, THEME.feedback_24,,, { junc_in : _connect[1], junc_out : _connect[2] }), - - menuItemAction("Loop", function(data) { - var junc_in = data.params.junc_in; - var junc_out = data.params.junc_out; - - var feed = nodeBuild("Node_Iterate_Inline", 0, 0).skipDefault(); - feed.attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; - feed.attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; - feed.scanJunc(); - - }, THEME.loop_24,,, { junc_in : _connect[1], junc_out : _connect[2] }), - ]; - - menuCall(,,, menu); - } - - value_dragging = noone; - connection_draw_mouse = noone; - } - - function draggingValue() { - if(!value_dragging.node.active) { - value_dragging = noone; - value_draggings = []; - return; - } - - if(key_mod_double(SHIFT)) { - var _n = value_dragging.node; - var _l = value_dragging.connect_type == JUNCTION_CONNECT.input? _n.inputs : _n.outputs; - var _i = value_dragging.connect_type == JUNCTION_CONNECT.input? _n.inputs_index : _n.outputs_index; - - array_push_unique(value_draggings, value_dragging); - - for (var i = 0, n = array_length(_i); i < n; i++) { - var _j = _l[| _i[i]]; - if(_j.type == value_dragging.type) - array_push_unique(value_draggings, _j); - } - - } else if(key_mod_press(SHIFT)) { - array_push_unique(value_draggings, value_dragging); - - if(value_focus) - array_push_unique(value_draggings, value_focus); - - for (var i = 0, n = array_length(value_draggings); i < n; i++) { - var _v = value_draggings[i]; - var xx = _v.x - 1; - var yy = _v.y - 1; - - shader_set(sh_node_circle); - shader_set_color("color", COLORS._main_accent); - shader_set_f("thickness", 0.05); - shader_set_f("antialias", 0.05); - draw_rectangle(xx - 12 * graph_s, yy - 12 * graph_s, xx + 12 * graph_s, yy + 12 * graph_s, false); - shader_reset(); - } - - if(mouse_release(mb_left)) { - value_dragging = noone; - connection_draw_mouse = noone; - } - - } else { - var xx = value_dragging.x; - var yy = value_dragging.y; - var _mx = mx; - var _my = my; - var target = noone; - - if(value_focus && value_focus != value_dragging) - target = value_focus; - - else if(!key_mod_press(CTRL) && node_hovering != noone) { - if(value_dragging.connect_type == JUNCTION_CONNECT.input) { - target = node_hovering.getOutput(my, value_dragging); - if(target != noone) node_hovering.active_draw_index = 1; - - } else { - target = node_hovering.getInput(my, value_dragging, 0); - if(target != noone) - node_hovering.active_draw_index = 1; - - } - } - - var _mmx = target != noone? target.x : _mx; - var _mmy = target != noone? target.y : _my; - - connection_draw_mouse = [ _mmx, _mmy ]; - connection_draw_target = target; - - value_dragging.drawJunction(graph_s, value_dragging.x, value_dragging.y); - if(target) target.drawJunction(graph_s, target.x, target.y); - - var _inline_ctx = value_dragging.node.inline_context; - - if(_inline_ctx) { - if(is_instanceof(value_dragging.node, _inline_ctx.input_node_type) && value_dragging.connect_type == JUNCTION_CONNECT.input) - _inline_ctx = noone; - else if(is_instanceof(value_dragging.node, _inline_ctx.output_node_type) && value_dragging.connect_type == JUNCTION_CONNECT.output) - _inline_ctx = noone; - - if(!_inline_ctx.modifiable) - _inline_ctx = noone; - } - - if(_inline_ctx && !key_mod_press(SHIFT)) - _inline_ctx.addPoint(mouse_graph_x, mouse_graph_y); - - if(mouse_release(mb_left)) - connectDraggingValueTo(target); - } - - if(mouse_release(mb_left)) value_draggings = []; - } - - function drawJunctionConnect() { - var _focus = pFOCUS && !view_hovering; - - if(value_dragging) - draggingValue(); - - if(value_dragging == noone && value_focus && mouse_press(mb_left, _focus) && !key_mod_press(ALT)) { - value_dragging = value_focus; - value_draggings = []; - value_drag_from = noone; - - if(value_dragging.connect_type == JUNCTION_CONNECT.output) { - if(key_mod_press(CTRL)) { - var _to = value_dragging.getJunctionTo(); - - if(array_length(_to)) { - value_dragging = _to[0]; - value_draggings = array_create(array_length(_to)); - - for( var i = 0, n = array_length(_to); i < n; i++ ) { - value_draggings[i] = _to[i]; - _to[i].removeFrom(); - } - } - } else if(array_exists(nodes_selecting_jun, value_dragging.node)) { - var _jlist = ds_priority_create(); - - for( var i = 0, n = array_length(nodes_selecting_jun); i < n; i++ ) { - var _node = nodes_selecting_jun[i]; - - if(_node == value_focus.node) { - ds_priority_add(_jlist, value_focus, value_focus.y); - } else { - for( var j = 0, m = array_length(_node.outputs); j < m; j++ ) { - var _junction = _node.outputs[j]; - if(!_junction.visible) continue; - if(value_bit(_junction.type) & value_bit(value_dragging.type) == 0) continue; - - ds_priority_add(_jlist, _junction, _junction.y); - break; - } - } - } - - while(!ds_priority_empty(_jlist)) - array_push(value_draggings, ds_priority_delete_min(_jlist)); - - ds_priority_destroy(_jlist); - } - } - - if(value_dragging.connect_type == JUNCTION_CONNECT.input) { - if(key_mod_press(CTRL) && value_dragging.value_from) { - value_drag_from = value_dragging; - - var fr = value_dragging.value_from; - value_dragging.removeFrom(); - value_dragging = fr; - } - } - } - - nodes_selecting_jun = array_clone(nodes_selecting, 1); - - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - if(!display_parameter.show_control && _node.is_controller) continue; - _node.drawJunctionNames(gr_x, gr_y, mx, my, graph_s); - } - - } - - function callAddDialog(ctx = getCurrentContext()) { // - var _dia = dialogCall(o_dialog_add_node, mouse_mx + 8, mouse_my + 8, { context: ctx }); - - with(_dia) { - node_target_x = other.mouse_grid_x; - node_target_y = other.mouse_grid_y; - node_target_x_raw = other.mouse_grid_x; - node_target_y_raw = other.mouse_grid_y; - junction_hovering = other.junction_hovering; - - resetPosition(); - alarm[0] = 1; - } - - return _dia; - } - - function drawContext() { // - draw_set_text(f_p0, fa_left, fa_center); - var xx = ui(16), tt, tw, th; - var bh = toolbar_height - ui(12); - var tbh = h - toolbar_height / 2; - - for(var i = -1; i < array_length(node_context); i++) { - if(i == -1) { - tt = __txt("Global"); - } else { - var _cnt = node_context[i]; - tt = _cnt.renamed? _cnt.display_name : _cnt.name; - } - - tw = string_width(tt); - th = string_height(tt); - - if(i < array_length(node_context) - 1) { - if(buttonInstant(THEME.button_hide_fill, xx - ui(6), tbh - bh / 2, tw + ui(12), bh, [mx, my], pFOCUS, pHOVER) == 2) { - node_hover = noone; - nodes_selecting = []; - PANEL_PREVIEW.resetNodePreview(); - - var _ctx = node_context[i + 1]; - var _nodeFocus = _ctx; - - if(i == -1) - resetContext(); - else { - array_resize(node_context, i + 1); - nodes_list = node_context[i].getNodeList(); - } - - nodes_selecting = [ _nodeFocus ]; - toCenterNode(nodes_selecting); - setContextFrame(true, _ctx); - break; - } - - draw_sprite_ui_uniform(THEME.arrow, 0, xx + tw + ui(16), tbh, 1, COLORS._main_icon); - } - - draw_set_color(COLORS._main_text); - draw_set_alpha(i < array_length(node_context) - 1? 0.33 : 1); - draw_text(xx, tbh, tt); - draw_set_alpha(1); - - xx += tw + ui(32); - } - - return xx; - } - - function drawToolBar() { // - toolbar_height = ui(40); - var ty = h - toolbar_height; - - if(pHOVER && point_in_rectangle(mx, my, 0, ty, w, h)) - mouse_on_graph = false; - - draw_sprite_stretched(THEME.toolbar, 0, 0, ty, w, h); - var cont_x = drawContext(); - - var tbx = w - ui(6); - var tby = ty + toolbar_height / 2; - var _m = [ mx, my ]; - - for( var i = 0, n = array_length(toolbars); i < n; i++ ) { - var tbs = toolbars[i]; - - for (var j = 0, m = array_length(tbs); j < m; j++) { - var tb = tbs[j]; - var tbObj = tb[0]; - - if(is_instanceof(tbObj, widget)) { - tbObj.setFocusHover(pFOCUS, pHOVER); - - var _wdw = ui(32); - var _wdx = tbx - _wdw; - if(_wdx < cont_x) break; - - var _param = new widgetParam(_wdx, ty + ui(8), _wdw, toolbar_height - ui(16), tb[1](), {}, _m, x, y); - _param.font = f_p3; - - tbObj.color = COLORS._main_text_sub; - tbObj.drawParam(_param); - - tbx -= _wdw + ui(4); - - } else { - var tbInd = tb[1](); - var tbTooltip = tb[2](); - - var bs = ui(28); - if(tbx - (bs + ui(4)) < cont_x) break; - - var b = buttonInstant(THEME.button_hide, tbx - bs, tby - bs / 2, bs, bs, _m, pFOCUS, pHOVER, tbTooltip, tbObj, tbInd); - if(b == 2) tb[3]( { x: x + tbx - bs, y: y + tby - bs / 2 } ); - tbx -= bs + ui(4); - } - - } - - tbx -= ui(2); - - draw_set_color(COLORS.panel_toolbar_separator); - draw_line_width(tbx, tby - toolbar_height / 2 + ui(8), tbx, tby + toolbar_height / 2 - ui(8), 2); - - if(tbx < cont_x) break; - tbx -= ui(6); - } - - } - - function drawMinimap() { // - if(!minimap_show) return; - var mx1 = w - ui(8); - var my1 = h - toolbar_height - ui(8); - var mx0 = mx1 - minimap_w; - var my0 = my1 - minimap_h; - - minimap_w = min(minimap_w, w - ui(16)); - minimap_h = min(minimap_h, h - ui(16) - toolbar_height); - - var mini_hover = false; - if(pHOVER && point_in_rectangle(mx, my, mx0, my0, mx1, my1)) { - mouse_on_graph = false; - mini_hover = true; - } - - var hover = mini_hover && !point_in_rectangle(mx, my, mx0, my0, mx0 + ui(16), my0 + ui(16)) && !minimap_dragging; - - if(!is_surface(minimap_surface) || surface_get_width_safe(minimap_surface) != minimap_w || surface_get_height_safe(minimap_surface) != minimap_h) { - minimap_surface = surface_create_valid(minimap_w, minimap_h); - } - - surface_set_target(minimap_surface); - draw_clear_alpha(COLORS.panel_bg_clear_inner, 0.75); - if(!array_empty(nodes_list)) { - var minx = 99999; - var maxx = -99999; - var miny = 99999; - var maxy = -99999; - - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - minx = min(_node.x - 32, minx); - maxx = max(_node.x + _node.w + 32, maxx); - - miny = min(_node.y - 32, miny); - maxy = max(_node.y + _node.h + 32, maxy); - } - - var cx = (minx + maxx) / 2; - var cy = (miny + maxy) / 2; - var spw = maxx - minx; - var sph = maxy - miny; - var ss = min(minimap_w / spw, minimap_h / sph); - - draw_set_alpha(0.4); - for(var i = 0; i < array_length(nodes_list); i++) { - var _node = nodes_list[i]; - - var nx = minimap_w / 2 + (_node.x - cx) * ss; - var ny = minimap_h / 2 + (_node.y - cy) * ss; - var nw = _node.w * ss; - var nh = _node.h * ss; - - draw_set_color(_node.getColor()); - draw_set_alpha(0.2 + 0.8 * (!is_instanceof(_node, Node_Frame))); - draw_rectangle(nx, ny, nx + nw, ny + nh, false); - draw_set_alpha(1); - } - draw_set_alpha(1); - - var gx = minimap_w / 2 - (graph_x + cx) * ss; - var gy = minimap_h / 2 - (graph_y + cy) * ss; - var gw = w / graph_s * ss; - var gh = h / graph_s * ss; - - draw_set_color(COLORS.panel_graph_minimap_focus); - draw_rectangle(gx, gy, gx + gw, gy + gh, 1); - - if(minimap_panning) { - graph_x = -((mx - mx0 - gw / 2) - minimap_w / 2) / ss - cx; - graph_y = -((my - my0 - gh / 2) - minimap_h / 2) / ss - cy; - - graph_x = round(graph_x); - graph_y = round(graph_y); - - if(mouse_release(mb_left)) - minimap_panning = false; - } - - if(mouse_click(mb_left, hover)) - minimap_panning = true; - } - - surface_reset_target(); - - draw_surface_ext_safe(minimap_surface, mx0, my0, 1, 1, 0, c_white, 0.5 + 0.35 * hover); - draw_set_color(COLORS.panel_graph_minimap_outline); - draw_rectangle(mx0, my0, mx1 - 1, my1 - 1, true); - - if(minimap_dragging) { - mouse_on_graph = false; - var sw = minimap_drag_sx + minimap_drag_mx - mx; - var sh = minimap_drag_sy + minimap_drag_my - my; - - minimap_w = max(ui(64), sw); - minimap_h = max(ui(64), sh); - - if(mouse_release(mb_left)) - minimap_dragging = false; - } - - if(pHOVER && point_in_rectangle(mx, my, mx0, my0, mx0 + ui(16), my0 + ui(16))) { - draw_sprite_ui(THEME.node_resize, 0, mx0 + ui(10), my0 + ui(10), 0.5, 0.5, 180, c_white, 0.75); - if(mouse_press(mb_left, pFOCUS)) { - minimap_dragging = true; - minimap_drag_sx = minimap_w; - minimap_drag_sy = minimap_h; - minimap_drag_mx = mx; - minimap_drag_my = my; - } - } else - draw_sprite_ui(THEME.node_resize, 0, mx0 + ui(10), my0 + ui(10), 0.5, 0.5, 180, c_white, 0.3); - } - - function drawSearch() { - if(!is_searching) return; - - var tw = ui(200); - var th = line_get_height(f_p2, 6); - - var pd = ui(6); - var ww = tw + pd * 2 + (ui(4) + ui(24)) * 3; - var hh = th + pd * 2; - - var x1 = w - ui(8); - var x0 = x1 - ww; - - var y0 = ui(8); - var y1 = y0 + hh; - - draw_sprite_stretched( THEME.ui_panel_bg, 3, x0, y0, ww, hh); - draw_sprite_stretched_add(THEME.ui_panel, 1, x0, y0, ww, hh, c_white, 0.25); - draw_sprite_stretched( THEME.button_hide_fill, 1, x0 + pd, y0 + pd, tw, th); - - tb_search.font = f_p2; - tb_search.setFocusHover(pFOCUS, pHOVER); - tb_search.draw(x0 + pd, y0 + pd, tw, th, search_string, [ mx, my ]); - - var bs = ui(24); - var bx = x1 - bs - pd; - var by = y0 + pd; - if(buttonInstant(THEME.button_hide_fill, bx, by, bs, bs, [ mx, my ], pFOCUS, pHOVER, "", THEME.cross_16) == 2 - || keyboard_check_pressed(vk_escape) - || keyboard_check_pressed(vk_enter)) - is_searching = false; - - bx -= bs + ui(4); - if(buttonInstant(THEME.button_hide_fill, bx, by, bs, bs, [ mx, my ], pFOCUS, pHOVER, "", THEME.arrow_wire_16, 0) == 2) { - if(!array_empty(search_result)) { - search_index = safe_mod(search_index + 1, array_length(search_result)); - nodes_selecting = [ search_result[search_index] ]; - toCenterNode(nodes_selecting); - } - } - - bx -= bs + ui(4); - if(buttonInstant(THEME.button_hide_fill, bx, by, bs, bs, [ mx, my ], pFOCUS, pHOVER, "", THEME.arrow_wire_16, 2) == 2) { - if(!array_empty(search_result)) { - search_index = safe_mod(search_index - 1 + array_length(search_result), array_length(search_result)); - nodes_selecting = [ search_result[search_index] ]; - toCenterNode(nodes_selecting); - } - } - - if(point_in_rectangle(mx, my, x0, y0, x1, y1)) - mouse_on_graph = false; - } - - function drawContextFrame() { - if(!context_framing) return; - context_frame_progress = lerp_float(context_frame_progress, 1, 8); - if(context_frame_progress == 1) - context_framing = false; - - var _fr_x0 = 0; - var _fr_y0 = 0; - var _fr_x1 = w; - var _fr_y1 = h - toolbar_height; - - var _to_x0 = context_frame_sx; - var _to_y0 = context_frame_sy; - var _to_x1 = context_frame_ex; - var _to_y1 = context_frame_ey; - - var prog = context_frame_direct? context_frame_progress : 1 - context_frame_progress; - var frm_x0 = lerp(_fr_x0, _to_x0, prog); - var frm_y0 = lerp(_fr_y0, _to_y0, prog); - var frm_x1 = lerp(_fr_x1, _to_x1, prog); - var frm_y1 = lerp(_fr_y1, _to_y1, prog); - - draw_set_color(COLORS._main_accent); - draw_set_alpha(0.8); - draw_roundrect_ext(frm_x0, frm_y0, frm_x1, frm_y1, THEME_VALUE.panel_corner_radius, THEME_VALUE.panel_corner_radius, true); - draw_set_alpha(1); - } - - function drawSlideShow() { - if(!project.useSlideShow) return; - - var amo = project.slideShow_amount; - var ind = project.slideShow_index; - var cur = project.slideShow_current; - - var _sl_w = (amo - 1) * ui(16) + ui(16 * 2); - var _sl_h = ui(32); - - var _sl_x = w / 2 - _sl_w / 2; - var _ss_x = _sl_x; - - var _sl_y = h - toolbar_height - ui(8) - _sl_h; - var _ss_y = _sl_y + _sl_h - ui(16); - - if(cur != noone && cur.slide_title != "") { - draw_set_text(f_p2, fa_center, fa_top, COLORS._main_icon_light); - var _txtw = string_width(cur.slide_title) + ui(32); - _sl_w = max(_sl_w, _txtw); - _sl_h = _sl_h + ui(8 + 12); - } - - slider_width = slider_width == 0? _sl_w : lerp_float(slider_width, _sl_w, 10); - _sl_x = w / 2 - slider_width / 2; - _sl_y = h - toolbar_height - ui(8) - _sl_h; - - draw_sprite_stretched(THEME.ui_panel_bg, 3, _sl_x, _sl_y, slider_width, _sl_h); - - if(cur != noone) draw_text_add(round(w / 2), round(_sl_y + ui(8)), cur.slide_title); - - var _hv = false; - - for(var i = 0; i < amo; i++) { - var _sx = _ss_x + ui(16) + i * ui(16); - var _sy = _ss_y; - - var cc = i == ind? COLORS._main_accent : COLORS._main_icon; - var aa = i == ind? 1 : .5; - var ss = i == ind? 1 : .8; - - var slid = struct_try_get(project.slideShow, project.slideShow_keys[i], noone); - - if(pHOVER && point_in_circle(mx, my, _sx, _sy, ui(8))) { - if(slid) TOOLTIP = slid.slide_title; - _hv = true; - aa = 1; - - if(mouse_press(mb_left, pFOCUS)) - setSlideShow(i); - } - - draw_sprite_ext(THEME.circle, 0, _sx, _sy, ss, ss, 0, cc, aa); - } - - if(point_in_rectangle(mx, my, _sl_x, _sl_y, _sl_x + slider_width, _sl_y + _sl_h)) { - mouse_on_graph = false; - - if(pHOVER && !_hv) { - draw_sprite_stretched_add(THEME.ui_panel_bg, 4, _sl_x, _sl_y, slider_width, _sl_h, COLORS._main_icon, 0.05); - draw_sprite_stretched_add(THEME.ui_panel, 1, _sl_x, _sl_y, slider_width, _sl_h, c_white, 0.1); - - if(mouse_press(mb_left, pFOCUS)) - setSlideShow((ind + 1) % amo); - } - } - } - - function drawContent(panel) { // //// Main Draw - if(!project.active) return; - - dragGraph(); - - toolbars = [ toolbars_general ]; - if(array_length(nodes_selecting) > 1) { - if(array_exists(nodes_selecting, nodes_select_anchor)) - array_push(toolbars, toolbars_halign, toolbars_valign, toolbars_distrib_space); - else - array_push(toolbars, toolbars_halign, toolbars_valign, toolbars_distrib); - } - - graph_cx = (w / 2) / graph_s - graph_x; - graph_cy = (h / 2) / graph_s - graph_y; - - var context = getCurrentContext(); - if(context != noone) title_raw += " > " + (context.renamed? context.display_name : context.name); - - bg_color = context == noone? COLORS.panel_bg_clear : merge_color(COLORS.panel_bg_clear, context.getColor(), 0.05); - draw_clear(bg_color); - node_bg_hovering = drawBasePreview(); - drawGrid(); - - var ovy = ui(8); - if(show_view_control == 2) ovy += ui(36); - // if(is_searching) ovy += line_get_height(f_p2, 20); - - drawNodes(); - - draw_set_text(f_p2, fa_right, fa_top, COLORS._main_text_sub); - draw_text_add(w - ui(8), ovy, $"x{graph_s_to}"); - - drawJunctionConnect(); - drawContextFrame(); - - mouse_on_graph = true; - drawToolBar(); - drawMinimap(); - - drawViewControl(); - - if(pFOCUS && !view_hovering) array_foreach(nodes_selecting, function(node) { node.focusStep(); }); - - if(UPDATE == RENDER_TYPE.full) draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering", "Rendering") + "..."); - else if(UPDATE == RENDER_TYPE.partial) draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering_partial", "Rendering partial") + "..."); - - graph_dragging_key = false; - graph_zooming_key = false; - - drawSearch() - - if(LIVE_UPDATE) { - draw_set_text(f_p0b, fa_right, fa_bottom, COLORS._main_value_negative); - draw_text(w - 8, h - toolbar_height, "Live Update"); - } - - drawSlideShow(); - - ////////////////////////////////// File drop ////////////////////////////////// - - if(pHOVER) { - var gr_x = graph_x * graph_s; - var gr_y = graph_y * graph_s; - var _gx = mx / graph_s - graph_x; - var _gy = my / graph_s - graph_y; - var _node_hover = noone; - - var _mx = (FILE_IS_DROPPING? FILE_DROPPING_X : mouse_mx) - x; - var _my = (FILE_IS_DROPPING? FILE_DROPPING_Y : mouse_my) - y; - - for(var i = 0; i < array_length(nodes_list); i++) { - var _n = nodes_list[i]; - if(is_instanceof(_n, Node_Frame)) continue; - - if(_n.pointIn(gr_x, gr_y, _mx, _my, graph_s)) - _node_hover = _n; - } - - if(DRAGGING || FILE_IS_DROPPING) - draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1); - - if(DRAGGING) { // file dropping - if(_node_hover && _node_hover.droppable(DRAGGING)) { - _node_hover.draw_droppable = true; - if(mouse_release(mb_left)) _node_hover.onDrop(DRAGGING); - - } else { - if(mouse_release(mb_left)) checkDropItem(); - } - } - - if(FILE_IS_DROPPING && _node_hover && _node_hover.dropPath != noone) - _node_hover.draw_droppable = true; - - if(FILE_DROPPED && !array_empty(FILE_DROPPING)) { - if(_node_hover && _node_hover.dropPath != noone) - _node_hover.dropPath(FILE_DROPPING); - else - run_in(1, load_file_path, [ FILE_DROPPING, _gx, _gy ]); - } - } - - } - - //// ============ Action ============ - - function createNodeHotkey(_node, _param = noone) { - var node; - - if(mouse_create_x == undefined || mouse_create_sx != mouse_grid_x || mouse_create_sy != mouse_grid_y) { - mouse_create_sx = mouse_grid_x; - mouse_create_sy = mouse_grid_y; - - mouse_create_x = mouse_grid_x; - mouse_create_y = mouse_grid_y; - } - - var _mx = mouse_create_x; - var _my = mouse_create_y; - var _gs = project.graphGrid.size; - - if(is_string(_node)) node = nodeBuild(_node, _mx, _my); - else node = _node(_mx, _my, getCurrentContext(), _param); - - if(node == noone) return; - - mouse_create_y = ceil((mouse_create_y + node.h + _gs / 2) / _gs) * _gs; - - if(value_dragging == noone) return; - - if(value_dragging.connect_type == JUNCTION_CONNECT.output) { - if(node.input_display_list != -1) { - for (var i = 0, n = array_length(node.input_display_list); i < n; i++) { - if(!is_real(node.input_display_list[i])) continue; - if(node.inputs[node.input_display_list[i]].setFrom(value_dragging)) break; - } - - } else { - for (var i = 0, n = array_length(node.inputs); i < n; i++) - if(node.inputs[i].setFrom(value_dragging)) break; - } - - } else if(value_dragging.connect_type == JUNCTION_CONNECT.input) { - for (var i = 0, n = array_length(node.outputs); i < n; i++) - if(value_dragging.setFrom(node.outputs[i])) break; - - } - - value_dragging = noone; - } - - function doTransform() { - for( var i = 0; i < array_length(nodes_selecting); i++ ) { - var node = nodes_selecting[i]; - if(array_empty(node.outputs)) continue; - - var _o = node.outputs[0]; - if(_o.type == VALUE_TYPE.surface || _o.type == VALUE_TYPE.dynaSurface) { - var tr = nodeBuild("Node_Transform", node.x + node.w + 64, node.y).skipDefault(); - tr.inputs[0].setFrom(_o); - } - } - } + menu_junc_color = menuItemGroup(__txt("Connection Color"), _item); + menu_junc_color.spacing = ui(24); + + + //// ============ Project ============ + + static setProject = function(project) { + self.project = project; + nodes_list = project.nodes; + + setTitle(); + run_in(2, function() /*=>*/ { + setSlideShow(0); + struct_override(display_parameter, project.graph_display_parameter); + }); + } + + //// ============ Views ============ + + function onFocusBegin() { // + PANEL_GRAPH = self; + PROJECT = project; + + nodes_select_drag = 0; + } + + function focusNode(_node) { // + if(_node == noone) { + nodes_selecting = []; + return; + } + + nodes_selecting = [ _node ]; + fullView(); + } + + function fullView() { + INLINE + toCenterNode(array_empty(nodes_selecting)? nodes_list : nodes_selecting); + } + + function dragGraph() { + if(graph_autopan) { + graph_x = lerp_float(graph_x, graph_pan_x_to, 32, 1); + graph_y = lerp_float(graph_y, graph_pan_y_to, 32, 1); + + if(graph_x == graph_pan_x_to && graph_y == graph_pan_y_to) + graph_autopan = false; + return; + } + + if(graph_dragging) { + if(!MOUSE_WRAPPING) { + var dx = mx - graph_drag_mx; + var dy = my - graph_drag_my; + + graph_x += dx / graph_s; + graph_y += dy / graph_s; + } + + graph_drag_mx = mx; + graph_drag_my = my; + setMouseWrap(); + + if(mouse_release(drag_key)) { + graph_dragging = false; + view_pan_tool = false; + } + } + + if(graph_zooming) { + if(!MOUSE_WRAPPING) { + var dy = -(my - graph_zoom_m) / 200; + + var _s = graph_s; + + graph_s_to = clamp(graph_s_to * (1 + dy), scale[0], scale[array_length(scale) - 1]); + graph_s = graph_s_to; + + if(_s != graph_s) { + var mb_x = (graph_zoom_mx - graph_x * _s) / _s; + var ma_x = (graph_zoom_mx - graph_x * graph_s) / graph_s; + var md_x = ma_x - mb_x; + graph_x += md_x; + + var mb_y = (graph_zoom_my - graph_y * _s) / _s; + var ma_y = (graph_zoom_my - graph_y * graph_s) / graph_s; + var md_y = ma_y - mb_y; + graph_y += md_y; + } + } + + graph_zoom_m = my; + setMouseWrap(); + + if(mouse_release(drag_key)) { + graph_zooming = false; + view_zoom_tool = false; + } + } + + if(mouse_on_graph && pFOCUS && graph_draggable) { + var _doDragging = false; + var _doZooming = false; + + if(mouse_press(PREFERENCES.pan_mouse_key)) { + _doDragging = true; + drag_key = PREFERENCES.pan_mouse_key; + + } else if(mouse_press(mb_left) && graph_dragging_key) { + _doDragging = true; + drag_key = mb_left; + + } else if(mouse_press(mb_left) && graph_zooming_key) { + _doZooming = true; + drag_key = mb_left; + } + + if(_doDragging) { + graph_dragging = true; + graph_drag_mx = mx; + graph_drag_my = my; + graph_drag_sx = graph_x; + graph_drag_sy = graph_y; + } + + if(_doZooming) { + graph_zooming = true; + graph_zoom_mx = mx; + graph_zoom_my = my; + graph_zoom_m = my; + graph_zoom_s = graph_s; + } + } + + if(mouse_on_graph && pHOVER && graph_draggable) { + var _s = graph_s; + if(mouse_wheel_down() && !key_mod_press_any()) { //zoom out + for( var i = 1, n = array_length(scale); i < n; i++ ) { + if(scale[i - 1] < graph_s_to && graph_s_to <= scale[i]) { + graph_s_to = scale[i - 1]; + break; + } + } + } + if(mouse_wheel_up() && !key_mod_press_any()) { // zoom in + for( var i = 1, n = array_length(scale); i < n; i++ ) { + if(scale[i - 1] <= graph_s_to && graph_s_to < scale[i]) { + graph_s_to = scale[i]; + break; + } + } + } + + graph_s = lerp_float(graph_s, graph_s_to, PREFERENCES.graph_zoom_smoooth); + + if(_s != graph_s) { + var mb_x = (mx - graph_x * _s) / _s; + var ma_x = (mx - graph_x * graph_s) / graph_s; + var md_x = ma_x - mb_x; + graph_x += md_x; + + var mb_y = (my - graph_y * _s) / _s; + var ma_y = (my - graph_y * graph_s) / graph_s; + var md_y = ma_y - mb_y; + graph_y += md_y; + } + } + + graph_draggable = true; + graph_x = round(graph_x); + graph_y = round(graph_y); + } + + function autoPanTo(_x, _y) { + graph_autopan = true; + graph_pan_x_to = _x; + graph_pan_y_to = _y; + } + + function setSlideShow(index, skip = false) { + var _targ = project.slideShowSet(index); + if(_targ == noone) return; + + setContext(_targ); + + var _gx = w / 2 / graph_s; + var _gy = h / 2 / graph_s; + + var _tx = _gx; + var _ty = _gy; + + switch(_targ.slide_anchor) { + case 0 : + _tx = _gx - _targ.x; + _ty = _gy - _targ.y; + break; + + case 1 : + _tx = 64 * graph_s - _targ.x; + _ty = 64 * graph_s - _targ.y; + break; + + } + + if(skip) { + graph_x = _tx; + graph_y = _ty; + + } else + autoPanTo(_tx, _ty, skip); + } + + //// =========== Context ========== + + + function getCurrentContext() { return array_empty(node_context)? noone : node_context[array_length(node_context) - 1]; } + + function getNodeList(cont = getCurrentContext()) { return cont == noone? project.nodes : cont.getNodeList(); } + + function setContext(context) { + if(context.group == getCurrentContext()) return; + + node_context = []; + nodes_list = project.nodes; + + var _ctxs = []; + var _ctx = context; + + while(_ctx.group != noone) { + array_insert(_ctxs, 0, _ctx.group); + _ctx = _ctx.group; + } + + for (var i = 0, n = array_length(_ctxs); i < n; i++) + addContext(_ctxs[i]); + } + + function resetContext() { + node_context = []; + nodes_list = project.nodes; + toCenterNode(); + } + + function addContext(node) { + var _node = node.getNodeBase(); + + nodes_list = _node.nodes; + array_push(node_context, _node); + + node_dragging = noone; + nodes_selecting = []; + selection_block = 1; + + setContextFrame(false, _node); + toCenterNode(); + } + + function setContextFrame(dirr, node) { + context_framing = true; + + context_frame_direct = dirr; + context_frame_progress = 0; + + context_frame_sx = w / 2 - 8; + context_frame_sy = h / 2 - 8; + context_frame_ex = context_frame_sx + 16; + context_frame_ey = context_frame_sy + 16; + + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + + context_frame_sx = gr_x + node.x * graph_s; + context_frame_sy = gr_y + node.y * graph_s; + context_frame_ex = context_frame_sx + node.w * graph_s; + context_frame_ey = context_frame_sy + node.h * graph_s; + } + + //// ============ Step ============ + + function stepBegin() { // + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + var m_x = (mx - gr_x) / graph_s; + var m_y = (my - gr_y) / graph_s; + mouse_graph_x = m_x; + mouse_graph_y = m_y; + + mouse_grid_x = round(m_x / project.graphGrid.size) * project.graphGrid.size; + mouse_grid_y = round(m_y / project.graphGrid.size) * project.graphGrid.size; + + setTitle(); + } + + //// ============ Draw ============ + + function drawGrid() { // + if(!display_parameter.show_grid) return; + var gls = project.graphGrid.size; + while(gls * graph_s < 8) gls *= 5; + + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + var gr_ls = gls * graph_s; + var xx = -gr_ls, xs = safe_mod(gr_x, gr_ls); + var yy = -gr_ls, ys = safe_mod(gr_y, gr_ls); + + draw_set_color(project.graphGrid.color); + var aa = 0.5; + if(graph_s < 0.25) + aa = 0.3; + var oa = project.graphGrid.opacity; + var ori = project.graphGrid.show_origin; + var hig = project.graphGrid.highlight; + + while(xx < w + gr_ls) { + draw_set_alpha( oa * aa * (1 + (round((xx + xs - gr_x) / gr_ls) % hig == 0) * 2) ); + draw_line(xx + xs, 0, xx + xs, h); + + if(ori && xx + xs - gr_x == 0) draw_line_width(xx + xs, 0, xx + xs, h, 3); + xx += gr_ls; + } + + while(yy < h + gr_ls) { + draw_set_alpha( oa * aa * (1 + (round((yy + ys - gr_y) / gr_ls) % hig == 0) * 2) ); + draw_line(0, yy + ys, w, yy + ys); + + if(ori && yy + ys - gr_y == 0) draw_line_width(0, yy + ys, w, yy + ys, 3); + yy += gr_ls; + } + draw_set_alpha(1); + } + + function drawViewControl() { // + if(h < ui(96)) return; + + view_hovering = false; + if(!show_view_control) return; + + var _side = show_view_control == 1? 1 : -1; + var _hab = pHOVER && !view_pan_tool && !view_zoom_tool; + + var d3_view_wz = ui(16); + + var _d3x = show_view_control == 1? + ui(8) + d3_view_wz : + w - ui(8) - d3_view_wz; + + var _d3y = ui(8) + d3_view_wz; + var _hv = false; + + if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { + _hv = true; + view_hovering = true; + + if(mouse_press(mb_left, pFOCUS)) { + drag_key = mb_left; + graph_dragging = true; + graph_drag_mx = mx; + graph_drag_my = my; + graph_drag_sx = graph_x; + graph_drag_sy = graph_y; + + view_pan_tool = true; + } + } + + if(view_pan_tool) + _hv = true; + + draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); + draw_sprite_ui(THEME.view_pan, 0, _d3x, _d3y, 1, 1, 0, view_pan_tool? COLORS._main_accent : COLORS._main_icon, 1); + + _d3x += (d3_view_wz + ui(4) + d3_view_wz) * _side; + _hv = false; + + if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { + _hv = true; + view_hovering = true; + + if(mouse_press(mb_left, pFOCUS)) { + drag_key = mb_left; + graph_zooming = true; + graph_zoom_mx = w / 2; + graph_zoom_my = h / 2; + graph_zoom_m = my; + graph_zoom_s = graph_s; + + view_zoom_tool = true; + } + } + + if(view_zoom_tool) + _hv = true; + + draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); + draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1); + + } + + function drawBasePreview() { // + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + var _hov = false; + + for(var i = 0; i < array_length(nodes_list); i++) { + var h = nodes_list[i].drawPreviewBackground(gr_x, gr_y, mx, my, graph_s); + _hov |= h; + } + + return _hov; + } + + function drawNodes() { // + if(selection_block-- > 0) return; + var _focus = pFOCUS && !view_hovering; + + display_parameter.highlight = + !array_empty(nodes_selecting) && ( + (PREFERENCES.connection_line_highlight == 1 && key_mod_press(ALT)) || + PREFERENCES.connection_line_highlight == 2 + ); + + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + + var log = false; + var t = get_timer(); + printIf(log, "============ Draw start ============"); + + _frame_hovering = frame_hovering; + frame_hovering = noone; + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + if(!display_parameter.show_control && _node.is_controller) continue; + + _node.cullCheck(gr_x, gr_y, graph_s, -32, -32, w + 32, h + 64); + _node.preDraw(gr_x, gr_y, graph_s, gr_x, gr_y); + } + printIf(log, $"Predraw time: {get_timer() - t}"); t = get_timer(); + + // draw frame + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + if(!display_parameter.show_control && _node.is_controller) continue; + + if(_node.drawNodeBG(gr_x, gr_y, mx, my, graph_s, display_parameter, self)) + frame_hovering = _node; + } + + printIf(log, $"Frame draw time: {get_timer() - t}"); t = get_timer(); + + // hover + node_hovering = noone; + if(pHOVER) + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + if(!display_parameter.show_control && _node.is_controller) continue; + + _node.branch_drawing = false; + + if(_node.pointIn(gr_x, gr_y, mx, my, graph_s)) + node_hovering = _node; + } + + if(node_hovering != noone) + _HOVERING_ELEMENT = node_hovering; + + if(DOUBLE_CLICK) { + // print($"Double click {node_hovering} || {_focus} || {instanceof(node_hovering)}"); + + if(node_hovering != noone && _focus && node_hovering.onDoubleClick != -1) + if(node_hovering.onDoubleClick(self)) { + DOUBLE_CLICK = false; + node_hovering = noone; + } + } + + if(node_hovering) node_hovering.onDrawHover(gr_x, gr_y, mx, my, graph_s); + + printIf(log, $"Hover time: {get_timer() - t}"); t = get_timer(); + + // ++++++++++++ interaction ++++++++++++ + if(mouse_on_graph && pHOVER) { + + // select + var _anc = nodes_select_anchor; + if(mouse_press(mb_left, _focus)) _anc = noone; + + 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, _focus)) { + if(key_mod_press(SHIFT)) { + if(node_hovering) { + if(array_exists(nodes_selecting, node_hovering)) + array_remove(nodes_selecting, node_hovering); + else + array_push(nodes_selecting, node_hovering); + } else + nodes_selecting = []; + + } else if(value_focus || node_hovering == noone) { + nodes_selecting = []; + + if(DOUBLE_CLICK && !PANEL_INSPECTOR.locked) + PANEL_INSPECTOR.inspecting = noone; + + } else { + if(is_instanceof(node_hovering, Node_Frame)) { + var fx0 = (node_hovering.x + graph_x) * graph_s; + var fy0 = (node_hovering.y + graph_y) * graph_s; + var fx1 = fx0 + node_hovering.w * graph_s; + var fy1 = fy0 + node_hovering.h * graph_s; + + nodes_selecting = [ node_hovering ]; + + if(!key_mod_press(CTRL)) + for(var i = 0; i < array_length(nodes_list); i++) { //select content + var _node = nodes_list[i]; + if(_node == node_hovering) continue; + if(!display_parameter.show_control && _node.is_controller) continue; + + if(!_node.selectable) 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(_w && _h && rectangle_inside_rectangle(fx0, fy0, fx1, fy1, _x, _y, _x + _w, _y + _h)) + array_push_unique(nodes_selecting, _node); + } + + } else if(DOUBLE_CLICK) { + PANEL_PREVIEW.setNodePreview(node_hovering); + + if(PREFERENCES.inspector_focus_on_double_click) { + if(PANEL_INSPECTOR.panel && struct_has(PANEL_INSPECTOR.panel, "switchContent")) + PANEL_INSPECTOR.panel.switchContent(PANEL_INSPECTOR); + } + + } else { + var hover_selected = false; + for( var i = 0; i < array_length(nodes_selecting); i++ ) { + if(nodes_selecting[i] != node_hovering) continue; + + hover_selected = true; + break; + } + + if(!hover_selected) + nodes_selecting = [ node_hovering ]; + + if(array_length(nodes_selecting) > 1) + _anc = nodes_select_anchor == node_hovering? noone : node_hovering; + } + + if(WIDGET_CURRENT) WIDGET_CURRENT.deactivate(); + array_foreach(nodes_selecting, function(node) { bringNodeToFront(node); }); + } + } + + nodes_select_anchor = _anc; + + + if(mouse_press(mb_right, _focus)) { // + node_hover = node_hovering; + + if(value_focus) { + // print($"Right click value focus {value_focus}"); + + __junction_hovering = value_focus; + + var menu = [ menu_junc_color ]; + + if(value_focus.connect_type == JUNCTION_CONNECT.output) { + var sep = false; + + for( var i = 0, n = array_length(value_focus.value_to); i < n; i++ ) { + if(!sep) { array_push(menu, -1); sep = true; } + + var _to = value_focus.value_to[i]; + var _lb = $"[{_to.node.display_name}] {_to.getName()}"; + array_push(menu, menuItem(_lb, function(data) /*=>*/ { data.params.juncTo.removeFrom(); }, THEME.cross, noone, noone, { juncTo: _to })); + } + + for( var i = 0, n = array_length(value_focus.value_to_loop); i < n; i++ ) { + if(!sep) { array_push(menu, -1); sep = true; } + + var _to = value_focus.value_to_loop[i]; + var _lb = $"[{_to.junc_in.node.display_name}] {_to.junc_in.getName()}"; + array_push(menu, menuItem(_lb, function(data) /*=>*/ { data.params.juncTo.destroy(); }, _to.icon_24, noone, noone, { juncTo: _to })); + } + } else { + var sep = false; + + if(value_focus.value_from) { + if(!sep) { array_push(menu, -1); sep = true; } + + var _jun = value_focus.value_from; + var _lb = $"[{_jun.node.display_name}] {_jun.getName()}"; + array_push(menu, menuItem(_lb, function(data) /*=>*/ { __junction_hovering.removeFrom(); }, THEME.cross)); + } + + if(value_focus.value_from_loop) { + if(!sep) { array_push(menu, -1); sep = true; } + + var _jun = value_focus.value_from_loop.junc_out; + var _lb = $"[{_jun.node.display_name}] {_jun.getName()}"; + array_push(menu, menuItem(_lb, function(data) /*=>*/ { __junction_hovering.removeFromLoop(); }, value_focus.value_from_loop.icon_24)); + } + } + + menuCall("graph_node_selected_menu",,, menu); + + } else if(node_hover && node_hover.draggable) { + // print($"Right click node hover {node_hover}"); + + var menu = []; + array_push(menu, menu_node_color, -1, menu_sent_to_preview, menu_send_to_window, menu_sent_to_inspector); + if(!DEMO) + array_push(menu, menu_send_export); + array_push(menu, -1, menu_toggle_preview, menu_toggle_render, menu_toggle_param, menu_hide_disconnect); + + if(is_instanceof(node_hover, Node_Collection)) + array_push(menu, -1, menu_open_group, menu_open_group_tab, menu_group_ungroup); + + if(node_hover.group != noone) + array_push(menu, menu_group_tool); + if(array_length(nodes_selecting) >= 2) + array_push(menu, -1, menu_nodes_group, menu_nodes_frame); + + array_push(menu, -1, menu_node_delete_merge, menu_node_delete_cut, menu_node_duplicate, menu_node_copy); + if(array_empty(nodes_selecting)) array_push(menu, menu_node_copy_prop, menu_node_paste_prop); + + array_push(menu, -1, menu_node_transform, menu_node_canvas); + + if(array_length(nodes_selecting) >= 2) + array_push(menu, -1, menu_nodes_align, menu_nodes_blend, menu_nodes_compose, menu_nodes_array); + + menuCall("graph_node_selected_multiple_menu",,, menu ); + + } else if(node_hover == noone) { + // print($"Right click not node hover"); + + var menu = []; + + __junction_hovering = junction_hovering; + if(junction_hovering != noone) + array_push(menu, menu_junc_color, menu_connection_tunnel, -1); + + array_push(menu, MENU_ITEMS.graph_copy.setActive(array_length(nodes_selecting))); + array_push(menu, MENU_ITEMS.graph_paste.setActive(clipboard_get_text() != "")); + + if(junction_hovering != noone) { + array_push(menu, -1); + + if(is_instanceof(junction_hovering, Node_Feedback_Inline)) { + var _jun = junction_hovering.junc_out; + array_push(menu, menuItem($"[{_jun.node.display_name}] {_jun.getName()}", function(data) /*=>*/ { __junction_hovering.destroy(); }, THEME.feedback)); + + } else { + var _jun = junction_hovering.value_from; + array_push(menu, menuItem($"[{_jun.node.display_name}] {_jun.getName()}", function(data) /*=>*/ { __junction_hovering.removeFrom(); }, THEME.cross)); + } + } + + var ctx = is_instanceof(frame_hovering, Node_Collection_Inline)? frame_hovering : getCurrentContext(); + var _diaAdd = callAddDialog(ctx); + + var _dia = menuCall("graph_node_selected_menu", o_dialog_add_node.dialog_x - ui(8), o_dialog_add_node.dialog_y + ui(4), menu, fa_right ); + _dia.passthrough = true; + setFocus(_diaAdd, "Dialog"); + } + } + + if(is_instanceof(frame_hovering, Node_Collection_Inline) && DOUBLE_CLICK && array_empty(nodes_selecting)) { // + nodes_selecting = [ frame_hovering ]; + + if(frame_hovering.onDoubleClick != -1) frame_hovering.onDoubleClick(self) + if(frame_hovering.previewable) PANEL_PREVIEW.setNodePreview(frame_hovering); + } + } + + printIf(log, $"Node selection time: {get_timer() - t}"); t = get_timer(); + + // draw active + for(var i = 0; i < array_length(nodes_selecting); i++) { + var _node = nodes_selecting[i]; + if(!_node) continue; + _node.drawActive(gr_x, gr_y, graph_s); + } + + if(nodes_select_anchor) nodes_select_anchor.active_draw_anchor = true; + + printIf(log, $"Draw active: {get_timer() - t}"); t = get_timer(); + + // draw connections + var aa = floor(min(8192 / w, 8192 / h, PREFERENCES.connection_line_aa)); + + connection_surface = surface_verify(connection_surface, w * aa, h * aa); + connection_surface_aa = surface_verify(connection_surface_aa, w, h); + surface_set_target(connection_surface); + DRAW_CLEAR + + var hov = noone; + var hoverable = !bool(node_dragging) && pHOVER; + var param = connection_param; + + param.active = hoverable; + param.setPos(gr_x, gr_y, graph_s, mx, my); + param.setBoundary(-64, -64, w + 64, h + 64); + param.setProp(array_length(nodes_list), display_parameter.highlight); + param.setDraw(aa, bg_color); + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + if(!display_parameter.show_control && _node.is_controller) continue; + + param.cur_layer = i + 1; + + var _hov = _node.drawConnections(param); + if(_hov != noone && is_struct(_hov)) hov = _hov; + } + + if(value_dragging && connection_draw_mouse != noone && !key_mod_press(SHIFT)) { + var _cmx = connection_draw_mouse[0]; + var _cmy = connection_draw_mouse[1]; + var _cmt = connection_draw_target; + + if(array_empty(value_draggings)) + value_dragging.drawConnectionMouse(param, _cmx, _cmy, _cmt); + else { + var _stIndex = array_find(value_draggings, value_dragging); + + for( var i = 0, n = array_length(value_draggings); i < n; i++ ) { + var _dmx = _cmx; + var _dmy = value_draggings[i].connect_type == JUNCTION_CONNECT.output? _cmy + (i - _stIndex) * 24 * graph_s : _cmy; + + value_draggings[i].drawConnectionMouse(param, _dmx, _dmy, _cmt); + } + } + } + + surface_reset_target(); + + gpu_set_texfilter(true); + surface_set_shader(connection_surface_aa, sh_downsample); + shader_set_f("down", aa); + shader_set_dim("dimension", connection_surface); + draw_surface_safe(connection_surface); + surface_reset_shader(); + gpu_set_texfilter(false); + + BLEND_ALPHA_MULP + draw_surface_safe(connection_surface_aa); + BLEND_NORMAL + + junction_hovering = node_hovering == noone? hov : noone; + + printIf(log, $"Draw connection: {get_timer() - t}"); t = get_timer(); + + // draw node + _value_focus = value_focus; + value_focus = noone; + + var t = get_timer(); + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + if(!display_parameter.show_control && _node.is_controller) continue; + nodes_list[i].drawNodeBehind(gr_x, gr_y, mx, my, graph_s); + } + + for( var i = 0, n = array_length(value_draggings); i < n; i++ ) + value_draggings[i].graph_selecting = true; + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + if(!display_parameter.show_control && _node.is_controller) continue; + if(is_instanceof(_node, Node_Frame)) continue; + try { + var val = _node.drawNode(gr_x, gr_y, mx, my, graph_s, display_parameter, self); + if(val) { + value_focus = val; + if(key_mod_press(SHIFT)) TOOLTIP = [ val.getValue(), val.type ]; + } + } catch(e) { + log_warning("NODE DRAW", exception_print(e)); + } + } + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + if(!display_parameter.show_control && _node.is_controller) continue; + if(!is_instanceof(nodes_list[i], Node_Frame)) + nodes_list[i].drawBadge(gr_x, gr_y, graph_s); + } + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + if(!display_parameter.show_control && _node.is_controller) continue; + nodes_list[i].drawNodeFG(gr_x, gr_y, mx, my, graph_s, display_parameter, self); + } + + if(PANEL_INSPECTOR && PANEL_INSPECTOR.prop_hover != noone) + value_focus = PANEL_INSPECTOR.prop_hover; + + printIf(log, $"Draw node: {get_timer() - t}"); t = get_timer(); + + // dragging + if(mouse_press(mb_left)) + node_dragging = noone; + + for(var i = 0; i < array_length(nodes_list); i++) + nodes_list[i].groupCheck(gr_x, gr_y, graph_s, mx, my); + + if(node_dragging && !key_mod_press(ALT)) { + var nx = node_drag_sx + (mouse_graph_x - node_drag_mx); + var ny = node_drag_sy + (mouse_graph_y - node_drag_my); + + if(!key_mod_press(CTRL) && project.graphGrid.snap) { + nx = round(nx / project.graphGrid.size) * project.graphGrid.size; + ny = round(ny / project.graphGrid.size) * project.graphGrid.size; + } + + if(node_drag_ox == -1 || node_drag_oy == -1) { + node_drag_ox = nx; + node_drag_oy = ny; + } else if(nx != node_drag_ox || ny != node_drag_oy) { + var dx = nx - node_drag_ox; + var dy = ny - node_drag_oy; + + for(var i = 0; i < array_length(nodes_selecting); i++) { + var _node = nodes_selecting[i]; + var _nx = _node.x + dx; + var _ny = _node.y + dy; + + if(!key_mod_press(CTRL) && project.graphGrid.snap) { + _nx = round(_nx / project.graphGrid.size) * project.graphGrid.size; + _ny = round(_ny / project.graphGrid.size) * project.graphGrid.size; + } + + _node.move(_nx, _ny, graph_s); + } + + node_drag_ox = nx; + node_drag_oy = ny; + } + + if(mouse_release(mb_left) && (nx != node_drag_sx || ny != node_drag_sy)) { + var shfx = node_drag_sx - nx; + var shfy = node_drag_sy - ny; + + UNDO_HOLDING = false; + for(var i = 0; i < array_length(nodes_selecting); i++) { + var _n = nodes_selecting[i]; + if(_n == noone) continue; + recordAction(ACTION_TYPE.var_modify, _n, [ _n.x + shfx, "x", "node x position" ]); + recordAction(ACTION_TYPE.var_modify, _n, [ _n.y + shfy, "y", "node y position" ]); + } + } + } + + if(mouse_release(mb_left)) + node_dragging = noone; + + printIf(log, $"Drag node time : {get_timer() - t}"); t = get_timer(); + + if(mouse_on_graph && _focus) { // + var _node = getFocusingNode(); + if(_node && _node.draggable && value_focus == noone) { + if(mouse_press(mb_left) && !key_mod_press(ALT)) { + node_dragging = _node; + node_drag_mx = mouse_graph_x; + node_drag_my = mouse_graph_y; + node_drag_sx = _node.x; + node_drag_sy = _node.y; + + node_drag_ox = -1; + node_drag_oy = -1; + } + } + + if(DOUBLE_CLICK && junction_hovering != noone) { + var _mx = round(mouse_graph_x / project.graphGrid.size) * project.graphGrid.size; + var _my = round(mouse_graph_y / project.graphGrid.size) * project.graphGrid.size; + + var _pin = nodeBuild("Node_Pin", _mx, _my).skipDefault(); + _pin.inputs[0].setFrom(junction_hovering.value_from); + junction_hovering.setFrom(_pin.outputs[0]); + } + } + + // draw selection frame + if(nodes_select_drag) { + if(point_distance(nodes_select_mx, nodes_select_my, mx, my) > 16) + nodes_select_drag = 2; + + if(nodes_select_drag == 2) { + draw_sprite_stretched_points_clamp(THEME.ui_selection, 0, nodes_select_mx, nodes_select_my, mx, my, COLORS._main_accent); + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + if(!display_parameter.show_control && _node.is_controller) continue; + if(!_node.selectable) continue; + if(is_instanceof(_node, Node_Frame) && !nodes_select_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; + + var _sel = _w && _h && rectangle_in_rectangle(_x, _y, _x + _w, _y + _h, nodes_select_mx, nodes_select_my, mx, my); + + if(!array_exists(nodes_selecting, _node) && _sel) + array_push(nodes_selecting, _node); + if(array_exists(nodes_selecting, _node) && !_sel) + array_remove(nodes_selecting, _node); + } + } + + if(mouse_release(mb_left)) + nodes_select_drag = 0; + } + + if(nodes_junction_d != noone) { + var shx = nodes_junction_dx + (mx - nodes_select_mx) / graph_s; + var shy = nodes_junction_dy + (my - nodes_select_my) / graph_s; + + shx = value_snap(shx, key_mod_press(CTRL)? 1 : 4); + shy = value_snap(shy, key_mod_press(CTRL)? 1 : 4); + + nodes_junction_d.draw_line_shift_x = shx; + nodes_junction_d.draw_line_shift_y = shy; + + if(mouse_release(mb_left)) + nodes_junction_d = noone; + } + + if(mouse_on_graph && !node_bg_hovering && mouse_press(mb_left, _focus) && !graph_dragging_key && !graph_zooming_key) { + if(is_instanceof(junction_hovering, NodeValue) && junction_hovering.draw_line_shift_hover) { + nodes_select_mx = mx; + nodes_select_my = my; + nodes_junction_d = junction_hovering; + nodes_junction_dx = junction_hovering.draw_line_shift_x; + nodes_junction_dy = junction_hovering.draw_line_shift_y; + + } else if(array_empty(nodes_selecting) && !value_focus && !drag_locking) { + nodes_select_drag = 1; + nodes_select_frame = frame_hovering == noone; + + nodes_select_mx = mx; + nodes_select_my = my; + } + drag_locking = false; + } + + + printIf(log, $"Draw selection frame : {get_timer() - t}"); t = get_timer(); + } + + function connectDraggingValueTo(target) { + var _connect = [ 0, noone, noone ]; + + if(is_instanceof(PANEL_INSPECTOR, Panel_Inspector) && PANEL_INSPECTOR.attribute_hovering != noone) { + PANEL_INSPECTOR.attribute_hovering(value_dragging); + + } else if(target != noone && target != value_dragging) { + + if(target.connect_type == value_dragging.connect_type) { + + if(value_dragging.connect_type == JUNCTION_CONNECT.input) { + if(target.value_from) { + value_dragging.setFrom(target.value_from); + target.removeFrom(); + } + + } else if(value_dragging.connect_type == JUNCTION_CONNECT.output) { + var _tos = target.getJunctionTo(); + + for (var i = 0, n = array_length(_tos); i < n; i++) + _tos[i].setFrom(value_dragging); + } + + } else { + var _addInput = target.value_from == noone && target.connect_type == JUNCTION_CONNECT.input && target.node.auto_input; + + if(value_dragging.connect_type == JUNCTION_CONNECT.input) { + if(array_empty(value_draggings)) + _connect = [ value_dragging.setFrom(target), value_dragging, target ]; + + else { + for( var i = 0, n = array_length(value_draggings); i < n; i++ ) + value_draggings[i].setFrom(target); + } + + } else if(_addInput && !array_empty(value_draggings)) { + for( var i = 0, n = array_length(value_draggings); i < n; i++ ) + target.node.addInput(value_draggings[i]); + + } else { + if(value_drag_from && target.value_from && value_drag_from.node == target.node) + value_drag_from.setFrom(target.value_from); + + if(array_empty(value_draggings)) + _connect = [ target.setFrom(value_dragging), target, value_dragging ]; + + else { + var _node = target.node; + var _indx = target.index; + + for( var i = 0, n = array_length(value_draggings); i < n; i++ ) { + _node.inputs[_indx].setFrom(value_draggings[i]); + if(++_indx > array_length(_node.inputs)) break; + } + } + + } + } + + } else { + if(value_dragging.connect_type == JUNCTION_CONNECT.input) + value_dragging.removeFrom(); + value_dragging.node.triggerRender(); + + if(value_focus != value_dragging) { + var ctx = is_instanceof(frame_hovering, Node_Collection_Inline)? frame_hovering : getCurrentContext(); + if(value_dragging.node.inline_context && !key_mod_press(SHIFT)) + ctx = value_dragging.node.inline_context; + + with(dialogCall(o_dialog_add_node, mouse_mx + 8, mouse_my + 8, { context: ctx })) { + node_target_x = other.mouse_grid_x; + node_target_y = other.mouse_grid_y; + node_target_x_raw = other.mouse_grid_x; + node_target_y_raw = other.mouse_grid_y; + node_called = other.value_dragging; + + alarm[0] = 1; + } + } + } + + if(_connect[0] == -7 && !is_instanceof(value_dragging.node, Node_Pin)) { + if(_connect[1].value_from_loop != noone) + _connect[1].value_from_loop.destroy(); + + var menu = [ + menuItem("Feedback", function(data) { + var junc_in = data.params.junc_in; + var junc_out = data.params.junc_out; + + var feed = nodeBuild("Node_Feedback_Inline", 0, 0).skipDefault(); + // feed.connectJunctions(junc_in, junc_out); + feed.attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; + feed.attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; + feed.scanJunc(); + + }, THEME.feedback_24,,, { junc_in : _connect[1], junc_out : _connect[2] }), + + menuItem("Loop", function(data) { + var junc_in = data.params.junc_in; + var junc_out = data.params.junc_out; + + var feed = nodeBuild("Node_Iterate_Inline", 0, 0).skipDefault(); + feed.attributes.junc_in = [ junc_in .node.node_id, junc_in .index ]; + feed.attributes.junc_out = [ junc_out.node.node_id, junc_out.index ]; + feed.scanJunc(); + + }, THEME.loop_24,,, { junc_in : _connect[1], junc_out : _connect[2] }), + ]; + + menuCall(,,, menu); + } + + value_dragging = noone; + connection_draw_mouse = noone; + } + + function draggingValue() { + if(!value_dragging.node.active) { + value_dragging = noone; + value_draggings = []; + return; + } + + if(key_mod_double(SHIFT)) { + var _n = value_dragging.node; + var _l = value_dragging.connect_type == JUNCTION_CONNECT.input? _n.inputs : _n.outputs; + var _i = value_dragging.connect_type == JUNCTION_CONNECT.input? _n.inputs_index : _n.outputs_index; + + array_push_unique(value_draggings, value_dragging); + + for (var i = 0, n = array_length(_i); i < n; i++) { + var _j = _l[| _i[i]]; + if(_j.type == value_dragging.type) + array_push_unique(value_draggings, _j); + } + + } else if(key_mod_press(SHIFT)) { + array_push_unique(value_draggings, value_dragging); + + if(value_focus) + array_push_unique(value_draggings, value_focus); + + for (var i = 0, n = array_length(value_draggings); i < n; i++) { + var _v = value_draggings[i]; + var xx = _v.x - 1; + var yy = _v.y - 1; + + shader_set(sh_node_circle); + shader_set_color("color", COLORS._main_accent); + shader_set_f("thickness", 0.05); + shader_set_f("antialias", 0.05); + draw_rectangle(xx - 12 * graph_s, yy - 12 * graph_s, xx + 12 * graph_s, yy + 12 * graph_s, false); + shader_reset(); + } + + if(mouse_release(mb_left)) { + value_dragging = noone; + connection_draw_mouse = noone; + } + + } else { + var xx = value_dragging.x; + var yy = value_dragging.y; + var _mx = mx; + var _my = my; + var target = noone; + + if(value_focus && value_focus != value_dragging) + target = value_focus; + + else if(!key_mod_press(CTRL) && node_hovering != noone) { + if(value_dragging.connect_type == JUNCTION_CONNECT.input) { + target = node_hovering.getOutput(my, value_dragging); + if(target != noone) node_hovering.active_draw_index = 1; + + } else { + target = node_hovering.getInput(my, value_dragging, 0); + if(target != noone) + node_hovering.active_draw_index = 1; + + } + } + + var _mmx = target != noone? target.x : _mx; + var _mmy = target != noone? target.y : _my; + + connection_draw_mouse = [ _mmx, _mmy ]; + connection_draw_target = target; + + value_dragging.drawJunction(graph_s, value_dragging.x, value_dragging.y); + if(target) target.drawJunction(graph_s, target.x, target.y); + + var _inline_ctx = value_dragging.node.inline_context; + + if(_inline_ctx) { + if(is_instanceof(value_dragging.node, _inline_ctx.input_node_type) && value_dragging.connect_type == JUNCTION_CONNECT.input) + _inline_ctx = noone; + else if(is_instanceof(value_dragging.node, _inline_ctx.output_node_type) && value_dragging.connect_type == JUNCTION_CONNECT.output) + _inline_ctx = noone; + + if(!_inline_ctx.modifiable) + _inline_ctx = noone; + } + + if(_inline_ctx && !key_mod_press(SHIFT)) + _inline_ctx.addPoint(mouse_graph_x, mouse_graph_y); + + if(mouse_release(mb_left)) + connectDraggingValueTo(target); + } + + if(mouse_release(mb_left)) value_draggings = []; + } + + function drawJunctionConnect() { + var _focus = pFOCUS && !view_hovering; + + if(value_dragging) + draggingValue(); + + if(value_dragging == noone && value_focus && mouse_press(mb_left, _focus) && !key_mod_press(ALT)) { + value_dragging = value_focus; + value_draggings = []; + value_drag_from = noone; + + if(value_dragging.connect_type == JUNCTION_CONNECT.output) { + if(key_mod_press(CTRL)) { + var _to = value_dragging.getJunctionTo(); + + if(array_length(_to)) { + value_dragging = _to[0]; + value_draggings = array_create(array_length(_to)); + + for( var i = 0, n = array_length(_to); i < n; i++ ) { + value_draggings[i] = _to[i]; + _to[i].removeFrom(); + } + } + } else if(array_exists(nodes_selecting_jun, value_dragging.node)) { + var _jlist = ds_priority_create(); + + for( var i = 0, n = array_length(nodes_selecting_jun); i < n; i++ ) { + var _node = nodes_selecting_jun[i]; + + if(_node == value_focus.node) { + ds_priority_add(_jlist, value_focus, value_focus.y); + } else { + for( var j = 0, m = array_length(_node.outputs); j < m; j++ ) { + var _junction = _node.outputs[j]; + if(!_junction.visible) continue; + if(value_bit(_junction.type) & value_bit(value_dragging.type) == 0) continue; + + ds_priority_add(_jlist, _junction, _junction.y); + break; + } + } + } + + while(!ds_priority_empty(_jlist)) + array_push(value_draggings, ds_priority_delete_min(_jlist)); + + ds_priority_destroy(_jlist); + } + } + + if(value_dragging.connect_type == JUNCTION_CONNECT.input) { + if(key_mod_press(CTRL) && value_dragging.value_from) { + value_drag_from = value_dragging; + + var fr = value_dragging.value_from; + value_dragging.removeFrom(); + value_dragging = fr; + } + } + } + + nodes_selecting_jun = array_clone(nodes_selecting, 1); + + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + if(!display_parameter.show_control && _node.is_controller) continue; + _node.drawJunctionNames(gr_x, gr_y, mx, my, graph_s); + } + + } + + function callAddDialog(ctx = getCurrentContext()) { // + var _dia = dialogCall(o_dialog_add_node, mouse_mx + 8, mouse_my + 8, { context: ctx }); + + with(_dia) { + node_target_x = other.mouse_grid_x; + node_target_y = other.mouse_grid_y; + node_target_x_raw = other.mouse_grid_x; + node_target_y_raw = other.mouse_grid_y; + junction_hovering = other.junction_hovering; + + resetPosition(); + alarm[0] = 1; + } + + return _dia; + } + + function drawContext() { // + draw_set_text(f_p0, fa_left, fa_center); + var xx = ui(16), tt, tw, th; + var bh = toolbar_height - ui(12); + var tbh = h - toolbar_height / 2; + + for(var i = -1; i < array_length(node_context); i++) { + if(i == -1) { + tt = __txt("Global"); + } else { + var _cnt = node_context[i]; + tt = _cnt.renamed? _cnt.display_name : _cnt.name; + } + + tw = string_width(tt); + th = string_height(tt); + + if(i < array_length(node_context) - 1) { + if(buttonInstant(THEME.button_hide_fill, xx - ui(6), tbh - bh / 2, tw + ui(12), bh, [mx, my], pFOCUS, pHOVER) == 2) { + node_hover = noone; + nodes_selecting = []; + PANEL_PREVIEW.resetNodePreview(); + + var _ctx = node_context[i + 1]; + var _nodeFocus = _ctx; + + if(i == -1) + resetContext(); + else { + array_resize(node_context, i + 1); + nodes_list = node_context[i].getNodeList(); + } + + nodes_selecting = [ _nodeFocus ]; + toCenterNode(nodes_selecting); + setContextFrame(true, _ctx); + break; + } + + draw_sprite_ui_uniform(THEME.arrow, 0, xx + tw + ui(16), tbh, 1, COLORS._main_icon); + } + + draw_set_color(COLORS._main_text); + draw_set_alpha(i < array_length(node_context) - 1? 0.33 : 1); + draw_text(xx, tbh, tt); + draw_set_alpha(1); + + xx += tw + ui(32); + } + + return xx; + } + + function drawToolBar() { // + toolbar_height = ui(40); + var ty = h - toolbar_height; + + if(pHOVER && point_in_rectangle(mx, my, 0, ty, w, h)) + mouse_on_graph = false; + + draw_sprite_stretched(THEME.toolbar, 0, 0, ty, w, h); + var cont_x = drawContext(); + + var tbx = w - ui(6); + var tby = ty + toolbar_height / 2; + var _m = [ mx, my ]; + + for( var i = 0, n = array_length(toolbars); i < n; i++ ) { + var tbs = toolbars[i]; + + for (var j = 0, m = array_length(tbs); j < m; j++) { + var tb = tbs[j]; + var tbObj = tb[0]; + + if(is_instanceof(tbObj, widget)) { + tbObj.setFocusHover(pFOCUS, pHOVER); + + var _wdw = ui(32); + var _wdx = tbx - _wdw; + if(_wdx < cont_x) break; + + var _param = new widgetParam(_wdx, ty + ui(8), _wdw, toolbar_height - ui(16), tb[1](), {}, _m, x, y); + _param.font = f_p3; + + tbObj.color = COLORS._main_text_sub; + tbObj.drawParam(_param); + + tbx -= _wdw + ui(4); + + } else { + var tbInd = tb[1](); + var tbTooltip = tb[2](); + + var bs = ui(28); + if(tbx - (bs + ui(4)) < cont_x) break; + + var b = buttonInstant(THEME.button_hide, tbx - bs, tby - bs / 2, bs, bs, _m, pFOCUS, pHOVER, tbTooltip, tbObj, tbInd); + if(b == 2) tb[3]( { x: x + tbx - bs, y: y + tby - bs / 2 } ); + tbx -= bs + ui(4); + } + + } + + tbx -= ui(2); + + draw_set_color(COLORS.panel_toolbar_separator); + draw_line_width(tbx, tby - toolbar_height / 2 + ui(8), tbx, tby + toolbar_height / 2 - ui(8), 2); + + if(tbx < cont_x) break; + tbx -= ui(6); + } + + } + + function drawMinimap() { // + if(!minimap_show) return; + var mx1 = w - ui(8); + var my1 = h - toolbar_height - ui(8); + var mx0 = mx1 - minimap_w; + var my0 = my1 - minimap_h; + + minimap_w = min(minimap_w, w - ui(16)); + minimap_h = min(minimap_h, h - ui(16) - toolbar_height); + + var mini_hover = false; + if(pHOVER && point_in_rectangle(mx, my, mx0, my0, mx1, my1)) { + mouse_on_graph = false; + mini_hover = true; + } + + var hover = mini_hover && !point_in_rectangle(mx, my, mx0, my0, mx0 + ui(16), my0 + ui(16)) && !minimap_dragging; + + if(!is_surface(minimap_surface) || surface_get_width_safe(minimap_surface) != minimap_w || surface_get_height_safe(minimap_surface) != minimap_h) { + minimap_surface = surface_create_valid(minimap_w, minimap_h); + } + + surface_set_target(minimap_surface); + draw_clear_alpha(COLORS.panel_bg_clear_inner, 0.75); + if(!array_empty(nodes_list)) { + var minx = 99999; + var maxx = -99999; + var miny = 99999; + var maxy = -99999; + + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + minx = min(_node.x - 32, minx); + maxx = max(_node.x + _node.w + 32, maxx); + + miny = min(_node.y - 32, miny); + maxy = max(_node.y + _node.h + 32, maxy); + } + + var cx = (minx + maxx) / 2; + var cy = (miny + maxy) / 2; + var spw = maxx - minx; + var sph = maxy - miny; + var ss = min(minimap_w / spw, minimap_h / sph); + + draw_set_alpha(0.4); + for(var i = 0; i < array_length(nodes_list); i++) { + var _node = nodes_list[i]; + + var nx = minimap_w / 2 + (_node.x - cx) * ss; + var ny = minimap_h / 2 + (_node.y - cy) * ss; + var nw = _node.w * ss; + var nh = _node.h * ss; + + draw_set_color(_node.getColor()); + draw_set_alpha(0.2 + 0.8 * (!is_instanceof(_node, Node_Frame))); + draw_rectangle(nx, ny, nx + nw, ny + nh, false); + draw_set_alpha(1); + } + draw_set_alpha(1); + + var gx = minimap_w / 2 - (graph_x + cx) * ss; + var gy = minimap_h / 2 - (graph_y + cy) * ss; + var gw = w / graph_s * ss; + var gh = h / graph_s * ss; + + draw_set_color(COLORS.panel_graph_minimap_focus); + draw_rectangle(gx, gy, gx + gw, gy + gh, 1); + + if(minimap_panning) { + graph_x = -((mx - mx0 - gw / 2) - minimap_w / 2) / ss - cx; + graph_y = -((my - my0 - gh / 2) - minimap_h / 2) / ss - cy; + + graph_x = round(graph_x); + graph_y = round(graph_y); + + if(mouse_release(mb_left)) + minimap_panning = false; + } + + if(mouse_click(mb_left, hover)) + minimap_panning = true; + } + + surface_reset_target(); + + draw_surface_ext_safe(minimap_surface, mx0, my0, 1, 1, 0, c_white, 0.5 + 0.35 * hover); + draw_set_color(COLORS.panel_graph_minimap_outline); + draw_rectangle(mx0, my0, mx1 - 1, my1 - 1, true); + + if(minimap_dragging) { + mouse_on_graph = false; + var sw = minimap_drag_sx + minimap_drag_mx - mx; + var sh = minimap_drag_sy + minimap_drag_my - my; + + minimap_w = max(ui(64), sw); + minimap_h = max(ui(64), sh); + + if(mouse_release(mb_left)) + minimap_dragging = false; + } + + if(pHOVER && point_in_rectangle(mx, my, mx0, my0, mx0 + ui(16), my0 + ui(16))) { + draw_sprite_ui(THEME.node_resize, 0, mx0 + ui(10), my0 + ui(10), 0.5, 0.5, 180, c_white, 0.75); + if(mouse_press(mb_left, pFOCUS)) { + minimap_dragging = true; + minimap_drag_sx = minimap_w; + minimap_drag_sy = minimap_h; + minimap_drag_mx = mx; + minimap_drag_my = my; + } + } else + draw_sprite_ui(THEME.node_resize, 0, mx0 + ui(10), my0 + ui(10), 0.5, 0.5, 180, c_white, 0.3); + } + + function drawSearch() { + if(!is_searching) return; + + var tw = ui(200); + var th = line_get_height(f_p2, 6); + + var pd = ui(6); + var ww = tw + pd * 2 + (ui(4) + ui(24)) * 3; + var hh = th + pd * 2; + + var x1 = w - ui(8); + var x0 = x1 - ww; + + var y0 = ui(8); + var y1 = y0 + hh; + + draw_sprite_stretched( THEME.ui_panel_bg, 3, x0, y0, ww, hh); + draw_sprite_stretched_add(THEME.ui_panel, 1, x0, y0, ww, hh, c_white, 0.25); + draw_sprite_stretched( THEME.button_hide_fill, 1, x0 + pd, y0 + pd, tw, th); + + tb_search.font = f_p2; + tb_search.setFocusHover(pFOCUS, pHOVER); + tb_search.draw(x0 + pd, y0 + pd, tw, th, search_string, [ mx, my ]); + + var bs = ui(24); + var bx = x1 - bs - pd; + var by = y0 + pd; + if(buttonInstant(THEME.button_hide_fill, bx, by, bs, bs, [ mx, my ], pFOCUS, pHOVER, "", THEME.cross_16) == 2 + || keyboard_check_pressed(vk_escape) + || keyboard_check_pressed(vk_enter)) + is_searching = false; + + bx -= bs + ui(4); + if(buttonInstant(THEME.button_hide_fill, bx, by, bs, bs, [ mx, my ], pFOCUS, pHOVER, "", THEME.arrow_wire_16, 0) == 2) { + if(!array_empty(search_result)) { + search_index = safe_mod(search_index + 1, array_length(search_result)); + nodes_selecting = [ search_result[search_index] ]; + toCenterNode(nodes_selecting); + } + } + + bx -= bs + ui(4); + if(buttonInstant(THEME.button_hide_fill, bx, by, bs, bs, [ mx, my ], pFOCUS, pHOVER, "", THEME.arrow_wire_16, 2) == 2) { + if(!array_empty(search_result)) { + search_index = safe_mod(search_index - 1 + array_length(search_result), array_length(search_result)); + nodes_selecting = [ search_result[search_index] ]; + toCenterNode(nodes_selecting); + } + } + + if(point_in_rectangle(mx, my, x0, y0, x1, y1)) + mouse_on_graph = false; + } + + function drawContextFrame() { + if(!context_framing) return; + context_frame_progress = lerp_float(context_frame_progress, 1, 8); + if(context_frame_progress == 1) + context_framing = false; + + var _fr_x0 = 0; + var _fr_y0 = 0; + var _fr_x1 = w; + var _fr_y1 = h - toolbar_height; + + var _to_x0 = context_frame_sx; + var _to_y0 = context_frame_sy; + var _to_x1 = context_frame_ex; + var _to_y1 = context_frame_ey; + + var prog = context_frame_direct? context_frame_progress : 1 - context_frame_progress; + var frm_x0 = lerp(_fr_x0, _to_x0, prog); + var frm_y0 = lerp(_fr_y0, _to_y0, prog); + var frm_x1 = lerp(_fr_x1, _to_x1, prog); + var frm_y1 = lerp(_fr_y1, _to_y1, prog); + + draw_set_color(COLORS._main_accent); + draw_set_alpha(0.8); + draw_roundrect_ext(frm_x0, frm_y0, frm_x1, frm_y1, THEME_VALUE.panel_corner_radius, THEME_VALUE.panel_corner_radius, true); + draw_set_alpha(1); + } + + function drawSlideShow() { + if(!project.useSlideShow) return; + + var amo = project.slideShow_amount; + var ind = project.slideShow_index; + var cur = project.slideShow_current; + + var _sl_w = (amo - 1) * ui(16) + ui(16 * 2); + var _sl_h = ui(32); + + var _sl_x = w / 2 - _sl_w / 2; + var _ss_x = _sl_x; + + var _sl_y = h - toolbar_height - ui(8) - _sl_h; + var _ss_y = _sl_y + _sl_h - ui(16); + + if(cur != noone && cur.slide_title != "") { + draw_set_text(f_p2, fa_center, fa_top, COLORS._main_icon_light); + var _txtw = string_width(cur.slide_title) + ui(32); + _sl_w = max(_sl_w, _txtw); + _sl_h = _sl_h + ui(8 + 12); + } + + slider_width = slider_width == 0? _sl_w : lerp_float(slider_width, _sl_w, 10); + _sl_x = w / 2 - slider_width / 2; + _sl_y = h - toolbar_height - ui(8) - _sl_h; + + draw_sprite_stretched(THEME.ui_panel_bg, 3, _sl_x, _sl_y, slider_width, _sl_h); + + if(cur != noone) draw_text_add(round(w / 2), round(_sl_y + ui(8)), cur.slide_title); + + var _hv = false; + + for(var i = 0; i < amo; i++) { + var _sx = _ss_x + ui(16) + i * ui(16); + var _sy = _ss_y; + + var cc = i == ind? COLORS._main_accent : COLORS._main_icon; + var aa = i == ind? 1 : .5; + var ss = i == ind? 1 : .8; + + var slid = struct_try_get(project.slideShow, project.slideShow_keys[i], noone); + + if(pHOVER && point_in_circle(mx, my, _sx, _sy, ui(8))) { + if(slid) TOOLTIP = slid.slide_title; + _hv = true; + aa = 1; + + if(mouse_press(mb_left, pFOCUS)) + setSlideShow(i); + } + + draw_sprite_ext(THEME.circle, 0, _sx, _sy, ss, ss, 0, cc, aa); + } + + if(point_in_rectangle(mx, my, _sl_x, _sl_y, _sl_x + slider_width, _sl_y + _sl_h)) { + mouse_on_graph = false; + + if(pHOVER && !_hv) { + draw_sprite_stretched_add(THEME.ui_panel_bg, 4, _sl_x, _sl_y, slider_width, _sl_h, COLORS._main_icon, 0.05); + draw_sprite_stretched_add(THEME.ui_panel, 1, _sl_x, _sl_y, slider_width, _sl_h, c_white, 0.1); + + if(mouse_press(mb_left, pFOCUS)) + setSlideShow((ind + 1) % amo); + } + } + } + + function drawContent(panel) { // //// Main Draw + if(!project.active) return; + + dragGraph(); + + toolbars = [ toolbars_general ]; + if(array_length(nodes_selecting) > 1) { + if(array_exists(nodes_selecting, nodes_select_anchor)) + array_push(toolbars, toolbars_halign, toolbars_valign, toolbars_distrib_space); + else + array_push(toolbars, toolbars_halign, toolbars_valign, toolbars_distrib); + } + + graph_cx = (w / 2) / graph_s - graph_x; + graph_cy = (h / 2) / graph_s - graph_y; + + var context = getCurrentContext(); + if(context != noone) title_raw += " > " + (context.renamed? context.display_name : context.name); + + bg_color = context == noone? COLORS.panel_bg_clear : merge_color(COLORS.panel_bg_clear, context.getColor(), 0.05); + draw_clear(bg_color); + node_bg_hovering = drawBasePreview(); + drawGrid(); + + var ovy = ui(8); + if(show_view_control == 2) ovy += ui(36); + // if(is_searching) ovy += line_get_height(f_p2, 20); + + drawNodes(); + + draw_set_text(f_p2, fa_right, fa_top, COLORS._main_text_sub); + draw_text_add(w - ui(8), ovy, $"x{graph_s_to}"); + + drawJunctionConnect(); + drawContextFrame(); + + mouse_on_graph = true; + drawToolBar(); + drawMinimap(); + + drawViewControl(); + + if(pFOCUS && !view_hovering) array_foreach(nodes_selecting, function(node) { node.focusStep(); }); + + if(UPDATE == RENDER_TYPE.full) draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering", "Rendering") + "..."); + else if(UPDATE == RENDER_TYPE.partial) draw_text(w - ui(8), ui(28), __txtx("panel_graph_rendering_partial", "Rendering partial") + "..."); + + graph_dragging_key = false; + graph_zooming_key = false; + + drawSearch() + + if(LIVE_UPDATE) { + draw_set_text(f_p0b, fa_right, fa_bottom, COLORS._main_value_negative); + draw_text(w - 8, h - toolbar_height, "Live Update"); + } + + drawSlideShow(); + + ////////////////////////////////// File drop ////////////////////////////////// + + if(pHOVER) { + var gr_x = graph_x * graph_s; + var gr_y = graph_y * graph_s; + var _gx = mx / graph_s - graph_x; + var _gy = my / graph_s - graph_y; + var _node_hover = noone; + + var _mx = (FILE_IS_DROPPING? FILE_DROPPING_X : mouse_mx) - x; + var _my = (FILE_IS_DROPPING? FILE_DROPPING_Y : mouse_my) - y; + + for(var i = 0; i < array_length(nodes_list); i++) { + var _n = nodes_list[i]; + if(is_instanceof(_n, Node_Frame)) continue; + + if(_n.pointIn(gr_x, gr_y, _mx, _my, graph_s)) + _node_hover = _n; + } + + if(DRAGGING || FILE_IS_DROPPING) + draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1); + + if(DRAGGING) { // file dropping + if(_node_hover && _node_hover.droppable(DRAGGING)) { + _node_hover.draw_droppable = true; + if(mouse_release(mb_left)) _node_hover.onDrop(DRAGGING); + + } else { + if(mouse_release(mb_left)) checkDropItem(); + } + } + + if(FILE_IS_DROPPING && _node_hover && _node_hover.dropPath != noone) + _node_hover.draw_droppable = true; + + if(FILE_DROPPED && !array_empty(FILE_DROPPING)) { + if(_node_hover && _node_hover.dropPath != noone) + _node_hover.dropPath(FILE_DROPPING); + else + run_in(1, load_file_path, [ FILE_DROPPING, _gx, _gy ]); + } + } + + } + + //// ============ Action ============ + + function createNodeHotkey(_node, _param = noone) { + var node; + + if(mouse_create_x == undefined || mouse_create_sx != mouse_grid_x || mouse_create_sy != mouse_grid_y) { + mouse_create_sx = mouse_grid_x; + mouse_create_sy = mouse_grid_y; + + mouse_create_x = mouse_grid_x; + mouse_create_y = mouse_grid_y; + } + + var _mx = mouse_create_x; + var _my = mouse_create_y; + var _gs = project.graphGrid.size; + + if(is_string(_node)) node = nodeBuild(_node, _mx, _my); + else node = _node(_mx, _my, getCurrentContext(), _param); + + if(node == noone) return; + + mouse_create_y = ceil((mouse_create_y + node.h + _gs / 2) / _gs) * _gs; + + if(value_dragging == noone) return; + + if(value_dragging.connect_type == JUNCTION_CONNECT.output) { + if(node.input_display_list != -1) { + for (var i = 0, n = array_length(node.input_display_list); i < n; i++) { + if(!is_real(node.input_display_list[i])) continue; + if(node.inputs[node.input_display_list[i]].setFrom(value_dragging)) break; + } + + } else { + for (var i = 0, n = array_length(node.inputs); i < n; i++) + if(node.inputs[i].setFrom(value_dragging)) break; + } + + } else if(value_dragging.connect_type == JUNCTION_CONNECT.input) { + for (var i = 0, n = array_length(node.outputs); i < n; i++) + if(value_dragging.setFrom(node.outputs[i])) break; + + } + + value_dragging = noone; + } + + function doTransform() { + for( var i = 0; i < array_length(nodes_selecting); i++ ) { + var node = nodes_selecting[i]; + if(array_empty(node.outputs)) continue; + + var _o = node.outputs[0]; + if(_o.type == VALUE_TYPE.surface || _o.type == VALUE_TYPE.dynaSurface) { + var tr = nodeBuild("Node_Transform", node.x + node.w + 64, node.y).skipDefault(); + tr.inputs[0].setFrom(_o); + } + } + } - function doDuplicate() { - if(array_empty(nodes_selecting)) return; - - var _map = {}; - var _pmap = {}; - var _node = []; - - for(var i = 0; i < array_length(nodes_selecting); i++) { - var _n = nodes_selecting[i]; - - if(_n.inline_parent_object != "") - _pmap[$ _n.inline_context.node_id] = _n.inline_parent_object; - - SAVE_NODE(_node, _n,,,, getCurrentContext()); - } - - _map.nodes = _node; - - ds_map_clear(APPEND_MAP); - APPEND_LIST = []; - - CLONING = true; - var _pmap_keys = variable_struct_get_names(_pmap); - for( var i = 0, n = array_length(_pmap_keys); i < n; i++ ) { - var _pkey = _pmap_keys[i]; - var _original = PROJECT.nodeMap[? _pkey]; - var _nodeS = _pmap[$ _pkey]; - - CLONING_GROUP = _original; - var _newGroup = nodeBuild(_nodeS, _original.x, _original.y).skipDefault(); - APPEND_MAP[? _pkey] = _newGroup; - } - - APPEND_LIST = __APPEND_MAP(_map,, APPEND_LIST); - recordAction(ACTION_TYPE.collection_loaded, array_clone(APPEND_LIST)); - CLONING = false; - - if(array_empty(APPEND_LIST)) return; - - for(var i = 0; i < array_length(nodes_selecting); i++) { - var _orignal = nodes_selecting[i]; - if(!_orignal.clonable) continue; - - var _cloned = ds_map_try_get(APPEND_MAP, _orignal.node_id, ""); - var _inline_ctx = _orignal.inline_context; - - if(_inline_ctx != noone && _cloned != "") { - _inline_ctx = ds_map_try_get(APPEND_MAP, _inline_ctx.node_id, _inline_ctx); - _inline_ctx.addNode(PROJECT.nodeMap[? _cloned]); - } - } - - var x0 = 99999999; - var y0 = 99999999; - for(var i = 0; i < array_length(APPEND_LIST); i++) { - var _node = APPEND_LIST[i]; - - x0 = min(x0, _node.x); - y0 = min(y0, _node.y); - } - - node_dragging = APPEND_LIST[0]; - node_drag_mx = x0; node_drag_my = y0; - node_drag_sx = x0; node_drag_sy = y0; - node_drag_ox = x0; node_drag_oy = y0; - - nodes_selecting = APPEND_LIST; - } + function doDuplicate() { + if(array_empty(nodes_selecting)) return; + + var _map = {}; + var _pmap = {}; + var _node = []; + + for(var i = 0; i < array_length(nodes_selecting); i++) { + var _n = nodes_selecting[i]; + + if(_n.inline_parent_object != "") + _pmap[$ _n.inline_context.node_id] = _n.inline_parent_object; + + SAVE_NODE(_node, _n,,,, getCurrentContext()); + } + + _map.nodes = _node; + + ds_map_clear(APPEND_MAP); + APPEND_LIST = []; + + CLONING = true; + var _pmap_keys = variable_struct_get_names(_pmap); + for( var i = 0, n = array_length(_pmap_keys); i < n; i++ ) { + var _pkey = _pmap_keys[i]; + var _original = PROJECT.nodeMap[? _pkey]; + var _nodeS = _pmap[$ _pkey]; + + CLONING_GROUP = _original; + var _newGroup = nodeBuild(_nodeS, _original.x, _original.y).skipDefault(); + APPEND_MAP[? _pkey] = _newGroup; + } + + APPEND_LIST = __APPEND_MAP(_map,, APPEND_LIST); + recordAction(ACTION_TYPE.collection_loaded, array_clone(APPEND_LIST)); + CLONING = false; + + if(array_empty(APPEND_LIST)) return; + + for(var i = 0; i < array_length(nodes_selecting); i++) { + var _orignal = nodes_selecting[i]; + if(!_orignal.clonable) continue; + + var _cloned = ds_map_try_get(APPEND_MAP, _orignal.node_id, ""); + var _inline_ctx = _orignal.inline_context; + + if(_inline_ctx != noone && _cloned != "") { + _inline_ctx = ds_map_try_get(APPEND_MAP, _inline_ctx.node_id, _inline_ctx); + _inline_ctx.addNode(PROJECT.nodeMap[? _cloned]); + } + } + + var x0 = 99999999; + var y0 = 99999999; + for(var i = 0; i < array_length(APPEND_LIST); i++) { + var _node = APPEND_LIST[i]; + + x0 = min(x0, _node.x); + y0 = min(y0, _node.y); + } + + node_dragging = APPEND_LIST[0]; + node_drag_mx = x0; node_drag_my = y0; + node_drag_sx = x0; node_drag_sy = y0; + node_drag_ox = x0; node_drag_oy = y0; + + nodes_selecting = APPEND_LIST; + } - function doInstance() { - var node = getFocusingNode(); - if(node == noone) return; - - if(node.instanceBase == noone) { - node.isInstancer = true; - - CLONING = true; - var _type = instanceof(node); - var _node = nodeBuild(_type, x, y).skipDefault(); - CLONING = false; - - _node.setInstance(node); - } - - var _nodeNew = _node.clone(); - - node_dragging = _nodeNew; - node_drag_mx = _nodeNew.x; node_drag_my = _nodeNew.y; - node_drag_sx = _nodeNew.x; node_drag_sy = _nodeNew.y; - node_drag_ox = _nodeNew.x; node_drag_oy = _nodeNew.y; - } + function doInstance() { + var node = getFocusingNode(); + if(node == noone) return; + + if(node.instanceBase == noone) { + node.isInstancer = true; + + CLONING = true; + var _type = instanceof(node); + var _node = nodeBuild(_type, x, y).skipDefault(); + CLONING = false; + + _node.setInstance(node); + } + + var _nodeNew = _node.clone(); + + node_dragging = _nodeNew; + node_drag_mx = _nodeNew.x; node_drag_my = _nodeNew.y; + node_drag_sx = _nodeNew.x; node_drag_sy = _nodeNew.y; + node_drag_ox = _nodeNew.x; node_drag_oy = _nodeNew.y; + } - function doCopy() { // - if(array_empty(nodes_selecting)) return; - clipboard_set_text(""); - - var _map = {}; - _map.nodes = []; - for(var i = 0; i < array_length(nodes_selecting); i++) - SAVE_NODE(_map.nodes, nodes_selecting[i],,,, getCurrentContext()); - - clipboard_set_text(json_stringify_minify(_map)); - } + function doCopy() { // + if(array_empty(nodes_selecting)) return; + clipboard_set_text(""); + + var _map = {}; + _map.nodes = []; + for(var i = 0; i < array_length(nodes_selecting); i++) + SAVE_NODE(_map.nodes, nodes_selecting[i],,,, getCurrentContext()); + + clipboard_set_text(json_stringify_minify(_map)); + } - function doPaste() { // - var txt = clipboard_get_text(); - var _map = json_try_parse(txt, noone); - - if(txt == "") return; - - if(is_struct(_map)) { - ds_map_clear(APPEND_MAP); - APPENDING = true; - CLONING = true; - var _app = __APPEND_MAP(_map); - APPENDING = false; - CLONING = false; - - if(_app == noone) - return; - - if(array_empty(_app)) - return; - - var x0 = 99999999; - var y0 = 99999999; - for(var i = 0; i < array_length(_app); i++) { - var _node = _app[i]; - - x0 = min(x0, _node.x); - y0 = min(y0, _node.y); - } - - node_dragging = _app[0]; - node_drag_mx = x0; node_drag_my = y0; - node_drag_sx = x0; node_drag_sy = y0; - node_drag_ox = x0; node_drag_oy = y0; - - nodes_selecting = _app; - return; - } - - var _ext = filename_ext_raw(txt); - - if(_ext == "pxc") - APPEND(txt); - - else if(_ext == "pxcc") - APPEND(txt); - - else if(_ext == "png") { - if(file_exists_empty(txt)) { - Node_create_Image_path(0, 0, txt); - return; - } - - var path = TEMPDIR + "url_pasted_" + string(irandom_range(100000, 999999)) + ".png"; - var img = http_get_file(txt, path); - CLONING = true; - var node = Node_create_Image(0, 0); - CLONING = false; - var args = [node, path]; - - global.FILE_LOAD_ASYNC[? img] = [ function(args) { - args[0].inputs[0].setValue(args[1]); - args[0].doUpdate(); - }, args]; - } - } + function doPaste() { // + var txt = clipboard_get_text(); + var _map = json_try_parse(txt, noone); + + if(txt == "") return; + + if(is_struct(_map)) { + ds_map_clear(APPEND_MAP); + APPENDING = true; + CLONING = true; + var _app = __APPEND_MAP(_map); + APPENDING = false; + CLONING = false; + + if(_app == noone) + return; + + if(array_empty(_app)) + return; + + var x0 = 99999999; + var y0 = 99999999; + for(var i = 0; i < array_length(_app); i++) { + var _node = _app[i]; + + x0 = min(x0, _node.x); + y0 = min(y0, _node.y); + } + + node_dragging = _app[0]; + node_drag_mx = x0; node_drag_my = y0; + node_drag_sx = x0; node_drag_sy = y0; + node_drag_ox = x0; node_drag_oy = y0; + + nodes_selecting = _app; + return; + } + + var _ext = filename_ext_raw(txt); + + if(_ext == "pxc") + APPEND(txt); + + else if(_ext == "pxcc") + APPEND(txt); + + else if(_ext == "png") { + if(file_exists_empty(txt)) { + Node_create_Image_path(0, 0, txt); + return; + } + + var path = TEMPDIR + "url_pasted_" + string(irandom_range(100000, 999999)) + ".png"; + var img = http_get_file(txt, path); + CLONING = true; + var node = Node_create_Image(0, 0); + CLONING = false; + var args = [node, path]; + + global.FILE_LOAD_ASYNC[? img] = [ function(args) { + args[0].inputs[0].setValue(args[1]); + args[0].doUpdate(); + }, args]; + } + } - function doBlend() { // - if(array_length(nodes_selecting) != 2) return; - - var _n0 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[0] : nodes_selecting[1]; - var _n1 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[1] : nodes_selecting[0]; - - var cx = max(_n0.x, _n1.x) + 160; - var cy = round((_n0.y + _n1.y) / 2 / 32) * 32; - - var _j0 = _n0.outputs[0]; - var _j1 = _n1.outputs[0]; - - if(_j0.type == VALUE_TYPE.surface && _j1.type == VALUE_TYPE.surface) { - var _blend = nodeBuild("Node_Blend", cx, cy, getCurrentContext()).skipDefault().skipDefault(); - _blend.inputs[0].setFrom(_j0); - _blend.inputs[1].setFrom(_j1); - - } else if((_j0.type == VALUE_TYPE.integer || _j0.type == VALUE_TYPE.float) && (_j1.type == VALUE_TYPE.integer || _j1.type == VALUE_TYPE.float)) { - var _blend = nodeBuild("Node_Math", cx, cy, getCurrentContext()).skipDefault().skipDefault(); - _blend.inputs[1].setFrom(_j0); - _blend.inputs[2].setFrom(_j1); - - } - - nodes_selecting = []; - } - - function doCompose() { // - if(array_empty(nodes_selecting)) return; - - var cx = nodes_selecting[0].x; - var cy = 0; - var pr = ds_priority_create(); - var amo = array_length(nodes_selecting); - var len = 0; - - for(var i = 0; i < amo; i++) { - var _node = nodes_selecting[i]; - if(array_length(_node.outputs) == 0) continue; - - if(_node.outputs[0].type != VALUE_TYPE.surface) continue; - - cx = max(cx, _node.x); - cy += _node.y; - - ds_priority_add(pr, _node, _node.y); - len++; - } - - cx = cx + 160; - cy = round(cy / len / 32) * 32; - - var _compose = nodeBuild("Node_Composite", cx, cy, getCurrentContext()).skipDefault(); - - repeat(len) { - var _node = ds_priority_delete_min(pr); - _compose.addInput(_node.outputs[0]); - } - - nodes_selecting = []; - ds_priority_destroy(pr); - } + function doBlend() { // + if(array_length(nodes_selecting) != 2) return; + + var _n0 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[0] : nodes_selecting[1]; + var _n1 = nodes_selecting[0].y < nodes_selecting[1].y? nodes_selecting[1] : nodes_selecting[0]; + + var cx = max(_n0.x, _n1.x) + 160; + var cy = round((_n0.y + _n1.y) / 2 / 32) * 32; + + var _j0 = _n0.outputs[0]; + var _j1 = _n1.outputs[0]; + + if(_j0.type == VALUE_TYPE.surface && _j1.type == VALUE_TYPE.surface) { + var _blend = nodeBuild("Node_Blend", cx, cy, getCurrentContext()).skipDefault().skipDefault(); + _blend.inputs[0].setFrom(_j0); + _blend.inputs[1].setFrom(_j1); + + } else if((_j0.type == VALUE_TYPE.integer || _j0.type == VALUE_TYPE.float) && (_j1.type == VALUE_TYPE.integer || _j1.type == VALUE_TYPE.float)) { + var _blend = nodeBuild("Node_Math", cx, cy, getCurrentContext()).skipDefault().skipDefault(); + _blend.inputs[1].setFrom(_j0); + _blend.inputs[2].setFrom(_j1); + + } + + nodes_selecting = []; + } + + function doCompose() { // + if(array_empty(nodes_selecting)) return; + + var cx = nodes_selecting[0].x; + var cy = 0; + var pr = ds_priority_create(); + var amo = array_length(nodes_selecting); + var len = 0; + + for(var i = 0; i < amo; i++) { + var _node = nodes_selecting[i]; + if(array_length(_node.outputs) == 0) continue; + + if(_node.outputs[0].type != VALUE_TYPE.surface) continue; + + cx = max(cx, _node.x); + cy += _node.y; + + ds_priority_add(pr, _node, _node.y); + len++; + } + + cx = cx + 160; + cy = round(cy / len / 32) * 32; + + var _compose = nodeBuild("Node_Composite", cx, cy, getCurrentContext()).skipDefault(); + + repeat(len) { + var _node = ds_priority_delete_min(pr); + _compose.addInput(_node.outputs[0]); + } + + nodes_selecting = []; + ds_priority_destroy(pr); + } - function doArray() { // - if(array_empty(nodes_selecting)) return; - - var cx = nodes_selecting[0].x; - var cy = 0; - var pr = ds_priority_create(); - var amo = array_length(nodes_selecting); - var len = 0; - - for(var i = 0; i < amo; i++) { - var _node = nodes_selecting[i]; - if(array_length(_node.outputs) == 0) continue; - - cx = max(cx, _node.x); - cy += _node.y; - - ds_priority_add(pr, _node, _node.y); - len++; - } - - cx = cx + 160; - cy = round(cy / len / 32) * 32; - - var _array = nodeBuild("Node_Array", cx, cy).skipDefault(); - - repeat(len) { - var _node = ds_priority_delete_min(pr); - _array.addInput(_node.outputs[0]); - } - - nodes_selecting = []; - ds_priority_destroy(pr); - } + function doArray() { // + if(array_empty(nodes_selecting)) return; + + var cx = nodes_selecting[0].x; + var cy = 0; + var pr = ds_priority_create(); + var amo = array_length(nodes_selecting); + var len = 0; + + for(var i = 0; i < amo; i++) { + var _node = nodes_selecting[i]; + if(array_length(_node.outputs) == 0) continue; + + cx = max(cx, _node.x); + cy += _node.y; + + ds_priority_add(pr, _node, _node.y); + len++; + } + + cx = cx + 160; + cy = round(cy / len / 32) * 32; + + var _array = nodeBuild("Node_Array", cx, cy).skipDefault(); + + repeat(len) { + var _node = ds_priority_delete_min(pr); + _array.addInput(_node.outputs[0]); + } + + nodes_selecting = []; + ds_priority_destroy(pr); + } - function doGroup() { // - if(array_empty(nodes_selecting)) return; - groupNodes(nodes_selecting); - } + function doGroup() { // + if(array_empty(nodes_selecting)) return; + groupNodes(nodes_selecting); + } - function doUngroup() { // - var _node = getFocusingNode(); - if(_node == noone) return; - if(!is_instanceof(_node, Node_Collection) || !_node.ungroupable) return; - - upgroupNode(_node); - } + function doUngroup() { // + var _node = getFocusingNode(); + if(_node == noone) return; + if(!is_instanceof(_node, Node_Collection) || !_node.ungroupable) return; + + upgroupNode(_node); + } - function doFrame() { // - var x0 = 999999, y0 = 999999, x1 = -999999, y1 = -999999; - - for( var i = 0; i < array_length(nodes_selecting); i++ ) { - var _node = nodes_selecting[i]; - x0 = min(x0, _node.x); - y0 = min(y0, _node.y); - x1 = max(x1, _node.x + _node.w); - y1 = max(y1, _node.y + _node.h); - } - - x0 -= 64; - y0 -= 64; - x1 += 64; - y1 += 64; - - var f = nodeBuild("Node_Frame", x0, y0, getCurrentContext()).skipDefault(); - f.inputs[0].setValue([x1 - x0, y1 - y0]); - } + function doFrame() { // + var x0 = 999999, y0 = 999999, x1 = -999999, y1 = -999999; + + for( var i = 0; i < array_length(nodes_selecting); i++ ) { + var _node = nodes_selecting[i]; + x0 = min(x0, _node.x); + y0 = min(y0, _node.y); + x1 = max(x1, _node.x + _node.w); + y1 = max(y1, _node.y + _node.h); + } + + x0 -= 64; + y0 -= 64; + x1 += 64; + y1 += 64; + + var f = nodeBuild("Node_Frame", x0, y0, getCurrentContext()).skipDefault(); + f.inputs[0].setValue([x1 - x0, y1 - y0]); + } - function doDelete(_merge = false) { // - __temp_merge = _merge; - - for(i = array_length(nodes_selecting) - 1; i >= 0; i--) { - var _node = array_safe_get_fast(nodes_selecting, i, 0); - if(_node && _node.manual_deletable) - _node.destroy(__temp_merge); - } - nodes_selecting = []; - } - - node_prop_clipboard = noone; - function doCopyProp() { // - if(node_hover == noone) return; - node_prop_clipboard = node_hover; - } - - function doPasteProp() { // - if(node_hover == noone) return; - if(node_prop_clipboard == noone) return; - if(!node_prop_clipboard.active) return; - - if(instanceof(node_prop_clipboard) != instanceof(node_hover)) return; - - var _vals = []; - for( var i = 0, n = array_length(node_prop_clipboard.inputs); i < n; i++ ) { - var _inp = node_prop_clipboard.inputs[i]; - _vals[i] = _inp.serialize(); - } - - for( var i = 0, n = array_length(node_hover.inputs); i < n; i++ ) { - var _inp = node_hover.inputs[i]; - if(_inp.value_from != noone) continue; - - _inp.applyDeserialize(_vals[i]); - } - - node_hover.clearInputCache(); - RENDER_PARTIAL - } - - function dropFile(path) { // - if(node_hovering && is_callable(node_hovering.on_drop_file)) - return node_hovering.on_drop_file(path); - return false; - } - - static checkDropItem = function() { // - var node = noone; - - switch(DRAGGING.type) { - case "Color": - node = nodeBuild("Node_Color", mouse_grid_x, mouse_grid_y).skipDefault(); - node.inputs[0].setValue(DRAGGING.data); - break; - - case "Palette": - node = nodeBuild("Node_Palette", mouse_grid_x, mouse_grid_y).skipDefault(); - node.inputs[0].setValue(DRAGGING.data); - break; - - case "Gradient": - node = nodeBuild("Node_Gradient_Out", mouse_grid_x, mouse_grid_y).skipDefault(); - node.inputs[0].setValue(DRAGGING.data); - break; - - case "Number": - if(is_array(DRAGGING.data) && array_length(DRAGGING.data) <= 4) { - switch(array_length(DRAGGING.data)) { - case 2 : node = nodeBuild("Node_Vector2", mouse_grid_x, mouse_grid_y).skipDefault(); break; - case 3 : node = nodeBuild("Node_Vector3", mouse_grid_x, mouse_grid_y).skipDefault(); break; - case 4 : node = nodeBuild("Node_Vector4", mouse_grid_x, mouse_grid_y).skipDefault(); break; - } - - for( var i = 0, n = array_length(DRAGGING.data); i < n; i++ ) - node.inputs[i].setValue(DRAGGING.data[i]); - } else { - node = nodeBuild("Node_Number", mouse_grid_x, mouse_grid_y).skipDefault(); - node.inputs[0].setValue(DRAGGING.data); - } - break; - - case "Bool": - node = nodeBuild("Node_Boolean", mouse_grid_x, mouse_grid_y).skipDefault(); - node.inputs[0].setValue(DRAGGING.data); - break; - - case "Text": - node = nodeBuild("Node_String", mouse_grid_x, mouse_grid_y).skipDefault(); - node.inputs[0].setValue(DRAGGING.data); - break; - - case "Path": - node = nodeBuild("Node_Path", mouse_grid_x, mouse_grid_y).skipDefault(); - break; - - case "Struct": - node = nodeBuild("Node_Struct", mouse_grid_x, mouse_grid_y).skipDefault(); - break; - - case "Asset": - var app = Node_create_Image_path(mouse_grid_x, mouse_grid_y, DRAGGING.data.path); - break; - - case "Collection": - var path = DRAGGING.data.path; - nodes_selecting = []; - - var app = APPEND(DRAGGING.data.path, getCurrentContext()); - - if(is_array(app)) { - var cx = 0; - var cy = 0; - var amo = array_length(app); - - for( var i = 0; i < amo; i++ ) { - cx += app[i].x; - cy += app[i].y; - } - - cx /= amo; - cy /= amo; - - for( var i = 0; i < amo; i++ ) { - app[i].x = app[i].x - cx + mouse_grid_x; - app[i].y = app[i].y - cy + mouse_grid_y; - } - - } else if(is_struct(app) && is_instanceof(app, Node)) { - app.x = mouse_grid_x; - app.y = mouse_grid_y; - } - break; - - case "Project": - run_in(1, function(path) { LOAD_PATH(path); }, [ DRAGGING.data.path ]); - break; - - } - - if(!key_mod_press(SHIFT) && node && struct_has(DRAGGING, "from") && DRAGGING.from.value_from == noone) { - for( var i = 0; i < array_length(node.outputs); i++ ) - if(DRAGGING.from.setFrom(node.outputs[i])) break; - } - } - - static bringNodeToFront = function(node) { // - if(!array_exists(nodes_list, node)) return; - - array_remove(nodes_list, node); - array_push(nodes_list, node); - } - - static onFullScreen = function() { run_in(1, fullView); } - - function searchNodes() { - nodes_selecting = []; - search_result = []; - search_index = 0; - - if(search_string == "") return; - - var _search = string_lower(search_string); - - for(var i = 0; i < array_length(nodes_list); i++) { - var _nl = nodes_list[i]; - var _name = string_lower(_nl.getDisplayName()); - - var _match = string_full_match(_name, _search); - _nl.search_match = _match; - - if( _match == -9999) continue; - - array_push(nodes_selecting, _nl); - array_push(search_result, _nl); - } - - if(!array_empty(nodes_selecting)) - toCenterNode(nodes_selecting); - } - - function toggleSearch() { - is_searching = !is_searching; - - if(is_searching) { - search_string = ""; - WIDGET_CURRENT = tb_search; - KEYBOARD_RESET - } - } - - function hideDisconnected() { - var _list = array_empty(nodes_selecting)? nodes_list : nodes_selecting; - - for (var i = 0, n = array_length(_list); i < n; i++) { - var _node = _list[i]; - - for(var j = 0; j < array_length(_node.inputs); j++) { - var _jun = _node.inputs[j]; - if(!_jun.isVisible()) continue; - - if(_jun.value_from == noone) - _jun.visible_manual = -1; - } - - for(var j = 0; j < array_length(_node.outputs); j++) { - var _jun = _node.outputs[j]; - if(!_jun.isVisible()) continue; - - if(array_empty(_jun.getJunctionTo())) - _jun.visible_manual = -1; - } - - _node.will_setHeight = true; - } - } - - function createTunnel() { - if(__junction_hovering == noone) return; - if(__junction_hovering.value_from == noone) return; - - var _jo = __junction_hovering.value_from; - var _ji = __junction_hovering; - - var _key = $"{__junction_hovering.name} {seed_random(3)}"; - - var _ti = nodeBuild("Node_Tunnel_In", _jo.rx + 32, _jo.ry).skipDefault(); - var _to = nodeBuild("Node_Tunnel_Out", _ji.rx - 32, _ji.ry).skipDefault(); - - _to.inputs[0].setValue(_key); - _ti.inputs[0].setValue(_key); - - _ti.inputs[1].setFrom(_jo); - _ji.setFrom(_to.outputs[0]); - } - - function createAction() { - if(array_empty(nodes_selecting)) return; - - var pan = new Panel_Action_Create(); - pan.setNodes(nodes_selecting); - pan.spr = PANEL_PREVIEW.getNodePreviewSurface(); - - var dia = dialogPanelCall(pan); - } - - //// =========== Serialize =========== - - static serialize = function() { - _map = { - name: instanceof(self), - - graph_x, - graph_y, - - graph_s, - graph_s_to, - }; - - if(!SAVING) _map.project = project; - - return _map; - } - - static deserialize = function(data) { - if(struct_has(data, "project")) setProject(data.project); - - graph_x = struct_try_get(data, "graph_x", graph_x); - graph_y = struct_try_get(data, "graph_y", graph_y); - - graph_s = struct_try_get(data, "graph_s", graph_s); - graph_s_to = struct_try_get(data, "graph_s_to", graph_s_to); - - return self; - } - - function close() { // - var panels = findPanels("Panel_Graph"); - - for( var i = 0, n = array_length(panels); i < n; i++ ) { - var _pan = panels[i]; - - if(_pan == self) continue; - - if(_pan.project == project) { //Not the last panel with that project, hence not closing the project just a panel. - panel.remove(self); - return; - } - } - - if(!project.modified || project.readonly) { - closeProject(project); - return; - } - - var dia = dialogCall(o_dialog_save); - dia.project = project; - } - - setProject(project); - initSize(); + function doDelete(_merge = false) { // + __temp_merge = _merge; + + for(i = array_length(nodes_selecting) - 1; i >= 0; i--) { + var _node = array_safe_get_fast(nodes_selecting, i, 0); + if(_node && _node.manual_deletable) + _node.destroy(__temp_merge); + } + nodes_selecting = []; + } + + node_prop_clipboard = noone; + function doCopyProp() { // + if(node_hover == noone) return; + node_prop_clipboard = node_hover; + } + + function doPasteProp() { // + if(node_hover == noone) return; + if(node_prop_clipboard == noone) return; + if(!node_prop_clipboard.active) return; + + if(instanceof(node_prop_clipboard) != instanceof(node_hover)) return; + + var _vals = []; + for( var i = 0, n = array_length(node_prop_clipboard.inputs); i < n; i++ ) { + var _inp = node_prop_clipboard.inputs[i]; + _vals[i] = _inp.serialize(); + } + + for( var i = 0, n = array_length(node_hover.inputs); i < n; i++ ) { + var _inp = node_hover.inputs[i]; + if(_inp.value_from != noone) continue; + + _inp.applyDeserialize(_vals[i]); + } + + node_hover.clearInputCache(); + RENDER_PARTIAL + } + + function dropFile(path) { // + if(node_hovering && is_callable(node_hovering.on_drop_file)) + return node_hovering.on_drop_file(path); + return false; + } + + static checkDropItem = function() { // + var node = noone; + + switch(DRAGGING.type) { + case "Color": + node = nodeBuild("Node_Color", mouse_grid_x, mouse_grid_y).skipDefault(); + node.inputs[0].setValue(DRAGGING.data); + break; + + case "Palette": + node = nodeBuild("Node_Palette", mouse_grid_x, mouse_grid_y).skipDefault(); + node.inputs[0].setValue(DRAGGING.data); + break; + + case "Gradient": + node = nodeBuild("Node_Gradient_Out", mouse_grid_x, mouse_grid_y).skipDefault(); + node.inputs[0].setValue(DRAGGING.data); + break; + + case "Number": + if(is_array(DRAGGING.data) && array_length(DRAGGING.data) <= 4) { + switch(array_length(DRAGGING.data)) { + case 2 : node = nodeBuild("Node_Vector2", mouse_grid_x, mouse_grid_y).skipDefault(); break; + case 3 : node = nodeBuild("Node_Vector3", mouse_grid_x, mouse_grid_y).skipDefault(); break; + case 4 : node = nodeBuild("Node_Vector4", mouse_grid_x, mouse_grid_y).skipDefault(); break; + } + + for( var i = 0, n = array_length(DRAGGING.data); i < n; i++ ) + node.inputs[i].setValue(DRAGGING.data[i]); + } else { + node = nodeBuild("Node_Number", mouse_grid_x, mouse_grid_y).skipDefault(); + node.inputs[0].setValue(DRAGGING.data); + } + break; + + case "Bool": + node = nodeBuild("Node_Boolean", mouse_grid_x, mouse_grid_y).skipDefault(); + node.inputs[0].setValue(DRAGGING.data); + break; + + case "Text": + node = nodeBuild("Node_String", mouse_grid_x, mouse_grid_y).skipDefault(); + node.inputs[0].setValue(DRAGGING.data); + break; + + case "Path": + node = nodeBuild("Node_Path", mouse_grid_x, mouse_grid_y).skipDefault(); + break; + + case "Struct": + node = nodeBuild("Node_Struct", mouse_grid_x, mouse_grid_y).skipDefault(); + break; + + case "Asset": + var app = Node_create_Image_path(mouse_grid_x, mouse_grid_y, DRAGGING.data.path); + break; + + case "Collection": + var path = DRAGGING.data.path; + nodes_selecting = []; + + var app = APPEND(DRAGGING.data.path, getCurrentContext()); + + if(is_array(app)) { + var cx = 0; + var cy = 0; + var amo = array_length(app); + + for( var i = 0; i < amo; i++ ) { + cx += app[i].x; + cy += app[i].y; + } + + cx /= amo; + cy /= amo; + + for( var i = 0; i < amo; i++ ) { + app[i].x = app[i].x - cx + mouse_grid_x; + app[i].y = app[i].y - cy + mouse_grid_y; + } + + } else if(is_struct(app) && is_instanceof(app, Node)) { + app.x = mouse_grid_x; + app.y = mouse_grid_y; + } + break; + + case "Project": + run_in(1, function(path) { LOAD_PATH(path); }, [ DRAGGING.data.path ]); + break; + + } + + if(!key_mod_press(SHIFT) && node && struct_has(DRAGGING, "from") && DRAGGING.from.value_from == noone) { + for( var i = 0; i < array_length(node.outputs); i++ ) + if(DRAGGING.from.setFrom(node.outputs[i])) break; + } + } + + static bringNodeToFront = function(node) { // + if(!array_exists(nodes_list, node)) return; + + array_remove(nodes_list, node); + array_push(nodes_list, node); + } + + static onFullScreen = function() { run_in(1, fullView); } + + function searchNodes() { + nodes_selecting = []; + search_result = []; + search_index = 0; + + if(search_string == "") return; + + var _search = string_lower(search_string); + + for(var i = 0; i < array_length(nodes_list); i++) { + var _nl = nodes_list[i]; + var _name = string_lower(_nl.getDisplayName()); + + var _match = string_full_match(_name, _search); + _nl.search_match = _match; + + if( _match == -9999) continue; + + array_push(nodes_selecting, _nl); + array_push(search_result, _nl); + } + + if(!array_empty(nodes_selecting)) + toCenterNode(nodes_selecting); + } + + function toggleSearch() { + is_searching = !is_searching; + + if(is_searching) { + search_string = ""; + WIDGET_CURRENT = tb_search; + KEYBOARD_RESET + } + } + + function hideDisconnected() { + var _list = array_empty(nodes_selecting)? nodes_list : nodes_selecting; + + for (var i = 0, n = array_length(_list); i < n; i++) { + var _node = _list[i]; + + for(var j = 0; j < array_length(_node.inputs); j++) { + var _jun = _node.inputs[j]; + if(!_jun.isVisible()) continue; + + if(_jun.value_from == noone) + _jun.visible_manual = -1; + } + + for(var j = 0; j < array_length(_node.outputs); j++) { + var _jun = _node.outputs[j]; + if(!_jun.isVisible()) continue; + + if(array_empty(_jun.getJunctionTo())) + _jun.visible_manual = -1; + } + + _node.will_setHeight = true; + } + } + + function createTunnel() { + if(__junction_hovering == noone) return; + if(__junction_hovering.value_from == noone) return; + + var _jo = __junction_hovering.value_from; + var _ji = __junction_hovering; + + var _key = $"{__junction_hovering.name} {seed_random(3)}"; + + var _ti = nodeBuild("Node_Tunnel_In", _jo.rx + 32, _jo.ry).skipDefault(); + var _to = nodeBuild("Node_Tunnel_Out", _ji.rx - 32, _ji.ry).skipDefault(); + + _to.inputs[0].setValue(_key); + _ti.inputs[0].setValue(_key); + + _ti.inputs[1].setFrom(_jo); + _ji.setFrom(_to.outputs[0]); + } + + function createAction() { + if(array_empty(nodes_selecting)) return; + + var pan = new Panel_Action_Create(); + pan.setNodes(nodes_selecting); + pan.spr = PANEL_PREVIEW.getNodePreviewSurface(); + + var dia = dialogPanelCall(pan); + } + + //// =========== Serialize =========== + + static serialize = function() { + _map = { + name: instanceof(self), + + graph_x, + graph_y, + + graph_s, + graph_s_to, + }; + + if(!SAVING) _map.project = project; + + return _map; + } + + static deserialize = function(data) { + if(struct_has(data, "project")) setProject(data.project); + + graph_x = struct_try_get(data, "graph_x", graph_x); + graph_y = struct_try_get(data, "graph_y", graph_y); + + graph_s = struct_try_get(data, "graph_s", graph_s); + graph_s_to = struct_try_get(data, "graph_s_to", graph_s_to); + + return self; + } + + function close() { // + var panels = findPanels("Panel_Graph"); + + for( var i = 0, n = array_length(panels); i < n; i++ ) { + var _pan = panels[i]; + + if(_pan == self) continue; + + if(_pan.project == project) { //Not the last panel with that project, hence not closing the project just a panel. + panel.remove(self); + return; + } + } + + if(!project.modified || project.readonly) { + closeProject(project); + return; + } + + var dia = dialogCall(o_dialog_save); + dia.project = project; + } + + setProject(project); + initSize(); } //// ========== File Drop ========== - + function load_file_path(path, _x = undefined, _y = undefined) { - if(!is_array(path)) path = [ path ]; - if(array_length(path) == 0) return; - - _x = _x == undefined? PANEL_GRAPH.graph_cx : _x; - _y = _y == undefined? PANEL_GRAPH.graph_cy : _y; - - var type = "others"; - - if(array_length(path) == 1 && directory_exists(path[0])) - type = "image"; - - for( var i = 0, n = array_length(path); i < n; i++ ) { - var p = path[i]; - var ext = string_lower(filename_ext(p)); - - switch(ext) { - case ".png" : - case ".jpg" : - case ".jpeg" : - type = "image"; - break; - } - } - - var is_multi = type == "image" && (array_length(path) > 1 || directory_exists(path[0])); - - if(is_multi) { - with(dialogCall(o_dialog_add_multiple_images, WIN_W / 2, WIN_H / 2)) - setPath(path); - } else { - if(!IS_CMD) PANEL_GRAPH.onStepBegin(); - - var node = noone; - for( var i = 0, n = array_length(path); i < n; i++ ) { - var p = path[i]; - var ext = filename_ext_raw(p); - - switch(ext) { - case "txt" : node = Node_create_Text_File_Read_path(_x, _y, p); break; - case "csv" : node = Node_create_CSV_File_Read_path(_x, _y, p); break; - case "json" : node = Node_create_Json_File_Read_path(_x, _y, p); break; - - case "ase" : - case "aseprite" : node = Node_create_ASE_File_Read_path(_x, _y, p); break; - - case "png" : - case "jpg" : - case "jpeg" : node = Node_create_Image_path(_x, _y, p); break; - - case "gif" : node = Node_create_Image_gif_path(_x, _y, p); break; - case "obj" : node = Node_create_3D_Obj_path(_x, _y, p); break; - case "wav" : node = Node_create_WAV_File_Read_path(_x, _y, p); break; - case "xml" : node = Node_create_XML_File_Read_path(_x, _y, p); break; - case "svg" : node = Node_create_SVG_path(_x, _y, p); break; - - case "pxc" : - case "cpxc" : LOAD_PATH(p); break; - case "pxcc" : APPEND(p); break; - - case "hex" : - case "gpl" : - case "pal" : - node = new Node_Palette(_x, _y, PANEL_GRAPH.getCurrentContext()).skipDefault(); - node.inputs[0].setValue(loadPalette(p)); - break; - } - - if(!IS_CMD) PANEL_GRAPH.mouse_grid_y += 160; - } - - // if(node && !IS_CMD) PANEL_GRAPH.toCenterNode(); - } + if(!is_array(path)) path = [ path ]; + if(array_length(path) == 0) return; + + _x = _x == undefined? PANEL_GRAPH.graph_cx : _x; + _y = _y == undefined? PANEL_GRAPH.graph_cy : _y; + + var type = "others"; + + if(array_length(path) == 1 && directory_exists(path[0])) + type = "image"; + + for( var i = 0, n = array_length(path); i < n; i++ ) { + var p = path[i]; + var ext = string_lower(filename_ext(p)); + + switch(ext) { + case ".png" : + case ".jpg" : + case ".jpeg" : + type = "image"; + break; + } + } + + var is_multi = type == "image" && (array_length(path) > 1 || directory_exists(path[0])); + + if(is_multi) { + with(dialogCall(o_dialog_add_multiple_images, WIN_W / 2, WIN_H / 2)) + setPath(path); + } else { + if(!IS_CMD) PANEL_GRAPH.onStepBegin(); + + var node = noone; + for( var i = 0, n = array_length(path); i < n; i++ ) { + var p = path[i]; + var ext = filename_ext_raw(p); + + switch(ext) { + case "txt" : node = Node_create_Text_File_Read_path(_x, _y, p); break; + case "csv" : node = Node_create_CSV_File_Read_path(_x, _y, p); break; + case "json" : node = Node_create_Json_File_Read_path(_x, _y, p); break; + + case "ase" : + case "aseprite" : node = Node_create_ASE_File_Read_path(_x, _y, p); break; + + case "png" : + case "jpg" : + case "jpeg" : node = Node_create_Image_path(_x, _y, p); break; + + case "gif" : node = Node_create_Image_gif_path(_x, _y, p); break; + case "obj" : node = Node_create_3D_Obj_path(_x, _y, p); break; + case "wav" : node = Node_create_WAV_File_Read_path(_x, _y, p); break; + case "xml" : node = Node_create_XML_File_Read_path(_x, _y, p); break; + case "svg" : node = Node_create_SVG_path(_x, _y, p); break; + + case "pxc" : + case "cpxc" : LOAD_PATH(p); break; + case "pxcc" : APPEND(p); break; + + case "hex" : + case "gpl" : + case "pal" : + node = new Node_Palette(_x, _y, PANEL_GRAPH.getCurrentContext()).skipDefault(); + node.inputs[0].setValue(loadPalette(p)); + break; + } + + if(!IS_CMD) PANEL_GRAPH.mouse_grid_y += 160; + } + + // if(node && !IS_CMD) PANEL_GRAPH.toCenterNode(); + } } \ No newline at end of file diff --git a/scripts/panel_inspector/panel_inspector.gml b/scripts/panel_inspector/panel_inspector.gml index 6cfddc4ec..c19684f58 100644 --- a/scripts/panel_inspector/panel_inspector.gml +++ b/scripts/panel_inspector/panel_inspector.gml @@ -1,1224 +1,1224 @@ #region funtion calls - function __fnInit_Inspector() { - registerFunction("Inspector", "Copy property", "C", MOD_KEY.ctrl, panel_inspector_copy_prop); - registerFunction("Inspector", "Paste property", "V", MOD_KEY.ctrl, panel_inspector_paste_prop); - registerFunction("Inspector", "Toggle animation", "I", MOD_KEY.none, panel_inspector_toggle_animation); - - registerFunction("", "Color picker", "", MOD_KEY.alt, panel_inspector_color_pick); - - registerFunction("Inspector", "Expand All Sections", "", MOD_KEY.none, panel_inspector_section_expand_all); - registerFunction("Inspector", "Collapse All Sections", "", MOD_KEY.none, panel_inspector_section_collapse_all); - - registerFunction("Inspector", "Reset", "", MOD_KEY.none, panel_inspector_reset); - registerFunction("Inspector", "Add", "", MOD_KEY.none, panel_inspector_add); - registerFunction("Inspector", "Remove", "", MOD_KEY.none, panel_inspector_remove); - registerFunction("Inspector", "Combine Axis", "", MOD_KEY.none, panel_inspector_axis_combine); - registerFunction("Inspector", "Separate Axis", "", MOD_KEY.none, panel_inspector_axis_separate); - registerFunction("Inspector", "Use Expression", "", MOD_KEY.none, panel_inspector_use_expression); - registerFunction("Inspector", "Disable Expression", "", MOD_KEY.none, panel_inspector_disable_expression); - registerFunction("Inspector", "Extract Value", "", MOD_KEY.none, panel_inspector_extract_single); - } - - function panel_inspector_copy_prop() { CALL("inspector_copy_property"); PANEL_INSPECTOR.propSelectCopy(); } - function panel_inspector_paste_prop() { CALL("inspector_paste_property"); PANEL_INSPECTOR.propSelectPaste(); } - function panel_inspector_toggle_animation() { CALL("inspector_toggle_animation"); PANEL_INSPECTOR.anim_toggling = true; } - - function panel_inspector_color_pick() { CALL("color_picker"); if(!PREFERENCES.alt_picker&& !MOUSE_BLOCK) return; PANEL_INSPECTOR.color_picking = true; } - - function panel_inspector_section_expand_all() { CALL("inspector_section_expand_all"); PANEL_INSPECTOR.section_expand_all(); } - function panel_inspector_section_collapse_all() { CALL("inspector_section_collapse_all"); PANEL_INSPECTOR.section_collapse_all(); } - - function panel_inspector_reset() { CALL("inspector_reset"); PANEL_INSPECTOR.junction_reset(); } - function panel_inspector_add() { CALL("inspector_add"); PANEL_INSPECTOR.junction_add(); } - function panel_inspector_remove() { CALL("inspector_remove"); PANEL_INSPECTOR.junction_remove(); } - function panel_inspector_axis_combine() { CALL("inspector_axis_combine"); PANEL_INSPECTOR.junction_axis_combine(); } - function panel_inspector_axis_separate() { CALL("inspector_axis_separate"); PANEL_INSPECTOR.junction_axis_separate(); } - function panel_inspector_use_expression() { CALL("inspector_use_expression"); PANEL_INSPECTOR.junction_use_expression(); } - function panel_inspector_disable_expression() { CALL("inspector_disable_expression"); PANEL_INSPECTOR.junction_disable_expression(); } - function panel_inspector_extract_single() { CALL("inspector_extract_single"); PANEL_INSPECTOR.junction_extract_single(); } - + function __fnInit_Inspector() { + registerFunction("", "Color picker", "", MOD_KEY.alt, panel_inspector_color_pick ).setMenu("color_picker") + + registerFunction("Inspector", "Copy property", "C", MOD_KEY.ctrl, panel_inspector_copy_prop ).setMenu("inspector_copy_property", THEME.copy) + registerFunction("Inspector", "Paste property", "V", MOD_KEY.ctrl, panel_inspector_paste_prop ).setMenu("inspector_paste_property", THEME.paste) + registerFunction("Inspector", "Toggle animation", "I", MOD_KEY.none, panel_inspector_toggle_animation ).setMenu("inspector_toggle_animation") + + registerFunction("Inspector", "Expand All Sections", "", MOD_KEY.none, panel_inspector_section_expand_all ).setMenu("inspector_expand_all_sections") + registerFunction("Inspector", "Collapse All Sections", "", MOD_KEY.none, panel_inspector_section_collapse_all ).setMenu("inspector_collapse_all_sections") + + registerFunction("Inspector", "Reset", "", MOD_KEY.none, panel_inspector_reset ).setMenu("inspector_reset") + registerFunction("Inspector", "Add", "", MOD_KEY.none, panel_inspector_add ).setMenu("inspector_add") + registerFunction("Inspector", "Remove", "", MOD_KEY.none, panel_inspector_remove ).setMenu("inspector_remove") + registerFunction("Inspector", "Combine Axis", "", MOD_KEY.none, panel_inspector_axis_combine ).setMenu("inspector_combine_axis") + registerFunction("Inspector", "Separate Axis", "", MOD_KEY.none, panel_inspector_axis_separate ).setMenu("inspector_separate_axis") + registerFunction("Inspector", "Use Expression", "", MOD_KEY.none, panel_inspector_use_expression ).setMenu("inspector_use_expression") + registerFunction("Inspector", "Disable Expression", "", MOD_KEY.none, panel_inspector_disable_expression ).setMenu("inspector_disable_expression") + registerFunction("Inspector", "Extract Value", "", MOD_KEY.none, panel_inspector_extract_single ).setMenu("inspector_extract_value") + } + + function panel_inspector_copy_prop() { CALL("inspector_copy_property"); PANEL_INSPECTOR.propSelectCopy(); } + function panel_inspector_paste_prop() { CALL("inspector_paste_property"); PANEL_INSPECTOR.propSelectPaste(); } + function panel_inspector_toggle_animation() { CALL("inspector_toggle_animation"); PANEL_INSPECTOR.anim_toggling = true; } + + function panel_inspector_color_pick() { CALL("color_picker"); if(!PREFERENCES.alt_picker&& !MOUSE_BLOCK) return; PANEL_INSPECTOR.color_picking = true; } + + function panel_inspector_section_expand_all() { CALL("inspector_section_expand_all"); PANEL_INSPECTOR.section_expand_all(); } + function panel_inspector_section_collapse_all() { CALL("inspector_section_collapse_all"); PANEL_INSPECTOR.section_collapse_all(); } + + function panel_inspector_reset() { CALL("inspector_reset"); PANEL_INSPECTOR.junction_reset(); } + function panel_inspector_add() { CALL("inspector_add"); PANEL_INSPECTOR.junction_add(); } + function panel_inspector_remove() { CALL("inspector_remove"); PANEL_INSPECTOR.junction_remove(); } + function panel_inspector_axis_combine() { CALL("inspector_axis_combine"); PANEL_INSPECTOR.junction_axis_combine(); } + function panel_inspector_axis_separate() { CALL("inspector_axis_separate"); PANEL_INSPECTOR.junction_axis_separate(); } + function panel_inspector_use_expression() { CALL("inspector_use_expression"); PANEL_INSPECTOR.junction_use_expression(); } + function panel_inspector_disable_expression() { CALL("inspector_disable_expression"); PANEL_INSPECTOR.junction_disable_expression(); } + function panel_inspector_extract_single() { CALL("inspector_extract_single"); PANEL_INSPECTOR.junction_extract_single(); } + #endregion function Inspector_Custom_Renderer(drawFn, registerFn = noone) : widget() constructor { - h = 64; - node = noone; - self.draw = drawFn; - - if(registerFn != noone) register = registerFn; - else { - register = function(parent = noone) { - if(!interactable) return; - self.parent = parent; - } - } - - static setNode = function(node) { self.node = node; return self; } - - static toString = function() { return $"Custon renderer"; } + h = 64; + node = noone; + self.draw = drawFn; + + if(registerFn != noone) register = registerFn; + else { + register = function(parent = noone) { + if(!interactable) return; + self.parent = parent; + } + } + + static setNode = function(node) { self.node = node; return self; } + + static toString = function() { return $"Custon renderer"; } } -function Inspector_Sprite(spr) constructor { self.spr = spr; } +function Inspector_Sprite(spr) constructor { self.spr = spr; } function Inspector_Spacer(height, line = false) constructor { self.h = height; self.line = line; } -function Inspector_Label( text, font = f_p3) constructor { self.text = text; self.font = font; } +function Inspector_Label( text, font = f_p3) constructor { self.text = text; self.font = font; } function Panel_Inspector() : PanelContent() constructor { - #region ---- main ---- - context_str = "Inspector"; - title = __txt("Inspector"); - icon = THEME.panel_inspector_icon; - - w = ui(400); - h = ui(640); - min_w = ui(160); - - locked = false; - focusable = true; - - inspecting = noone; - inspectings = []; - inspectGroup = false; - top_bar_h = ui(100); - - static initSize = function() { - content_w = w - ui(32); - content_h = h - top_bar_h - ui(12); - } - initSize(); - - view_mode_tooltip = new tooltipSelector("View", [ "Compact", "Spacious" ]) - #endregion - - #region ---- properties ---- - prop_hover = noone; - prop_selecting = noone; - - prop_highlight = noone; - prop_highlight_time = 0; - - prop_dragging = noone; - prop_sel_drag_x = 0; - prop_sel_drag_y = 0; - - color_picking = false; - - picker_index = 0; - picker_change = false; - - attribute_hovering = noone; - #endregion - - globalvar_viewer_init(); - drawWidgetInit(); - - #region ---- header labels ---- - tb_node_name = new textBox(TEXTBOX_INPUT.text, function(txt) /*=>*/ { if(inspecting) inspecting.setDisplayName(txt); }); - - tb_prop_filter = new textBox(TEXTBOX_INPUT.text, function(txt) /*=>*/ { filter_text = txt; }); - tb_prop_filter.no_empty = false; - tb_prop_filter.auto_update = true; - tb_prop_filter.font = f_p0; - tb_prop_filter.color = COLORS._main_text_sub; - tb_prop_filter.align = fa_center; - tb_prop_filter.hide = true; - filter_text = ""; - - prop_page_button = new buttonGroup([ "Properties", "Settings", THEME.message_16 ], function(val) /*=>*/ { prop_page = val; }); - prop_page_button.buttonSpr = [ THEME.button_hide_left, THEME.button_hide_middle, THEME.button_hide_right ]; - prop_page_button.font = f_p2; - prop_page_button.fColor = COLORS._main_text_sub; - prop_page = 0; - #endregion - - #region ---- metadata ---- - current_meta = -1; - meta_tb[0] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.description = str; }); - meta_tb[1] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.author = str; }); - meta_tb[2] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.contact = str; }); - meta_tb[3] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.alias = str; }); - meta_tb[4] = new textArrayBox(noone, META_TAGS); - for( var i = 0, n = array_length(meta_tb); i < n; i++ ) - meta_tb[i].hide = true; - - meta_display = [ - [ __txt("Project Settings"), false ], - [ __txt("Metadata"), true ], - [ __txtx("panel_globalvar", "Global variables"), true, button(function() { panelAdd("Panel_Globalvar", true); }, THEME.node_goto).setIcon(THEME.node_goto, 0, COLORS._main_icon) ], - [ __txt("Group Properties"), true ], - ]; - - meta_steam_avatar = new checkBox(function() { STEAM_UGC_ITEM_AVATAR = !STEAM_UGC_ITEM_AVATAR; }); - #endregion - - #region ---- workshop ---- - workshop_uploading = false; - #endregion - - #region ++++ menus ++++ - static nodeExpandAll = function(node) { - if(node.input_display_list == -1) return; - - var dlist = node.input_display_list; - for( var i = 0, n = array_length(dlist); i < n; i++ ) { - if(!is_array(dlist[i])) continue; - dlist[i][@ 1] = false; - } - } - - static nodeCollapseAll = function(node) { - if(node.input_display_list == -1) return; - - var dlist = node.input_display_list; - for( var i = 0, n = array_length(dlist); i < n; i++ ) { - if(!is_array(dlist[i])) continue; - dlist[i][@ 1] = true; - } - } - - function section_expand_all() { - if(inspecting != noone) nodeExpandAll(inspecting); - for( var i = 0, n = array_length(inspectings); i < n; i++ ) - nodeExpandAll(inspectings[i]); - } - - function section_collapse_all() { - if(inspecting != noone) nodeCollapseAll(inspecting); - for( var i = 0, n = array_length(inspectings); i < n; i++ ) - 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(); } + #region ---- main ---- + context_str = "Inspector"; + title = __txt("Inspector"); + icon = THEME.panel_inspector_icon; + + w = ui(400); + h = ui(640); + min_w = ui(160); + + locked = false; + focusable = true; + + inspecting = noone; + inspectings = []; + inspectGroup = false; + top_bar_h = ui(100); + + static initSize = function() { + content_w = w - ui(32); + content_h = h - top_bar_h - ui(12); + } + initSize(); + + view_mode_tooltip = new tooltipSelector("View", [ "Compact", "Spacious" ]) + #endregion + + #region ---- properties ---- + prop_hover = noone; + prop_selecting = noone; + + prop_highlight = noone; + prop_highlight_time = 0; + + prop_dragging = noone; + prop_sel_drag_x = 0; + prop_sel_drag_y = 0; + + color_picking = false; + + picker_index = 0; + picker_change = false; + + attribute_hovering = noone; + #endregion + + globalvar_viewer_init(); + drawWidgetInit(); + + #region ---- header labels ---- + tb_node_name = new textBox(TEXTBOX_INPUT.text, function(txt) /*=>*/ { if(inspecting) inspecting.setDisplayName(txt); }); + + tb_prop_filter = new textBox(TEXTBOX_INPUT.text, function(txt) /*=>*/ { filter_text = txt; }); + tb_prop_filter.no_empty = false; + tb_prop_filter.auto_update = true; + tb_prop_filter.font = f_p0; + tb_prop_filter.color = COLORS._main_text_sub; + tb_prop_filter.align = fa_center; + tb_prop_filter.hide = true; + filter_text = ""; + + prop_page_button = new buttonGroup([ "Properties", "Settings", THEME.message_16 ], function(val) /*=>*/ { prop_page = val; }); + prop_page_button.buttonSpr = [ THEME.button_hide_left, THEME.button_hide_middle, THEME.button_hide_right ]; + prop_page_button.font = f_p2; + prop_page_button.fColor = COLORS._main_text_sub; + prop_page = 0; + #endregion + + #region ---- metadata ---- + current_meta = -1; + meta_tb[0] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.description = str; }); + meta_tb[1] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.author = str; }); + meta_tb[2] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.contact = str; }); + meta_tb[3] = new textArea(TEXTBOX_INPUT.text, function(str) { current_meta.alias = str; }); + meta_tb[4] = new textArrayBox(noone, META_TAGS); + for( var i = 0, n = array_length(meta_tb); i < n; i++ ) + meta_tb[i].hide = true; + + meta_display = [ + [ __txt("Project Settings"), false ], + [ __txt("Metadata"), true ], + [ __txtx("panel_globalvar", "Global variables"), true, button(function() { panelAdd("Panel_Globalvar", true); }, THEME.node_goto).setIcon(THEME.node_goto, 0, COLORS._main_icon) ], + [ __txt("Group Properties"), true ], + ]; + + meta_steam_avatar = new checkBox(function() { STEAM_UGC_ITEM_AVATAR = !STEAM_UGC_ITEM_AVATAR; }); + #endregion + + #region ---- workshop ---- + workshop_uploading = false; + #endregion + + #region ++++ menus ++++ + static nodeExpandAll = function(node) { + if(node.input_display_list == -1) return; + + var dlist = node.input_display_list; + for( var i = 0, n = array_length(dlist); i < n; i++ ) { + if(!is_array(dlist[i])) continue; + dlist[i][@ 1] = false; + } + } + + static nodeCollapseAll = function(node) { + if(node.input_display_list == -1) return; + + var dlist = node.input_display_list; + for( var i = 0, n = array_length(dlist); i < n; i++ ) { + if(!is_array(dlist[i])) continue; + dlist[i][@ 1] = true; + } + } + + function section_expand_all() { + if(inspecting != noone) nodeExpandAll(inspecting); + for( var i = 0, n = array_length(inspectings); i < n; i++ ) + nodeExpandAll(inspectings[i]); + } + + function section_collapse_all() { + if(inspecting != noone) nodeCollapseAll(inspecting); + for( var i = 0, n = array_length(inspectings); i < n; i++ ) + 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(); } - group_menu = [ - menuItemAction(__txt("Expand all"), panel_inspector_section_expand_all), - menuItemAction(__txt("Collapse all"), panel_inspector_section_collapse_all), - ] - - __dialog_junction = noone; - menu_junc_reset_value = menuItemAction(__txtx("panel_inspector_reset", "Reset value"), panel_inspector_reset); - menu_junc_add_anim = menuItemAction(__txtx("panel_inspector_add", "Add animation"), panel_inspector_add); - menu_junc_rem_anim = menuItemAction(__txtx("panel_inspector_remove", "Remove animation"), panel_inspector_remove); - menu_junc_combine_axis = menuItemAction(__txtx("panel_inspector_axis_combine", "Combine axis"), panel_inspector_axis_combine); - menu_junc_separate_axis = menuItemAction(__txtx("panel_inspector_axis_separate", "Separate axis"), panel_inspector_axis_separate); - menu_junc_expression_ena = menuItemAction(__txtx("panel_inspector_use_expression", "Use expression"), panel_inspector_use_expression); - menu_junc_expression_dis = menuItemAction(__txtx("panel_inspector_disable_expression", "Disable expression"), panel_inspector_disable_expression); - menu_junc_extract = menuItemAction(__txtx("panel_inspector_extract_single", "Extract to node"), panel_inspector_extract_single); - - menu_junc_copy = menuItemAction(__txt("Copy"), panel_inspector_copy_prop, THEME.copy); - menu_junc_paste = menuItemAction(__txt("Paste"), panel_inspector_paste_prop, THEME.paste); - - function setSelectingItemColor(color) { - if(__dialog_junction == noone) return; - - __dialog_junction.setColor(color); - - var _val_to = __dialog_junction.getJunctionTo(); - for( var i = 0, n = array_length(_val_to); i < n; i++ ) - _val_to[i].setColor(color); - } - - var _clrs = COLORS.labels; - var _item = array_create(array_length(_clrs)); - - for( var i = 0, n = array_length(_clrs); i < n; i++ ) { - _item[i] = [ - [ THEME.timeline_color, i > 0, _clrs[i] ], - function(_data) { - setSelectingItemColor(_data.color); - }, "", { color: i == 0? -1 : _clrs[i] } - ]; - } - - array_push(_item, [ - [ THEME.timeline_color, 2 ], - function(_data) { - colorSelectorCall(__dialog_junction? __dialog_junction.color : c_white, setSelectingItemColor); - } - ]); - - menu_junc_color = menuItemGroup(__txt("Color"), _item); - menu_junc_color.spacing = ui(24); - #endregion - - function setInspecting(inspecting, _lock = false, _focus = true) { - if(locked) return; - - self.inspecting = inspecting; - if(_lock) locked = true; - focusable = _focus; - - if(inspecting != noone) - inspecting.onInspect(); - contentPane.scroll_y = 0; - contentPane.scroll_y_to = 0; - - picker_index = 0; - } - - function getInspecting() { - if(inspecting == noone) return noone; - return inspecting.active? inspecting : noone; - } - - function onFocusBegin() { if(!focusable) return; PANEL_INSPECTOR = self; } - - function onResize() { - initSize(); - contentPane.resize(content_w, content_h); - } - - static drawMeta = function(_y, _m) { - var con_w = contentPane.surface_w - ui(4); - var _hover = pHOVER && contentPane.hover; - - var context = PANEL_GRAPH.getCurrentContext(); - var meta = context == noone? PROJECT.meta : context.metadata; - if(meta == noone) return 0; - current_meta = meta; - - var hh = ui(8); - var yy = _y + ui(8); - - var rx = x + ui(16); - var ry = y + top_bar_h; - var lbh = viewMode? ui(32) : ui(26); - - attribute_hovering = noone; - - for( var i = 0, n = array_length(meta_display); i < n; i++ ) { - if(i == 3 && PANEL_GRAPH.getCurrentContext() == noone) continue; - - var _meta = meta_display[i]; - var _txt = array_safe_get_fast(_meta, 0); - var _b = array_safe_get_fast(_meta, 2, noone); - var _x1 = con_w - (_b != noone) * ui(30); - - if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, _x1, yy + lbh)) { - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, con_w, lbh, COLORS.panel_inspector_group_hover, 1); - - if(mouse_press(mb_left, pFOCUS)) - meta_display[i][1] = !meta_display[i][1]; - } else - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, con_w, lbh, COLORS.panel_inspector_group_bg, 1); - - if(_b != noone) { - _b.setFocusHover(pFOCUS, _hover); - _b.draw(_x1, yy + ui(2), ui(28), lbh - ui(4), _m, THEME.button_hide_fill); - if(_b.inBBOX(_m)) contentPane.hover_content = true; - } - - draw_sprite_ui(THEME.arrow, meta_display[i][1]? 0 : 3, ui(16), yy + lbh / 2, 1, 1, 0, COLORS.panel_inspector_group_bg, 1); - - draw_set_text(viewMode? f_p0 : f_p1, fa_left, fa_center, COLORS._main_text_inner); - draw_text_add(ui(32), yy + lbh / 2, _txt); - - yy += lbh + ui(viewMode? 8 : 6); - hh += lbh + ui(viewMode? 8 : 6); - - if(meta_display[i][1]) continue; - - var _font = viewMode == INSP_VIEW_MODE.spacious? f_p0 : f_p2; - - switch(i) { - case 0 : - var _edt = PROJECT.attributeEditor; - var _lh, wh; - - for( var j = 0; j < array_length(_edt); j++ ) { - var title = _edt[j][0]; - var param = _edt[j][1]; - var editW = _edt[j][2]; - var drpFn = _edt[j][3]; - - var widx = ui(8); - var widy = yy; - - draw_set_text(_font, fa_left, fa_top, COLORS._main_text_inner); - draw_text_over(ui(16), viewMode == INSP_VIEW_MODE.spacious? yy : yy + ui(3), __txt(title)); - - if(viewMode == INSP_VIEW_MODE.spacious) { - _lh = line_get_height(); - yy += _lh + ui(6); - hh += _lh + ui(6); - - } else if(viewMode == INSP_VIEW_MODE.compact) { - _lh = line_get_height() + ui(6); - } - - editW.setFocusHover(pFOCUS, _hover); - if(pFOCUS) editW.register(contentPane); - - var wh = 0; - var _data = PROJECT.attributes[$ param]; - var _wdx = viewMode == INSP_VIEW_MODE.spacious? ui(16) : ui(140); - var _wdy = yy; - var _wdw = w - ui(48) - _wdx; - var _wdh = viewMode == INSP_VIEW_MODE.spacious? TEXTBOX_HEIGHT : _lh; - - var _param = new widgetParam(_wdx, _wdy, _wdw, _wdh, _data, {}, _m, rx, ry); - _param.font = _font; - - wh = editW.drawParam(_param); - if(editW.inBBOX(_m)) contentPane.hover_content = true; - - var jun = PANEL_GRAPH.value_dragging; - var widw = con_w - ui(16); - var widh = viewMode == INSP_VIEW_MODE.spacious? _lh + ui(6) + wh + ui(4) : max(wh, _lh); - - if(jun != noone && _hover && point_in_rectangle(_m[0], _m[1], widx, widy, widx + widw, widy + widh)) { - draw_sprite_stretched_ext(THEME.ui_panel, 1, widx, widy, widw, widh, COLORS._main_value_positive, 1); - attribute_hovering = drpFn; - } - - if(viewMode == INSP_VIEW_MODE.spacious) { - yy += wh + ui(8); - hh += wh + ui(8); - - } else if(viewMode == INSP_VIEW_MODE.compact) { - yy += max(wh, _lh) + ui(6); - hh += max(wh, _lh) + ui(6); - } - } - - break; - - case 1 : - var _wdx = viewMode == INSP_VIEW_MODE.spacious? ui(16) : ui(140); - var _wdw = w - ui(48) - _wdx; - - for( var j = 0; j < array_length(meta.displays); j++ ) { - var display = meta.displays[j]; - - draw_set_text(_font, fa_left, fa_top, COLORS._main_text_inner); - draw_text_over(ui(16), viewMode == INSP_VIEW_MODE.spacious? yy : yy + ui(3), __txt(display[0])); - - if(viewMode == INSP_VIEW_MODE.spacious) { - _lh = line_get_height(); - yy += _lh + ui(6); - hh += _lh + ui(6); - - } else if(viewMode == INSP_VIEW_MODE.compact) { - _lh = line_get_height() + ui(6); - } - - meta_tb[j].setFocusHover(pFOCUS, _hover); - if(pFOCUS) meta_tb[j].register(contentPane); - - var _dataFunc = display[1]; - var _data = _dataFunc(meta); - var _wdy = yy; - var _wdh = display[2]; - - var _param = new widgetParam(_wdx, _wdy, _wdw, _wdh, _data, {}, _m, rx, ry); - _param.font = _font; - - switch(instanceof(meta_tb[j])) { - case "textArrayBox" : meta_tb[j].arraySet = current_meta.tags; break; - } - - wh = meta_tb[j].drawParam(_param); - if(meta_tb[j].inBBOX(_m)) contentPane.hover_content = true; - - if(viewMode == INSP_VIEW_MODE.spacious) { - yy += wh + ui(8); - hh += wh + ui(8); - - } else if(viewMode == INSP_VIEW_MODE.compact) { - yy += max(wh, _lh) + ui(6); - hh += max(wh, _lh) + ui(6); - } - } - - if(STEAM_ENABLED) { - meta_steam_avatar.setFocusHover(pFOCUS, _hover); - if(pFOCUS) meta_steam_avatar.register(contentPane); - - draw_set_text(_font, fa_left, fa_top, COLORS._main_text_inner); - draw_text_over(ui(16), viewMode == INSP_VIEW_MODE.spacious? yy : yy + ui(3), __txt("Show Avatar")); - - if(viewMode == INSP_VIEW_MODE.spacious) { - _lh = line_get_height(); - yy += _lh + ui(6); - hh += _lh + ui(6); - } - - var _param = new widgetParam(_wdx, yy, _wdw, TEXTBOX_HEIGHT, STEAM_UGC_ITEM_AVATAR, {}, _m, rx, ry); - _param.font = _font; - - wh = meta_steam_avatar.drawParam(_param); - if(meta_steam_avatar.inBBOX(_m)) contentPane.hover_content = true; - - yy += wh + ui(6); hh += wh + ui(6); - if(viewMode == INSP_VIEW_MODE.spacious) { yy += ui(2); hh += ui(2); } - } - - break; - - case 2 : - if(findPanel("Panel_Globalvar")) { - yy += ui(4); - hh += ui(4); - continue; - } - - if(_m[1] > yy) contentPane.hover_content = true; - - var glPar = globalvar_viewer_draw(ui(16), yy, contentPane.surface_w - ui(24), _m, pFOCUS, _hover, contentPane, ui(16) + x, top_bar_h + y); - var gvh = glPar[0]; - - yy += gvh + ui(8); - hh += gvh + ui(8); - - var bh = ui(36); - var bx = ui(16); - var by = yy; - var bbw = contentPane.surface_w - ui(24); - - if(var_editing) { - var bw = bbw / 2 - ui(4); - - if(buttonInstant(THEME.button_hide, bx, by, bw, bh, _m, pFOCUS, _hover) == 2) - var_editing = !var_editing; - - var txt = __txt("Apply"); - var icon = THEME.accept; - var colr = COLORS._main_value_positive; - - draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_icon) - var bxc = bx + bw / 2 - (string_width(txt) + ui(48)) / 2; - var byc = by + bh / 2; - draw_sprite_ui(icon, 0, bxc + ui(24), byc,,,, colr); - draw_text_over(bxc + ui(48), byc, txt); - - bx += bw + ui(4); - - if(buttonInstant(THEME.button_hide, bx, by, bw, bh, _m, pFOCUS, _hover) == 2) - PROJECT.globalNode.createValue(); - - var txt = __txt("Add"); - var icon = THEME.add; - - draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_icon) - var bxc = bx + bw / 2 - (string_width(txt) + ui(48)) / 2; - var byc = by + bh / 2; - draw_sprite_ui(icon, 0, bxc + ui(24), byc,,,, colr); - draw_text_over(bxc + ui(48), byc, txt); - - } else { - var bw = bbw; - - if(buttonInstant(THEME.button_hide, bx, by, bw, bh, _m, pFOCUS, _hover) == 2) - var_editing = !var_editing; - - var txt = __txt("Edit"); - var icon = THEME.gear; - var colr = COLORS._main_icon; - - draw_set_text(f_p0b, fa_left, fa_center, colr) - var bxc = bx + bw / 2 - (string_width(txt) + ui(48)) / 2; - var byc = by + bh / 2; - draw_sprite_ui(icon, 0, bxc + ui(24), byc,,,, colr); - draw_text_over(bxc + ui(48), byc, txt); - } - - break; - - case 3 : - var context = PANEL_GRAPH.getCurrentContext(); - var _h = drawNodeProperties(yy, _m, context); - - yy += _h; - hh += _h; - break; - } - - yy += ui(viewMode? 4 : 2); - hh += ui(viewMode? 4 : 2); - } - - return hh; - } - - static highlightProp = function(prop) { - prop_highlight = prop; - prop_highlight_time = 60; - } - - static drawNodeProperties = function(_y, _m, _inspecting = inspecting) { - var con_w = contentPane.surface_w - ui(4); - var _hover = pHOVER && contentPane.hover; - - _inspecting.inspecting = true; - prop_hover = noone; - var jun = noone; - var amoIn = is_array(_inspecting.input_display_list)? array_length(_inspecting.input_display_list) : array_length(_inspecting.inputs); - var amoOut = is_array(_inspecting.output_display_list)? array_length(_inspecting.output_display_list) : array_length(_inspecting.outputs); - var amo = inspectGroup == 0? amoIn + 1 + amoOut : amoIn; - var hh = 0; - - //tb_prop_filter.register(contentPane); - //tb_prop_filter.setFocusHover(pHOVER, pFOCUS); - //tb_prop_filter.draw(ui(32), _y + ui(4), con_w - ui(64), ui(28), filter_text, _m); - //draw_sprite_ui(THEME.search, 0, ui(32 + 16), _y + ui(4 + 14), 1, 1, 0, COLORS._main_icon, 1); - - var xc = con_w / 2; - - if(prop_page == 1) { // attribute/settings editor - hh += ui(8); - var hg = ui(32); - var yy = _y + hh; - var wx1 = con_w - ui(8); - var ww = max(ui(180), con_w / 3); - var wx0 = wx1 - ww; - - for( var i = 0, n = array_length(_inspecting.attributeEditors); i < n; i++ ) { - var edt = _inspecting.attributeEditors[i]; - - if(is_string(edt)) { - var lby = yy + ui(12); - draw_set_alpha(0.5); - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); - draw_text_add(xc, lby, edt); - - var lbw = string_width(edt) / 2; - draw_set_color(COLORS._main_text_sub); - draw_line_round(xc + lbw + ui(16), lby, wx1, lby, 2); - draw_line_round(xc - lbw - ui(16), lby, ui(8), lby, 2); - draw_set_alpha(1.0); - - yy += ui(32); - hh += ui(32); - continue; - } - - var val = edt[1](); - edt[2].setFocusHover(pFOCUS, pHOVER); - - if(instanceof(edt[2]) == "buttonClass") { - edt[2].text = edt[0]; - edt[2].draw(ui(8), yy, con_w - ui(16), hg, _m); - - if(edt[2].inBBOX(_m)) contentPane.hover_content = true; - yy += hg + ui(8); - hh += hg + ui(8); - continue; - } - - draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); - draw_text_add(ui(8), yy + hg / 2, edt[0]); - - var _param = new widgetParam(wx0, yy, ww, hg, val, {}, _m, x + contentPane.x, y + contentPane.y); - _param.s = hg; - var _wh = edt[2].drawParam(_param); - var _hg = max(hg, _wh); - - if(edt[2].inBBOX(_m)) contentPane.hover_content = true; - yy += _hg + ui(8); - hh += _hg + ui(8); - } - return hh; - - } else if(prop_page == 2) { - var _logs = _inspecting.messages; - _inspecting.messages_bub = false; - var _tmw = ui(64); - var yy = _y; - var hh = ui(64); - - var con_w = contentPane.surface_w; - var con_h = contentPane.surface_h - yy; - - draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, 0, yy, con_w, con_h, merge_color(CDEF.main_ltgrey, CDEF.main_white, 0.5)); - yy += ui(8); - - for (var i = array_length(_logs) - 1; i >= 0; i--) { - var _log = _logs[i]; - - var _time = _log[0]; - var _text = _log[1]; - - draw_set_text(f_p3, fa_left, fa_top, COLORS._main_text_sub); - var _hg = string_height_ext(_text, -1, con_w - _tmw - ui(10 + 8)) + ui(4); - if(i % 2) draw_sprite_stretched_ext(THEME.ui_panel_bg, 4, ui(4), yy, con_w - ui(8), _hg, CDEF.main_dkblack, 0.25); - - draw_text_add(ui(10), yy + ui(2), _time); - - draw_set_color(COLORS._main_text); - draw_text_ext_add(_tmw + ui(10), yy + ui(2), _text, -1, con_w - _tmw - ui(10 + 8)); - - yy += _hg; - hh += _hg; - } - - return hh; - } - - var color_picker_index = 0; - var pickers = []; - var _colsp = false; - - for(var i = 0; i < amo; i++) { - var yy = hh + _y; - - if(i < amoIn) { // inputs - if(!is_array(_inspecting.input_display_list)) jun = _inspecting.inputs[i]; - else if(is_real(_inspecting.input_display_list[i])) jun = _inspecting.inputs[_inspecting.input_display_list[i]]; - else jun = _inspecting.input_display_list[i]; - - } else if(i == amoIn) { // output label - hh += ui(8 + 32 + 8); - - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy + ui(8), con_w, ui(32), COLORS.panel_inspector_output_label, 0.8); - draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); - draw_text_add(xc, yy + ui(8 + 16), __txt("Outputs")); - continue; - - } else { // outputs - var _oi = i - amoIn - 1; - - if(!is_array(_inspecting.output_display_list)) jun = _inspecting.outputs[_oi]; - else if(is_real(_inspecting.output_display_list[_oi])) jun = _inspecting.outputs[_inspecting.output_display_list[_oi]]; - else jun = _inspecting.output_display_list[_oi]; - } - - #region draw custom displayer - - if(is_instanceof(jun, Inspector_Spacer)) { // SPACER - var _hh = ui(jun.h); - var _yy = yy + _hh / 2 - ui(2); - - if(jun.line) { - draw_set_color(COLORS.panel_inspector_key_separator); - draw_line(ui(8), _yy, con_w - ui(8), _yy); - } - - hh += _hh; - continue; - - } else if(is_instanceof(jun, Inspector_Sprite)) { // SPRITE - var _spr = jun.spr; - var _sh = sprite_get_height(_spr); - - draw_sprite(_spr, 0, xc, yy); - - hh += _sh + ui(8); - continue; - - } else if(is_instanceof(jun, Inspector_Label)) { // TEXT - var _txt = jun.text; - - draw_set_text(jun.font, fa_left, fa_top, COLORS._main_text_sub); - var _sh = string_height_ext(_txt, -1, con_w - ui(16)) + ui(16); - draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, 0, yy, con_w, _sh, COLORS._main_icon_light); - draw_text_ext_add(ui(8), yy + ui(8), _txt, -1, con_w - ui(16)); - - hh += _sh + ui(8); - continue; - - } else if(is_instanceof(jun, Inspector_Custom_Renderer)) { - jun.register(contentPane); - jun.rx = ui(16) + x; - jun.ry = top_bar_h + y; - - var _wdh = jun.draw(ui(6), yy, con_w - ui(12), _m, _hover, pFOCUS) + ui(8); - if(!is_undefined(_wdh)) hh += _wdh; - continue; - } else if(is_array(jun)) { // LABEL - var pad = i && _colsp == false? ui(4) : 0 - _colsp = false; - yy += pad; - - var txt = __txt(jun[0]); - var coll = jun[1] && filter_text == ""; - var lbh = viewMode? ui(32) : ui(26); - var togl = array_safe_get_fast(jun, 2, noone); - if(togl != noone) var toging = _inspecting.getInputData(togl); - - var lbx = (togl != noone) * ui(40); - var lbw = con_w - lbx; - var ltx = lbx + ui(32); - - if(_hover && point_in_rectangle(_m[0], _m[1], lbx, yy, con_w, yy + lbh)) { - contentPane.hover_content = true; - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, lbx, yy, lbw, lbh, COLORS.panel_inspector_group_hover, 1); - - if(mouse_press(mb_left, pFOCUS)) - jun[@ 1] = !coll; - if(mouse_press(mb_right, pFOCUS)) - menuCall("inspector_group_menu",,, group_menu,, _inspecting); - } else - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, lbx, yy, lbw, lbh, COLORS.panel_inspector_group_bg, 1); - - if(filter_text == "") - draw_sprite_ui(THEME.arrow, 0, lbx + ui(16), yy + lbh / 2, 1, 1, -90 + coll * 90, COLORS.panel_inspector_group_bg, 1); - - var cc, aa = 1; - - if(togl != noone) { - if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, ui(32), yy + lbh)) { - contentPane.hover_content = true; - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, ui(32), lbh, COLORS.panel_inspector_group_hover, 1); - - if(mouse_press(mb_left, pFOCUS)) - _inspecting.inputs[togl].setValue(!toging); - } else - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, ui(32), lbh, COLORS.panel_inspector_group_bg, 1); - - cc = toging? COLORS._main_accent : COLORS.panel_inspector_group_bg; - aa = 0.5 + toging * 0.5; - - draw_sprite_ui(THEME.inspector_checkbox, 0, ui(16), yy + lbh / 2, 1, 1, 0, cc, 1); - if(toging) - draw_sprite_ui(THEME.inspector_checkbox, 1, ui(16), yy + lbh / 2, 1, 1, 0, cc, 1); - } - - draw_set_text(viewMode? f_p0 : f_p1, fa_left, fa_center, COLORS._main_text, aa); - draw_text_add(ltx, yy + lbh / 2, txt); - draw_set_alpha(1); - - hh += lbh + ui(viewMode? 8 : 6) + pad; - - if(coll) { // skip - _colsp = true; - var j = i + 1; - var _len = array_length(_inspecting.input_display_list); - - while(j < _len) { - var j_jun = _inspecting.input_display_list[j]; - if(is_array(j_jun)) - break; - j++; - } - - i = j - 1; - } - - continue; - - } - - #endregion - - if(!is_instanceof(jun, NodeValue)) continue; - - if(!jun.show_in_inspector || jun.type == VALUE_TYPE.object) continue; - if(filter_text != "") { - var pos = string_pos(filter_text, string_lower(jun.getName())); - if(pos == 0) continue; - } - - #region ++++ draw widget ++++ - var _font = viewMode == INSP_VIEW_MODE.spacious? f_p0 : f_p2; - - var lb_h = line_get_height(_font) + ui(8); - var lb_w = line_get_width(jun.getName(), _font) + ui(16); - var lb_x = ui(48) + (ui(24) * (jun.color != -1)); - var padd = ui(8); - - var _selY = yy; - - var widg = drawWidget(ui(16), yy, contentPane.surface_w - ui(24), _m, jun, false, pHOVER && contentPane.hover, pFOCUS, contentPane, ui(16) + x, top_bar_h + y); - var widH = widg[0]; - var mbRight = widg[1]; - var widHov = widg[2]; - - var lbHov = point_in_rectangle(_m[0], _m[1], lb_x, _selY + ui(2), lb_x + lb_w, _selY + lb_h - ui(4)); - if(lbHov) { - contentPane.hover_content = true; - draw_sprite_stretched_ext(THEME.button_hide, 1, lb_x, _selY + ui(2), lb_w, lb_h - ui(4), COLORS._main_icon, 1); - } - - if(widHov) contentPane.hover_content = true; - - hh += lb_h + widH + padd; - - var _selY1 = yy + lb_h + widH + ui(2); - var _selH = _selY1 - _selY + (viewMode * ui(4)); - - if(jun == prop_highlight && prop_highlight_time) { - if(prop_highlight_time == 60) - contentPane.setScroll(_y - yy); - var aa = min(1, prop_highlight_time / 30); - draw_sprite_stretched_ext(THEME.ui_panel, 1, ui(4), yy, contentPane.surface_w - ui(4), _selH, COLORS._main_accent, aa); - } - - if(_hover && lbHov && prop_dragging == noone && mouse_press(mb_left, pFOCUS)) { - prop_dragging = jun; - - prop_sel_drag_x = mouse_mx; - prop_sel_drag_y = mouse_my; - } - #endregion - - if(jun.connect_type == JUNCTION_CONNECT.input && jun.type == VALUE_TYPE.color && jun.display_type == VALUE_DISPLAY._default) { // color picker - pickers[color_picker_index] = jun; - color_picker_index++; - } - - if(_hover && point_in_rectangle(_m[0], _m[1], ui(4), _selY, contentPane.surface_w - ui(4), _selY + _selH)) { // mouse in widget - _HOVERING_ELEMENT = jun; - - var hov = PANEL_GRAPH.value_dragging != noone || (NODE_DROPPER_TARGET != noone && NODE_DROPPER_TARGET != jun); - - if(hov) { - draw_sprite_stretched_ext(THEME.ui_panel, 1, ui(4), _selY, contentPane.surface_w - ui(8), _selH, COLORS._main_value_positive, 1); - if(mouse_press(mb_left, NODE_DROPPER_TARGET_CAN)) { - NODE_DROPPER_TARGET.expression += $"{jun.node.internalName}.{jun.connect_type == JUNCTION_CONNECT.input? "inputs" : "outputs"}.{jun.internalName}"; - NODE_DROPPER_TARGET.expressionUpdate(); - } - } else - 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); - anim_toggling = false; - } - - prop_hover = jun; - - if(mouse_press(mb_left, pFOCUS)) - prop_selecting = jun; - - if(mouse_press(mb_right, pFOCUS && mbRight)) { #region right click menu - var _menuItem = [ menu_junc_color, -1 ]; - - if(i < amoIn) { - array_push(_menuItem, menu_junc_reset_value, jun.is_anim? menu_junc_rem_anim : menu_junc_add_anim); - if(jun.sepable) array_push(_menuItem, jun.sep_axis? menu_junc_combine_axis : menu_junc_separate_axis); - array_push(_menuItem, -1); - } - - array_push(_menuItem, jun.expUse? menu_junc_expression_dis : menu_junc_expression_ena, -1, menu_junc_copy); - if(jun.connect_type == JUNCTION_CONNECT.input) - array_push(_menuItem, menu_junc_paste); - - if(jun.connect_type == JUNCTION_CONNECT.input && jun.extract_node != "") { - if(is_array(jun.extract_node)) { - var ext = menuItemAction(__txtx("panel_inspector_extract_multiple", "Extract to..."), function(_dat) { - var arr = []; - for(var i = 0; i < array_length(__dialog_junction.extract_node); i++) { - var _rec = __dialog_junction.extract_node[i]; - array_push(arr, menuItemAction(_rec, function(_dat) { __dialog_junction.extractNode(_dat.name); })); - } - - return submenuCall(_dat, arr); - }).setIsShelf(); - array_push(_menuItem, ext); - } else - array_push(_menuItem, menu_junc_extract); - } - - var dia = menuCall("inspector_value_menu",,, _menuItem,, jun); - __dialog_junction = jun; - } #endregion - } - } - - #region color picker - // if(key_mod_press(ALT) && color_picker_index) - // pickers[picker_index].editWidget.onColorPick(); - - if(MESSAGE != noone && MESSAGE.type == "Color") { - var inp = array_safe_get_fast(pickers, picker_index, 0); - if(is_struct(inp)) { - inp.setValue(MESSAGE.data); - MESSAGE = noone; - } - } - - color_picking = false; - #endregion - - #region drag - if(prop_dragging) { - if(DRAGGING == noone && point_distance(prop_sel_drag_x, prop_sel_drag_y, mouse_mx, mouse_my) > 16) { - prop_dragging.dragValue(); - prop_dragging = noone; - } - - if(mouse_release(mb_left)) - prop_dragging = noone; - } - #endregion - - if(prop_highlight_time) { - prop_highlight_time--; - if(prop_highlight_time == 0) - prop_highlight = noone; - } - - return hh; - } - - contentPane = new scrollPane(content_w, content_h, function(_y, _m) { - var con_w = contentPane.surface_w - ui(4); - - draw_clear_alpha(COLORS.panel_bg_clear, 0); - - if(point_in_rectangle(_m[0], _m[1], 0, 0, con_w, content_h) && mouse_press(mb_left, pFOCUS)) - prop_selecting = noone; - - if(inspecting == noone) return drawMeta(_y, _m); - - prop_page_button.data[2] = inspecting.messages_bub? THEME.message_16_grey_bubble : THEME.message_16_grey; - prop_page_button.setFocusHover(pFOCUS, pHOVER); - prop_page_button.draw(ui(32), _y + ui(4), contentPane.w - ui(76), ui(24), prop_page, _m, x + contentPane.x, y + contentPane.y); - - var _hh = ui(40); - _y += _hh; - - if(is_instanceof(inspecting, Node_Canvas) && inspecting.nodeTool != noone && is_instanceof(inspecting.nodeTool.nodeObject, Node)) - return drawNodeProperties(_y, _m, inspecting.nodeTool.nodeObject); - - if(inspectGroup >= 0) - return drawNodeProperties(_y, _m, inspecting); - - if(is_instanceof(inspecting, Node_Frame)) - return drawNodeProperties(_y, _m, inspecting); - - for( var i = 0, n = min(10, array_length(inspectings)); i < n; i++ ) { - if(i) { - _y += ui(8); - _hh += ui(8); - } - - if(n > 1) { - draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, _y, con_w, ui(32), COLORS.panel_inspector_output_label, 0.9); - draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); - - var _tx = inspectings[i].getFullName(); - draw_text_add(con_w / 2, _y + ui(16), _tx); - - _y += ui(32 + 8); - _hh += ui(32 + 8); - } - - var _h = drawNodeProperties(_y, _m, inspectings[i]); - _y += _h; - _hh += _h; - } - - return _hh + ui(64); - }); - - function propSelectCopy() { - if(!prop_selecting) return; - clipboard_set_text(prop_selecting.getString()); - } - - function propSelectPaste() { - if(!prop_selecting) return; - prop_selecting.setString(clipboard_get_text()); - } - - function drawInspectingNode() { - tb_node_name.font = f_h5; - tb_node_name.hide = true; - tb_node_name.align = fa_center; - tb_node_name.format = TEXT_AREA_FORMAT.node_title; - tb_node_name.setFocusHover(pFOCUS, pHOVER); - - var txt = inspecting.renamed? inspecting.display_name : inspecting.name; - if(inspectGroup == 1) txt = $"[{array_length(PANEL_GRAPH.nodes_selecting)}] {txt}"; - else if(inspectGroup == -1) txt = $"[{array_length(PANEL_GRAPH.nodes_selecting)}] Multiple nodes"; - - tb_node_name.draw(ui(64), ui(14), w - ui(128), ui(32), txt, [ mx, my ]); - - if(inspectGroup >= 0) { - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); - draw_text_add(w / 2 + ui(8), ui(56), inspecting.name); - - draw_set_text(f_p3, fa_center, fa_center, COLORS._main_text_sub); - draw_set_alpha(0.65); - draw_text_add(w / 2, ui(76), inspecting.internalName); - draw_set_alpha(1); - } - - var bx = ui(8); - var by = ui(12); - - if(inspectGroup == 0) { - draw_set_font(f_p1); - var lx = w / 2 - string_width(inspecting.name) / 2 - ui(10); - var ly = ui(56 - 8); - if(buttonInstant(THEME.button_hide, lx, ly, ui(16), ui(16), [mx, my], pFOCUS, pHOVER, __txt("Lock"), THEME.lock_12, !locked, locked? COLORS._main_icon_light : COLORS._main_icon) == 2) - locked = !locked; - - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txt("Presets"), THEME.preset, 1) == 2) - dialogPanelCall(new Panel_Presets(inspecting), x + bx, y + by + ui(36)); - } else { - draw_sprite_ui_uniform(THEME.preset, 1, bx + ui(32) / 2, by + ui(32) / 2, 1, COLORS._main_icon_dark); - } - - //////////////////////////////////////////////////////////////////// INSPECTOR ACTIONS //////////////////////////////////////////////////////////////////// - - var bx = w - ui(44); - var by = ui(12); - - if(inspecting.hasInspector1Update(true)) { - var icon = inspecting.insp1UpdateIcon; - var ac = inspecting.insp1UpdateActive; - var cc = ac? icon[2] : COLORS._main_icon_dark; - var tt = inspecting.insp1UpdateTooltip; - if(inspectGroup) tt += " [All]"; - - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS && ac, pHOVER && ac, tt, icon[0], icon[1], cc) == 2) { - if(inspectGroup == 1) { - for( var i = 0, n = array_length(inspectings); i < n; i++ ) inspectings[i].inspector1Update(); - } else - inspecting.inspector1Update(); - } - } else - draw_sprite_ui(THEME.sequence_control, 1, bx + ui(16), by + ui(16),,,, COLORS._main_icon_dark); - - if(inspecting.hasInspector2Update()) { - by += ui(36); - var icon = inspecting.insp2UpdateIcon; - var ac = inspecting.insp2UpdateActive; - var cc = ac? icon[2] : COLORS._main_icon_dark; - var tt = inspecting.insp2UpdateTooltip; - if(inspectGroup) tt += " [All]"; - - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS && ac, pHOVER && ac, tt, icon[0], icon[1], cc) = 2) { - if(inspectGroup) { - for( var i = 0, n = array_length(inspectings); i < n; i++ ) inspectings[i].inspector2Update(); - } else - inspecting.inspector2Update(); - } - } - } - - function drawContent(panel) { // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - draw_clear_alpha(COLORS.panel_bg_clear, 0); - - draw_sprite_stretched(THEME.ui_panel_bg, 1, ui(8), top_bar_h - ui(8), w - ui(16), h - top_bar_h); - - if(inspecting && !inspecting.active) inspecting = noone; - - view_mode_tooltip.index = viewMode; - if(buttonInstant(THEME.button_hide, ui(8), ui(48), ui(32), ui(32), [mx, my], pFOCUS, pHOVER, view_mode_tooltip, THEME.inspector_view, viewMode) == 2) { - viewMode = !viewMode; - PREFERENCES.inspector_view_default = viewMode; - } - - if(inspecting) { - var _nodes = PANEL_GRAPH.nodes_selecting; - - inspectGroup = array_length(_nodes) > 1; - inspectings = array_empty(_nodes)? [ inspecting ] : _nodes; - - for( var i = 1, n = array_length(_nodes); i < n; i++ ) { - if(instanceof(_nodes[i]) != instanceof(_nodes[0])) { - inspectGroup = -1; - break; - } - } - - if(is_instanceof(inspecting, Node_Frame)) inspectGroup = 0; - - title = inspecting.renamed? inspecting.display_name : inspecting.name; - inspecting.inspectorStep(); - drawInspectingNode(); - - } else { - title = __txt("Inspector"); - - var txt = "Untitled"; - var context = PANEL_GRAPH.getCurrentContext(); - - if(context == noone && file_exists_empty(PROJECT.path)) - txt = string_replace(filename_name(PROJECT.path), filename_ext(PROJECT.path), ""); - else if(context != noone) - txt = context.name; - - draw_set_text(f_h5, fa_center, fa_center, COLORS._main_text); - draw_text_add(w / 2, ui(30), txt); - - if(PROJECT.meta.steam == FILE_STEAM_TYPE.steamOpen) { - var _tw = string_width(txt) / 2; - BLEND_ADD - draw_sprite_ui(THEME.steam, 0, w / 2 - _tw - ui(16), ui(29), 1, 1, 0, COLORS._main_icon); - BLEND_NORMAL - } - - var bx = w - ui(44); - var by = ui(12); - - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_set_default", "Set Metadata as default"), THEME.save, 0, COLORS._main_icon) == 2) - json_save_struct(DIRECTORY + "meta.json", PROJECT.meta.serialize()); - - by += ui(36); - if(STEAM_ENABLED && !workshop_uploading) { - if(PROJECT.path == "") { - buttonInstant(noone, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_workshop_save", "Save file before upload"), THEME.workshop_upload, 0, COLORS._main_icon, 0.5); - } else { - if(PROJECT.meta.steam == FILE_STEAM_TYPE.local) { //project made locally - if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_workshop_upload", "Upload to Steam Workshop"), THEME.workshop_upload, 0, COLORS._main_icon) == 2) { - var s = PANEL_PREVIEW.getNodePreviewSurface(); - if(is_surface(s)) { - PROJECT.meta.author_steam_id = STEAM_USER_ID; - PROJECT.meta.steam = FILE_STEAM_TYPE.steamUpload; - SAVE_AT(PROJECT, PROJECT.path); - - steam_ugc_create_project(); - workshop_uploading = true; - } else - noti_warning("Please send any node to preview panel to use as a thumbnail.") - } - } - - if(PROJECT.meta.steam && PROJECT.meta.author_steam_id == STEAM_USER_ID) { - if(PROJECT.meta.steam == FILE_STEAM_TYPE.steamUpload) { - buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], false, pHOVER, __txtx("panel_inspector_workshop_restart", "Open project from the workshop tab to update."), THEME.workshop_update, 0, COLORS._main_icon); - } else if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_workshop_update", "Update Steam Workshop content"), THEME.workshop_update, 0, COLORS._main_icon) == 2) { - SAVE_AT(PROJECT, PROJECT.path); - steam_ugc_update_project(); - workshop_uploading = true; - } - } - } - } - - if(workshop_uploading) { - draw_sprite_ui(THEME.loading_s, 0, bx + ui(16), by + ui(16),,, current_time / 5, COLORS._main_icon); - if(STEAM_UGC_ITEM_UPLOADING == false) - workshop_uploading = false; - } - } - - contentPane.setFocusHover(pFOCUS, pHOVER); - contentPane.draw(ui(16), top_bar_h, mx - ui(16), my - top_bar_h); - - if(!locked && PANEL_GRAPH.getFocusingNode() && inspecting != PANEL_GRAPH.getFocusingNode()) - setInspecting(PANEL_GRAPH.getFocusingNode()); - - } - - //// =========== Serialize =========== - - static serialize = function() { - return { - name: instanceof(self), - inspecting : node_get_id(inspecting), - inspectings : array_map(inspectings, function(n) { return node_get_id(n) }), - - locked, - }; - } - - static deserialize = function(data) { - inspecting = node_from_id(data.inspecting); - inspectings = array_map(data.inspectings, function(n) { return node_from_id(n); }); - - locked = struct_try_get(data, "locked", locked); - - return self; - } - + group_menu = [ + MENU_ITEMS.inspector_expand_all_sections, + MENU_ITEMS.inspector_collapse_all_sections, + ] + + __dialog_junction = noone; + menu_junc_reset_value = MENU_ITEMS.inspector_reset; + menu_junc_add_anim = MENU_ITEMS.inspector_add; + menu_junc_rem_anim = MENU_ITEMS.inspector_remove; + menu_junc_combine_axis = MENU_ITEMS.inspector_combine_axis; + menu_junc_separate_axis = MENU_ITEMS.inspector_separate_axis; + menu_junc_expression_ena = MENU_ITEMS.inspector_use_expression; + menu_junc_expression_dis = MENU_ITEMS.inspector_disable_expression; + menu_junc_extract = MENU_ITEMS.inspector_extract_value; + + menu_junc_copy = MENU_ITEMS.inspector_copy_property; + menu_junc_paste = MENU_ITEMS.inspector_paste_property; + + function setSelectingItemColor(color) { + if(__dialog_junction == noone) return; + + __dialog_junction.setColor(color); + + var _val_to = __dialog_junction.getJunctionTo(); + for( var i = 0, n = array_length(_val_to); i < n; i++ ) + _val_to[i].setColor(color); + } + + var _clrs = COLORS.labels; + var _item = array_create(array_length(_clrs)); + + for( var i = 0, n = array_length(_clrs); i < n; i++ ) { + _item[i] = [ + [ THEME.timeline_color, i > 0, _clrs[i] ], + function(_data) { + setSelectingItemColor(_data.color); + }, "", { color: i == 0? -1 : _clrs[i] } + ]; + } + + array_push(_item, [ + [ THEME.timeline_color, 2 ], + function(_data) { + colorSelectorCall(__dialog_junction? __dialog_junction.color : c_white, setSelectingItemColor); + } + ]); + + menu_junc_color = menuItemGroup(__txt("Color"), _item); + menu_junc_color.spacing = ui(24); + #endregion + + function setInspecting(inspecting, _lock = false, _focus = true) { + if(locked) return; + + self.inspecting = inspecting; + if(_lock) locked = true; + focusable = _focus; + + if(inspecting != noone) + inspecting.onInspect(); + contentPane.scroll_y = 0; + contentPane.scroll_y_to = 0; + + picker_index = 0; + } + + function getInspecting() { + if(inspecting == noone) return noone; + return inspecting.active? inspecting : noone; + } + + function onFocusBegin() { if(!focusable) return; PANEL_INSPECTOR = self; } + + function onResize() { + initSize(); + contentPane.resize(content_w, content_h); + } + + static drawMeta = function(_y, _m) { + var con_w = contentPane.surface_w - ui(4); + var _hover = pHOVER && contentPane.hover; + + var context = PANEL_GRAPH.getCurrentContext(); + var meta = context == noone? PROJECT.meta : context.metadata; + if(meta == noone) return 0; + current_meta = meta; + + var hh = ui(8); + var yy = _y + ui(8); + + var rx = x + ui(16); + var ry = y + top_bar_h; + var lbh = viewMode? ui(32) : ui(26); + + attribute_hovering = noone; + + for( var i = 0, n = array_length(meta_display); i < n; i++ ) { + if(i == 3 && PANEL_GRAPH.getCurrentContext() == noone) continue; + + var _meta = meta_display[i]; + var _txt = array_safe_get_fast(_meta, 0); + var _b = array_safe_get_fast(_meta, 2, noone); + var _x1 = con_w - (_b != noone) * ui(30); + + if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, _x1, yy + lbh)) { + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, con_w, lbh, COLORS.panel_inspector_group_hover, 1); + + if(mouse_press(mb_left, pFOCUS)) + meta_display[i][1] = !meta_display[i][1]; + } else + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, con_w, lbh, COLORS.panel_inspector_group_bg, 1); + + if(_b != noone) { + _b.setFocusHover(pFOCUS, _hover); + _b.draw(_x1, yy + ui(2), ui(28), lbh - ui(4), _m, THEME.button_hide_fill); + if(_b.inBBOX(_m)) contentPane.hover_content = true; + } + + draw_sprite_ui(THEME.arrow, meta_display[i][1]? 0 : 3, ui(16), yy + lbh / 2, 1, 1, 0, COLORS.panel_inspector_group_bg, 1); + + draw_set_text(viewMode? f_p0 : f_p1, fa_left, fa_center, COLORS._main_text_inner); + draw_text_add(ui(32), yy + lbh / 2, _txt); + + yy += lbh + ui(viewMode? 8 : 6); + hh += lbh + ui(viewMode? 8 : 6); + + if(meta_display[i][1]) continue; + + var _font = viewMode == INSP_VIEW_MODE.spacious? f_p0 : f_p2; + + switch(i) { + case 0 : + var _edt = PROJECT.attributeEditor; + var _lh, wh; + + for( var j = 0; j < array_length(_edt); j++ ) { + var title = _edt[j][0]; + var param = _edt[j][1]; + var editW = _edt[j][2]; + var drpFn = _edt[j][3]; + + var widx = ui(8); + var widy = yy; + + draw_set_text(_font, fa_left, fa_top, COLORS._main_text_inner); + draw_text_over(ui(16), viewMode == INSP_VIEW_MODE.spacious? yy : yy + ui(3), __txt(title)); + + if(viewMode == INSP_VIEW_MODE.spacious) { + _lh = line_get_height(); + yy += _lh + ui(6); + hh += _lh + ui(6); + + } else if(viewMode == INSP_VIEW_MODE.compact) { + _lh = line_get_height() + ui(6); + } + + editW.setFocusHover(pFOCUS, _hover); + if(pFOCUS) editW.register(contentPane); + + var wh = 0; + var _data = PROJECT.attributes[$ param]; + var _wdx = viewMode == INSP_VIEW_MODE.spacious? ui(16) : ui(140); + var _wdy = yy; + var _wdw = w - ui(48) - _wdx; + var _wdh = viewMode == INSP_VIEW_MODE.spacious? TEXTBOX_HEIGHT : _lh; + + var _param = new widgetParam(_wdx, _wdy, _wdw, _wdh, _data, {}, _m, rx, ry); + _param.font = _font; + + wh = editW.drawParam(_param); + if(editW.inBBOX(_m)) contentPane.hover_content = true; + + var jun = PANEL_GRAPH.value_dragging; + var widw = con_w - ui(16); + var widh = viewMode == INSP_VIEW_MODE.spacious? _lh + ui(6) + wh + ui(4) : max(wh, _lh); + + if(jun != noone && _hover && point_in_rectangle(_m[0], _m[1], widx, widy, widx + widw, widy + widh)) { + draw_sprite_stretched_ext(THEME.ui_panel, 1, widx, widy, widw, widh, COLORS._main_value_positive, 1); + attribute_hovering = drpFn; + } + + if(viewMode == INSP_VIEW_MODE.spacious) { + yy += wh + ui(8); + hh += wh + ui(8); + + } else if(viewMode == INSP_VIEW_MODE.compact) { + yy += max(wh, _lh) + ui(6); + hh += max(wh, _lh) + ui(6); + } + } + + break; + + case 1 : + var _wdx = viewMode == INSP_VIEW_MODE.spacious? ui(16) : ui(140); + var _wdw = w - ui(48) - _wdx; + + for( var j = 0; j < array_length(meta.displays); j++ ) { + var display = meta.displays[j]; + + draw_set_text(_font, fa_left, fa_top, COLORS._main_text_inner); + draw_text_over(ui(16), viewMode == INSP_VIEW_MODE.spacious? yy : yy + ui(3), __txt(display[0])); + + if(viewMode == INSP_VIEW_MODE.spacious) { + _lh = line_get_height(); + yy += _lh + ui(6); + hh += _lh + ui(6); + + } else if(viewMode == INSP_VIEW_MODE.compact) { + _lh = line_get_height() + ui(6); + } + + meta_tb[j].setFocusHover(pFOCUS, _hover); + if(pFOCUS) meta_tb[j].register(contentPane); + + var _dataFunc = display[1]; + var _data = _dataFunc(meta); + var _wdy = yy; + var _wdh = display[2]; + + var _param = new widgetParam(_wdx, _wdy, _wdw, _wdh, _data, {}, _m, rx, ry); + _param.font = _font; + + switch(instanceof(meta_tb[j])) { + case "textArrayBox" : meta_tb[j].arraySet = current_meta.tags; break; + } + + wh = meta_tb[j].drawParam(_param); + if(meta_tb[j].inBBOX(_m)) contentPane.hover_content = true; + + if(viewMode == INSP_VIEW_MODE.spacious) { + yy += wh + ui(8); + hh += wh + ui(8); + + } else if(viewMode == INSP_VIEW_MODE.compact) { + yy += max(wh, _lh) + ui(6); + hh += max(wh, _lh) + ui(6); + } + } + + if(STEAM_ENABLED) { + meta_steam_avatar.setFocusHover(pFOCUS, _hover); + if(pFOCUS) meta_steam_avatar.register(contentPane); + + draw_set_text(_font, fa_left, fa_top, COLORS._main_text_inner); + draw_text_over(ui(16), viewMode == INSP_VIEW_MODE.spacious? yy : yy + ui(3), __txt("Show Avatar")); + + if(viewMode == INSP_VIEW_MODE.spacious) { + _lh = line_get_height(); + yy += _lh + ui(6); + hh += _lh + ui(6); + } + + var _param = new widgetParam(_wdx, yy, _wdw, TEXTBOX_HEIGHT, STEAM_UGC_ITEM_AVATAR, {}, _m, rx, ry); + _param.font = _font; + + wh = meta_steam_avatar.drawParam(_param); + if(meta_steam_avatar.inBBOX(_m)) contentPane.hover_content = true; + + yy += wh + ui(6); hh += wh + ui(6); + if(viewMode == INSP_VIEW_MODE.spacious) { yy += ui(2); hh += ui(2); } + } + + break; + + case 2 : + if(findPanel("Panel_Globalvar")) { + yy += ui(4); + hh += ui(4); + continue; + } + + if(_m[1] > yy) contentPane.hover_content = true; + + var glPar = globalvar_viewer_draw(ui(16), yy, contentPane.surface_w - ui(24), _m, pFOCUS, _hover, contentPane, ui(16) + x, top_bar_h + y); + var gvh = glPar[0]; + + yy += gvh + ui(8); + hh += gvh + ui(8); + + var bh = ui(36); + var bx = ui(16); + var by = yy; + var bbw = contentPane.surface_w - ui(24); + + if(var_editing) { + var bw = bbw / 2 - ui(4); + + if(buttonInstant(THEME.button_hide, bx, by, bw, bh, _m, pFOCUS, _hover) == 2) + var_editing = !var_editing; + + var txt = __txt("Apply"); + var icon = THEME.accept; + var colr = COLORS._main_value_positive; + + draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_icon) + var bxc = bx + bw / 2 - (string_width(txt) + ui(48)) / 2; + var byc = by + bh / 2; + draw_sprite_ui(icon, 0, bxc + ui(24), byc,,,, colr); + draw_text_over(bxc + ui(48), byc, txt); + + bx += bw + ui(4); + + if(buttonInstant(THEME.button_hide, bx, by, bw, bh, _m, pFOCUS, _hover) == 2) + PROJECT.globalNode.createValue(); + + var txt = __txt("Add"); + var icon = THEME.add; + + draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_icon) + var bxc = bx + bw / 2 - (string_width(txt) + ui(48)) / 2; + var byc = by + bh / 2; + draw_sprite_ui(icon, 0, bxc + ui(24), byc,,,, colr); + draw_text_over(bxc + ui(48), byc, txt); + + } else { + var bw = bbw; + + if(buttonInstant(THEME.button_hide, bx, by, bw, bh, _m, pFOCUS, _hover) == 2) + var_editing = !var_editing; + + var txt = __txt("Edit"); + var icon = THEME.gear; + var colr = COLORS._main_icon; + + draw_set_text(f_p0b, fa_left, fa_center, colr) + var bxc = bx + bw / 2 - (string_width(txt) + ui(48)) / 2; + var byc = by + bh / 2; + draw_sprite_ui(icon, 0, bxc + ui(24), byc,,,, colr); + draw_text_over(bxc + ui(48), byc, txt); + } + + break; + + case 3 : + var context = PANEL_GRAPH.getCurrentContext(); + var _h = drawNodeProperties(yy, _m, context); + + yy += _h; + hh += _h; + break; + } + + yy += ui(viewMode? 4 : 2); + hh += ui(viewMode? 4 : 2); + } + + return hh; + } + + static highlightProp = function(prop) { + prop_highlight = prop; + prop_highlight_time = 60; + } + + static drawNodeProperties = function(_y, _m, _inspecting = inspecting) { + var con_w = contentPane.surface_w - ui(4); + var _hover = pHOVER && contentPane.hover; + + _inspecting.inspecting = true; + prop_hover = noone; + var jun = noone; + var amoIn = is_array(_inspecting.input_display_list)? array_length(_inspecting.input_display_list) : array_length(_inspecting.inputs); + var amoOut = is_array(_inspecting.output_display_list)? array_length(_inspecting.output_display_list) : array_length(_inspecting.outputs); + var amo = inspectGroup == 0? amoIn + 1 + amoOut : amoIn; + var hh = 0; + + //tb_prop_filter.register(contentPane); + //tb_prop_filter.setFocusHover(pHOVER, pFOCUS); + //tb_prop_filter.draw(ui(32), _y + ui(4), con_w - ui(64), ui(28), filter_text, _m); + //draw_sprite_ui(THEME.search, 0, ui(32 + 16), _y + ui(4 + 14), 1, 1, 0, COLORS._main_icon, 1); + + var xc = con_w / 2; + + if(prop_page == 1) { // attribute/settings editor + hh += ui(8); + var hg = ui(32); + var yy = _y + hh; + var wx1 = con_w - ui(8); + var ww = max(ui(180), con_w / 3); + var wx0 = wx1 - ww; + + for( var i = 0, n = array_length(_inspecting.attributeEditors); i < n; i++ ) { + var edt = _inspecting.attributeEditors[i]; + + if(is_string(edt)) { + var lby = yy + ui(12); + draw_set_alpha(0.5); + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text_add(xc, lby, edt); + + var lbw = string_width(edt) / 2; + draw_set_color(COLORS._main_text_sub); + draw_line_round(xc + lbw + ui(16), lby, wx1, lby, 2); + draw_line_round(xc - lbw - ui(16), lby, ui(8), lby, 2); + draw_set_alpha(1.0); + + yy += ui(32); + hh += ui(32); + continue; + } + + var val = edt[1](); + edt[2].setFocusHover(pFOCUS, pHOVER); + + if(instanceof(edt[2]) == "buttonClass") { + edt[2].text = edt[0]; + edt[2].draw(ui(8), yy, con_w - ui(16), hg, _m); + + if(edt[2].inBBOX(_m)) contentPane.hover_content = true; + yy += hg + ui(8); + hh += hg + ui(8); + continue; + } + + draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + draw_text_add(ui(8), yy + hg / 2, edt[0]); + + var _param = new widgetParam(wx0, yy, ww, hg, val, {}, _m, x + contentPane.x, y + contentPane.y); + _param.s = hg; + var _wh = edt[2].drawParam(_param); + var _hg = max(hg, _wh); + + if(edt[2].inBBOX(_m)) contentPane.hover_content = true; + yy += _hg + ui(8); + hh += _hg + ui(8); + } + return hh; + + } else if(prop_page == 2) { + var _logs = _inspecting.messages; + _inspecting.messages_bub = false; + var _tmw = ui(64); + var yy = _y; + var hh = ui(64); + + var con_w = contentPane.surface_w; + var con_h = contentPane.surface_h - yy; + + draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, 0, yy, con_w, con_h, merge_color(CDEF.main_ltgrey, CDEF.main_white, 0.5)); + yy += ui(8); + + for (var i = array_length(_logs) - 1; i >= 0; i--) { + var _log = _logs[i]; + + var _time = _log[0]; + var _text = _log[1]; + + draw_set_text(f_p3, fa_left, fa_top, COLORS._main_text_sub); + var _hg = string_height_ext(_text, -1, con_w - _tmw - ui(10 + 8)) + ui(4); + if(i % 2) draw_sprite_stretched_ext(THEME.ui_panel_bg, 4, ui(4), yy, con_w - ui(8), _hg, CDEF.main_dkblack, 0.25); + + draw_text_add(ui(10), yy + ui(2), _time); + + draw_set_color(COLORS._main_text); + draw_text_ext_add(_tmw + ui(10), yy + ui(2), _text, -1, con_w - _tmw - ui(10 + 8)); + + yy += _hg; + hh += _hg; + } + + return hh; + } + + var color_picker_index = 0; + var pickers = []; + var _colsp = false; + + for(var i = 0; i < amo; i++) { + var yy = hh + _y; + + if(i < amoIn) { // inputs + if(!is_array(_inspecting.input_display_list)) jun = _inspecting.inputs[i]; + else if(is_real(_inspecting.input_display_list[i])) jun = _inspecting.inputs[_inspecting.input_display_list[i]]; + else jun = _inspecting.input_display_list[i]; + + } else if(i == amoIn) { // output label + hh += ui(8 + 32 + 8); + + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy + ui(8), con_w, ui(32), COLORS.panel_inspector_output_label, 0.8); + draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); + draw_text_add(xc, yy + ui(8 + 16), __txt("Outputs")); + continue; + + } else { // outputs + var _oi = i - amoIn - 1; + + if(!is_array(_inspecting.output_display_list)) jun = _inspecting.outputs[_oi]; + else if(is_real(_inspecting.output_display_list[_oi])) jun = _inspecting.outputs[_inspecting.output_display_list[_oi]]; + else jun = _inspecting.output_display_list[_oi]; + } + + #region draw custom displayer + + if(is_instanceof(jun, Inspector_Spacer)) { // SPACER + var _hh = ui(jun.h); + var _yy = yy + _hh / 2 - ui(2); + + if(jun.line) { + draw_set_color(COLORS.panel_inspector_key_separator); + draw_line(ui(8), _yy, con_w - ui(8), _yy); + } + + hh += _hh; + continue; + + } else if(is_instanceof(jun, Inspector_Sprite)) { // SPRITE + var _spr = jun.spr; + var _sh = sprite_get_height(_spr); + + draw_sprite(_spr, 0, xc, yy); + + hh += _sh + ui(8); + continue; + + } else if(is_instanceof(jun, Inspector_Label)) { // TEXT + var _txt = jun.text; + + draw_set_text(jun.font, fa_left, fa_top, COLORS._main_text_sub); + var _sh = string_height_ext(_txt, -1, con_w - ui(16)) + ui(16); + draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, 0, yy, con_w, _sh, COLORS._main_icon_light); + draw_text_ext_add(ui(8), yy + ui(8), _txt, -1, con_w - ui(16)); + + hh += _sh + ui(8); + continue; + + } else if(is_instanceof(jun, Inspector_Custom_Renderer)) { + jun.register(contentPane); + jun.rx = ui(16) + x; + jun.ry = top_bar_h + y; + + var _wdh = jun.draw(ui(6), yy, con_w - ui(12), _m, _hover, pFOCUS) + ui(8); + if(!is_undefined(_wdh)) hh += _wdh; + continue; + } else if(is_array(jun)) { // LABEL + var pad = i && _colsp == false? ui(4) : 0 + _colsp = false; + yy += pad; + + var txt = __txt(jun[0]); + var coll = jun[1] && filter_text == ""; + var lbh = viewMode? ui(32) : ui(26); + var togl = array_safe_get_fast(jun, 2, noone); + if(togl != noone) var toging = _inspecting.getInputData(togl); + + var lbx = (togl != noone) * ui(40); + var lbw = con_w - lbx; + var ltx = lbx + ui(32); + + if(_hover && point_in_rectangle(_m[0], _m[1], lbx, yy, con_w, yy + lbh)) { + contentPane.hover_content = true; + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, lbx, yy, lbw, lbh, COLORS.panel_inspector_group_hover, 1); + + if(mouse_press(mb_left, pFOCUS)) + jun[@ 1] = !coll; + if(mouse_press(mb_right, pFOCUS)) + menuCall("inspector_group_menu",,, group_menu,, _inspecting); + } else + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, lbx, yy, lbw, lbh, COLORS.panel_inspector_group_bg, 1); + + if(filter_text == "") + draw_sprite_ui(THEME.arrow, 0, lbx + ui(16), yy + lbh / 2, 1, 1, -90 + coll * 90, COLORS.panel_inspector_group_bg, 1); + + var cc, aa = 1; + + if(togl != noone) { + if(_hover && point_in_rectangle(_m[0], _m[1], 0, yy, ui(32), yy + lbh)) { + contentPane.hover_content = true; + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, ui(32), lbh, COLORS.panel_inspector_group_hover, 1); + + if(mouse_press(mb_left, pFOCUS)) + _inspecting.inputs[togl].setValue(!toging); + } else + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, yy, ui(32), lbh, COLORS.panel_inspector_group_bg, 1); + + cc = toging? COLORS._main_accent : COLORS.panel_inspector_group_bg; + aa = 0.5 + toging * 0.5; + + draw_sprite_ui(THEME.inspector_checkbox, 0, ui(16), yy + lbh / 2, 1, 1, 0, cc, 1); + if(toging) + draw_sprite_ui(THEME.inspector_checkbox, 1, ui(16), yy + lbh / 2, 1, 1, 0, cc, 1); + } + + draw_set_text(viewMode? f_p0 : f_p1, fa_left, fa_center, COLORS._main_text, aa); + draw_text_add(ltx, yy + lbh / 2, txt); + draw_set_alpha(1); + + hh += lbh + ui(viewMode? 8 : 6) + pad; + + if(coll) { // skip + _colsp = true; + var j = i + 1; + var _len = array_length(_inspecting.input_display_list); + + while(j < _len) { + var j_jun = _inspecting.input_display_list[j]; + if(is_array(j_jun)) + break; + j++; + } + + i = j - 1; + } + + continue; + + } + + #endregion + + if(!is_instanceof(jun, NodeValue)) continue; + + if(!jun.show_in_inspector || jun.type == VALUE_TYPE.object) continue; + if(filter_text != "") { + var pos = string_pos(filter_text, string_lower(jun.getName())); + if(pos == 0) continue; + } + + #region ++++ draw widget ++++ + var _font = viewMode == INSP_VIEW_MODE.spacious? f_p0 : f_p2; + + var lb_h = line_get_height(_font) + ui(8); + var lb_w = line_get_width(jun.getName(), _font) + ui(16); + var lb_x = ui(48) + (ui(24) * (jun.color != -1)); + var padd = ui(8); + + var _selY = yy; + + var widg = drawWidget(ui(16), yy, contentPane.surface_w - ui(24), _m, jun, false, pHOVER && contentPane.hover, pFOCUS, contentPane, ui(16) + x, top_bar_h + y); + var widH = widg[0]; + var mbRight = widg[1]; + var widHov = widg[2]; + + var lbHov = point_in_rectangle(_m[0], _m[1], lb_x, _selY + ui(2), lb_x + lb_w, _selY + lb_h - ui(4)); + if(lbHov) { + contentPane.hover_content = true; + draw_sprite_stretched_ext(THEME.button_hide, 1, lb_x, _selY + ui(2), lb_w, lb_h - ui(4), COLORS._main_icon, 1); + } + + if(widHov) contentPane.hover_content = true; + + hh += lb_h + widH + padd; + + var _selY1 = yy + lb_h + widH + ui(2); + var _selH = _selY1 - _selY + (viewMode * ui(4)); + + if(jun == prop_highlight && prop_highlight_time) { + if(prop_highlight_time == 60) + contentPane.setScroll(_y - yy); + var aa = min(1, prop_highlight_time / 30); + draw_sprite_stretched_ext(THEME.ui_panel, 1, ui(4), yy, contentPane.surface_w - ui(4), _selH, COLORS._main_accent, aa); + } + + if(_hover && lbHov && prop_dragging == noone && mouse_press(mb_left, pFOCUS)) { + prop_dragging = jun; + + prop_sel_drag_x = mouse_mx; + prop_sel_drag_y = mouse_my; + } + #endregion + + if(jun.connect_type == JUNCTION_CONNECT.input && jun.type == VALUE_TYPE.color && jun.display_type == VALUE_DISPLAY._default) { // color picker + pickers[color_picker_index] = jun; + color_picker_index++; + } + + if(_hover && point_in_rectangle(_m[0], _m[1], ui(4), _selY, contentPane.surface_w - ui(4), _selY + _selH)) { // mouse in widget + _HOVERING_ELEMENT = jun; + + var hov = PANEL_GRAPH.value_dragging != noone || (NODE_DROPPER_TARGET != noone && NODE_DROPPER_TARGET != jun); + + if(hov) { + draw_sprite_stretched_ext(THEME.ui_panel, 1, ui(4), _selY, contentPane.surface_w - ui(8), _selH, COLORS._main_value_positive, 1); + if(mouse_press(mb_left, NODE_DROPPER_TARGET_CAN)) { + NODE_DROPPER_TARGET.expression += $"{jun.node.internalName}.{jun.connect_type == JUNCTION_CONNECT.input? "inputs" : "outputs"}.{jun.internalName}"; + NODE_DROPPER_TARGET.expressionUpdate(); + } + } else + 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); + anim_toggling = false; + } + + prop_hover = jun; + + if(mouse_press(mb_left, pFOCUS)) + prop_selecting = jun; + + if(mouse_press(mb_right, pFOCUS && mbRight)) { #region right click menu + var _menuItem = [ menu_junc_color, -1 ]; + + if(i < amoIn) { + array_push(_menuItem, menu_junc_reset_value, jun.is_anim? menu_junc_rem_anim : menu_junc_add_anim); + if(jun.sepable) array_push(_menuItem, jun.sep_axis? menu_junc_combine_axis : menu_junc_separate_axis); + array_push(_menuItem, -1); + } + + array_push(_menuItem, jun.expUse? menu_junc_expression_dis : menu_junc_expression_ena, -1, menu_junc_copy); + if(jun.connect_type == JUNCTION_CONNECT.input) + array_push(_menuItem, menu_junc_paste); + + if(jun.connect_type == JUNCTION_CONNECT.input && jun.extract_node != "") { + if(is_array(jun.extract_node)) { + var ext = menuItem(__txtx("panel_inspector_extract_multiple", "Extract to..."), function(_dat) { + var arr = []; + for(var i = 0; i < array_length(__dialog_junction.extract_node); i++) { + var _rec = __dialog_junction.extract_node[i]; + array_push(arr, menuItem(_rec, function(_dat) { __dialog_junction.extractNode(_dat.name); })); + } + + return submenuCall(_dat, arr); + }).setIsShelf(); + array_push(_menuItem, ext); + } else + array_push(_menuItem, menu_junc_extract); + } + + var dia = menuCall("inspector_value_menu",,, _menuItem,, jun); + __dialog_junction = jun; + } #endregion + } + } + + #region color picker + // if(key_mod_press(ALT) && color_picker_index) + // pickers[picker_index].editWidget.onColorPick(); + + if(MESSAGE != noone && MESSAGE.type == "Color") { + var inp = array_safe_get_fast(pickers, picker_index, 0); + if(is_struct(inp)) { + inp.setValue(MESSAGE.data); + MESSAGE = noone; + } + } + + color_picking = false; + #endregion + + #region drag + if(prop_dragging) { + if(DRAGGING == noone && point_distance(prop_sel_drag_x, prop_sel_drag_y, mouse_mx, mouse_my) > 16) { + prop_dragging.dragValue(); + prop_dragging = noone; + } + + if(mouse_release(mb_left)) + prop_dragging = noone; + } + #endregion + + if(prop_highlight_time) { + prop_highlight_time--; + if(prop_highlight_time == 0) + prop_highlight = noone; + } + + return hh; + } + + contentPane = new scrollPane(content_w, content_h, function(_y, _m) { + var con_w = contentPane.surface_w - ui(4); + + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + if(point_in_rectangle(_m[0], _m[1], 0, 0, con_w, content_h) && mouse_press(mb_left, pFOCUS)) + prop_selecting = noone; + + if(inspecting == noone) return drawMeta(_y, _m); + + prop_page_button.data[2] = inspecting.messages_bub? THEME.message_16_grey_bubble : THEME.message_16_grey; + prop_page_button.setFocusHover(pFOCUS, pHOVER); + prop_page_button.draw(ui(32), _y + ui(4), contentPane.w - ui(76), ui(24), prop_page, _m, x + contentPane.x, y + contentPane.y); + + var _hh = ui(40); + _y += _hh; + + if(is_instanceof(inspecting, Node_Canvas) && inspecting.nodeTool != noone && is_instanceof(inspecting.nodeTool.nodeObject, Node)) + return drawNodeProperties(_y, _m, inspecting.nodeTool.nodeObject); + + if(inspectGroup >= 0) + return drawNodeProperties(_y, _m, inspecting); + + if(is_instanceof(inspecting, Node_Frame)) + return drawNodeProperties(_y, _m, inspecting); + + for( var i = 0, n = min(10, array_length(inspectings)); i < n; i++ ) { + if(i) { + _y += ui(8); + _hh += ui(8); + } + + if(n > 1) { + draw_sprite_stretched_ext(THEME.s_box_r5_clr, 0, 0, _y, con_w, ui(32), COLORS.panel_inspector_output_label, 0.9); + draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); + + var _tx = inspectings[i].getFullName(); + draw_text_add(con_w / 2, _y + ui(16), _tx); + + _y += ui(32 + 8); + _hh += ui(32 + 8); + } + + var _h = drawNodeProperties(_y, _m, inspectings[i]); + _y += _h; + _hh += _h; + } + + return _hh + ui(64); + }); + + function propSelectCopy() { + if(!prop_selecting) return; + clipboard_set_text(prop_selecting.getString()); + } + + function propSelectPaste() { + if(!prop_selecting) return; + prop_selecting.setString(clipboard_get_text()); + } + + function drawInspectingNode() { + tb_node_name.font = f_h5; + tb_node_name.hide = true; + tb_node_name.align = fa_center; + tb_node_name.format = TEXT_AREA_FORMAT.node_title; + tb_node_name.setFocusHover(pFOCUS, pHOVER); + + var txt = inspecting.renamed? inspecting.display_name : inspecting.name; + if(inspectGroup == 1) txt = $"[{array_length(PANEL_GRAPH.nodes_selecting)}] {txt}"; + else if(inspectGroup == -1) txt = $"[{array_length(PANEL_GRAPH.nodes_selecting)}] Multiple nodes"; + + tb_node_name.draw(ui(64), ui(14), w - ui(128), ui(32), txt, [ mx, my ]); + + if(inspectGroup >= 0) { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text_sub); + draw_text_add(w / 2 + ui(8), ui(56), inspecting.name); + + draw_set_text(f_p3, fa_center, fa_center, COLORS._main_text_sub); + draw_set_alpha(0.65); + draw_text_add(w / 2, ui(76), inspecting.internalName); + draw_set_alpha(1); + } + + var bx = ui(8); + var by = ui(12); + + if(inspectGroup == 0) { + draw_set_font(f_p1); + var lx = w / 2 - string_width(inspecting.name) / 2 - ui(10); + var ly = ui(56 - 8); + if(buttonInstant(THEME.button_hide, lx, ly, ui(16), ui(16), [mx, my], pFOCUS, pHOVER, __txt("Lock"), THEME.lock_12, !locked, locked? COLORS._main_icon_light : COLORS._main_icon) == 2) + locked = !locked; + + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txt("Presets"), THEME.preset, 1) == 2) + dialogPanelCall(new Panel_Presets(inspecting), x + bx, y + by + ui(36)); + } else { + draw_sprite_ui_uniform(THEME.preset, 1, bx + ui(32) / 2, by + ui(32) / 2, 1, COLORS._main_icon_dark); + } + + //////////////////////////////////////////////////////////////////// INSPECTOR ACTIONS //////////////////////////////////////////////////////////////////// + + var bx = w - ui(44); + var by = ui(12); + + if(inspecting.hasInspector1Update(true)) { + var icon = inspecting.insp1UpdateIcon; + var ac = inspecting.insp1UpdateActive; + var cc = ac? icon[2] : COLORS._main_icon_dark; + var tt = inspecting.insp1UpdateTooltip; + if(inspectGroup) tt += " [All]"; + + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS && ac, pHOVER && ac, tt, icon[0], icon[1], cc) == 2) { + if(inspectGroup == 1) { + for( var i = 0, n = array_length(inspectings); i < n; i++ ) inspectings[i].inspector1Update(); + } else + inspecting.inspector1Update(); + } + } else + draw_sprite_ui(THEME.sequence_control, 1, bx + ui(16), by + ui(16),,,, COLORS._main_icon_dark); + + if(inspecting.hasInspector2Update()) { + by += ui(36); + var icon = inspecting.insp2UpdateIcon; + var ac = inspecting.insp2UpdateActive; + var cc = ac? icon[2] : COLORS._main_icon_dark; + var tt = inspecting.insp2UpdateTooltip; + if(inspectGroup) tt += " [All]"; + + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS && ac, pHOVER && ac, tt, icon[0], icon[1], cc) = 2) { + if(inspectGroup) { + for( var i = 0, n = array_length(inspectings); i < n; i++ ) inspectings[i].inspector2Update(); + } else + inspecting.inspector2Update(); + } + } + } + + function drawContent(panel) { // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + draw_clear_alpha(COLORS.panel_bg_clear, 0); + + draw_sprite_stretched(THEME.ui_panel_bg, 1, ui(8), top_bar_h - ui(8), w - ui(16), h - top_bar_h); + + if(inspecting && !inspecting.active) inspecting = noone; + + view_mode_tooltip.index = viewMode; + if(buttonInstant(THEME.button_hide, ui(8), ui(48), ui(32), ui(32), [mx, my], pFOCUS, pHOVER, view_mode_tooltip, THEME.inspector_view, viewMode) == 2) { + viewMode = !viewMode; + PREFERENCES.inspector_view_default = viewMode; + } + + if(inspecting) { + var _nodes = PANEL_GRAPH.nodes_selecting; + + inspectGroup = array_length(_nodes) > 1; + inspectings = array_empty(_nodes)? [ inspecting ] : _nodes; + + for( var i = 1, n = array_length(_nodes); i < n; i++ ) { + if(instanceof(_nodes[i]) != instanceof(_nodes[0])) { + inspectGroup = -1; + break; + } + } + + if(is_instanceof(inspecting, Node_Frame)) inspectGroup = 0; + + title = inspecting.renamed? inspecting.display_name : inspecting.name; + inspecting.inspectorStep(); + drawInspectingNode(); + + } else { + title = __txt("Inspector"); + + var txt = "Untitled"; + var context = PANEL_GRAPH.getCurrentContext(); + + if(context == noone && file_exists_empty(PROJECT.path)) + txt = string_replace(filename_name(PROJECT.path), filename_ext(PROJECT.path), ""); + else if(context != noone) + txt = context.name; + + draw_set_text(f_h5, fa_center, fa_center, COLORS._main_text); + draw_text_add(w / 2, ui(30), txt); + + if(PROJECT.meta.steam == FILE_STEAM_TYPE.steamOpen) { + var _tw = string_width(txt) / 2; + BLEND_ADD + draw_sprite_ui(THEME.steam, 0, w / 2 - _tw - ui(16), ui(29), 1, 1, 0, COLORS._main_icon); + BLEND_NORMAL + } + + var bx = w - ui(44); + var by = ui(12); + + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_set_default", "Set Metadata as default"), THEME.save, 0, COLORS._main_icon) == 2) + json_save_struct(DIRECTORY + "meta.json", PROJECT.meta.serialize()); + + by += ui(36); + if(STEAM_ENABLED && !workshop_uploading) { + if(PROJECT.path == "") { + buttonInstant(noone, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_workshop_save", "Save file before upload"), THEME.workshop_upload, 0, COLORS._main_icon, 0.5); + } else { + if(PROJECT.meta.steam == FILE_STEAM_TYPE.local) { //project made locally + if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_workshop_upload", "Upload to Steam Workshop"), THEME.workshop_upload, 0, COLORS._main_icon) == 2) { + var s = PANEL_PREVIEW.getNodePreviewSurface(); + if(is_surface(s)) { + PROJECT.meta.author_steam_id = STEAM_USER_ID; + PROJECT.meta.steam = FILE_STEAM_TYPE.steamUpload; + SAVE_AT(PROJECT, PROJECT.path); + + steam_ugc_create_project(); + workshop_uploading = true; + } else + noti_warning("Please send any node to preview panel to use as a thumbnail.") + } + } + + if(PROJECT.meta.steam && PROJECT.meta.author_steam_id == STEAM_USER_ID) { + if(PROJECT.meta.steam == FILE_STEAM_TYPE.steamUpload) { + buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], false, pHOVER, __txtx("panel_inspector_workshop_restart", "Open project from the workshop tab to update."), THEME.workshop_update, 0, COLORS._main_icon); + } else if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("panel_inspector_workshop_update", "Update Steam Workshop content"), THEME.workshop_update, 0, COLORS._main_icon) == 2) { + SAVE_AT(PROJECT, PROJECT.path); + steam_ugc_update_project(); + workshop_uploading = true; + } + } + } + } + + if(workshop_uploading) { + draw_sprite_ui(THEME.loading_s, 0, bx + ui(16), by + ui(16),,, current_time / 5, COLORS._main_icon); + if(STEAM_UGC_ITEM_UPLOADING == false) + workshop_uploading = false; + } + } + + contentPane.setFocusHover(pFOCUS, pHOVER); + contentPane.draw(ui(16), top_bar_h, mx - ui(16), my - top_bar_h); + + if(!locked && PANEL_GRAPH.getFocusingNode() && inspecting != PANEL_GRAPH.getFocusingNode()) + setInspecting(PANEL_GRAPH.getFocusingNode()); + + } + + //// =========== Serialize =========== + + static serialize = function() { + return { + name: instanceof(self), + inspecting : node_get_id(inspecting), + inspectings : array_map(inspectings, function(n) { return node_get_id(n) }), + + locked, + }; + } + + static deserialize = function(data) { + inspecting = node_from_id(data.inspecting); + inspectings = array_map(data.inspectings, function(n) { return node_from_id(n); }); + + locked = struct_try_get(data, "locked", locked); + + return self; + } + } \ No newline at end of file diff --git a/scripts/panel_menu/panel_menu.gml b/scripts/panel_menu/panel_menu.gml index a074d602d..5d99dc14f 100644 --- a/scripts/panel_menu/panel_menu.gml +++ b/scripts/panel_menu/panel_menu.gml @@ -1,724 +1,774 @@ +#region + function global_fullscreen() { CALL("fullscreen"); winMan_setFullscreen(!window_is_fullscreen); } + function global_project_close() { CALL("close_project"); PANEL_GRAPH.close(); } + function global_project_close_all() { CALL("close_project_all"); for( var i = array_length(PROJECTS) - 1; i >= 0; i-- ) closeProject(PROJECTS[i]); } + function global_theme_reload() { CALL("reload_theme"); loadGraphic(PREFERENCES.theme); resetPanel(); } + + function global_render_all() { CALL("render_all"); RENDER_ALL_REORDER } + function global_export_all() { + for (var i = 0, n = array_length(PROJECT.allNodes); i < n; i++) { + var node = PROJECT.allNodes[i]; + + if(!node.active) continue; + if(instanceof(node) != "Node_Export") continue; + + node.doInspectorAction(); + } + } + + function __fnInit_Global() { + registerFunction("", "New file", "N", MOD_KEY.ctrl, NEW ).setMenu("new_file", THEME.new_file) + + if(!DEMO) { + registerFunction("", "Save", "S", MOD_KEY.ctrl, SAVE ).setMenu("save", THEME.save) + registerFunction("", "Save as", "S", MOD_KEY.ctrl | MOD_KEY.shift, SAVE_AS ).setMenu("save_as", THEME.save) + registerFunction("", "Save at", "", MOD_KEY.none, SAVE_AT ).setMenu("save_at", THEME.save) + .setArg([ ARG("project", function() { return PROJECT; }, true), ARG("path", ""), ARG("log", "save at ") ]) + + registerFunction("", "Save all", "S", MOD_KEY.ctrl | MOD_KEY.alt, SAVE_ALL ).setMenu("save_all", THEME.icon_save_all) + registerFunction("", "Open", "O", MOD_KEY.ctrl, LOAD ).setMenu("open", THEME.noti_icon_file_load) + registerFunction("", "Open Safe", "", MOD_KEY.none, LOAD_SAFE ).setMenu("open_safe", THEME.noti_icon_file_load) + + registerFunction("", "Open at", "", MOD_KEY.none, LOAD_AT ).setMenu("open_at", THEME.noti_icon_file_load) + .setArg([ ARG("path", ""), ARG("readonly", false), ARG("override", false) ]) + + registerFunction("", "Append", "", MOD_KEY.none, APPEND ).setMenu("append", ) + .setArg([ ARG("path", ""), ARG("context", function() { return PANEL_GRAPH.getCurrentContext() }, true) ]) + + registerFunction("", "Import .zip", "", MOD_KEY.none, __IMPORT_ZIP ).setMenu("import_zip", ) + registerFunction("", "Export .zip", "", MOD_KEY.none, __EXPORT_ZIP ).setMenu("export_zip", ) + + registerFunction("", "Recent Files", "", MOD_KEY.none, + function(_dat) { + var arr = []; + for(var i = 0; i < min(10, ds_list_size(RECENT_FILES)); i++) { + var _rec = RECENT_FILES[| i]; + array_push(arr, menuItem(_rec, function(_dat) { LOAD_PATH(_dat.name); })); + } + return submenuCall(_dat, arr) + }).setMenu("recent_files",, true) + } + + registerFunction("", "Undo", "Z", MOD_KEY.ctrl, UNDO ).setMenu("undo", ) + registerFunction("", "Redo", "Z", MOD_KEY.ctrl | MOD_KEY.shift, REDO ).setMenu("redo", ) + + registerFunction("", "Full panel", "`", MOD_KEY.none, set_focus_fullscreen ).setMenu("full_panel", ) + registerFunction("", "Reset layout", vk_f10, MOD_KEY.ctrl, resetPanel ).setMenu("reset_layout", ) + + registerFunction("", "Fullscreen", vk_f11, MOD_KEY.none, global_fullscreen ).setMenu("fullscreen", ) + registerFunction("", "Render all", vk_f5, MOD_KEY.none, global_render_all ).setMenu("render_all", [ THEME.sequence_control, 1 ]) + registerFunction("", "Export all", "", MOD_KEY.none, global_export_all ).setMenu("export_all", ) + + registerFunction("", "Close file", "Q", MOD_KEY.ctrl, global_project_close ).setMenu("close_file", ) + registerFunction("", "Close all files", "", MOD_KEY.none, global_project_close_all ).setMenu("close_all_files",) + registerFunction("", "Close program", vk_f4, MOD_KEY.alt, window_close ).setMenu("close_software", ) + registerFunction("", "Close project", "", MOD_KEY.none, closeProject ).setMenu("close_project", ) + .setArg([ ARG("project", function() { return PROJECT; }, true) ]) + + registerFunction("", "Reload theme", vk_f10, MOD_KEY.ctrl | MOD_KEY.shift, global_theme_reload ).setMenu("reload_theme", ) + } +#endregion + function Panel_Menu() : PanelContent() constructor { - title = __txt("Menu"); - auto_pin = true; - - noti_flash = 0; - noti_flash_color = COLORS._main_accent; - noti_icon = noone; - noti_icon_show = 0; - noti_icon_time = 0; - - vertical_break = ui(240); - version_name_copy = 0; - - var _right = PREFERENCES.panel_menu_right_control; - if(_right) action_buttons = ["exit", "maximize", "minimize", "fullscreen"]; - else action_buttons = ["exit", "minimize", "maximize", "fullscreen"]; - - #region file - menu_file_nondemo = [ - menuItemAction(__txt("New"), NEW, THEME.new_file), - menuItemAction(__txt("Open") + "...", LOAD, THEME.noti_icon_file_load) - .setShiftMenu(menuItemAction(__txt("Open in safe mode") + "...", LOAD_SAFE, THEME.noti_icon_file_load)), - - menuItemAction(__txt("Save"), SAVE, THEME.save), - menuItemAction(__txt("Save as") + "...", SAVE_AS, THEME.save), - menuItemAction(__txt("Save all"), SAVE_ALL, THEME.icon_save_all), - menuItemAction(__txt("Recent files"), function(_dat) { - var arr = []; - for(var i = 0; i < min(10, ds_list_size(RECENT_FILES)); i++) { - var _rec = RECENT_FILES[| i]; - array_push(arr, menuItemAction(_rec, function(_dat) { LOAD_PATH(_dat.name); })); - } - - return submenuCall(_dat, arr); - }).setIsShelf(), - menuItemAction(__txtx("panel_menu_auto_save_folder", "Open autosave folder"), open_autosave_folder, THEME.save_auto), - menuItemAction(__txt("Import"), function(_dat) { - var arr = [ menuItemAction(__txt("Portable project (.zip)") + "...", __IMPORT_ZIP), ]; - return submenuCall(_dat, arr); - }).setIsShelf(), - - menuItemAction(__txt("Export"), function(_dat) { - var arr = [ menuItemAction(__txt("Portable project (.zip)") + "...", __EXPORT_ZIP), ]; - return submenuCall(_dat, arr); - }).setIsShelf(), - -1, - ]; - - menu_file = [ - menuItemAction(__txt("Preferences") + "...", call_dialog_preference, THEME.gear), - menuItemAction(__txt("Splash screen"), call_dialog_splash), - -1, - menuItemAction(__txt("Addons"), function(_dat) { - var arr = [ - menuItemAction(__txt("Addons") + "...", call_panel_addon), - menuItemAction(__txtx("panel_menu_addons_key", "Key displayer"), function() { - if(instance_exists(addon_key_displayer)) { - instance_destroy(addon_key_displayer); - return; - } - - instance_create_depth(0, 0, 0, addon_key_displayer); - }), - -1 - ]; - - for( var i = 0, n = array_length(ADDONS); i < n; i++ ) { - var _dir = ADDONS[i].name; - array_push(arr, menuItemAction(_dir, function(_dat) { addonTrigger(_dat.name); } )); - } - - return submenuCall(_dat, arr); - }, THEME.addon_icon ).setIsShelf(), - -1, - menuItemAction(__txt("Fullscreen"), global_fullscreen), - menuItemAction(__txt("Close current project"), global_project_close), - menuItemAction(__txt("Close all projects"), global_project_close_all), - menuItemAction(__txt("Close program"), window_close), - ]; - - if(!DEMO) menu_file = array_append(menu_file_nondemo, menu_file); - #endregion - - #region help - menu_help = [ - menuItemAction(__txtx("panel_menu_help_video", "Tutorial videos"), function() { url_open("https://www.youtube.com/@makhamdev"); }, THEME.youtube), - menuItemAction(__txtx("panel_menu_help_wiki", "Community Wiki"), function() { url_open("https://pixel-composer.fandom.com/wiki/Pixel_Composer_Wiki"); }, THEME.wiki), - -1, - menuItemAction(__txtx("panel_menu_local_directory", "Open local directory"), function() { shellOpenExplorer(DIRECTORY); }, THEME.folder), - menuItemAction(__txtx("panel_menu_autosave_directory", "Open autosave directory"), function() { shellOpenExplorer(DIRECTORY + "autosave/"); }, THEME.folder), - menuItemAction(__txtx("panel_menu_reset_default", "Reset default collection, assets"), function() { - zip_unzip("data/Collections.zip", DIRECTORY + "Collections"); - zip_unzip("data/Assets.zip", DIRECTORY + "Assets"); - }), - -1, - menuItemAction(__txtx("panel_menu_connect_patreon", "Connect to Patreon"), function() { dialogPanelCall(new Panel_Patreon()); }, THEME.patreon), - ]; - #endregion - - #region //////// MENU //////// - menuItem_undo = menuItemAction(__txt("Undo"), UNDO, THEME.undo); - menuItem_redo = menuItemAction(__txt("Redo"), REDO, THEME.redo); - - menus = [ - [ __txt("File"), menu_file ], - - [ __txt("Edit"), [ - menuItem_undo, - menuItem_redo, - menuItemAction(__txt("History"), call_panel_history), - ]], - - [ __txt("Preview"), [ - menuItemAction(__txtx("panel_menu_center_preview", "Center preview"), panel_preview_focus_content, THEME.icon_center_canvas), - menuItemAction(__txtx("panel_menu_save_current_preview_as", "Save current preview as..."), panel_preview_save_current_frame), - menuItemGroup(__txtx("panel_menu_preview_background", "Preview background"), [ - [ s_preview_transparent, function() { PANEL_PREVIEW.canvas_bg = -1; } ], - [ s_preview_white, function() { PANEL_PREVIEW.canvas_bg = c_white; } ], - [ s_preview_black, function() { PANEL_PREVIEW.canvas_bg = c_black; } ], - ]), - ]], - - [ __txt("Animation"), [ - menuItemAction(__txtx("panel_menu_animation_setting", "Animation Settings..."), panel_animation_settings, THEME.animation_setting), - -1, - menuItemAction(__txtx("panel_menu_animation_scaler", "Animation Scaler..."), panel_animation_scale, THEME.animation_timing), - ]], - - [ __txt("Rendering"), [ - menuItemAction(__txtx("panel_menu_render_all_nodes", "Render all nodes"), global_render_all, [ THEME.sequence_control, 1 ]), - menuItemAction(__txtx("panel_menu_execute_exports", "Execute all export nodes"), global_export_all), - menuItemAction(__txtx("panel_menu_export_render_all", "Render disabled node when export"), - function() { PREFERENCES.render_all_export = !PREFERENCES.render_all_export; },,, - function() { return PREFERENCES.render_all_export; }), - ]], - - [ __txt("Panels"), [ - menuItemAction(__txt("Workspace"), function(_dat) { - var arr = [], lays = []; - var f = file_find_first(DIRECTORY + "layouts/*", 0); - while(f != "") { - array_push(lays, filename_name_only(f)); - f = file_find_next(); - } - - array_push(arr, menuItemAction(__txtx("panel_menu_save_layout", "Save layout"), function() { - var dia = dialogCall(o_dialog_file_name, mouse_mx + ui(8), mouse_my + ui(8)); - dia.name = PREFERENCES.panel_layout_file; - dia.onModify = function(name) { - var cont = panelSerialize(); - json_save_struct(DIRECTORY + "layouts/" + name + ".json", cont); - }; - })); - - array_push(arr, menuItemAction(__txtx("panel_menu_reset_layout", "Reset layout"), resetPanel)); - array_push(arr, -1); - - for(var i = 0; i < array_length(lays); i++) { - array_push(arr, menuItemAction(lays[i], - function(_dat) { - PREFERENCES.panel_layout_file = _dat.name; - PREF_SAVE(); - setPanel(); - },,, function(item) { return item.name == PREFERENCES.panel_layout_file; } )); - } - - return submenuCall(_dat, arr); - }).setIsShelf(), - -1, - menuItemAction(__txt("Collections"), call_panel_Collection, noone, function() /*=>*/ { return findPanel("Panel_Collection") != noone; } ), - menuItemAction(__txt("Graph"), call_panel_Graph, noone, function() /*=>*/ { return findPanel("Panel_Graph") != noone; } ), - menuItemAction(__txt("Preview"), call_panel_Preview, noone, function() /*=>*/ { return findPanel("Panel_Preview") != noone; } ), - menuItemAction(__txt("Inspector"), call_panel_Inspector, noone, function() /*=>*/ { return findPanel("Panel_Inspector") != noone; } ), - menuItemAction(__txt("Workspace"), call_panel_Workspace, noone, function() /*=>*/ { return findPanel("Panel_Workspace") != noone; } ), - menuItemAction(__txt("Animation"), call_panel_Animation, noone, function() /*=>*/ { return findPanel("Panel_Animation") != noone; } ), - menuItemAction(__txt("Notifications"), call_panel_Notification, noone, function() /*=>*/ { return findPanel("Panel_Notification") != noone; } ), - menuItemAction(__txt("Global Variables"), call_panel_Globalvar, noone, function() /*=>*/ { return findPanel("Panel_Globalvar") != noone; } ), - menuItemAction(__txt("File Explorer"), call_panel_File_Explorer, noone, function() /*=>*/ { return findPanel("Panel_File_Explorer") != noone; } ), - - menuItemAction(__txt("Nodes"), function(_dat) { - return submenuCall(_dat, [ - menuItemAction(__txt("Align"), call_panel_Node_Align, noone, function() /*=>*/ { return findPanel("Panel_Node_Align") != noone; } ), - menuItemAction(__txt("Nodes"), call_panel_Nodes, noone, function() /*=>*/ { return findPanel("Panel_Nodes") != noone; } ), - menuItemAction(__txt("Tunnels"), call_panel_Tunnels, noone, function() /*=>*/ { return findPanel("Panel_Tunnels") != noone; } ), - ]); - } ).setIsShelf(), - - menuItemAction(__txt("Color"), function(_dat) { - return submenuCall(_dat, [ - menuItemAction(__txt("Color"), call_panel_Color, noone, function() /*=>*/ { return findPanel("Panel_Color") != noone; } ), - menuItemAction(__txt("Palettes"), call_panel_Palette, noone, function() /*=>*/ { return findPanel("Panel_Palette") != noone; } ), - menuItemAction(__txt("Gradients"), call_panel_Gradient, noone, function() /*=>*/ { return findPanel("Panel_Gradient") != noone; } ), - -1, - menuItemAction(__txt("Palette Mixer"), call_panel_Palette_Mixer, noone, function() /*=>*/ { return findPanel("Panel_Palette_Mixer") != noone; } ), - ]); - } ).setIsShelf(), - - menuItemAction(__txt("Histogram"), call_panel_Preview_Histogram, noone, function() /*=>*/ { return findPanel("Panel_Preview_Histogram") != noone; } ), - ]], - - [ __txt("Help"), menu_help ], - ]; - #endregion - - if(TESTING) { - array_push(menus, [ __txt("Dev"), [ - menuItemAction(__txtx("panel_debug_console", "Console"), call_panel_Console), - menuItemAction(__txtx("panel_debug_overlay", "Debug overlay"), function() /*=>*/ { show_debug_overlay(true); }), - menuItemAction(__txtx("panel_menu_tester", "Tester"), function() /*=>*/ { var dia = dialogPanelCall(new Panel_Test()); dia.destroy_on_click_out = false; }), - -1, - - menuItemAction(__txtx("panel_menu_test_load_all", "Load all current collections"), function() /*=>*/ { __test_load_current_collections(); }), - menuItemAction(__txtx("panel_menu_test_update_all", "Update all current collections"), function() /*=>*/ { __test_update_current_collections(); }), - menuItemAction(__txtx("panel_menu_test_add_meta", "Add metadata to current collections"), function() /*=>*/ { __test_metadata_current_collections(); }), - menuItemAction(__txtx("panel_menu_test_update_sam", "Update sample projects"), function() /*=>*/ { __test_update_sample_projects(); }), - -1, - menuItemAction(__txtx("panel_menu_test_load_nodes", "Load all nodes"), function() /*=>*/ { __test_load_all_nodes(); }), - menuItemAction(__txtx("panel_menu_test_gen_guide", "Generate node guide"), function() /*=>*/ { var dia = dialogPanelCall(new Panel_Node_Data_Gen()); dia.destroy_on_click_out = false; }), - menuItemAction(__txtx("panel_menu_test_gen_theme", "Generate theme object"), function() /*=>*/ { __test_generate_theme(); }), - -1, - menuItemAction(__txtx("panel_menu_test_warning", "Display Warning"), function() /*=>*/ { noti_warning("Error message") }), - menuItemAction(__txtx("panel_menu_test_error", "Display Error"), function() /*=>*/ { noti_error("Error message") }), - menuItemAction(__txtx("panel_menu_test_crash", "Force crash"), function() /*=>*/ { print(1 + "a"); }), - -1, - menuItemAction(__txt("Misc."), function(_dat) { - return submenuCall(_dat, [ menuItemAction(__txtx("panel_menu_node_credit", "Node credit dialog"), function() /*=>*/ { var dia = dialogPanelCall(new Panel_Node_Cost()); }), ]); - } ).setIsShelf(), - ]]); - } - - menu_help_steam = array_clone(menu_help); - array_push(menu_help_steam, -1, - menuItemAction(__txtx("panel_menu_steam_workshop", "Steam Workshop"), function() /*=>*/ { steam_activate_overlay_browser("https://steamcommunity.com/app/2299510/workshop/"); }, THEME.steam) ); - - function onFocusBegin() { PANEL_MENU = self; } - - function setNotiIcon(icon) { - noti_icon = icon; - noti_icon_time = 90; - } - - function undoUpdate() { - var txt; - - if(ds_stack_empty(UNDO_STACK)) { - txt = __txt("Undo"); - } else { - var act = ds_stack_top(UNDO_STACK); - if(array_length(act) > 1) - txt = $"{__txt("Undo")} {array_length(act)} {__txt("Actions")}"; - else - txt = $"{__txt("Undo")} {act[0]}"; - } - - menuItem_undo.active = !ds_stack_empty(UNDO_STACK); - menuItem_undo.name = txt; - - if(ds_stack_empty(REDO_STACK)) { - txt = __txt("Redo"); - } else { - var act = ds_stack_top(REDO_STACK); - if(array_length(act) > 1) - txt = $"{__txt("Redo")} {array_length(act)} {__txt("Actions")}"; - else - txt = $"{__txt("Redo")} {act[0]}"; - } - - menuItem_redo.active = !ds_stack_empty(REDO_STACK); - menuItem_redo.name = txt; - } - - function drawContent(panel) { - var _right = PREFERENCES.panel_menu_right_control; - var _draggable = pFOCUS; - - draw_clear_alpha(COLORS.panel_bg_clear, 1); - menus[6][1] = STEAM_ENABLED? menu_help_steam : menu_help; - var hori = w > h; - - var xx = ui(40); - var yy = ui(8); - - #region about icon - if(hori) { - if(PREFERENCES.panel_menu_right_control) - xx = ui(24); - else { - xx = ui(140); - draw_set_color(COLORS._main_icon_dark); - draw_line_round(xx, ui(8), xx, h - ui(8), 3); - } - - var bx = xx; - if(!PREFERENCES.panel_menu_right_control) - bx = w - ui(24); - - draw_sprite_ui_uniform(THEME.icon_24, 0, bx, h / 2, 1, c_white); - if(pHOVER && point_in_rectangle(mx, my, bx - ui(16), 0, bx + ui(16), ui(32))) { - _draggable = false; - if(mouse_press(mb_left, pFOCUS)) - dialogCall(o_dialog_about); - } - } else { - var bx = ui(20); - var by = h - ui(20); - - draw_sprite_ui_uniform(THEME.icon_24, 0, bx, by, 1, c_white); - if(pHOVER && point_in_rectangle(mx, my, bx - ui(16), by - ui(16), bx + ui(16), by + ui(16))) { - _draggable = false; - if(mouse_press(mb_left, pFOCUS)) - dialogCall(o_dialog_about); - } - } - #endregion - - #region menu - if(hori) { - if(PREFERENCES.panel_menu_right_control) - xx += ui(20); - else - xx += ui(8); - yy = 0; - } else { - xx = ui(8); - yy = w < vertical_break? ui(72) : ui(40); - } - - var sx = xx; - var xc, x0, x1, yc, y0, y1, _mx = xx; - var row = 1, maxRow = ceil(h / ui(40)); - - var _ww = 0; - for(var i = 0; i < array_length(menus) - 1; i++) { - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text); - var ww = string_width(menus[i][0]) + ui(16 + 8); - _ww += ww; - if(_ww > w * 0.4 - sx) { - row++; - _ww = 0; - } - } - - row = min(row, maxRow); - var _curRow = 0, currY; - var _rowH = (h - ui(12)) / row; - var _ww = 0; - - for(var i = 0; i < array_length(menus); i++) { - var _menu = menus[i]; - var _name = _menu[0]; - - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text); - var ww = string_width(_name) + ui(16); - var hh = line_get_height() + ui(8); - - if(hori) { - xc = xx + ww / 2; - - x0 = xx; - x1 = xx + ww; - y0 = ui(6) + _rowH * _curRow; - y1 = y0 + _rowH; - - yc = (y0 + y1) / 2; - currY = yc; - } else { - xc = w / 2; - yc = yy + hh / 2; - - x0 = ui(6); - x1 = w - ui(6); - y0 = yy; - y1 = yy + hh; - } - - if(pHOVER && point_in_rectangle(mx, my, x0, y0, x1, y1)) { - _draggable = false; - draw_sprite_stretched(THEME.s_box_r2_clr, 0, x0, y0, x1 - x0, y1 - y0); - - if((mouse_press(mb_left, pFOCUS)) || instance_exists(o_dialog_menubox)) { - if(hori) menuCall($"main_{_name}_menu", x + x0, y + y1, _menu[1]); - else menuCall($"main_{_name}_menu", x + x1, y + y0, _menu[1]); - } - } - - draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text); - draw_text_add(xc, yc, _name); - - if(hori) { - xx += ww + 8; - _mx = max(_mx, xx); - _ww += ww + 8; - if(_ww > w * 0.6 - sx) { - _curRow++; - _ww = 0; - xx = sx; - } - } else - yy += hh + 8; - } - #endregion - - #region notification - var warning_amo = ds_list_size(WARNING); - var error_amo = ds_list_size(ERRORS); - - if(hori) { - var nx0 = _mx + ui(24); - var ny0 = h / 2; - } else { - var nx0 = ui(8); - var ny0 = yy + ui(16); - } - - draw_set_text(f_p0, fa_left, fa_center); - var wr_w = ui(20) + ui(8) + string_width(string(warning_amo)); - var er_w = ui(20) + ui(8) + string_width(string(error_amo)); - - if(noti_icon_time > 0) { - noti_icon_show = lerp_float(noti_icon_show, 1, 4); - noti_icon_time--; - } else - noti_icon_show = lerp_float(noti_icon_show, 0, 4); - - var nw = hori? ui(16) + wr_w + ui(16) + er_w + noti_icon_show * ui(32) : w - ui(16); - var nh = ui(32); - - noti_flash = lerp_linear(noti_flash, 0, 0.02); - var ev = animation_curve_eval(ac_flash, noti_flash); - var cc = merge_color(c_white, noti_flash_color, ev); - - if(pHOVER && point_in_rectangle(mx, my, nx0, ny0 - nh / 2, nx0 + nw, ny0 + nh / 2)) { - _draggable = false; - draw_sprite_stretched_ext(THEME.s_box_r2_clr, 0, nx0, ny0 - nh / 2, nw, nh, cc, 1); - if(mouse_press(mb_left, pFOCUS)) { - var dia = dialogPanelCall(new Panel_Notification(), nx0, ny0 + nh / 2 + ui(4)); - dia.anchor = ANCHOR.left | ANCHOR.top; - } - - TOOLTIP = $"{warning_amo} {__txt("Warnings")} {error_amo} {__txt("Errors")}"; - } else - draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, nx0, ny0 - nh / 2, nw, nh, cc, 1); - - gpu_set_blendmode(bm_add); - draw_sprite_stretched_ext(THEME.s_box_r2, 0, nx0, ny0 - nh / 2, nw, nh, cc, ev / 2); - gpu_set_blendmode(bm_normal); - - if(noti_icon_show > 0) - draw_sprite_ui(noti_icon, 0, nx0 + nw - ui(16), ny0,,,,, noti_icon_show); - - draw_set_color(COLORS._main_text_inner); - var wr_x = hori? nx0 + ui(8) : w / 2 - (wr_w + er_w + ui(16)) / 2; - draw_sprite_ui_uniform(THEME.noti_icon_warning, warning_amo? 1 : 0, wr_x + ui(10), ny0); - draw_text_int(wr_x + ui(28), ny0, warning_amo); - - wr_x += wr_w + ui(16); - draw_sprite_ui_uniform(THEME.noti_icon_error, error_amo? 1 : 0, wr_x + ui(10), ny0); - draw_text_int(wr_x + ui(28), ny0, error_amo); - - if(hori) nx0 += nw + ui(8); - else ny0 += nh + ui(8); - #endregion - - #region addons - var wh = ui(32); - if(!hori) nx0 = ui(8); - - if(instance_exists(addon)) { - draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); - - var name = string(instance_number(addon)) + " "; - var ww = hori? string_width(name) + ui(40) : w - ui(16); - - if(pHOVER && point_in_rectangle(mx, my, nx0, ny0 - wh / 2, nx0 + ww, ny0 + wh / 2)) { - _draggable = false; - TOOLTIP = __txt("Addons"); - draw_sprite_stretched(THEME.s_box_r2_clr, 0, nx0, ny0 - wh / 2, ww, wh); - if(mouse_press(mb_left, pFOCUS)) - dialogPanelCall(new Panel_Addon()); - } else - draw_sprite_stretched(THEME.ui_panel_bg, 1, nx0, ny0 - wh / 2, ww, wh); - draw_text_int(nx0 + ui(8), ny0, name); - draw_sprite_ui(THEME.addon_icon, 0, nx0 + ui(20) + string_width(name), ny0 + ui(1),,,, COLORS._main_icon); - - if(hori) nx0 += ww + ui(4); - else ny0 += hh + ui(4); - } - #endregion - - var x1 = _right? w - ui(6) : ui(8 + 28); - - #region actions - var bs = ui(28); - - for( var i = 0, n = array_length(action_buttons); i < n; i++ ) { - var action = action_buttons[i]; - - switch(action) { - case "exit": - var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_exit, 0, COLORS._main_accent); - if(b) _draggable = false; - if(b == 2) window_close(); - break; - case "maximize": - var win_max = window_is_maximized || window_is_fullscreen; - if(OS == os_macosx) - win_max = __win_is_maximized; - - var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_maximize, win_max, [ COLORS._main_icon, CDEF.lime ]); - if(b) _draggable = false; - if(b == 2) { - if(OS == os_windows) { - if(window_is_fullscreen) { - winMan_setFullscreen(false); - winMan_Unmaximize(); - } else if(window_is_maximized) { - winMan_Unmaximize(); - DISPLAY_REFRESH - } else { - winMan_Maximize(); - DISPLAY_REFRESH - } - } else if(OS == os_macosx) { - if(__win_is_maximized) mac_window_minimize(); - else mac_window_maximize(); - } - } - break; - case "minimize": - var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_minimize, 0, [ COLORS._main_icon, CDEF.yellow ]); - if(b) _draggable = false; - if(b == -2) { - if(OS == os_windows) - winMan_Minimize(); - else if(OS == os_macosx) - mac_window_dock(); - } - break; - case "fullscreen": - var win_full = window_is_fullscreen; - var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_fullscreen, win_full, [ COLORS._main_icon, CDEF.cyan ]); - if(b) _draggable = false; - if(b == 2) { - if(OS == os_windows) - winMan_setFullscreen(!win_full); - else if(OS == os_macosx) { - if(win_full) { - winMan_setFullscreen(false); - mac_window_minimize(); - } else - winMan_setFullscreen(true); - } - } - break; - } - - if(_right) x1 -= bs + ui(4); - else x1 += bs + ui(4); - } - #endregion - - #region version - var _xx1 = _right? x1 : w - ui(40); - - var txt = "v. " + string(VERSION_STRING); - if(STEAM_ENABLED) txt += " Steam"; - - version_name_copy = lerp_float(version_name_copy, 0, 10); - var tc = merge_color(COLORS._main_text_sub, COLORS._main_value_positive, min(1, version_name_copy)); - var sc = merge_color(c_white, COLORS._main_value_positive, min(1, version_name_copy)); - - if(hori) { - draw_set_text(f_p0, fa_center, fa_center, tc); - var ww = string_width(txt) + ui(12); - var _x0 = _xx1 - ww; - var _y0 = ui(6); - var _x1 = _xx1; - var _y1 = h - ui(6); - - if(pHOVER && point_in_rectangle(mx, my, _x0, _y0, _x1, _y1)) { - _draggable = false; - draw_sprite_stretched_ext(THEME.button_hide_fill, 1, _x0, _y0, _x1 - _x0, _y1 - _y0, sc, 1); - - if(mouse_press(mb_left, pFOCUS)) - dialogCall(o_dialog_release_note); - if(mouse_press(mb_right, pFOCUS)) { - clipboard_set_text(VERSION_STRING); - version_name_copy = 3; - } - } - - draw_text(round((_x0 + _x1) / 2), round((_y0 + _y1) / 2), txt); - _xx1 = _x0 - ui(8); - } else { - var _xx1 = ui(40); - var y1 = h - ui(20); - - draw_set_text(f_p0, fa_left, fa_center, tc); - var ww = string_width(txt) + ui(12); - if(pHOVER && point_in_rectangle(mx, my, _xx1, y1 - ui(16), _xx1 + ww, y1 + ui(16))) { - _draggable = false; - draw_sprite_stretched_ext(THEME.button_hide_fill, 1, _xx1, y1 - ui(16), ww, ui(32), sc, 1); - - if(mouse_press(mb_left, pFOCUS)) - dialogCall(o_dialog_release_note); - if(mouse_press(mb_right, pFOCUS)) { - clipboard_set_text(VERSION_STRING); - version_name_copy = 3; - } - } - - draw_text_int(_xx1 + ui(6), y1, txt); - } - #endregion - - #region title - var txt = ""; - if(PROJECT.safeMode) txt += $"[{__txt("SAFE MODE")}] "; - if(PROJECT.readonly) txt += $"[{__txt("READ ONLY")}] "; - - txt += PROJECT.path == ""? __txt("Untitled") : filename_name(PROJECT.path); - if(PROJECT.modified) txt += "*"; - txt += " - Pixel Composer"; - if(DEMO) txt += " DEMO"; - - var tx0, tx1, tcx; - var ty0, ty1; - var tbx0, tby0; - var maxW; - - if(hori) { - tx0 = nx0; - tx1 = _xx1; - ty0 = 0; - ty1 = h; - tcx = (tx0 + tx1) / 2; - } else { - tx0 = ui(8); - tx1 = w < vertical_break? w - ui(16) : w - ui(144); - ty0 = w < vertical_break? ui(36) : ui(6); - - tcx = tx0; - if(!_right && w >= vertical_break) { - tx0 = x1 - bs; - tx1 = w - ui(16); - } - } - - maxW = abs(tx0 - tx1); - - draw_set_font(f_p0b); - var tc = string_cut(txt, maxW); - var tw = string_width(tc) + ui(16); - var th = ui(28); - - if(hori) { - tbx0 = tcx - tw / 2; - tby0 = ty1 / 2 - ui(14); - } else { - tbx0 = tx0; - tby0 = ty0; - } - - var _b = buttonInstant(THEME.button_hide_fill, tbx0, tby0, tw, th, [mx, my], pFOCUS, pHOVER); - var _hov = _b > 0; - - if(_b) _draggable = false; - if(_b == 2) { - _hov = true; - var arr = []; - var tip = []; - for(var i = 0; i < min(10, ds_list_size(RECENT_FILES)); i++) { - var _rec = RECENT_FILES[| i]; - var _dat = RECENT_FILE_DATA[| i]; - array_push(arr, menuItemAction(_rec, function(_dat) { LOAD_PATH(_dat.name); })); - array_push(tip, [ method(_dat, _dat.getThumbnail), VALUE_TYPE.surface ]); - } - - var dia = hori? menuCall("title_recent_menu", x + tcx, y + h, arr, fa_center) : menuCall("title_recent_menu", x + w, y + tby0, arr); - dia.tooltips = tip; - } - - if(hori) { - draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); - draw_text_int(tcx, (ty0 + ty1) / 2, tc); - } else { - draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_text_sub); - draw_text_int(tx0 + ui(8), tby0 + th / 2, tc); - } - - if(IS_PATREON && PREFERENCES.show_supporter_icon) { - var _tw = string_width(tc); - var _th = string_height(tc); - var _cx, _cy; - - if(hori) { - _cx = tcx + _tw / 2; - _cy = (ty0 + ty1) / 2 - _th / 2; - } else { - _cx = tx0 + ui(8) + _tw; - _cy = tby0 + th / 2 - _th / 2; - } - - _cx += ui(2); - _cy += ui(6); - - var _ib = COLORS._main_text_sub; - - if(pHOVER && point_in_rectangle(mx, my, _cx - 12, _cy - 12, _cx + 12, _cy + 12)) { - TOOLTIP = __txt("Supporter"); - _ib = COLORS._main_accent; - } - - draw_sprite_ext(s_patreon_supporter, 0, _cx, _cy, 1, 1, 0, _hov? COLORS._main_icon_dark : COLORS.panel_bg_clear, 1); - draw_sprite_ext(s_patreon_supporter, 1, _cx, _cy, 1, 1, 0, _ib, 1); - } - #endregion - - #region drag - if(mouse_press(mb_left, _draggable)) - winMan_initDrag(0b10000); - #endregion - } + title = __txt("Menu"); + auto_pin = true; + + noti_flash = 0; + noti_flash_color = COLORS._main_accent; + noti_icon = noone; + noti_icon_show = 0; + noti_icon_time = 0; + + vertical_break = ui(240); + version_name_copy = 0; + + var _right = PREFERENCES.panel_menu_right_control; + if(_right) action_buttons = ["exit", "maximize", "minimize", "fullscreen"]; + else action_buttons = ["exit", "minimize", "maximize", "fullscreen"]; + + menu_file_nondemo = [ + MENU_ITEMS.new_file, + MENU_ITEMS.open, + // .setShiftMenu(menuItemAction(__txt("Open in safe mode") + "...", LOAD_SAFE, THEME.noti_icon_file_load)), + + MENU_ITEMS.save, + MENU_ITEMS.save_as, + MENU_ITEMS.save_all, + MENU_ITEMS.recent_files, + + MENU_ITEMS.autosave_folder, + menuItemAction(__txt("Import"), function(_dat) { var arr = [ MENU_ITEMS.import_zip, ]; return submenuCall(_dat, arr); }).setIsShelf(), + menuItemAction(__txt("Export"), function(_dat) { var arr = [ MENU_ITEMS.export_zip, ]; return submenuCall(_dat, arr); }).setIsShelf(), + -1, + ]; + + menu_file = [ + MENU_ITEMS.preference, + MENU_ITEMS.splash_screen, + -1, + menuItemAction(__txt("Addons"), function(_dat) { + var arr = [ + MENU_ITEMS.addons, + menuItemAction(__txtx("panel_menu_addons_key", "Key displayer"), function() { + if(instance_exists(addon_key_displayer)) { + instance_destroy(addon_key_displayer); + return; + } + + instance_create_depth(0, 0, 0, addon_key_displayer); + }), + -1 + ]; + + for( var i = 0, n = array_length(ADDONS); i < n; i++ ) { + var _dir = ADDONS[i].name; + array_push(arr, menuItemAction(_dir, function(_dat) { addonTrigger(_dat.name); } )); + } + + return submenuCall(_dat, arr); + }, THEME.addon_icon ).setIsShelf(), + -1, + MENU_ITEMS.fullscreen, + MENU_ITEMS.close_file, + MENU_ITEMS.close_all_files, + MENU_ITEMS.close_software, + ]; + + if(!DEMO) menu_file = array_append(menu_file_nondemo, menu_file); + + menu_help = [ + menuItem(__txtx("panel_menu_help_video", "Tutorial videos"), function() { url_open("https://www.youtube.com/@makhamdev"); }, THEME.youtube), + menuItem(__txtx("panel_menu_help_wiki", "Community Wiki"), function() { url_open("https://pixel-composer.fandom.com/wiki/Pixel_Composer_Wiki"); }, THEME.wiki), + -1, + menuItem(__txtx("panel_menu_local_directory", "Open local directory"), function() { shellOpenExplorer(DIRECTORY); }, THEME.folder), + menuItem(__txtx("panel_menu_autosave_directory", "Open autosave directory"), function() { shellOpenExplorer(DIRECTORY + "autosave/"); }, THEME.folder), + menuItem(__txtx("panel_menu_reset_default", "Reset default collection, assets"), function() { + zip_unzip("data/Collections.zip", DIRECTORY + "Collections"); + zip_unzip("data/Assets.zip", DIRECTORY + "Assets"); + }), + -1, + menuItem(__txtx("panel_menu_connect_patreon", "Connect to Patreon"), function() { dialogPanelCall(new Panel_Patreon()); }, THEME.patreon), + ]; + + menuItem_undo = MENU_ITEMS.undo; + menuItem_redo = MENU_ITEMS.redo; + + menus = [ + [ __txt("File"), menu_file ], + + [ __txt("Edit"), [ + menuItem_undo, + menuItem_redo, + MENU_ITEMS.history, + ]], + + [ __txt("Preview"), [ + MENU_ITEMS.preview_focus_content, + MENU_ITEMS.preview_save_current_frame, + menuItemGroup(__txtx("panel_menu_preview_background", "Preview background"), [ + [ s_preview_transparent, function() { PANEL_PREVIEW.canvas_bg = -1; } ], + [ s_preview_white, function() { PANEL_PREVIEW.canvas_bg = c_white; } ], + [ s_preview_black, function() { PANEL_PREVIEW.canvas_bg = c_black; } ], + ]), + ]], + + [ __txt("Animation"), [ + MENU_ITEMS.animation_settings, + MENU_ITEMS.animation_scaler, + ]], + + [ __txt("Rendering"), [ + MENU_ITEMS.render_all, + MENU_ITEMS.export_all, + menuItem(__txtx("panel_menu_export_render_all", "Render disabled node when export"), + function() { PREFERENCES.render_all_export = !PREFERENCES.render_all_export; },,, + function() { return PREFERENCES.render_all_export; }), + ]], + + [ __txt("Panels"), [ + menuItem(__txt("Workspace"), function(_dat) { + var arr = [], lays = []; + var f = file_find_first(DIRECTORY + "layouts/*", 0); + while(f != "") { + array_push(lays, filename_name_only(f)); + f = file_find_next(); + } + + array_push(arr, menuItem(__txtx("panel_menu_save_layout", "Save layout"), function() { + var dia = dialogCall(o_dialog_file_name, mouse_mx + ui(8), mouse_my + ui(8)); + dia.name = PREFERENCES.panel_layout_file; + dia.onModify = function(name) { + var cont = panelSerialize(); + json_save_struct(DIRECTORY + "layouts/" + name + ".json", cont); + }; + })); + + array_push(arr, MENU_ITEMS.reset_layout); + array_push(arr, -1); + + for(var i = 0; i < array_length(lays); i++) { + array_push(arr, menuItem(lays[i], + function(_dat) { + PREFERENCES.panel_layout_file = _dat.name; + PREF_SAVE(); + setPanel(); + },,, function(item) { return item.name == PREFERENCES.panel_layout_file; } )); + } + + return submenuCall(_dat, arr); + }).setIsShelf(), + -1, + + MENU_ITEMS.collections_panel, + MENU_ITEMS.graph_panel, + MENU_ITEMS.preview_panel, + MENU_ITEMS.inspector_panel, + MENU_ITEMS.workspace_panel, + MENU_ITEMS.animation_panel, + MENU_ITEMS.notification_panel, + MENU_ITEMS.globalvar_panel, + MENU_ITEMS.file_explorer_panel, + + menuItem(__txt("Nodes"), function(_dat) { + return submenuCall(_dat, [ + MENU_ITEMS.align_panel, + MENU_ITEMS.nodes_panel, + MENU_ITEMS.tunnels_panel, + ]); + } ).setIsShelf(), + + menuItem(__txt("Color"), function(_dat) { + return submenuCall(_dat, [ + MENU_ITEMS.color_panel, + MENU_ITEMS.palettes_panel, + MENU_ITEMS.palettes_mixer_panel, + MENU_ITEMS.gradients_panel, + ]); + } ).setIsShelf(), + + MENU_ITEMS.preview_histogram, + ]], + + [ __txt("Help"), menu_help ], + ]; + + if(TESTING) { + array_push(menus, [ __txt("Dev"), [ + MENU_ITEMS.console_panel, + menuItem(__txtx("panel_debug_overlay", "Debug overlay"), function() /*=>*/ { show_debug_overlay(true); }), + menuItem(__txtx("panel_menu_tester", "Tester"), function() /*=>*/ { var dia = dialogPanelCall(new Panel_Test()); dia.destroy_on_click_out = false; }), + -1, + + menuItem(__txtx("panel_menu_test_load_all", "Load all current collections"), function() /*=>*/ { __test_load_current_collections(); }), + menuItem(__txtx("panel_menu_test_update_all", "Update all current collections"), function() /*=>*/ { __test_update_current_collections(); }), + menuItem(__txtx("panel_menu_test_add_meta", "Add metadata to current collections"), function() /*=>*/ { __test_metadata_current_collections(); }), + menuItem(__txtx("panel_menu_test_update_sam", "Update sample projects"), function() /*=>*/ { __test_update_sample_projects(); }), + -1, + menuItem(__txtx("panel_menu_test_load_nodes", "Load all nodes"), function() /*=>*/ { __test_load_all_nodes(); }), + menuItem(__txtx("panel_menu_test_gen_guide", "Generate node guide"), function() /*=>*/ { var dia = dialogPanelCall(new Panel_Node_Data_Gen()); dia.destroy_on_click_out = false; }), + menuItem(__txtx("panel_menu_test_gen_theme", "Generate theme object"), function() /*=>*/ { __test_generate_theme(); }), + -1, + menuItem(__txtx("panel_menu_test_warning", "Display Warning"), function() /*=>*/ { noti_warning("Error message") }), + menuItem(__txtx("panel_menu_test_error", "Display Error"), function() /*=>*/ { noti_error("Error message") }), + menuItem(__txtx("panel_menu_test_crash", "Force crash"), function() /*=>*/ { print(1 + "a"); }), + -1, + menuItem(__txt("Misc."), function(_dat) { + return submenuCall(_dat, [ menuItem(__txtx("panel_menu_node_credit", "Node credit dialog"), function() /*=>*/ { var dia = dialogPanelCall(new Panel_Node_Cost()); }), ]); + } ).setIsShelf(), + ]]); + } + + menu_help_steam = array_clone(menu_help); + array_push(menu_help_steam, -1, + menuItem(__txtx("panel_menu_steam_workshop", "Steam Workshop"), function() /*=>*/ { steam_activate_overlay_browser("https://steamcommunity.com/app/2299510/workshop/"); }, THEME.steam) ); + + function onFocusBegin() { PANEL_MENU = self; } + + function setNotiIcon(icon) { + noti_icon = icon; + noti_icon_time = 90; + } + + function undoUpdate() { + var txt; + + if(ds_stack_empty(UNDO_STACK)) { + txt = __txt("Undo"); + } else { + var act = ds_stack_top(UNDO_STACK); + if(array_length(act) > 1) + txt = $"{__txt("Undo")} {array_length(act)} {__txt("Actions")}"; + else + txt = $"{__txt("Undo")} {act[0]}"; + } + + menuItem_undo.active = !ds_stack_empty(UNDO_STACK); + menuItem_undo.name = txt; + + if(ds_stack_empty(REDO_STACK)) { + txt = __txt("Redo"); + } else { + var act = ds_stack_top(REDO_STACK); + if(array_length(act) > 1) + txt = $"{__txt("Redo")} {array_length(act)} {__txt("Actions")}"; + else + txt = $"{__txt("Redo")} {act[0]}"; + } + + menuItem_redo.active = !ds_stack_empty(REDO_STACK); + menuItem_redo.name = txt; + } + + function drawContent(panel) { + var _right = PREFERENCES.panel_menu_right_control; + var _draggable = pFOCUS; + + draw_clear_alpha(COLORS.panel_bg_clear, 1); + menus[6][1] = STEAM_ENABLED? menu_help_steam : menu_help; + var hori = w > h; + + var xx = ui(40); + var yy = ui(8); + + #region about icon + if(hori) { + if(PREFERENCES.panel_menu_right_control) + xx = ui(24); + else { + xx = ui(140); + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx, ui(8), xx, h - ui(8), 3); + } + + var bx = xx; + if(!PREFERENCES.panel_menu_right_control) + bx = w - ui(24); + + draw_sprite_ui_uniform(THEME.icon_24, 0, bx, h / 2, 1, c_white); + if(pHOVER && point_in_rectangle(mx, my, bx - ui(16), 0, bx + ui(16), ui(32))) { + _draggable = false; + if(mouse_press(mb_left, pFOCUS)) + dialogCall(o_dialog_about); + } + } else { + var bx = ui(20); + var by = h - ui(20); + + draw_sprite_ui_uniform(THEME.icon_24, 0, bx, by, 1, c_white); + if(pHOVER && point_in_rectangle(mx, my, bx - ui(16), by - ui(16), bx + ui(16), by + ui(16))) { + _draggable = false; + if(mouse_press(mb_left, pFOCUS)) + dialogCall(o_dialog_about); + } + } + #endregion + + #region menu + if(hori) { + if(PREFERENCES.panel_menu_right_control) + xx += ui(20); + else + xx += ui(8); + yy = 0; + } else { + xx = ui(8); + yy = w < vertical_break? ui(72) : ui(40); + } + + var sx = xx; + var xc, x0, x1, yc, y0, y1, _mx = xx; + var row = 1, maxRow = ceil(h / ui(40)); + + var _ww = 0; + for(var i = 0; i < array_length(menus) - 1; i++) { + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text); + var ww = string_width(menus[i][0]) + ui(16 + 8); + _ww += ww; + if(_ww > w * 0.4 - sx) { + row++; + _ww = 0; + } + } + + row = min(row, maxRow); + var _curRow = 0, currY; + var _rowH = (h - ui(12)) / row; + var _ww = 0; + + for(var i = 0; i < array_length(menus); i++) { + var _menu = menus[i]; + var _name = _menu[0]; + + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text); + var ww = string_width(_name) + ui(16); + var hh = line_get_height() + ui(8); + + if(hori) { + xc = xx + ww / 2; + + x0 = xx; + x1 = xx + ww; + y0 = ui(6) + _rowH * _curRow; + y1 = y0 + _rowH; + + yc = (y0 + y1) / 2; + currY = yc; + } else { + xc = w / 2; + yc = yy + hh / 2; + + x0 = ui(6); + x1 = w - ui(6); + y0 = yy; + y1 = yy + hh; + } + + if(pHOVER && point_in_rectangle(mx, my, x0, y0, x1, y1)) { + _draggable = false; + draw_sprite_stretched(THEME.s_box_r2_clr, 0, x0, y0, x1 - x0, y1 - y0); + + if((mouse_press(mb_left, pFOCUS)) || instance_exists(o_dialog_menubox)) { + if(hori) menuCall($"main_{_name}_menu", x + x0, y + y1, _menu[1]); + else menuCall($"main_{_name}_menu", x + x1, y + y0, _menu[1]); + } + } + + draw_set_text(f_p1, fa_center, fa_center, COLORS._main_text); + draw_text_add(xc, yc, _name); + + if(hori) { + xx += ww + 8; + _mx = max(_mx, xx); + _ww += ww + 8; + if(_ww > w * 0.6 - sx) { + _curRow++; + _ww = 0; + xx = sx; + } + } else + yy += hh + 8; + } + #endregion + + #region notification + var warning_amo = ds_list_size(WARNING); + var error_amo = ds_list_size(ERRORS); + + if(hori) { + var nx0 = _mx + ui(24); + var ny0 = h / 2; + } else { + var nx0 = ui(8); + var ny0 = yy + ui(16); + } + + draw_set_text(f_p0, fa_left, fa_center); + var wr_w = ui(20) + ui(8) + string_width(string(warning_amo)); + var er_w = ui(20) + ui(8) + string_width(string(error_amo)); + + if(noti_icon_time > 0) { + noti_icon_show = lerp_float(noti_icon_show, 1, 4); + noti_icon_time--; + } else + noti_icon_show = lerp_float(noti_icon_show, 0, 4); + + var nw = hori? ui(16) + wr_w + ui(16) + er_w + noti_icon_show * ui(32) : w - ui(16); + var nh = ui(32); + + noti_flash = lerp_linear(noti_flash, 0, 0.02); + var ev = animation_curve_eval(ac_flash, noti_flash); + var cc = merge_color(c_white, noti_flash_color, ev); + + if(pHOVER && point_in_rectangle(mx, my, nx0, ny0 - nh / 2, nx0 + nw, ny0 + nh / 2)) { + _draggable = false; + draw_sprite_stretched_ext(THEME.s_box_r2_clr, 0, nx0, ny0 - nh / 2, nw, nh, cc, 1); + if(mouse_press(mb_left, pFOCUS)) { + var dia = dialogPanelCall(new Panel_Notification(), nx0, ny0 + nh / 2 + ui(4)); + dia.anchor = ANCHOR.left | ANCHOR.top; + } + + TOOLTIP = $"{warning_amo} {__txt("Warnings")} {error_amo} {__txt("Errors")}"; + } else + draw_sprite_stretched_ext(THEME.ui_panel_bg, 1, nx0, ny0 - nh / 2, nw, nh, cc, 1); + + gpu_set_blendmode(bm_add); + draw_sprite_stretched_ext(THEME.s_box_r2, 0, nx0, ny0 - nh / 2, nw, nh, cc, ev / 2); + gpu_set_blendmode(bm_normal); + + if(noti_icon_show > 0) + draw_sprite_ui(noti_icon, 0, nx0 + nw - ui(16), ny0,,,,, noti_icon_show); + + draw_set_color(COLORS._main_text_inner); + var wr_x = hori? nx0 + ui(8) : w / 2 - (wr_w + er_w + ui(16)) / 2; + draw_sprite_ui_uniform(THEME.noti_icon_warning, warning_amo? 1 : 0, wr_x + ui(10), ny0); + draw_text_int(wr_x + ui(28), ny0, warning_amo); + + wr_x += wr_w + ui(16); + draw_sprite_ui_uniform(THEME.noti_icon_error, error_amo? 1 : 0, wr_x + ui(10), ny0); + draw_text_int(wr_x + ui(28), ny0, error_amo); + + if(hori) nx0 += nw + ui(8); + else ny0 += nh + ui(8); + #endregion + + #region addons + var wh = ui(32); + if(!hori) nx0 = ui(8); + + if(instance_exists(addon)) { + draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + + var name = string(instance_number(addon)) + " "; + var ww = hori? string_width(name) + ui(40) : w - ui(16); + + if(pHOVER && point_in_rectangle(mx, my, nx0, ny0 - wh / 2, nx0 + ww, ny0 + wh / 2)) { + _draggable = false; + TOOLTIP = __txt("Addons"); + draw_sprite_stretched(THEME.s_box_r2_clr, 0, nx0, ny0 - wh / 2, ww, wh); + if(mouse_press(mb_left, pFOCUS)) + dialogPanelCall(new Panel_Addon()); + } else + draw_sprite_stretched(THEME.ui_panel_bg, 1, nx0, ny0 - wh / 2, ww, wh); + draw_text_int(nx0 + ui(8), ny0, name); + draw_sprite_ui(THEME.addon_icon, 0, nx0 + ui(20) + string_width(name), ny0 + ui(1),,,, COLORS._main_icon); + + if(hori) nx0 += ww + ui(4); + else ny0 += hh + ui(4); + } + #endregion + + var x1 = _right? w - ui(6) : ui(8 + 28); + + #region actions + var bs = ui(28); + + for( var i = 0, n = array_length(action_buttons); i < n; i++ ) { + var action = action_buttons[i]; + + switch(action) { + case "exit": + var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_exit, 0, COLORS._main_accent); + if(b) _draggable = false; + if(b == 2) window_close(); + break; + case "maximize": + var win_max = window_is_maximized || window_is_fullscreen; + if(OS == os_macosx) + win_max = __win_is_maximized; + + var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_maximize, win_max, [ COLORS._main_icon, CDEF.lime ]); + if(b) _draggable = false; + if(b == 2) { + if(OS == os_windows) { + if(window_is_fullscreen) { + winMan_setFullscreen(false); + winMan_Unmaximize(); + } else if(window_is_maximized) { + winMan_Unmaximize(); + DISPLAY_REFRESH + } else { + winMan_Maximize(); + DISPLAY_REFRESH + } + } else if(OS == os_macosx) { + if(__win_is_maximized) mac_window_minimize(); + else mac_window_maximize(); + } + } + break; + case "minimize": + var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_minimize, 0, [ COLORS._main_icon, CDEF.yellow ]); + if(b) _draggable = false; + if(b == -2) { + if(OS == os_windows) + winMan_Minimize(); + else if(OS == os_macosx) + mac_window_dock(); + } + break; + case "fullscreen": + var win_full = window_is_fullscreen; + var b = buttonInstant(THEME.button_hide_fill, x1 - bs, ui(6), bs, bs, [mx, my], true, pHOVER,, THEME.window_fullscreen, win_full, [ COLORS._main_icon, CDEF.cyan ]); + if(b) _draggable = false; + if(b == 2) { + if(OS == os_windows) + winMan_setFullscreen(!win_full); + else if(OS == os_macosx) { + if(win_full) { + winMan_setFullscreen(false); + mac_window_minimize(); + } else + winMan_setFullscreen(true); + } + } + break; + } + + if(_right) x1 -= bs + ui(4); + else x1 += bs + ui(4); + } + #endregion + + #region version + var _xx1 = _right? x1 : w - ui(40); + + var txt = "v. " + string(VERSION_STRING); + if(STEAM_ENABLED) txt += " Steam"; + + version_name_copy = lerp_float(version_name_copy, 0, 10); + var tc = merge_color(COLORS._main_text_sub, COLORS._main_value_positive, min(1, version_name_copy)); + var sc = merge_color(c_white, COLORS._main_value_positive, min(1, version_name_copy)); + + if(hori) { + draw_set_text(f_p0, fa_center, fa_center, tc); + var ww = string_width(txt) + ui(12); + var _x0 = _xx1 - ww; + var _y0 = ui(6); + var _x1 = _xx1; + var _y1 = h - ui(6); + + if(pHOVER && point_in_rectangle(mx, my, _x0, _y0, _x1, _y1)) { + _draggable = false; + draw_sprite_stretched_ext(THEME.button_hide_fill, 1, _x0, _y0, _x1 - _x0, _y1 - _y0, sc, 1); + + if(mouse_press(mb_left, pFOCUS)) + dialogCall(o_dialog_release_note); + if(mouse_press(mb_right, pFOCUS)) { + clipboard_set_text(VERSION_STRING); + version_name_copy = 3; + } + } + + draw_text(round((_x0 + _x1) / 2), round((_y0 + _y1) / 2), txt); + _xx1 = _x0 - ui(8); + } else { + var _xx1 = ui(40); + var y1 = h - ui(20); + + draw_set_text(f_p0, fa_left, fa_center, tc); + var ww = string_width(txt) + ui(12); + if(pHOVER && point_in_rectangle(mx, my, _xx1, y1 - ui(16), _xx1 + ww, y1 + ui(16))) { + _draggable = false; + draw_sprite_stretched_ext(THEME.button_hide_fill, 1, _xx1, y1 - ui(16), ww, ui(32), sc, 1); + + if(mouse_press(mb_left, pFOCUS)) + dialogCall(o_dialog_release_note); + if(mouse_press(mb_right, pFOCUS)) { + clipboard_set_text(VERSION_STRING); + version_name_copy = 3; + } + } + + draw_text_int(_xx1 + ui(6), y1, txt); + } + #endregion + + #region title + var txt = ""; + if(PROJECT.safeMode) txt += $"[{__txt("SAFE MODE")}] "; + if(PROJECT.readonly) txt += $"[{__txt("READ ONLY")}] "; + + txt += PROJECT.path == ""? __txt("Untitled") : filename_name(PROJECT.path); + if(PROJECT.modified) txt += "*"; + txt += " - Pixel Composer"; + if(DEMO) txt += " DEMO"; + + var tx0, tx1, tcx; + var ty0, ty1; + var tbx0, tby0; + var maxW; + + if(hori) { + tx0 = nx0; + tx1 = _xx1; + ty0 = 0; + ty1 = h; + tcx = (tx0 + tx1) / 2; + } else { + tx0 = ui(8); + tx1 = w < vertical_break? w - ui(16) : w - ui(144); + ty0 = w < vertical_break? ui(36) : ui(6); + + tcx = tx0; + if(!_right && w >= vertical_break) { + tx0 = x1 - bs; + tx1 = w - ui(16); + } + } + + maxW = abs(tx0 - tx1); + + draw_set_font(f_p0b); + var tc = string_cut(txt, maxW); + var tw = string_width(tc) + ui(16); + var th = ui(28); + + if(hori) { + tbx0 = tcx - tw / 2; + tby0 = ty1 / 2 - ui(14); + } else { + tbx0 = tx0; + tby0 = ty0; + } + + var _b = buttonInstant(THEME.button_hide_fill, tbx0, tby0, tw, th, [mx, my], pFOCUS, pHOVER); + var _hov = _b > 0; + + if(_b) _draggable = false; + if(_b == 2) { + _hov = true; + var arr = []; + var tip = []; + for(var i = 0; i < min(10, ds_list_size(RECENT_FILES)); i++) { + var _rec = RECENT_FILES[| i]; + var _dat = RECENT_FILE_DATA[| i]; + array_push(arr, menuItem(_rec, function(_dat) { LOAD_PATH(_dat.name); })); + array_push(tip, [ method(_dat, _dat.getThumbnail), VALUE_TYPE.surface ]); + } + + var dia = hori? menuCall("title_recent_menu", x + tcx, y + h, arr, fa_center) : menuCall("title_recent_menu", x + w, y + tby0, arr); + dia.tooltips = tip; + } + + if(hori) { + draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); + draw_text_int(tcx, (ty0 + ty1) / 2, tc); + } else { + draw_set_text(f_p0b, fa_left, fa_center, COLORS._main_text_sub); + draw_text_int(tx0 + ui(8), tby0 + th / 2, tc); + } + + if(IS_PATREON && PREFERENCES.show_supporter_icon) { + var _tw = string_width(tc); + var _th = string_height(tc); + var _cx, _cy; + + if(hori) { + _cx = tcx + _tw / 2; + _cy = (ty0 + ty1) / 2 - _th / 2; + } else { + _cx = tx0 + ui(8) + _tw; + _cy = tby0 + th / 2 - _th / 2; + } + + _cx += ui(2); + _cy += ui(6); + + var _ib = COLORS._main_text_sub; + + if(pHOVER && point_in_rectangle(mx, my, _cx - 12, _cy - 12, _cx + 12, _cy + 12)) { + TOOLTIP = __txt("Supporter"); + _ib = COLORS._main_accent; + } + + draw_sprite_ext(s_patreon_supporter, 0, _cx, _cy, 1, 1, 0, _hov? COLORS._main_icon_dark : COLORS.panel_bg_clear, 1); + draw_sprite_ext(s_patreon_supporter, 1, _cx, _cy, 1, 1, 0, _ib, 1); + } + #endregion + + #region drag + if(mouse_press(mb_left, _draggable)) + winMan_initDrag(0b10000); + #endregion + } } \ No newline at end of file diff --git a/scripts/panel_notification/panel_notification.gml b/scripts/panel_notification/panel_notification.gml index 3bdb9a17c..59f2737f8 100644 --- a/scripts/panel_notification/panel_notification.gml +++ b/scripts/panel_notification/panel_notification.gml @@ -1,36 +1,40 @@ +#region funtion calls + function __fnInit_Notification() { + registerFunction("Notifications", "Clear log messages", "", MOD_KEY.none, notification_clear_all ).setMenu("noti_clear_all"); + registerFunction("Notifications", "Clear warning messages", "", MOD_KEY.none, notification_clear_log ).setMenu("noti_clear_log"); + registerFunction("Notifications", "Clear all notifications", "", MOD_KEY.none, notification_clear_warning ).setMenu("noti_clear_warning"); + + registerFunction("Notifications", "Open log file", "", MOD_KEY.none, notification_open_log ).setMenu("noti_open_log"); + + } + + function notification_clear_all() { CALL("notification_clear_all"); ds_list_clear(STATUSES); } + function notification_clear_log() { CALL("notification_clear_log"); for( var i = ds_list_size(STATUSES) - 1; i >= 0; i-- ) if(STATUSES[| i].type == NOTI_TYPE.log) ds_list_delete(STATUSES, i); } + function notification_clear_warning() { CALL("notification_clear_warning"); for( var i = ds_list_size(STATUSES) - 1; i >= 0; i-- ) if(STATUSES[| i].type == NOTI_TYPE.warning) ds_list_delete(STATUSES, i); } + + function notification_open_log() { CALL("notification_open_log"); shellOpenExplorer(DIRECTORY + "log/log.txt"); } + +#endregion + function Panel_Notification() : PanelContent() constructor { title = __txt("Notifications"); w = ui(720); h = ui(480); title_height = 64; - padding = 20; + padding = 20; - current_page = 0; - filter = NOTI_TYPE.log | NOTI_TYPE.warning | NOTI_TYPE.error; - showHeader = false; + current_page = 0; + filter = NOTI_TYPE.log | NOTI_TYPE.warning | NOTI_TYPE.error; + showHeader = false; + noti_selecting = noone; rightClickMenu = [ - menuItemAction(__txtx("noti_clear_log", "Clear log messages"), function() { - for( var i = ds_list_size(STATUSES) - 1; i >= 0; i-- ) { - if(STATUSES[| i].type == NOTI_TYPE.log) - ds_list_delete(STATUSES, i); - } - }), - menuItemAction(__txtx("noti_clear_warn", "Clear warning messages"), function() { - for( var i = ds_list_size(STATUSES) - 1; i >= 0; i-- ) { - if(STATUSES[| i].type == NOTI_TYPE.warning) - ds_list_delete(STATUSES, i); - } - }), + MENU_ITEMS.noti_clear_all, + MENU_ITEMS.noti_clear_log, + MENU_ITEMS.noti_clear_warning, -1, - menuItemAction(__txtx("noti_clear_all", "Clear all notifications"), function() { - ds_list_clear(STATUSES); - }), - -1, - menuItemAction(__txtx("noti_open_log", "Open log file"), function() { - shellOpenExplorer(DIRECTORY + "log/log.txt"); - }), + MENU_ITEMS.noti_open_log, ]; function onResize() { @@ -76,16 +80,13 @@ function Panel_Notification() : PanelContent() constructor { noti.onClick(); if(mouse_press(mb_right, pFOCUS)) { - var dia = menuCall("notification_menu",,, [ - menuItemAction(__txtx("noti_copy_message", "Copy notification message"), function() { - clipboard_set_text(o_dialog_menubox.noti.txt); - }), - menuItemAction(__txtx("noti_delete_message", "Delete notification"), function() { - ds_list_remove(STATUSES, o_dialog_menubox.noti); - }), - ],, noti); + noti_selecting = noti; + + var dia = menuCall("notification_menu",,, [ + menuItem(__txtx("noti_copy_message", "Copy notification message"), function() { clipboard_set_text(noti_selecting.txt); }), + menuItem(__txtx("noti_delete_message", "Delete notification"), function() { ds_list_remove(STATUSES, noti_selecting); }), + ]); - dia.noti = noti; } } diff --git a/scripts/panel_palette/panel_palette.gml b/scripts/panel_palette/panel_palette.gml index c81f1e6b3..5748dfcce 100644 --- a/scripts/panel_palette/panel_palette.gml +++ b/scripts/panel_palette/panel_palette.gml @@ -14,17 +14,17 @@ function Panel_Palette() : PanelContent() constructor { __save_palette_data = []; view_label = true; - menu_refresh = menuItemAction(__txt("Refresh"), function() { __initPalette(); }); - menu_add = menuItemAction(__txt("Add"), function(_dat) { + menu_refresh = menuItem(__txt("Refresh"), function() { __initPalette(); }); + menu_add = menuItem(__txt("Add"), function(_dat) { return submenuCall(_dat, [ - menuItemAction(__txt("File..."), function() { + menuItem(__txt("File..."), function() { var _p = get_open_filename("hex|*.hex|gpl|*.gpl|Image|.png", "palette"); if(!file_exists_empty(_p)) return; file_copy(_p, $"{DIRECTORY}Palettes/{filename_name(_p)}"); __initPalette(); }), - menuItemAction(__txt("Lospec..."), function() { + menuItem(__txt("Lospec..."), function() { fileNameCall("", function(txt) { if(txt == "") return; txt = string_lower(txt); @@ -37,8 +37,8 @@ function Panel_Palette() : PanelContent() constructor { ]); }).setIsShelf(); - menu_stretch = menuItemAction(__txt("Stretch"), function() { PREFERENCES.palette_stretch = !PREFERENCES.palette_stretch; }, noone, noone, function() /*=>*/ {return PREFERENCES.palette_stretch}); - menu_mini = menuItemAction(__txt("Label"), function() { view_label = !view_label; }, noone, noone, function() /*=>*/ {return view_label}); + menu_stretch = menuItem(__txt("Stretch"), function() { PREFERENCES.palette_stretch = !PREFERENCES.palette_stretch; }, noone, noone, function() /*=>*/ {return PREFERENCES.palette_stretch}); + menu_mini = menuItem(__txt("Label"), function() { view_label = !view_label; }, noone, noone, function() /*=>*/ {return view_label}); function onResize() { sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding)); @@ -164,10 +164,10 @@ function Panel_Palette() : PanelContent() constructor { menu_add, menu_refresh, -1, - menuItemAction(__txtx("palette_editor_set_default", "Set as default"), function() { + menuItem(__txtx("palette_editor_set_default", "Set as default"), function() { PROJECT.setPalette(array_clone(hovering.palette)); }), - menuItemAction(__txtx("palette_editor_delete", "Delete palette"), function() { + menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { file_delete(hovering.path); __initPalette(); }), diff --git a/scripts/panel_palette_mixer/panel_palette_mixer.gml b/scripts/panel_palette_mixer/panel_palette_mixer.gml index 9e25585b2..ac3f239dd 100644 --- a/scripts/panel_palette_mixer/panel_palette_mixer.gml +++ b/scripts/panel_palette_mixer/panel_palette_mixer.gml @@ -188,7 +188,7 @@ function Panel_Palette_Mixer() : PanelContent() constructor { var _b = buttonInstant(THEME.button_hide, _bx, _by, _bs, pal_h, [ mx, my ], pFOCUS, pHOVER, "", THEME.hamburger_s); if(_b == 2) { menuCall("",,, [ - menuItemAction("Save palette as...", function() { + menuItem("Save palette as...", function() { var _path = get_save_filename_pxc("Hex paleete|*.hex", "Palette"); if(_path != "") { var _str = palette_string_hex(palette, false); @@ -392,7 +392,7 @@ function Panel_Palette_Mixer() : PanelContent() constructor { conn_menu_ctx = [ blnd_hovering ]; menuCall(,,, [ - menuItemAction("Delete Blend point", function() { array_delete(palette_data.blends, conn_menu_ctx[0], 1); } ), + menuItem("Delete Blend point", function() { array_delete(palette_data.blends, conn_menu_ctx[0], 1); } ), ]); } @@ -443,7 +443,7 @@ function Panel_Palette_Mixer() : PanelContent() constructor { conn_menu_ctx = [ conn[0], conn[1], _con_rat ]; menuCall(,,, [ - menuItemAction("New Blend point", function() { array_push(palette_data.blends, { from : conn_menu_ctx[0], to : conn_menu_ctx[1], amount : conn_menu_ctx[2] }) } ), + menuItem("New Blend point", function() { array_push(palette_data.blends, { from : conn_menu_ctx[0], to : conn_menu_ctx[1], amount : conn_menu_ctx[2] }) } ), ]); } @@ -467,18 +467,18 @@ function Panel_Palette_Mixer() : PanelContent() constructor { if(mouse_press(mb_right)) { menuCall(,,, [ - menuItemAction("Center view", function() { centerView(); } ), + menuItem("Center view", function() { centerView(); } ), -1, - menuItemAction("Save mixed...", function() { + menuItem("Save mixed...", function() { var _path = get_save_filename_pxc("JSON|*.json", "New mixed"); if(_path != "") save_palette_mixer(palette_data, _path); }, THEME.save), - menuItemAction("Load mixed...", function() { + menuItem("Load mixed...", function() { var _path = get_open_filename_pxc("JSON|*.json", ""); if(_path != "") palette_data = load_palette_mixer(_path); }, THEME.noti_icon_file_load), -1, - menuItemAction("Clear palette", function() { palette_data = { nodes: [], connections: [], blends: [], } }, THEME.cross), + menuItem("Clear palette", function() { palette_data = { nodes: [], connections: [], blends: [], } }, THEME.cross), ]); } } diff --git a/scripts/panel_presets/panel_presets.gml b/scripts/panel_presets/panel_presets.gml index 9d0a10aaa..b67b3e6b8 100644 --- a/scripts/panel_presets/panel_presets.gml +++ b/scripts/panel_presets/panel_presets.gml @@ -4,6 +4,12 @@ function panel_preset_replace() { CHECK_PANEL_PRESETS CALL("panel_preset_replace function panel_preset_delete() { CHECK_PANEL_PRESETS CALL("panel_preset_delete"); file_delete(FOCUS_CONTENT.selecting_preset.path); FOCUS_CONTENT.__initPresets(); } function panel_preset_reset() { CHECK_PANEL_PRESETS CALL("panel_preset_reset"); FOCUS_CONTENT.newPresetFromNode("_default"); } +function __fnInit_Presets() { + registerFunction("Presets", "Replace", "", MOD_KEY.none, panel_preset_replace).setMenu("preset_replace").hidePalette(); + registerFunction("Presets", "Delete", "", MOD_KEY.none, panel_preset_delete ).setMenu("preset_delete", THEME.cross).hidePalette(); + registerFunction("Presets", "Reset To Default", "", MOD_KEY.none, panel_preset_reset ).setMenu("preset_reset") +} + function Panel_Presets(_node) : PanelContent() constructor { title = __txt("Presets"); padding = 8; @@ -29,17 +35,13 @@ function Panel_Presets(_node) : PanelContent() constructor { directory_verify($"{DIRECTORY}Presets/{instanceof(node)}/"); __initPresets(); - registerFunction("Presets", "Replace", "", MOD_KEY.none, panel_preset_replace); - registerFunction("Presets", "Delete", "", MOD_KEY.none, panel_preset_delete); - registerFunction("Presets", "Reset To Default", "", MOD_KEY.none, panel_preset_reset); - context_menu = [ - menuItemAction(__txt("Replace preset"), panel_preset_replace), - menuItemAction(__txt("Delete"), panel_preset_delete, THEME.cross), + MENU_ITEMS.preset_replace, + MENU_ITEMS.preset_delete, ]; context_def = [ - menuItemAction(__txt("Set to default"), panel_preset_reset), + MENU_ITEMS.preset_reset, ]; thumbnail_mask = surface_create(1, 1); diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index 79a7b6bff..f230288c4 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -1,2270 +1,2268 @@ #region funtion calls - function __fnInit_Preview() { - registerFunction("Preview", "Focus content", "F", MOD_KEY.none, panel_preview_focus_content); - registerFunction("Preview", "Save current frame", "S", MOD_KEY.shift, panel_preview_save_current_frame); - registerFunction("Preview", "Save to focused file", "", MOD_KEY.none, panel_preview_saveCurrentFrameToFocus); - registerFunction("Preview", "Save all current frame", "", MOD_KEY.none, panel_preview_save_all_current_frame); - registerFunction("Preview", "Preview window", "P", MOD_KEY.ctrl, panel_preview_preview_window); - registerFunction("Preview", "Toggle grid", "G", MOD_KEY.ctrl, panel_preview_toggle_grid); - - registerFunction("Preview", "Pan", "", MOD_KEY.ctrl, panel_preview_pan); - registerFunction("Preview", "Zoom", "", MOD_KEY.alt | MOD_KEY.ctrl, panel_preview_zoom); - - registerFunction("Preview", "3D Front view", vk_numpad1, MOD_KEY.none, panel_preview_3d_view_front); - registerFunction("Preview", "3D Back view", vk_numpad1, MOD_KEY.alt, panel_preview_3d_view_back); - registerFunction("Preview", "3D Right view ", vk_numpad3, MOD_KEY.none, panel_preview_3d_view_right); - registerFunction("Preview", "3D Left view ", vk_numpad3, MOD_KEY.alt, panel_preview_3d_view_left); - registerFunction("Preview", "3D Top view", vk_numpad7, MOD_KEY.none, panel_preview_3d_view_top); - registerFunction("Preview", "3D Bottom view", vk_numpad7, MOD_KEY.alt, panel_preview_3d_view_bottom); - - registerFunction("Preview", "Scale x1", "1", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(1); }); - registerFunction("Preview", "Scale x2", "2", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(2); }); - registerFunction("Preview", "Scale x4", "3", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(4); }); - registerFunction("Preview", "Scale x8", "4", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(8); }); - - registerFunction("Preview", "Set Tile Off", "", MOD_KEY.none, panel_preview_set_tile_off); - registerFunction("Preview", "Set Tile Horizontal", "", MOD_KEY.none, panel_preview_set_tile_horizontal); - registerFunction("Preview", "Set Tile Vertical", "", MOD_KEY.none, panel_preview_set_tile_vertical); - registerFunction("Preview", "Set Tile Both", "", MOD_KEY.none, panel_preview_set_tile_both); - registerFunction("Preview", "Toggle Tile", "", MOD_KEY.none, panel_preview_set_tile_toggle); - - registerFunction("Preview", "New Preview Window", "", MOD_KEY.none, panel_preview_new_preview_window); - registerFunction("Preview", "Save Current Frame", "", MOD_KEY.none, panel_preview_saveCurrentFrame); - registerFunction("Preview", "Save All Current Frames", "", MOD_KEY.none, panel_preview_saveAllCurrentFrames); - registerFunction("Preview", "Copy Current Frame", "", MOD_KEY.none, panel_preview_copyCurrentFrame); - registerFunction("Preview", "Copy Color", "", MOD_KEY.none, panel_preview_copy_color); - registerFunction("Preview", "Copy Color Hex", "", MOD_KEY.none, panel_preview_copy_color_hex); - } - - function panel_preview_focus_content() { CALL("preview_focus_content"); PANEL_PREVIEW.fullView(); } - function panel_preview_save_current_frame() { CALL("preview_save_current_frame"); PANEL_PREVIEW.saveCurrentFrame(); } - function panel_preview_saveCurrentFrameToFocus() { CALL("preview_save_to_focused_file"); PANEL_PREVIEW.saveCurrentFrameToFocus(); } - function panel_preview_save_all_current_frame() { CALL("preview_save_all_current_frame"); PANEL_PREVIEW.saveAllCurrentFrames(); } - function panel_preview_preview_window() { CALL("preview_preview_window"); PANEL_PREVIEW.create_preview_window(PANEL_PREVIEW.getNodePreview()); } - function panel_preview_toggle_grid() { CALL("preview_toggle_grid"); PROJECT.previewGrid.show = !PROJECT.previewGrid.show; } - - function panel_preview_pan() { CALL("preview_pan"); PANEL_PREVIEW.canvas_dragging_key = true; } - function panel_preview_zoom() { CALL("preview_zoom"); PANEL_PREVIEW.canvas_zooming_key = true; } - - function panel_preview_3d_view_front() { CALL("preview_3d_front_view"); PANEL_PREVIEW.d3_view_action_front(); } - function panel_preview_3d_view_back() { CALL("preview_3d_back_view"); PANEL_PREVIEW.d3_view_action_back(); } - function panel_preview_3d_view_right() { CALL("preview_3d_right_view"); PANEL_PREVIEW.d3_view_action_right(); } - function panel_preview_3d_view_left() { CALL("preview_3d_left_view"); PANEL_PREVIEW.d3_view_action_left(); } - function panel_preview_3d_view_top() { CALL("preview_3d_top_view"); PANEL_PREVIEW.d3_view_action_top(); } - function panel_preview_3d_view_bottom() { CALL("preview_3d_bottom_view"); PANEL_PREVIEW.d3_view_action_bottom(); } - - function panel_preview_set_zoom(zoom) { CALL("preview_preview_set_zoom"); PANEL_PREVIEW.fullView(zoom); } - - function panel_preview_set_tile_off() { CALL("preview_set_tile_off"); PANEL_PREVIEW.set_tile_off(); } - function panel_preview_set_tile_horizontal() { CALL("preview_set_tile_horizontal"); PANEL_PREVIEW.set_tile_horizontal(); } - function panel_preview_set_tile_vertical() { CALL("preview_set_tile_vertical"); PANEL_PREVIEW.set_tile_vertical(); } - function panel_preview_set_tile_both() { CALL("preview_set_tile_both"); PANEL_PREVIEW.set_tile_both(); } - function panel_preview_set_tile_toggle() { CALL("preview_set_tile_toggle"); PANEL_PREVIEW.set_tile_toggle(); } - - function panel_preview_new_preview_window() { CALL("preview_new_preview_window"); PANEL_PREVIEW.new_preview_window(); } - function panel_preview_saveCurrentFrame() { CALL("preview_saveCurrentFrame"); PANEL_PREVIEW.saveCurrentFrame(); } - function panel_preview_saveAllCurrentFrames() { CALL("preview_saveAllCurrentFrames"); PANEL_PREVIEW.saveAllCurrentFrames(); } - function panel_preview_copyCurrentFrame() { CALL("preview_copyCurrentFrame"); PANEL_PREVIEW.copyCurrentFrame(); } - function panel_preview_copy_color() { CALL("preview_copy_color"); PANEL_PREVIEW.copy_color(); } - function panel_preview_copy_color_hex() { CALL("preview_copy_color_hex"); PANEL_PREVIEW.copy_color_hex(); } - + function __fnInit_Preview() { + registerFunction("Preview", "Focus content", "F", MOD_KEY.none, panel_preview_focus_content ).setMenu("preview_focus_content", THEME.icon_center_canvas) + registerFunction("Preview", "Save current frame", "S", MOD_KEY.shift, panel_preview_save_current_frame ).setMenu("preview_save_current_frame") + registerFunction("Preview", "Save to focused file", "", MOD_KEY.none, panel_preview_saveCurrentFrameToFocus ).setMenu("preview_save_to_focused_file") + registerFunction("Preview", "Save all current frame", "", MOD_KEY.none, panel_preview_save_all_current_frame ).setMenu("preview_save_all_current_frame") + registerFunction("Preview", "Preview window", "P", MOD_KEY.ctrl, panel_preview_preview_window ).setMenu("preview_preview_window") + registerFunction("Preview", "Toggle grid", "G", MOD_KEY.ctrl, panel_preview_toggle_grid ).setMenu("preview_toggle_grid") + + registerFunction("Preview", "Pan", "", MOD_KEY.ctrl, panel_preview_pan ).setMenu("preview_pan") + registerFunction("Preview", "Zoom", "", MOD_KEY.alt | MOD_KEY.ctrl, panel_preview_zoom ).setMenu("preview_zoom") + + registerFunction("Preview", "3D Front view", vk_numpad1, MOD_KEY.none, panel_preview_3d_view_front ).setMenu("preview_3d_front_view") + registerFunction("Preview", "3D Back view", vk_numpad1, MOD_KEY.alt, panel_preview_3d_view_back ).setMenu("preview_3d_back_view") + registerFunction("Preview", "3D Right view ", vk_numpad3, MOD_KEY.none, panel_preview_3d_view_right ).setMenu("preview_3d_right_view") + registerFunction("Preview", "3D Left view ", vk_numpad3, MOD_KEY.alt, panel_preview_3d_view_left ).setMenu("preview_3d_left_view") + registerFunction("Preview", "3D Top view", vk_numpad7, MOD_KEY.none, panel_preview_3d_view_top ).setMenu("preview_3d_top_view") + registerFunction("Preview", "3D Bottom view", vk_numpad7, MOD_KEY.alt, panel_preview_3d_view_bottom ).setMenu("preview_3d_bottom_view") + + registerFunction("Preview", "Scale x1", "1", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(1) } ).setMenu("preview_scale_x1") + registerFunction("Preview", "Scale x2", "2", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(2) } ).setMenu("preview_scale_x2") + registerFunction("Preview", "Scale x4", "3", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(4) } ).setMenu("preview_scale_x4") + registerFunction("Preview", "Scale x8", "4", MOD_KEY.none, function() /*=>*/ { panel_preview_set_zoom(8) } ).setMenu("preview_scale_x8") + + registerFunction("Preview", "Set Tile Off", "", MOD_KEY.none, panel_preview_set_tile_off ).setMenu("preview_set_tile_off") + registerFunction("Preview", "Set Tile Horizontal", "", MOD_KEY.none, panel_preview_set_tile_horizontal ).setMenu("preview_set_tile_horizontal") + registerFunction("Preview", "Set Tile Vertical", "", MOD_KEY.none, panel_preview_set_tile_vertical ).setMenu("preview_set_tile_vertical") + registerFunction("Preview", "Set Tile Both", "", MOD_KEY.none, panel_preview_set_tile_both ).setMenu("preview_set_tile_both") + registerFunction("Preview", "Toggle Tile", "", MOD_KEY.none, panel_preview_set_tile_toggle ).setMenu("preview_toggle_tile") + + registerFunction("Preview", "New Preview Window", "", MOD_KEY.none, panel_preview_new_preview_window ).setMenu("preview_new_preview_window") + registerFunction("Preview", "Save Current Frame", "", MOD_KEY.none, panel_preview_saveCurrentFrame ).setMenu("preview_save_current_frame") + registerFunction("Preview", "Save All Current Frames", "", MOD_KEY.none, panel_preview_saveAllCurrentFrames ).setMenu("preview_save_all_current_frames") + registerFunction("Preview", "Copy Current Frame", "", MOD_KEY.none, panel_preview_copyCurrentFrame ).setMenu("preview_copy_current_frame", THEME.copy) + registerFunction("Preview", "Copy Color", "", MOD_KEY.none, panel_preview_copy_color ).setMenu("preview_copy_color") + registerFunction("Preview", "Copy Color Hex", "", MOD_KEY.none, panel_preview_copy_color_hex ).setMenu("preview_copy_color_hex") + } + + function panel_preview_focus_content() { CALL("preview_focus_content"); PANEL_PREVIEW.fullView(); } + function panel_preview_save_current_frame() { CALL("preview_save_current_frame"); PANEL_PREVIEW.saveCurrentFrame(); } + function panel_preview_saveCurrentFrameToFocus() { CALL("preview_save_to_focused_file"); PANEL_PREVIEW.saveCurrentFrameToFocus(); } + function panel_preview_save_all_current_frame() { CALL("preview_save_all_current_frame"); PANEL_PREVIEW.saveAllCurrentFrames(); } + function panel_preview_preview_window() { CALL("preview_preview_window"); PANEL_PREVIEW.create_preview_window(PANEL_PREVIEW.getNodePreview()); } + function panel_preview_toggle_grid() { CALL("preview_toggle_grid"); PROJECT.previewGrid.show = !PROJECT.previewGrid.show; } + + function panel_preview_pan() { CALL("preview_pan"); PANEL_PREVIEW.canvas_dragging_key = true; } + function panel_preview_zoom() { CALL("preview_zoom"); PANEL_PREVIEW.canvas_zooming_key = true; } + + function panel_preview_3d_view_front() { CALL("preview_3d_front_view"); PANEL_PREVIEW.d3_view_action_front(); } + function panel_preview_3d_view_back() { CALL("preview_3d_back_view"); PANEL_PREVIEW.d3_view_action_back(); } + function panel_preview_3d_view_right() { CALL("preview_3d_right_view"); PANEL_PREVIEW.d3_view_action_right(); } + function panel_preview_3d_view_left() { CALL("preview_3d_left_view"); PANEL_PREVIEW.d3_view_action_left(); } + function panel_preview_3d_view_top() { CALL("preview_3d_top_view"); PANEL_PREVIEW.d3_view_action_top(); } + function panel_preview_3d_view_bottom() { CALL("preview_3d_bottom_view"); PANEL_PREVIEW.d3_view_action_bottom(); } + + function panel_preview_set_zoom(zoom) { CALL("preview_preview_set_zoom"); PANEL_PREVIEW.fullView(zoom); } + + function panel_preview_set_tile_off() { CALL("preview_set_tile_off"); PANEL_PREVIEW.set_tile_off(); } + function panel_preview_set_tile_horizontal() { CALL("preview_set_tile_horizontal"); PANEL_PREVIEW.set_tile_horizontal(); } + function panel_preview_set_tile_vertical() { CALL("preview_set_tile_vertical"); PANEL_PREVIEW.set_tile_vertical(); } + function panel_preview_set_tile_both() { CALL("preview_set_tile_both"); PANEL_PREVIEW.set_tile_both(); } + function panel_preview_set_tile_toggle() { CALL("preview_set_tile_toggle"); PANEL_PREVIEW.set_tile_toggle(); } + + function panel_preview_new_preview_window() { CALL("preview_new_preview_window"); PANEL_PREVIEW.new_preview_window(); } + function panel_preview_saveCurrentFrame() { CALL("preview_saveCurrentFrame"); PANEL_PREVIEW.saveCurrentFrame(); } + function panel_preview_saveAllCurrentFrames() { CALL("preview_saveAllCurrentFrames"); PANEL_PREVIEW.saveAllCurrentFrames(); } + function panel_preview_copyCurrentFrame() { CALL("preview_copyCurrentFrame"); PANEL_PREVIEW.copyCurrentFrame(); } + function panel_preview_copy_color() { CALL("preview_copy_color"); PANEL_PREVIEW.copy_color(); } + function panel_preview_copy_color_hex() { CALL("preview_copy_color_hex"); PANEL_PREVIEW.copy_color_hex(); } + #endregion function Panel_Preview() : PanelContent() constructor { - title = __txt("Preview"); - context_str = "Preview"; - icon = THEME.panel_preview_icon; - - last_focus = noone; - - #region ---- canvas control & sample ---- - function initSize() { - canvas_x = w / 2; - canvas_y = h / 2; - } - run_in(1, function() { initSize() }); - - canvas_x = 0; - canvas_y = 0; - canvas_s = 1; - canvas_w = ui(128); - canvas_h = ui(128); - canvas_a = 0; - - canvas_bg = -1; - - do_fullView = false; - - canvas_hover = true; - canvas_dragging_key = false; - canvas_dragging = false; - canvas_drag_key = 0; - canvas_drag_mx = 0; - canvas_drag_my = 0; - canvas_drag_sx = 0; - canvas_drag_sy = 0; - - canvas_zooming_key = false; - canvas_zooming = false; - canvas_zoom_mx = 0; - canvas_zoom_my = 0; - canvas_zoom_m = 0; - canvas_zoom_s = 0; - - view_pan_tool = false; - view_zoom_tool = false; - - sample_color = noone; - sample_x = noone; - sample_y = noone; - - #endregion - - #region ---- preview ---- - locked = false; - preview_node = [ noone, noone ]; - preview_surfaces = [ 0, 0 ]; - preview_surface = [ 0, 0 ]; - tile_surface = surface_create(1, 1); - - preview_x = 0; - preview_x_to = 0; - preview_x_max = 0; - preview_sequence = [ 0, 0 ]; - _preview_sequence = preview_sequence; - preview_rate = 10; - - right_menu_x = 0; - right_menu_y = 8; - mouse_on_preview = 0; - _mouse_on_preview = 0; - - resetViewOnDoubleClick = true; - - splitView = 0; - splitPosition = 0.5; - splitSelection = 0; - - splitViewDragging = false; - splitViewStart = 0; - splitViewMouse = 0; - - tileMode = 0; - - bg_color = COLORS.panel_bg_clear; - - mouse_pos_string = ""; - - show_info = true; - show_view_control = 1; - #endregion - - #region ---- tool ---- - tool_x = 0; - tool_x_to = 0; - tool_x_max = 0; - - tool_y = 0; - tool_y_to = 0; - tool_y_max = 0; - - tool_ry = 0; - tool_ry_to = 0; - tool_ry_max = 0; - - tool_current = noone; - - toolbar_width = ui(40); - toolbar_height = ui(40); - - tool_hovering = noone; - tool_side_draw_l = false; - tool_side_draw_r = false; - overlay_hovering = false; - view_hovering = false; - - sbChannel = new scrollBox([], function(index) { - var node = __getNodePreview(); - if(node == noone) return; - - node.preview_channel = sbChannelIndex[index].index; - node.setHeight(); - }); - - sbChannelIndex = []; - sbChannel.font = f_p1; - sbChannel.align = fa_left; - #endregion - - #region ---- 3d ---- - d3_active = NODE_3D.none; - d3_active_transition = 0; - - d3_surface = noone; - d3_surface_normal = noone; - d3_surface_depth = noone; - d3_surface_outline = noone; - d3_surface_bg = noone; - d3_preview_channel = 0; - - d3_deferData = noone; - d3_drawBG = false; - - global.SKY_SPHERE = new __3dUVSphere(0.5, 16, 8, true); - - #region camera - d3_view_camera = new __3dCamera(); - d3_camW = 1; - d3_camH = 1; - - d3_view_camera.setFocusAngle(135, 45, 4); - d3_camLerp = 0; - d3_camLerp_x = 0; - d3_camLerp_y = 0; - - d3_camTarget = new __vec3(); - - d3_camPanning = false; - d3_camPan_mx = 0; - d3_camPan_my = 0; - - d3_zoom_speed = 0.2; - d3_pan_speed = 2; - #endregion - - #region scene - d3_scene = new __3dScene(d3_view_camera, "Preview panel"); - d3_scene.lightAmbient = $404040; - d3_scene.cull_mode = cull_counterclockwise; - d3_scene_preview = d3_scene; - - d3_scene_light_enabled = true; - - d3_scene_light0 = new __3dLightDirectional(); - d3_scene_light0.transform.position.set(-1, -2, 3); - d3_scene_light0.color = $FFFFFF; - d3_scene_light0.shadow_active = false; - d3_scene_light0.shadow_map_scale = 4; - - d3_scene_light1 = new __3dLightDirectional(); - d3_scene_light1.transform.position.set(1, 2, -3); - d3_scene_light1.color = $505050; - #endregion - - #region tool - d3_tool_snap = false; - d3_tool_snap_position = 1; - d3_tool_snap_rotation = 15; - #endregion - #endregion - - tb_framerate = new textBox(TEXTBOX_INPUT.number, function(val) { preview_rate = real(val); }); - - #region ++++ toolbars & actions ++++ - function set_tile_off() { tileMode = 0; } - function set_tile_horizontal() { tileMode = 1; } - function set_tile_vertical() { tileMode = 2; } - function set_tile_both() { tileMode = 3; } - function set_tile_toggle() { tileMode = (tileMode + 1) % 4; } - - function new_preview_window() { create_preview_window(getNodePreview()); } - function copy_color() { clipboard_set_text(sample_color); } - function copy_color_hex() { clipboard_set_text(color_get_hex(sample_color)); } - - topbar_height = ui(32); - toolbar_height = ui(40); - toolbars = [ - [ - THEME.icon_reset_when_preview, - function() { return resetViewOnDoubleClick; }, - function() { return resetViewOnDoubleClick? __txtx("panel_preview_center_canvas_on_preview", "Center canvas on preview") : - __txtx("panel_preview_keep_canvas_on_preview", "Keep canvas on preview"); }, - function() { resetViewOnDoubleClick = !resetViewOnDoubleClick; } - ], - [ - THEME.icon_split_view, - function() { return splitView; }, - function() { - switch(splitView) { - case 0 : return __txtx("panel_preview_split_view_off", "Split view off"); - case 1 : return __txtx("panel_preview_horizontal_split_view", "Horizontal split view"); - case 2 : return __txtx("panel_preview_vertical_split_view", "Vertical split view"); - } - return __txtx("panel_preview_split_view", "Split view"); - }, - function() { splitView = (splitView + 1) % 3; } - ], - [ - THEME.icon_tile_view, - function() { var t = [3, 0, 1, 2]; return array_safe_get_fast(t, tileMode); }, - function() { - switch(tileMode) { - case 0 : return __txtx("panel_preview_tile_off", "Tile off"); - case 1 : return __txtx("panel_preview_tile_horizontal", "Tile horizontal"); - case 2 : return __txtx("panel_preview_tile_vertical", "Tile vertical"); - case 3 : return __txtx("panel_preview_tile_both", "Tile both"); - } - return __txtx("panel_preview_tile_mode", "Tile mode"); - }, - function(data) { - menuCall("preview_tile_menu", data.x + ui(28), data.y + ui(28), [ - menuItemAction(__txtx("panel_preview_tile_off", "Tile off"), panel_preview_set_tile_off), - menuItemAction(__txtx("panel_preview_tile_horizontal", "Tile horizontal"), panel_preview_set_tile_horizontal), - menuItemAction(__txtx("panel_preview_tile_vertical", "Tile vertical"), panel_preview_set_tile_vertical), - menuItemAction(__txtx("panel_preview_tile_both", "Tile both"), panel_preview_set_tile_both), - ]); - } - ], - [ - THEME.icon_grid_setting, - function() { return 0; }, - function() { return __txtx("grid_title", "Grid setting") }, - function(param) { - var dia = dialogPanelCall(new Panel_Preview_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); - } - ], - [ - THEME.onion_skin, - function() { return 0; }, - function() { return __txt("Onion Skin") }, - function(param) { - var dia = dialogPanelCall(new Panel_Preview_Onion_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); - } - ], - ]; - - toolbars_3d = [ - [ - THEME.d3d_preview_settings, - function() /*=>*/ {return 0}, - function() /*=>*/ {return __txt("3D Preview Settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_3D_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - [ - THEME.d3d_snap_settings, - function() /*=>*/ {return 0}, - function() /*=>*/ {return __txt("3D Snap Settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - ]; - - toolbars_3d_sdf = [ - [ - THEME.d3d_preview_settings, - function() /*=>*/ {return 0}, - function() /*=>*/ {return __txt("3D SDF Preview Settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_3D_SDF_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - [ - THEME.d3d_snap_settings, - function() /*=>*/ {return 0}, - function() /*=>*/ {return __txt("3D Snap Settings")}, - function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } - ], - ]; - - tooltip_center = new tooltipHotkey(__txtx("panel_preview_center_canvas", "Center canvas"), "Preview", "Focus content"); - tooltip_export = new tooltipHotkey(__txtx("panel_preview_export_canvas", "Export canvas"), "Preview", "Save current frame"); - - actions = [ - [ - THEME.lock, - __txtx("panel_preview_lock_preview", "Lock previewing node"), - function() { locked = !locked; }, - function() { return !locked; }, - ], - [ - THEME.icon_preview_export, - tooltip_export, - function() { saveCurrentFrame(); }, - function() { return 0; }, - ], - [ - THEME.icon_center_canvas, - tooltip_center, - function() { fullView(); }, - function() { return 0; }, - ], - [ - THEME.icon_visibility, - __txtx("graph_visibility_title", "Visibility settings"), - function(param) { - dialogPanelCall(new Panel_Preview_View_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); - }, - function() { return 0; }, - ], - ]; - - static d3_view_action_front = function() { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = 0; } - static d3_view_action_back = function() { d3_camLerp = 1; d3_camLerp_x = 180; d3_camLerp_y = 0; } - static d3_view_action_right = function() { d3_camLerp = 1; d3_camLerp_x = 90; d3_camLerp_y = 0; } - static d3_view_action_left = function() { d3_camLerp = 1; d3_camLerp_x = -90; d3_camLerp_y = 0; } - static d3_view_action_bottom = function() { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = -89; } - static d3_view_action_top = function() { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = 89; } - #endregion - - ////============ DATA ============ - - function setNodePreview(node) { - if(locked) return; - - if(resetViewOnDoubleClick) - do_fullView = true; - - preview_node[splitView? splitSelection : 0] = node; - } - - function removeNodePreview(node) { #region - if(locked) return; - - if(preview_node[0] == node) preview_node[0] = noone; - if(preview_node[1] == node) preview_node[1] = noone; - } #endregion - - function resetNodePreview() { - preview_node = [ noone, noone ]; - locked = false; - } - - function __getNodePreview() { return preview_node[splitView? splitSelection : 0]; } - function getNodePreview() { - var _node = __getNodePreview(); - if(_node == noone) return noone; - - if(!_node.project.active) { - resetNodePreview(); - return noone; - } - - if(is_instanceof(_node, Node)) - _node = _node.getPreviewingNode(); - - return _node; - } - - function getNodePreviewSurface() { return preview_surfaces[splitView? splitSelection : 0]; } - function getNodePreviewSequence() { return preview_sequence[splitView? splitSelection : 0]; } - - function getPreviewData() { #region - preview_surfaces = [ noone, noone ]; - preview_sequence = [ noone, noone ]; - - for( var i = 0; i < 2; i++ ) { - var node = preview_node[i]; - - if(node == noone) continue; - if(!node.active) { - resetNodePreview(); - return; - } - - var value = node.getPreviewValues(); - - if(is_array(value)) { - preview_sequence[i] = value; - canvas_a = array_length(value); - } else { - preview_surfaces[i] = value; - canvas_a = 0; - } - - if(preview_sequence[i] != noone) { - if(array_length(preview_sequence[i]) == 0) return; - preview_surfaces[i] = preview_sequence[i][safe_mod(node.preview_index, array_length(preview_sequence[i]))]; - } - } - - var prevS = getNodePreviewSurface(); - - if(is_surface(prevS)) { - canvas_w = surface_get_width_safe(prevS); - canvas_h = surface_get_height_safe(prevS); - } - } #endregion - - function onFocusBegin() { PANEL_PREVIEW = self; } - - ////============ VIEW ============ - - function dragCanvas() { #region - if(canvas_dragging) { - if(!MOUSE_WRAPPING) { - var dx = mx - canvas_drag_mx; - var dy = my - canvas_drag_my; - - canvas_x += dx; - canvas_y += dy; - } - - canvas_drag_mx = mx; - canvas_drag_my = my; - setMouseWrap(); - - if(mouse_release(canvas_drag_key)) { - canvas_dragging = false; - view_pan_tool = false; - } - } - - if(canvas_zooming) { - if(!MOUSE_WRAPPING) { - // var mdx = mx - canvas_zoom_mx; - var mdy = my - canvas_zoom_m; - - var dd = -(mdy) / 200; - - var _s = canvas_s; - canvas_s = clamp(canvas_s * (1 + dd), 0.10, 64); - - if(_s != canvas_s) { - var dx = (canvas_s - _s) * ((canvas_zoom_mx - canvas_x) / _s); - var dy = (canvas_s - _s) * ((canvas_zoom_my - canvas_y) / _s); - canvas_x -= dx; - canvas_y -= dy; - } - } - - canvas_zoom_m = my; - setMouseWrap(); - - if(mouse_release(canvas_drag_key)) { - canvas_zooming = false; - view_zoom_tool = false; - } - } - - if(pHOVER && canvas_hover) { - var _doDragging = false; - var _doZooming = false; - - if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) { - _doDragging = true; - canvas_drag_key = PREFERENCES.pan_mouse_key; - - } else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) { - _doDragging = true; - canvas_drag_key = mb_left; - - } else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) { - _doZooming = true; - canvas_drag_key = mb_left; - } - - if(_doDragging) { - canvas_dragging = true; - canvas_drag_mx = mx; - canvas_drag_my = my; - canvas_drag_sx = canvas_x; - canvas_drag_sy = canvas_y; - } - - if(_doZooming) { - canvas_zooming = true; - canvas_zoom_mx = mx; - canvas_zoom_my = my; - canvas_zoom_m = my; - canvas_zoom_s = canvas_s; - } - - var _canvas_s = canvas_s; - var inc = 0.1; - if(canvas_s > 16) inc = 2; - else if(canvas_s > 8) inc = 1; - else if(canvas_s > 3) inc = 0.5; - else if(canvas_s > 1) inc = 0.25; - - if(mouse_wheel_down() && !key_mod_press_any()) canvas_s = max(round(canvas_s / inc) * inc - inc, 0.10); - if(mouse_wheel_up() && !key_mod_press_any()) canvas_s = min(round(canvas_s / inc) * inc + inc, 1024); - - if(_canvas_s != canvas_s) { - var dx = (canvas_s - _canvas_s) * ((mx - canvas_x) / _canvas_s); - var dy = (canvas_s - _canvas_s) * ((my - canvas_y) / _canvas_s); - canvas_x -= dx; - canvas_y -= dy; - } - } - - canvas_dragging_key = false; - canvas_zooming_key = false; - canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height); - } #endregion - - function dragCanvas3D() { #region - if(d3_camLerp) { - d3_view_camera.focus_angle_x = lerp_float(d3_view_camera.focus_angle_x, d3_camLerp_x, 3, 1); - d3_view_camera.focus_angle_y = lerp_float(d3_view_camera.focus_angle_y, d3_camLerp_y, 3, 1); - - if(d3_view_camera.focus_angle_x == d3_camLerp_x && d3_view_camera.focus_angle_y == d3_camLerp_y) - d3_camLerp = false; - } - - if(d3_camPanning) { - if(!MOUSE_WRAPPING) { - var dx = mx - d3_camPan_mx; - var dy = my - d3_camPan_my; - - var px = d3_view_camera.focus_angle_x; - var py = d3_view_camera.focus_angle_y; - var ax = px + dx * 0.2 * d3_pan_speed; - var ay = py + dy * 0.1 * d3_pan_speed; - - //if(py < 90 && ay >= 90) ax -= 180; - //if(py > 90 && ay <= 90) ax += 180; - - //print($"{ax},\t{ay}"); - - d3_view_camera.focus_angle_x = ax; - d3_view_camera.focus_angle_y = ay; - } - - d3_camPan_mx = mx; - d3_camPan_my = my; - setMouseWrap(); - - if(mouse_release(canvas_drag_key)) { - d3_camPanning = false; - view_pan_tool = false; - } - } - - if(canvas_zooming) { - if(!MOUSE_WRAPPING) { - var dy = -(my - canvas_zoom_m) / 200; - d3_view_camera.focus_dist = clamp(d3_view_camera.focus_dist + dy, 1, 1000); - } - - canvas_zoom_m = my; - setMouseWrap(); - - if(mouse_release(canvas_drag_key)) { - canvas_zooming = false; - view_zoom_tool = false; - } - } - - if(pHOVER && canvas_hover) { - var _doDragging = false; - var _doZooming = false; - - if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) { - _doDragging = true; - canvas_drag_key = PREFERENCES.pan_mouse_key; - - } else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) { - - _doDragging = true; - canvas_drag_key = mb_left; - } else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) { - - _doZooming = true; - canvas_drag_key = mb_left; - } - - if(_doDragging) { - d3_camPanning = true; - d3_camPan_mx = mx; - d3_camPan_my = my; - } - - if(_doZooming) { - canvas_zooming = true; - canvas_zoom_m = my; - } - - if(mouse_wheel_up()) d3_view_camera.focus_dist = max( 1, d3_view_camera.focus_dist * (1 - d3_zoom_speed)); - if(mouse_wheel_down()) d3_view_camera.focus_dist = min(1000, d3_view_camera.focus_dist * (1 + d3_zoom_speed)); - } - - canvas_dragging_key = false; - canvas_zooming_key = false; - canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height); - } #endregion - - function fullView(scale = 0) { - var bbox = noone; - - var node = getNodePreview(); - if(node != noone) bbox = node.getPreviewBoundingBox(); - if(bbox == noone) bbox = BBOX().fromWH(0, 0, PROJECT.attributes.surface_dimension[0], PROJECT.attributes.surface_dimension[1]); - - var _x = bbox.x0, _y = bbox.y0; - var _w = bbox.w, _h = bbox.h; - - if(_w == 0 || _h == 0) { - _x = 0; - _y = 0; - _w = DEF_SURF_W; - _h = DEF_SURF_H; - } - - var tl = tool_side_draw_l * 40; - var tr = tool_side_draw_r * 40; - var ss = scale == 0? min((w - 32 - tl - tr) / _w, (h - 32 - toolbar_height * 2) / _h) : scale; - - canvas_s = ss; - canvas_x = w / 2 - _w * canvas_s / 2 - _x * canvas_s + (tl - tr) / 2; - canvas_y = h / 2 - _h * canvas_s / 2 - _y * canvas_s; - } - - function drawNodeChannel(_node, _x, _y) { - if(array_length(_node.outputs) < 2) return 0; - - var chName = []; - sbChannelIndex = []; - - var currName = _node.outputs[_node.preview_channel].name; - draw_set_text(sbChannel.font, fa_center, fa_center); - var ww = 0; - var hh = TEXTBOX_HEIGHT - ui(2); - var _am = _node.getOutputJunctionAmount(); - - for( var i = 0; i < _am; i++ ) { - var _outi = _node.getOutputJunctionIndex(i); - var _outj = _node.outputs[_outi]; - - array_push(chName, _outj.name); - array_push(sbChannelIndex, _outj); - ww = max(ww, string_width(_outj.name) + ui(40)); - } - - - if(!array_empty(chName)) { - sbChannel.data_list = chName; - sbChannel.setFocusHover(pFOCUS, pHOVER); - sbChannel.draw(_x - ww, _y - hh / 2, ww, hh, currName, [mx, my], x, y); - right_menu_y += ui(40); - } - - return ww + ui(4); - } - - static onFullScreen = function() { run_in(1, fullView); } - - ////============ DRAW ============ - - function drawOnionSkin(node, psx, psy, ss) { #region - var _surf = preview_surfaces[0]; - var _rang = PROJECT.onion_skin.range; - - var _alph = PROJECT.onion_skin.alpha; - var _colr = PROJECT.onion_skin.color; - - var _step = PROJECT.onion_skin.step; - var _top = PROJECT.onion_skin.on_top; - - var fr = CURRENT_FRAME; - var st = min(_rang[0], _rang[1]); - var ed = max(_rang[0], _rang[1]); - - st = sign(st) * floor(abs(st) / _step) * _step; - ed = sign(ed) * floor(abs(ed) / _step) * _step; - - st += fr; - ed += fr; - - var surf, aa, cc; - - if(!_top) { - draw_surface_ext_safe(_surf, psx, psy, ss, ss); - BLEND_ADD - } - - for( var i = st; i <= ed; i += _step ) { - surf = node.getCacheFrame(i); - if(!is_surface(surf)) continue; - - aa = power(_alph, abs((i - fr) / _step)); - cc = c_white; - if(i < fr) cc = _colr[0]; - else if(i > fr) cc = _colr[1]; - - draw_surface_ext_safe(surf, psx, psy, ss, ss, 0, cc, aa); - } - - BLEND_NORMAL - - if(_top) draw_surface_ext_safe(_surf, psx, psy, ss, ss); - - } #endregion - - function drawNodePreview() { #region - var ss = canvas_s; - var psx = 0, psy = 0; - var psw = 0, psh = 0; - var pswd = 0, pshd = 0; - var psx1 = 0, psy1 = 0; - - var ssx = 0, ssy = 0; - var ssw = 0, ssh = 0; - - if(is_surface(preview_surfaces[0])) { - psx = canvas_x + preview_node[0].preview_x * ss; - psy = canvas_y + preview_node[0].preview_y * ss; - - psw = surface_get_width_safe(preview_surfaces[0]); - psh = surface_get_height_safe(preview_surfaces[0]); - pswd = psw * ss; - pshd = psh * ss; - - psx1 = psx + pswd; - psy1 = psy + pshd; - } - - if(is_surface(preview_surfaces[1])) { - var ssx = canvas_x + preview_node[1].preview_x * ss; - var ssy = canvas_y + preview_node[1].preview_y * ss; - - var ssw = surface_get_width_safe(preview_surfaces[1]); - var ssh = surface_get_height_safe(preview_surfaces[1]); - } - - var _node = getNodePreview(); - if(_node) title = _node.renamed? _node.display_name : _node.name; - - #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Draw Surfaces <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - var _ps0 = is_surface(preview_surfaces[0]); - var _ps1 = is_surface(preview_surfaces[1]); - - if(_ps0) { - var _sw = surface_get_width_safe(preview_surfaces[0]); - var _sh = surface_get_height_safe(preview_surfaces[0]); - - preview_surface[0] = surface_verify(preview_surface[0], _sw, _sh); - - surface_set_shader(preview_surface[0], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample); - shader_set_f("palette", PROJECT.palettes); - shader_set_i("keys", array_length(PROJECT.attributes.palette)); - shader_set_i("alpha", 1); - - draw_surface_safe(preview_surfaces[0]); - surface_reset_shader(); - } - - if(_ps1) { - var _sw = surface_get_width_safe(preview_surfaces[1]); - var _sh = surface_get_height_safe(preview_surfaces[1]); - - preview_surface[1] = surface_verify(preview_surface[1], _sw, _sh); - - surface_set_shader(preview_surface[1], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample); - shader_set_f("palette", PROJECT.palettes); - shader_set_i("keys", array_length(PROJECT.attributes.palette)); - shader_set_i("alpha", 1); - - draw_surface_safe(preview_surfaces[1]); - surface_reset_shader(); - } - - switch(splitView) { - case 0 : - if(_ps0) { - preview_node[0].previewing = 1; - - switch(tileMode) { - case 0 : - if(PROJECT.onion_skin.enabled) drawOnionSkin(_node, psx, psy, ss); - else draw_surface_ext(preview_surface[0], psx, psy, ss, ss, 0, c_white, preview_node[0].preview_alpha); - break; - - case 1 : - tile_surface = surface_verify(tile_surface, w, surface_get_height_safe(preview_surface[0]) * ss); - surface_set_target(tile_surface); - DRAW_CLEAR - draw_surface_tiled_ext_safe(preview_surface[0], psx, 0, ss, ss, 0, c_white, 1); - surface_reset_target(); - draw_surface_safe(tile_surface, 0, psy); - break; - - case 2 : - tile_surface = surface_verify(tile_surface, surface_get_width_safe(preview_surface[0]) * ss, h); - surface_set_target(tile_surface); - DRAW_CLEAR - draw_surface_tiled_ext_safe(preview_surface[0], 0, psy, ss, ss, 0, c_white, 1); - surface_reset_target(); - draw_surface_safe(tile_surface, psx, 0); - break; - - case 3 : - draw_surface_tiled_ext_safe(preview_surface[0], psx, psy, ss, ss, 0, c_white, 1); break; - } - } - break; - case 1 : - var sp = splitPosition * w; - - if(_ps0) { - preview_node[0].previewing = 2; - var maxX = min(sp, psx1); - var sW = min(psw, (maxX - psx) / ss); - - if(sW > 0) - draw_surface_part_ext_safe(preview_surface[0], 0, 0, sW, psh, psx, psy, ss, ss, 0, c_white, 1); - } - - if(_ps1) { - preview_node[1].previewing = 3; - var minX = max(ssx, sp); - var sX = (minX - ssx) / ss; - var spx = max(sp, ssx); - - if(sX >= 0 && sX < ssw) - draw_surface_part_ext_safe(preview_surface[1], sX, 0, ssw - sX, ssh, spx, ssy, ss, ss, 0, c_white, 1); - } - break; - case 2 : - var sp = splitPosition * h; - - if(_ps0) { - preview_node[0].previewing = 4; - var maxY = min(sp, psy1); - var sH = min(psh, (maxY - psy) / ss); - - if(sH > 0) - draw_surface_part_ext_safe(preview_surface[0], 0, 0, psw, sH, psx, psy, ss, ss, 0, c_white, 1); - } - - if(_ps1) { - preview_node[1].previewing = 5; - var minY = max(ssy, sp); - var sY = (minY - ssy) / ss; - var spy = max(sp, ssy); - - if(sY >= 0 && sY < ssh) - draw_surface_part_ext_safe(preview_surface[1], 0, sY, ssw, ssh - sY, ssx, spy, ss, ss, 0, c_white, 1); - } - break; - } - #endregion - - if(!instance_exists(o_dialog_menubox)) { #region color sample - sample_color = noone; - sample_x = noone; - sample_y = noone; - - if(mouse_on_preview && (mouse_press(mb_right) || key_mod_press(CTRL))) { - var _sx = sample_x; - var _sy = sample_y; - - sample_x = floor((mx - canvas_x) / canvas_s); - sample_y = floor((my - canvas_y) / canvas_s); - var surf = getNodePreviewSurface(); - sample_color = surface_get_pixel_ext(surf, sample_x, sample_y); - - //print($"{dec_to_hex(sample_color)}: {color_get_alpha(int64(sample_color))}"); - } - } #endregion - - if(is_surface(preview_surfaces[0])) { #region outline - if(PROJECT.previewGrid.pixel && canvas_s >= 16) { - - var gw = pswd / canvas_s; - var gh = pshd / canvas_s; - - var cx = canvas_x; - var cy = canvas_y; - - draw_set_color(PROJECT.previewGrid.color); - draw_set_alpha(PROJECT.previewGrid.opacity * 0.5 * clamp((canvas_s - 16) / 16, 0, 1)); - - for( var i = 1; i < gw; i++ ) { - var _xx = cx + i * canvas_s; - draw_line(_xx, cy, _xx, cy + pshd); - } - - for( var i = 1; i < gh; i++ ) { - var _yy = cy + i * canvas_s; - draw_line(cx, _yy - 1, cx + pswd, _yy - 1); - } - - draw_set_alpha(1); - } - - if(PROJECT.previewGrid.show) { - var _gw = PROJECT.previewGrid.size[0] * canvas_s; - var _gh = PROJECT.previewGrid.size[1] * canvas_s; - - var gw = pswd / _gw; - var gh = pshd / _gh; - - var cx = canvas_x; - var cy = canvas_y; - - draw_set_color(PROJECT.previewGrid.color); - draw_set_alpha(PROJECT.previewGrid.opacity); - - for( var i = 1; i < gw; i++ ) { - var _xx = cx + i * _gw; - draw_line(_xx, cy, _xx, cy + pshd); - } - - for( var i = 1; i < gh; i++ ) { - var _yy = cy + i * _gh; - draw_line(cx, _yy, cx + pswd, _yy); - } - - draw_set_alpha(1); - } - - draw_set_color(COLORS.panel_preview_surface_outline); - draw_rectangle(psx, psy, psx + pswd - 1, psy + pshd - 1, true); - } #endregion - } #endregion - - function draw3DPolygon(_node) { #region - surface_depth_disable(false); - - _node.previewing = 1; - - d3_scene_preview = struct_has(_node, "scene")? _node.scene : d3_scene; - d3_scene_preview.camera = d3_view_camera; - - #region view - var _pos, targ, _blend = 1; - - targ = d3_camTarget; - _pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist); - - if(d3_active_transition == 1) { - var _up = new __vec3(0, 0, -1); - - d3_view_camera.position._lerp_float(_pos, 5, 0.1); - d3_view_camera.focus._lerp_float( targ, 5, 0.1); - d3_view_camera.up._lerp_float( _up, 5, 0.1); - - if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) - d3_active_transition = 0; - } else if(d3_active_transition == -1) { - var _pos = new __vec3(0, 0, 8); - var targ = new __vec3(0, 0, 0); - var _up = new __vec3(0, 1, 0); - - d3_view_camera.position._lerp_float(_pos, 5, 0.1); - d3_view_camera.focus._lerp_float( targ, 5, 0.1); - d3_view_camera.up._lerp_float( _up, 5, 0.1); - - _blend = d3_view_camera.position.distance(_pos) / 2; - _blend = clamp(_blend, 0, 1); - - if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) - d3_active_transition = 0; - } else { - d3_view_camera.position.set(_pos); - d3_view_camera.focus.set(targ); - } - - d3_view_camera.setViewSize(w, h); - d3_view_camera.setMatrix(); - #endregion - - #region background - surface_free_safe(d3_surface_bg); - - if(d3_scene_preview != d3_scene) - d3_surface_bg = d3_scene_preview.renderBackground(w, h); - #endregion - - #region shadow - if(d3_scene_preview == d3_scene) { - d3_scene_light0.shadow_map_scale = d3_view_camera.focus_dist * 2; - - var _prev_obj = _node.getPreviewObject(); - if(_prev_obj != noone) { - d3_scene_light0.submitShadow(d3_scene_preview, _prev_obj); - _prev_obj.submitShadow(d3_scene_preview, _prev_obj); - } - } - #endregion - - d3_surface = surface_verify(d3_surface, w, h); - d3_surface_normal = surface_verify(d3_surface_normal, w, h); - d3_surface_depth = surface_verify(d3_surface_depth, w, h); - d3_surface_outline = surface_verify(d3_surface_outline, w, h); - - #region defer - var _prev_obj = _node.getPreviewObject(); - if(_prev_obj) d3_deferData = d3_scene_preview.deferPass(_prev_obj, w, h, d3_deferData); - #endregion - - #region grid - surface_set_target_ext(0, d3_surface); - surface_set_target_ext(1, d3_surface_normal); - surface_set_target_ext(2, d3_surface_depth); - - draw_clear_alpha(bg_color, 0); - - d3_view_camera.applyCamera(); - - gpu_set_ztestenable(true); - gpu_set_zwriteenable(false); - - if(OS != os_macosx) { - gpu_set_cullmode(cull_noculling); - - shader_set(sh_d3d_grid_view); - var _dist = round(d3_view_camera.focus.distance(d3_view_camera.position)); - var _tx = round(d3_view_camera.focus.x); - var _ty = round(d3_view_camera.focus.y); - - var _scale = _dist * 2; - while(_scale > 32) _scale /= 2; - - shader_set_f("axisBlend", _blend); - shader_set_f("scale", _scale); - shader_set_f("shift", _tx / _dist / 2, _ty / _dist / 2); - draw_sprite_stretched(s_fx_pixel, 0, _tx - _dist, _ty - _dist, _dist * 2, _dist * 2); - shader_reset(); - } - - gpu_set_zwriteenable(true); - #endregion - - #region draw - d3_scene_preview.reset(); - gpu_set_cullmode(cull_counterclockwise); - - var _prev_obj = _node.getPreviewObjects(); - - if(d3_scene_preview == d3_scene) { - if(d3_scene_light_enabled) { - d3_scene_preview.addLightDirectional(d3_scene_light0); - d3_scene_preview.addLightDirectional(d3_scene_light1); - } - } - - for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { - var _prev = _prev_obj[i]; - if(_prev == noone) continue; - - _prev.submitShader(d3_scene_preview); - } - - d3_scene_preview.apply(d3_deferData); - - for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { - var _prev = _prev_obj[i]; - if(_prev == noone) continue; - - _prev.submitUI(d3_scene_preview); - } - - gpu_set_cullmode(cull_noculling); - surface_reset_target(); - - draw_clear(bg_color); - - switch(d3_preview_channel) { - case 0 : - if(d3_scene_preview.draw_background) - draw_surface_safe(d3_surface_bg); - - draw_surface_safe(d3_surface); - - if(is_struct(d3_deferData)) { - BLEND_MULTIPLY - draw_surface_safe(d3_deferData.ssao); - BLEND_NORMAL - } - break; - case 1 : draw_surface_safe(d3_surface_normal); break; - case 2 : draw_surface_safe(d3_surface_depth); break; - } - #endregion - - #region outline - var inspect_node = PANEL_INSPECTOR.getInspecting(); - - if(inspect_node && inspect_node.is_3D == NODE_3D.polygon) { - var _inspect_obj = inspect_node.getPreviewObjectOutline(); - - surface_set_target(d3_surface_outline); - draw_clear(c_black); - - d3_scene_preview.camera.applyCamera(); - - gpu_set_ztestenable(false); - for( var i = 0, n = array_length(_inspect_obj); i < n; i++ ) { - if(_inspect_obj[i] == noone) continue; - _inspect_obj[i].submitSel(d3_scene_preview); - } - surface_reset_target(); - - shader_set(sh_d3d_outline); - shader_set_dim("dimension", d3_surface_outline); - shader_set_color("outlineColor", COLORS._main_accent); - draw_surface_safe(d3_surface_outline); - shader_reset(); - } - #endregion - - d3_scene_preview.camera.resetCamera(); - - surface_depth_disable(true); - } #endregion - - function draw3DSdf(_node) { #region - _node.previewing = 1; - - var _env = _node.environ; - var _obj = _node.object; - - d3_scene_preview = d3_scene; - d3_scene_preview.camera = d3_view_camera; - - #region view - d3_view_camera.fov = max(1, _env.fov * 1.23); - var _pos, targ, _blend = 1; - - targ = d3_camTarget; - _pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist); - - if(d3_active_transition == 1) { - var _up = new __vec3(0, 0, -1); - - d3_view_camera.position._lerp_float(_pos, 5, 0.1); - d3_view_camera.focus._lerp_float( targ, 5, 0.1); - d3_view_camera.up._lerp_float( _up, 5, 0.1); - - if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) - d3_active_transition = 0; - } else if(d3_active_transition == -1) { - var _pos = new __vec3(0, 0, 8); - var targ = new __vec3(0, 0, 0); - var _up = new __vec3(0, 1, 0); - - d3_view_camera.position._lerp_float(_pos, 5, 0.1); - d3_view_camera.focus._lerp_float( targ, 5, 0.1); - d3_view_camera.up._lerp_float( _up, 5, 0.1); - - _blend = d3_view_camera.position.distance(_pos) / 2; - _blend = clamp(_blend, 0, 1); - - if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) - d3_active_transition = 0; - } else { - d3_view_camera.position.set(_pos); - d3_view_camera.focus.set(targ); - } - - d3_view_camera.setViewSize(w, h); - d3_view_camera.setMatrix(); - #endregion - - draw_clear(bg_color); - - gpu_set_texfilter(true); - shader_set(sh_rm_primitive); - var zm = 4 / d3_view_camera.focus_dist; - - shader_set_f("camRotation", [ d3_view_camera.focus_angle_y, -d3_view_camera.focus_angle_x, 0 ]); - shader_set_f("camScale", zm); - shader_set_f("camRatio", w / h); - shader_set_i("shapeAmount", 0); - - _env.apply(); - if(_obj) _obj.apply(); - - shader_set_i("drawBg", d3_drawBG); - shader_set_f("depthInt", 0); - - var _scale = zm / 2; - var _step = 1; - while(_scale > 32) { - _scale /= 2; - _step /= 2; - } - - shader_set_i("drawGrid", true); - shader_set_f("gridStep", _step); - shader_set_f("gridScale", zm / 2); - shader_set_f("axisBlend", 1.); - shader_set_f("viewRange", [ d3_view_camera.view_near, d3_view_camera.view_far ]); - - draw_sprite_stretched(s_fx_pixel, 0, 0, 0, w, h); - shader_reset(); - gpu_set_texfilter(false); - - } #endregion - - function draw3D() { - var _node = getNodePreview(); - if(_node == noone) return; - - switch(d3_active) { - case NODE_3D.polygon : draw3DPolygon(_node); break; - case NODE_3D.sdf : draw3DSdf(_node); break; - } - } - - function drawPreviewOverlay() { #region - right_menu_y = toolbar_height - ui(4); - if(show_view_control == 2) { - if(d3_active) right_menu_y += ui(72); - else right_menu_y += ui(40); - } - - toolbar_draw = false; - - var _node = getNodePreview(); - - #region status texts (top right) - draw_set_text(f_p2, fa_right, fa_top, COLORS._main_text); - var _lh = line_get_height(); - - if(right_menu_x == 0) right_menu_x = w - ui(8); - - if(show_info) { - if(PANEL_PREVIEW == self) { - draw_set_color(COLORS._main_text_accent); - draw_text(right_menu_x, right_menu_y, __txt("Active")); - right_menu_y += _lh; - } - - var txt = $"{__txt("fps")} {fps}"; - if(PREFERENCES.panel_preview_show_real_fps) - txt += $" / {FPS_REAL}"; - - draw_set_color(fps >= PROJECT.animator.framerate? COLORS._main_text_sub : COLORS._main_value_negative); - draw_text(right_menu_x, right_menu_y, txt); - right_menu_y += _lh; - - draw_set_color(COLORS._main_text_sub); - draw_text(right_menu_x, right_menu_y, $"{__txt("Frame")} {CURRENT_FRAME + 1}/{TOTAL_FRAMES}"); - - if(d3_active == NODE_3D.none) { - right_menu_y += _lh; - draw_text(right_menu_x, right_menu_y, $"x{canvas_s}"); - - if(pHOVER) { - right_menu_y += _lh; - var mpx = floor((mx - canvas_x) / canvas_s); - var mpy = floor((my - canvas_y) / canvas_s); - draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]"); - - if(mouse_pos_string != "") { - right_menu_y += _lh; - draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}"); - } - } - - if(_node != noone) { - right_menu_y += _lh; - var txt = $"{canvas_w} x {canvas_h}px"; - if(canvas_a) txt = $"{canvas_a} x {txt}"; - - draw_text(right_menu_x, right_menu_y, txt); - - right_menu_x = w - ui(8); - right_menu_y += _lh; - } - } - - mouse_pos_string = ""; - } - - right_menu_x = w - ui(8); - - #endregion - - var pseq = getNodePreviewSequence(); - if(pseq == noone) return; - - if(!array_equals(pseq, _preview_sequence)) { - _preview_sequence = pseq; - preview_x = 0; - preview_x_to = 0; - } - - var prev_size = ui(48); - preview_x = lerp_float(preview_x, preview_x_to, 4); - - if(pHOVER && my > h - toolbar_height - prev_size - ui(16) && my > toolbar_height) { - canvas_hover = false; - - if(mouse_wheel_down() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to - prev_size * SCROLL_SPEED, - preview_x_max, 0); - if(mouse_wheel_up() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to + prev_size * SCROLL_SPEED, - preview_x_max, 0); - } - - #region surface array - preview_x_max = 0; - - if(array_length(pseq) > 1) { - var _xx = tool_side_draw_l * ui(40); - var xx = _xx + preview_x + ui(8); - var yy = h - toolbar_height - prev_size - ui(8); - - if(my > yy - 8) mouse_on_preview = 0; - var hoverable = pHOVER && point_in_rectangle(mx, my, _xx, ui(32), w, h - toolbar_height); - - for(var i = 0; i < array_length(pseq); i++) { - var prev = pseq[i]; - if(is_instanceof(prev, __d3dMaterial)) - prev = prev.surface; - if(!is_surface(prev)) continue; - - var prev_w = surface_get_width_safe(prev); - var prev_h = surface_get_height_safe(prev); - var ss = prev_size / max(prev_w, prev_h); - var prev_sw = prev_w * ss; - - draw_set_color(COLORS.panel_preview_surface_outline); - draw_rectangle(xx, yy, xx + prev_w * ss, yy + prev_h * ss, true); - - if(hoverable && point_in_rectangle(mx, my, xx, yy, xx + prev_sw, yy + prev_h * ss)) { - if(mouse_press(mb_left, pFOCUS)) { - _node.preview_index = i; - _node.onValueUpdate(0); - if(resetViewOnDoubleClick) - do_fullView = true; - } - draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 1); - } else { - draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 0.5); - } - - if(i == _node.preview_index) { - draw_set_color(COLORS._main_accent); - draw_rectangle(xx, yy, xx + prev_sw, yy + prev_h * ss, true); - } - - xx += prev_sw + ui(8); - preview_x_max += prev_sw + ui(8); - } - } - #endregion - - preview_x_max = max(preview_x_max - ui(100), 0); - } #endregion - - function drawViewController() { - if(!show_view_control) return; - - var _side = show_view_control == 1? 1 : -1; - var _view_x = show_view_control == 1? - tool_side_draw_l * toolbar_width + ui(8) : - w - tool_side_draw_r * toolbar_width - ui(8); - var _view_y = topbar_height + ui(8); - var _hab = pHOVER && tool_hovering == noone && !view_pan_tool && !view_zoom_tool; - view_hovering = false; - - if(d3_active) { - var d3_view_wr = ui(32); - - var _d3x = _view_x + d3_view_wr * _side; - var _d3y = _view_y + d3_view_wr; - var _hv = false; - - if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wr)) { - _hv = true; - view_hovering = true; - - if(mouse_press(mb_left, pFOCUS)) { - canvas_drag_key = mb_left; - d3_camPanning = true; - d3_camPan_mx = mx; - d3_camPan_my = my; - - view_pan_tool = true; - } - } - - if(view_pan_tool) - _hv = true; - - draw_circle_ui(_d3x, _d3y, d3_view_wr, _hv? 0 : 0.02, COLORS._main_icon, 0.3); - - var _qview = new BBMOD_Quaternion().FromEuler(d3_view_camera.focus_angle_y, -d3_view_camera.focus_angle_x, 0); - var _as = [ - new BBMOD_Vec3(-1, 0, 0), - new BBMOD_Vec3(0, 0, 1), - new BBMOD_Vec3(0, -1, 0), - ]; - - for(var i = 0; i < 3; i++) { - _as[i] = _qview.Rotate(_as[i]); - - draw_set_color(COLORS.axis[i]); - draw_line_round(_d3x, _d3y, _d3x + _as[i].X * (d3_view_wr * 0.75), _d3y + _as[i].Y * (d3_view_wr * 0.75), 3); - } - - var d3_view_wz = ui(16); - var _d3x = _view_x + (d3_view_wr * 2 + ui(20)) * _side; - var _d3y = _view_y + d3_view_wz; - var _hv = false; - - if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { - _hv = true; - view_hovering = true; - - if(mouse_press(mb_left, pFOCUS)) { - canvas_drag_key = mb_left; - canvas_zooming = true; - canvas_zoom_m = my; - view_zoom_tool = true; - } - } - - if(view_zoom_tool) - _hv = true; - - draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); - draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1); - - } else { - var d3_view_wz = ui(16); - - var _d3x = _view_x + d3_view_wz * _side; - var _d3y = _view_y + d3_view_wz; - var _hv = false; - - if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { - _hv = true; - view_hovering = true; - - if(mouse_press(mb_left, pFOCUS)) { - canvas_drag_key = mb_left; - canvas_dragging = true; - canvas_drag_mx = mx; - canvas_drag_my = my; - canvas_drag_sx = canvas_x; - canvas_drag_sy = canvas_y; - - view_pan_tool = true; - } - } - - if(view_pan_tool) - _hv = true; - - draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); - draw_sprite_ui(THEME.view_pan, 0, _d3x, _d3y, 1, 1, 0, view_pan_tool? COLORS._main_accent : COLORS._main_icon, 1); - - _d3x += (d3_view_wz + ui(4) + d3_view_wz) * _side; - _d3y = _view_y + d3_view_wz; - _hv = false; - - if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { - _hv = true; - view_hovering = true; - - if(mouse_press(mb_left, pFOCUS)) { - canvas_drag_key = mb_left; - canvas_zooming = true; - canvas_zoom_mx = w / 2; - canvas_zoom_my = h / 2; - canvas_zoom_m = my; - canvas_zoom_s = canvas_s; - - view_zoom_tool = true; - } - } - - if(view_zoom_tool) - _hv = true; - - draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); - draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1); - } - } - - function drawNodeTools(active, _node) { #region - var _mx = mx; - var _my = my; - var overHover = pHOVER && mouse_on_preview == 1; - var tool_size = ui(32); - - var cx = canvas_x + _node.preview_x * canvas_s; - var cy = canvas_y + _node.preview_y * canvas_s; - var _snx = 0, _sny = 0; - - tool_side_draw_l = _node.tools != -1; - tool_side_draw_r = _node.rightTools != -1; - - if(_node.tools != -1 && point_in_rectangle(_mx, _my, 0, 0, toolbar_width, h)) { - overHover = false; - mouse_on_preview = 0; - } - - overHover &= !view_hovering; - overHover &= tool_hovering == noone && !overlay_hovering; - overHover &= !canvas_dragging && !canvas_zooming; - overHover &= point_in_rectangle(mx, my, (_node.tools != -1) * toolbar_width, toolbar_height, w, h - toolbar_height); - - var overActive = active && overHover; - - var params = { w, h, toolbar_height }; - var mouse_free = false; - - if(_node.is_3D == NODE_3D.none) { - if(key_mod_press(CTRL)) { - _snx = PROJECT.previewGrid.show? PROJECT.previewGrid.size[0] : 1; - _sny = PROJECT.previewGrid.show? PROJECT.previewGrid.size[1] : 1; - } else if(PROJECT.previewGrid.snap) { - _snx = PROJECT.previewGrid.size[0]; - _sny = PROJECT.previewGrid.size[1]; - } - - mouse_free = _node.drawOverlay(overHover, overActive, cx, cy, canvas_s, _mx, _my, _snx, _sny, params); - - } else { - if(key_mod_press(CTRL) || d3_tool_snap) { - _snx = d3_tool_snap_position; - _sny = d3_tool_snap_rotation; - } - - mouse_free = _node.drawOverlay3D(overActive, d3_scene, _mx, _my, _snx, _sny, params); - } - - #region node overlay - overlay_hovering = false; - - if(_node.drawPreviewToolOverlay(pHOVER, pFOCUS, _mx, _my, { x, y, w, h, toolbar_height, - x0: _node.tools == -1? 0 : ui(40), - x1: w, - y0: toolbar_height - ui(8), - y1: h - toolbar_height - })) { - canvas_hover = false; - overlay_hovering = true; - } - #endregion - - var _tool = tool_hovering; - tool_hovering = noone; - - if(_node.tools == -1) { - tool_current = noone; - return; - } - - var aa = d3_active? 0.8 : 1; - draw_sprite_stretched_ext(THEME.tool_side, 1, 0, ui(32), toolbar_width, h - toolbar_height - ui(32), c_white, aa); - - tool_y_max = 0; - tool_y = lerp_float(tool_y, tool_y_to, 5); - var xx = ui(1) + toolbar_width / 2; - var yy = ui(34) + tool_size / 2 + tool_y; - var pd = 2; - var thov = pHOVER && point_in_rectangle(mx, my, 0, toolbar_height, toolbar_width, h - toolbar_height); - if(thov) canvas_hover = false; - - for(var i = 0; i < array_length(_node.tools); i++) { #region left tools - var tool = _node.tools[i]; - var _x0 = xx - tool_size / 2; - var _y0 = yy - tool_size / 2; - var _x1 = xx + tool_size / 2; - var _y1 = yy + tool_size / 2; - - if(tool == -1) { - draw_set_color(COLORS._main_icon_dark); - draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); - - yy += ui(8); - tool_y_max += ui(8); - continue; - } - - if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) - tool_hovering = tool; - - if(tool.subtools > 0 && _tool == tool) { #region hovering subtools - var s_ww = tool_size * tool.subtools; - var s_hh = tool_size; - draw_sprite_stretched(THEME.s_box_r2_clr, 0, _x0 - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); - - var stool = tool.spr; - - for( var j = 0; j < array_length(stool); j++ ) { - var _sxx = xx + j * tool_size; - var _syy = yy; - - var _sx0 = _sxx - tool_size / 2; - var _sy0 = _syy - tool_size / 2; - var _sx1 = _sxx + tool_size / 2; - var _sy1 = _syy + tool_size / 2; - - if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { - TOOLTIP = tool.getDisplayName(j); - draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); - - if(mouse_press(mb_left, pFOCUS)) - tool.toggle(j); - } - - if(tool_current == tool && tool.selecting == j) { - draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); - draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); - } - - draw_sprite_colored(stool[j], 0, _sxx, _syy); - } - - if(point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x0 + s_ww, _y1 - 1)) - tool_hovering = tool; - #endregion - - } else { #region single tools - if(tool_hovering == tool) { - draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2); - TOOLTIP = tool.getDisplayName(); - - if(mouse_press(mb_left, pFOCUS)) - tool.toggle(); - } - - if(pFOCUS && WIDGET_CURRENT == noone) { - var _key = tool.checkHotkey(); - - if(keyboard_check_pressed(ord(string(i + 1))) || (_key != noone && _key.isPressing())) - tool.toggleKeyboard(); - } - - if(tool_current == tool) { - draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); - draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); - } - - if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); - else draw_sprite_colored(tool.spr, 0, xx, yy); - #endregion - } - - yy += tool_size; - tool_y_max += tool_size; - } #endregion - - var _h = _node.drawTools == noone? 0 : _node.drawTools(_mx, _my, xx, yy - tool_size / 2, tool_size, thov, pFOCUS); - yy += _h; - tool_y_max += _h; - - tool_y_max = max(0, tool_y_max - h + toolbar_height * 2); - if(thov && !key_mod_press_any()) { - if(mouse_wheel_up()) tool_y_to = clamp(tool_y_to + ui(64) * SCROLL_SPEED, -tool_y_max, 0); - if(mouse_wheel_down()) tool_y_to = clamp(tool_y_to - ui(64) * SCROLL_SPEED, -tool_y_max, 0); - } - - if(_node.rightTools != -1) { - right_menu_x = w - toolbar_width - ui(8); - tool_ry_max = 0; - tool_ry = lerp_float(tool_ry, tool_ry_to, 5); - - var _tbx = w - toolbar_width; - var xx = _tbx + toolbar_width / 2; - var yy = ui(34) + tool_size / 2 + tool_ry; - - var _sw = -toolbar_width / sprite_get_width(THEME.tool_side); - var _sh = h - toolbar_height - ui(32) / sprite_get_height(THEME.tool_side); - - draw_sprite_ext(THEME.tool_side, 1, w + 1, ui(32), _sw, _sh, 0, c_white, aa); - - var thov = pHOVER && point_in_rectangle(mx, my, _tbx, toolbar_height, w, h - toolbar_height); - if(thov) canvas_hover = false; - - for(var i = 0; i < array_length(_node.rightTools); i++) { #region right tools - var tool = _node.rightTools[i]; - var _x0 = xx - tool_size / 2; - var _y0 = yy - tool_size / 2; - var _x1 = xx + tool_size / 2; - var _y1 = yy + tool_size / 2; - - if(tool == -1) { - draw_set_color(COLORS._main_icon_dark); - draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); - - yy += ui(8); - tool_ry_max += ui(8); - continue; - } - - if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) - tool_hovering = tool; - - if(tool.subtools > 0 && _tool == tool) { #region hovering subtools - - var stool = tool.spr; - var s_ww = tool_size * tool.subtools; - var s_hh = tool_size; - var tx = _x0 - s_ww + tool_size; - draw_sprite_stretched(THEME.s_box_r2_clr, 0, tx - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); - - var _am = array_length(stool); - - for( var j = 0; j < _am; j++ ) { - var _sind = _am - 1 - j; - var _sxx = tx + j * tool_size + tool_size / 2; - var _syy = yy; - - var _sx0 = _sxx - tool_size / 2; - var _sy0 = _syy - tool_size / 2; - var _sx1 = _sxx + tool_size / 2; - var _sy1 = _syy + tool_size / 2; - - draw_sprite_colored(stool[_sind], 0, _sxx, _syy); - - if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { - TOOLTIP = tool.getDisplayName(_sind); - draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); - - if(mouse_press(mb_left, pFOCUS)) - tool.toggle(_sind); - } - - if(tool_current == tool && tool.selecting == _sind) { - draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); - draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); - } - } - - if(point_in_rectangle(_mx, _my, tx, _y0 + 1, tx + s_ww, _y1 - 1)) - tool_hovering = tool; - #endregion - } else { #region single tools - if(tool_hovering == tool) { - draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2); - TOOLTIP = tool.getDisplayName(); - - if(mouse_press(mb_left, pFOCUS)) - tool.toggle(); - } - - if(pFOCUS && WIDGET_CURRENT == noone) { - var _key = tool.checkHotkey(); - if(keyboard_check_pressed(ord(string(i + 1))) || (_key != noone && _key.isPressing())) - tool.toggleKeyboard(); - } - - if(tool_current == tool) { - draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); - draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); - } - - if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); - else draw_sprite_colored(tool.spr, 0, xx, yy); - #endregion - } - - yy += tool_size; - tool_ry_max += tool_size; - } #endregion - - tool_ry_max = max(0, tool_ry_max - h + toolbar_height * 2); - if(thov && !key_mod_press_any()) { - if(mouse_wheel_up()) tool_ry_to = clamp(tool_ry_to + ui(64) * SCROLL_SPEED, -tool_ry_max, 0); - if(mouse_wheel_down()) tool_ry_to = clamp(tool_ry_to - ui(64) * SCROLL_SPEED, -tool_ry_max, 0); - } - } - } #endregion - - function drawToolBar(_tool, _node) { - var ty = h - toolbar_height; - var aa = d3_active? 0.8 : 1; - draw_sprite_stretched_ext(THEME.toolbar, 1, 0, 0, w, topbar_height, c_white, aa); - draw_sprite_stretched_ext(THEME.toolbar, 0, 0, ty, w, toolbar_height, c_white, aa); - - if(_tool && tool_current != noone) { // tool settings - var settings = array_merge(_tool.getToolSettings(), tool_current.settings); - - tool_x = lerp_float(tool_x, tool_x_to, 5); - var tolx = tool_x + ui(8); - var toly = ui(8); - var tolw = ui(48); - var tolh = toolbar_height - ui(20); - var tol_max_w = ui(16); - - for( var i = 0, n = array_length(settings); i < n; i++ ) { - var sett = settings[i]; - var nme = sett[0]; - var wdg = sett[1]; - var key = sett[2]; - var atr = sett[3]; - - if(nme != "") { - tolx += ui(8) + bool(i == 0) * ui(8); - tol_max_w += ui(8) + bool(i == 0) * ui(8); - } - - draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub); - if(nme != "") { - draw_text(tolx, toolbar_height / 2 - ui(2), nme); - tolx += string_width(nme) + ui(8); - tol_max_w += string_width(nme) + ui(8); - } - - wdg.setFocusHover(pFOCUS, pHOVER); - var _tool_font = f_p3; - - switch(instanceof(wdg)) { - case "textBox" : - tolw = ui(40); - if(wdg.side_button != noone) tolw += tolh + ui(8); - break; - - case "buttonGroup": - case "checkBoxGroup" : - tolw = tolh * wdg.size; - break; - - case "checkBox" : - tolw = tolh; - break; - - case "scrollBox" : - tolw = ui(96); - _tool_font = f_p2; - break; - - case "buttonClass" : - tolw = wdg.text == ""? tolh : tolw; - break; - } - - var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) - params.s = tolh; - params.font = _tool_font; - - wdg.drawParam(params); - - tolx += tolw + ui(8); - tol_max_w += tolw + ui(8); - } - - tol_max_w = max(0, tol_max_w - w); - if(point_in_rectangle(mx, my, 0, 0, w, toolbar_height) && !key_mod_press_any()) { - if(mouse_wheel_up()) tool_x_to = clamp(tool_x_to + ui(64) * SCROLL_SPEED, -tol_max_w, 0); - if(mouse_wheel_down()) tool_x_to = clamp(tool_x_to - ui(64) * SCROLL_SPEED, -tol_max_w, 0); - } - - } else { // color sampler - var cx = ui(8); - var cy = ui(8); - var cw = ui(32); - var ch = topbar_height - ui(16); - - if(sample_color != noone) { - draw_set_color(sample_color); - draw_set_alpha(1); - draw_rectangle(cx, cy, cx + cw, cy + ch, false); - } - - draw_set_color(COLORS.panel_toolbar_outline); - draw_rectangle(cx, cy, cx + cw, cy + ch, true); - - if(sample_color != noone) { - var tx = cx + cw + ui(16); - var hx = color_get_hex(sample_color); - draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); - draw_text(tx, cy + ch / 2, hx); - - tx += string_width(hx) + ui(8); - draw_set_color(COLORS._main_text_sub); - draw_text(tx, cy + ch / 2, $"({color_get_alpha(sample_color)})"); - } - } - - var tbx = toolbar_height / 2; - var tby = ty + toolbar_height / 2; - - var _toolbars = toolbars; - - switch(d3_active) { - case NODE_3D.none : _toolbars = toolbars; break; - case NODE_3D.polygon : _toolbars = toolbars_3d; break; - case NODE_3D.sdf : _toolbars = toolbars_3d_sdf; break; - } - - for( var i = 0, n = array_length(_toolbars); i < n; i++ ) { - var tb = _toolbars[i]; - var tbSpr = tb[0]; - var tbInd = tb[1](); - var tbTooltip = tb[2](); - var tbActive = tb[3]; - - var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbInd); - if(b == 2) tbActive( { x: x + tbx - ui(14), y: y + tby - ui(14) } ); - - tbx += ui(32); - } - - tbx = w - toolbar_height / 2; - for( var i = 0, n = array_length(actions); i < n; i++ ) { - var tb = actions[i]; - var tbSpr = tb[0]; - var tbTooltip = tb[1]; - var tbIndex = tb[3](); - - var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbIndex); - if(b == 2) tb[2]( { x: x + tbx - ui(14), y: y + tby - ui(14) } ); - - tbx -= ui(32); - } - - draw_set_color(COLORS.panel_toolbar_separator); - draw_line_width(tbx + ui(12), tby - toolbar_height / 2 + ui(8), tbx + ui(12), tby + toolbar_height / 2 - ui(8), 2); - - var _nodeRaw = __getNodePreview(); - if(_nodeRaw) tbx -= drawNodeChannel(_nodeRaw, tbx, tby); - } - - function drawSplitView() { #region - if(splitView == 0) return; - - draw_set_color(COLORS.panel_preview_split_line); - - if(splitViewDragging) { - if(splitView == 1) { - var cx = splitViewStart + (mx - splitViewMouse); - splitPosition = clamp(cx / w, .1, .9); - } else if(splitView == 2) { - var cy = splitViewStart + (my - splitViewMouse); - splitPosition = clamp(cy / h, .1, .9); - } - - if(mouse_release(mb_left)) - splitViewDragging = false; - } - - if(splitView == 1) { - var sx = w * splitPosition; - - if(mouse_on_preview && point_in_rectangle(mx, my, sx - ui(4), 0, sx + ui(4), h)) { - draw_line_width(sx, 0, sx, h, 2); - if(mouse_press(mb_left, pFOCUS)) { - splitViewDragging = true; - splitViewStart = sx; - splitViewMouse = mx; - } - } else - draw_line_width(sx, 0, sx, h, 1); - - draw_sprite_ui_uniform(THEME.icon_active_split, 0, splitSelection? sx + ui(16) : sx - ui(16), toolbar_height + ui(16),, COLORS._main_accent); - - if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) { - if(point_in_rectangle(mx, my, 0, 0, sx, h)) - splitSelection = 0; - else if(point_in_rectangle(mx, my, sx, 0, w, h)) - splitSelection = 1; - } - } else { - var sy = h * splitPosition; - - if(mouse_on_preview && point_in_rectangle(mx, my, 0, sy - ui(4), w, sy + ui(4))) { - draw_line_width(0, sy, w, sy, 2); - if(mouse_press(mb_left, pFOCUS)) { - splitViewDragging = true; - splitViewStart = sy; - splitViewMouse = my; - } - } else - draw_line_width(0, sy, w, sy, 1); - draw_sprite_ui_uniform(THEME.icon_active_split, 0, ui(16), splitSelection? sy + ui(16) : sy - ui(16),, COLORS._main_accent); - - if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) { - if(point_in_rectangle(mx, my, 0, 0, w, sy)) - splitSelection = 0; - else if(point_in_rectangle(mx, my, 0, sy, w, h)) - splitSelection = 1; - } - } - } #endregion - - function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< - mouse_on_preview = pHOVER && point_in_rectangle(mx, my, 0, topbar_height, w, h - toolbar_height); - - if(do_fullView) run_in(1, fullView); - do_fullView = false; - - var _prev_node = getNodePreview(); - d3_active = _prev_node == noone? NODE_3D.none : _prev_node.is_3D; - bg_color = lerp_color(bg_color, d3_active? COLORS.panel_3d_bg : COLORS.panel_bg_clear, 0.3); - - draw_clear(bg_color); - if(canvas_bg == -1) { - if(canvas_s >= 0.1) draw_sprite_tiled_ext(s_transparent, 0, canvas_x, canvas_y, canvas_s, canvas_s, COLORS.panel_preview_transparent, 1); - } else - draw_clear(canvas_bg); - - draw_set_color(COLORS._main_icon_dark); - draw_line_width(canvas_x, 0, canvas_x, h, 1); - draw_line_width(0, canvas_y, w, canvas_y, 1); - - title = __txt("Preview"); - - getPreviewData(); - - if(_prev_node) { - if(d3_active) { - dragCanvas3D(); - draw3D(); - } else { - dragCanvas(); - drawNodePreview(); - } - } else dragCanvas(); - - drawPreviewOverlay(); - - var inspect_node = PANEL_INSPECTOR.getInspecting(); - var tool = noone; - - drawViewController(); - - tool_side_draw_l = false; - tool_side_draw_r = false; - - if(PANEL_PREVIEW == self) { - if(inspect_node) { - tool = inspect_node.getTool(); - if(tool) drawNodeTools(pFOCUS, tool); - } else - tool_current = noone; - } - - if(d3_active == NODE_3D.none) drawSplitView(); - - drawToolBar(tool, _prev_node); - - if(mouse_on_preview && mouse_press(mb_right, pFOCUS) && !key_mod_press(SHIFT)) { - menuCall("preview_context_menu",,, [ - menuItemAction(__txtx("panel_graph_preview_window", "Send to preview window"), panel_preview_new_preview_window), - -1, - menuItemAction(__txtx("panel_preview_save", "Save current preview as") + "...", panel_preview_saveCurrentFrame), - menuItemAction(__txtx("panel_preview_save_all", "Save all current previews as") + "...", panel_preview_saveAllCurrentFrames), - -1, - menuItemAction($"{__txtx("panel_preview_copy_image", "Copy image")}", panel_preview_copyCurrentFrame, THEME.copy), - menuItemAction($"{__txtx("panel_preview_copy_color", "Copy color")} [{sample_color}]", panel_preview_copy_color), - menuItemAction($"{__txtx("panel_preview_copy_hex", "Copy hex")} [{color_get_hex(sample_color)}]", panel_preview_copy_color_hex), - ],, getNodePreview()); - } - - ////////////////////////////////// File drop ////////////////////////////////// - - if(pHOVER) { - var _node = getNodePreview(); - - if(_node && _node.dropPath != noone) { - - if(DRAGGING && DRAGGING.type == "Asset") { - draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1); - - if(mouse_release(mb_left)) - _node.dropPath(DRAGGING.data.path); - } - - if(FILE_IS_DROPPING) - draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1); - - if(FILE_DROPPED && !array_empty(FILE_DROPPING)) - _node.dropPath(FILE_DROPPING[0]); - } - } - - } #endregion - - ////=========== ACTION =========== - - function copyCurrentFrame() { #region - var prevS = getNodePreviewSurface(); - if(!is_surface(prevS)) return; - - var buff = buffer_create(surface_get_width_safe(prevS) * surface_get_height_safe(prevS) * 4, buffer_fixed, 1); - var s = surface_create(surface_get_width_safe(prevS), surface_get_height_safe(prevS)); - - surface_set_target(s); - shader_set(sh_BGR); - draw_surface_safe(prevS); - shader_reset(); - surface_reset_target(); - - buffer_get_surface(buff, s, 0); - surface_free(s); - - clipboard_set_bitmap(buffer_get_address(buff), surface_get_width_safe(prevS), surface_get_height_safe(prevS)); - } #endregion - - function saveCurrentFrameToFocus() { #region - var prevS = getNodePreviewSurface(); - - if(!is_surface(prevS)) return; - if(!is_struct(PANEL_FILE)) return; - - var _fileO = PANEL_FILE.file_focus; - if(_fileO == noone) return; - - var path = _fileO.path; - if(path == "") return; - - if(filename_ext(path) != ".png") path += ".png"; - - surface_save_safe(prevS, path); - _fileO.refreshThumbnail(); - } #endregion - - function saveCurrentFrame() { #region - var prevS = getNodePreviewSurface(); - var _node = getNodePreview(); - - if(_node == noone) return; - if(!is_surface(prevS)) return; - - var path = get_save_filename_pxc("image|*.png;*.jpg", _node.display_name == ""? "export" : _node.display_name, "Save surface as"); - key_release(); - - if(path == "") return; - if(filename_ext(path) != ".png") path += ".png"; - - surface_save_safe(prevS, path); - } #endregion - - function saveAllCurrentFrames() { #region - var _node = getNodePreview(); - - if(_node == noone) return; - - var path = get_save_filename_pxc("image|*.png;*.jpg", _node.display_name == ""? "export" : _node.display_name, "Save surfaces as"); - key_release(); - - if(path == "") return; - - var ext = ".png"; - var name = string_replace_all(path, ext, ""); - var ind = 0; - - var pseq = getNodePreviewSequence(); - for(var i = 0; i < array_length(pseq); i++) { - var prev = pseq[i]; - if(!is_surface(prev)) continue; - var _name = name + string(ind) + ext; - surface_save_safe(prev, _name); - ind++; - } - } #endregion - - //// =========== Serialize =========== - - static serialize = function() { - return { - name: instanceof(self), - preview_node : [ node_get_id(preview_node[0]), node_get_id(preview_node[1]) ], - - canvas_x, - canvas_y, - canvas_s, - - locked, - }; - } - - static deserialize = function(data) { - if(struct_has(data, "preview_node")) - preview_node = [ node_from_id(data.preview_node[0]), node_from_id(data.preview_node[1]) ]; - - canvas_x = struct_try_get(data, "canvas_x", canvas_x); - canvas_y = struct_try_get(data, "canvas_y", canvas_y); - canvas_s = struct_try_get(data, "canvas_s", canvas_s); - - locked = struct_try_get(data, "locked", locked); - - run_in(1, fullView) - return self; - } - + title = __txt("Preview"); + context_str = "Preview"; + icon = THEME.panel_preview_icon; + + last_focus = noone; + + #region ---- canvas control & sample ---- + function initSize() { + canvas_x = w / 2; + canvas_y = h / 2; + } + run_in(1, function() { initSize() }); + + canvas_x = 0; + canvas_y = 0; + canvas_s = 1; + canvas_w = ui(128); + canvas_h = ui(128); + canvas_a = 0; + + canvas_bg = -1; + + do_fullView = false; + + canvas_hover = true; + canvas_dragging_key = false; + canvas_dragging = false; + canvas_drag_key = 0; + canvas_drag_mx = 0; + canvas_drag_my = 0; + canvas_drag_sx = 0; + canvas_drag_sy = 0; + + canvas_zooming_key = false; + canvas_zooming = false; + canvas_zoom_mx = 0; + canvas_zoom_my = 0; + canvas_zoom_m = 0; + canvas_zoom_s = 0; + + view_pan_tool = false; + view_zoom_tool = false; + + sample_color = noone; + sample_x = noone; + sample_y = noone; + + #endregion + + #region ---- preview ---- + locked = false; + preview_node = [ noone, noone ]; + preview_surfaces = [ 0, 0 ]; + preview_surface = [ 0, 0 ]; + tile_surface = surface_create(1, 1); + + preview_x = 0; + preview_x_to = 0; + preview_x_max = 0; + preview_sequence = [ 0, 0 ]; + _preview_sequence = preview_sequence; + preview_rate = 10; + + right_menu_x = 0; + right_menu_y = 8; + mouse_on_preview = 0; + _mouse_on_preview = 0; + + resetViewOnDoubleClick = true; + + splitView = 0; + splitPosition = 0.5; + splitSelection = 0; + + splitViewDragging = false; + splitViewStart = 0; + splitViewMouse = 0; + + tileMode = 0; + + bg_color = COLORS.panel_bg_clear; + + mouse_pos_string = ""; + + show_info = true; + show_view_control = 1; + #endregion + + #region ---- tool ---- + tool_x = 0; + tool_x_to = 0; + tool_x_max = 0; + + tool_y = 0; + tool_y_to = 0; + tool_y_max = 0; + + tool_ry = 0; + tool_ry_to = 0; + tool_ry_max = 0; + + tool_current = noone; + + toolbar_width = ui(40); + toolbar_height = ui(40); + + tool_hovering = noone; + tool_side_draw_l = false; + tool_side_draw_r = false; + overlay_hovering = false; + view_hovering = false; + + sbChannel = new scrollBox([], function(index) { + var node = __getNodePreview(); + if(node == noone) return; + + node.preview_channel = sbChannelIndex[index].index; + node.setHeight(); + }); + + sbChannelIndex = []; + sbChannel.font = f_p1; + sbChannel.align = fa_left; + #endregion + + #region ---- 3d ---- + d3_active = NODE_3D.none; + d3_active_transition = 0; + + d3_surface = noone; + d3_surface_normal = noone; + d3_surface_depth = noone; + d3_surface_outline = noone; + d3_surface_bg = noone; + d3_preview_channel = 0; + + d3_deferData = noone; + d3_drawBG = false; + + global.SKY_SPHERE = new __3dUVSphere(0.5, 16, 8, true); + + #region camera + d3_view_camera = new __3dCamera(); + d3_camW = 1; + d3_camH = 1; + + d3_view_camera.setFocusAngle(135, 45, 4); + d3_camLerp = 0; + d3_camLerp_x = 0; + d3_camLerp_y = 0; + + d3_camTarget = new __vec3(); + + d3_camPanning = false; + d3_camPan_mx = 0; + d3_camPan_my = 0; + + d3_zoom_speed = 0.2; + d3_pan_speed = 2; + #endregion + + #region scene + d3_scene = new __3dScene(d3_view_camera, "Preview panel"); + d3_scene.lightAmbient = $404040; + d3_scene.cull_mode = cull_counterclockwise; + d3_scene_preview = d3_scene; + + d3_scene_light_enabled = true; + + d3_scene_light0 = new __3dLightDirectional(); + d3_scene_light0.transform.position.set(-1, -2, 3); + d3_scene_light0.color = $FFFFFF; + d3_scene_light0.shadow_active = false; + d3_scene_light0.shadow_map_scale = 4; + + d3_scene_light1 = new __3dLightDirectional(); + d3_scene_light1.transform.position.set(1, 2, -3); + d3_scene_light1.color = $505050; + #endregion + + #region tool + d3_tool_snap = false; + d3_tool_snap_position = 1; + d3_tool_snap_rotation = 15; + #endregion + #endregion + + tb_framerate = new textBox(TEXTBOX_INPUT.number, function(val) { preview_rate = real(val); }); + + #region ++++ toolbars & actions ++++ + function set_tile_off() { tileMode = 0; } + function set_tile_horizontal() { tileMode = 1; } + function set_tile_vertical() { tileMode = 2; } + function set_tile_both() { tileMode = 3; } + function set_tile_toggle() { tileMode = (tileMode + 1) % 4; } + + function new_preview_window() { create_preview_window(getNodePreview()); } + function copy_color() { clipboard_set_text(sample_color); } + function copy_color_hex() { clipboard_set_text(color_get_hex(sample_color)); } + + topbar_height = ui(32); + toolbar_height = ui(40); + toolbars = [ + [ + THEME.icon_reset_when_preview, + function() { return resetViewOnDoubleClick; }, + function() { return resetViewOnDoubleClick? __txtx("panel_preview_center_canvas_on_preview", "Center canvas on preview") : + __txtx("panel_preview_keep_canvas_on_preview", "Keep canvas on preview"); }, + function() { resetViewOnDoubleClick = !resetViewOnDoubleClick; } + ], + [ + THEME.icon_split_view, + function() { return splitView; }, + function() { + switch(splitView) { + case 0 : return __txtx("panel_preview_split_view_off", "Split view off"); + case 1 : return __txtx("panel_preview_horizontal_split_view", "Horizontal split view"); + case 2 : return __txtx("panel_preview_vertical_split_view", "Vertical split view"); + } + return __txtx("panel_preview_split_view", "Split view"); + }, + function() { splitView = (splitView + 1) % 3; } + ], + [ + THEME.icon_tile_view, + function() { var t = [3, 0, 1, 2]; return array_safe_get_fast(t, tileMode); }, + function() { + switch(tileMode) { + case 0 : return __txtx("panel_preview_tile_off", "Tile off"); + case 1 : return __txtx("panel_preview_tile_horizontal", "Tile horizontal"); + case 2 : return __txtx("panel_preview_tile_vertical", "Tile vertical"); + case 3 : return __txtx("panel_preview_tile_both", "Tile both"); + } + return __txtx("panel_preview_tile_mode", "Tile mode"); + }, + function(data) { + menuCall("preview_tile_menu", data.x + ui(28), data.y + ui(28), [ + MENU_ITEMS.preview_set_tile_off, + MENU_ITEMS.preview_set_tile_horizontal, + MENU_ITEMS.preview_set_tile_vertical, + MENU_ITEMS.preview_set_tile_both, + ]); + } + ], + [ + THEME.icon_grid_setting, + function() { return 0; }, + function() { return __txtx("grid_title", "Grid setting") }, + function(param) { + var dia = dialogPanelCall(new Panel_Preview_Grid_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); + } + ], + [ + THEME.onion_skin, + function() { return 0; }, + function() { return __txt("Onion Skin") }, + function(param) { + var dia = dialogPanelCall(new Panel_Preview_Onion_Setting(), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); + } + ], + ]; + + toolbars_3d = [ + [ + THEME.d3d_preview_settings, + function() /*=>*/ {return 0}, + function() /*=>*/ {return __txt("3D Preview Settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_3D_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + [ + THEME.d3d_snap_settings, + function() /*=>*/ {return 0}, + function() /*=>*/ {return __txt("3D Snap Settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + ]; + + toolbars_3d_sdf = [ + [ + THEME.d3d_preview_settings, + function() /*=>*/ {return 0}, + function() /*=>*/ {return __txt("3D SDF Preview Settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_3D_SDF_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + [ + THEME.d3d_snap_settings, + function() /*=>*/ {return 0}, + function() /*=>*/ {return __txt("3D Snap Settings")}, + function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_Snap_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); } + ], + ]; + + tooltip_center = new tooltipHotkey(__txtx("panel_preview_center_canvas", "Center canvas"), "Preview", "Focus content"); + tooltip_export = new tooltipHotkey(__txtx("panel_preview_export_canvas", "Export canvas"), "Preview", "Save current frame"); + + actions = [ + [ + THEME.lock, + __txtx("panel_preview_lock_preview", "Lock previewing node"), + function() /*=>*/ { locked = !locked; }, + function() /*=>*/ {return !locked}, + ], + [ + THEME.icon_preview_export, + tooltip_export, + function() /*=>*/ { saveCurrentFrame(); }, + function() /*=>*/ {return 0}, + ], + [ + THEME.icon_center_canvas, + tooltip_center, + function() /*=>*/ { fullView(); }, + function() /*=>*/ {return 0}, + ], + [ + THEME.icon_visibility, + __txtx("graph_visibility_title", "Visibility settings"), + function(param) /*=>*/ { dialogPanelCall(new Panel_Preview_View_Setting(self), param.x, param.y, { anchor: ANCHOR.bottom | ANCHOR.left }); }, + function() /*=>*/ {return 0}, + ], + ]; + + static d3_view_action_front = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = 0; } + static d3_view_action_back = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 180; d3_camLerp_y = 0; } + static d3_view_action_right = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 90; d3_camLerp_y = 0; } + static d3_view_action_left = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = -90; d3_camLerp_y = 0; } + static d3_view_action_bottom = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = -89; } + static d3_view_action_top = function() /*=>*/ { d3_camLerp = 1; d3_camLerp_x = 0; d3_camLerp_y = 89; } + #endregion + + ////============ DATA ============ + + function setNodePreview(node) { + if(locked) return; + + if(resetViewOnDoubleClick) + do_fullView = true; + + preview_node[splitView? splitSelection : 0] = node; + } + + function removeNodePreview(node) { #region + if(locked) return; + + if(preview_node[0] == node) preview_node[0] = noone; + if(preview_node[1] == node) preview_node[1] = noone; + } #endregion + + function resetNodePreview() { + preview_node = [ noone, noone ]; + locked = false; + } + + function __getNodePreview() { return preview_node[splitView? splitSelection : 0]; } + function getNodePreview() { + var _node = __getNodePreview(); + if(_node == noone) return noone; + + if(!_node.project.active) { + resetNodePreview(); + return noone; + } + + if(is_instanceof(_node, Node)) + _node = _node.getPreviewingNode(); + + return _node; + } + + function getNodePreviewSurface() { return preview_surfaces[splitView? splitSelection : 0]; } + function getNodePreviewSequence() { return preview_sequence[splitView? splitSelection : 0]; } + + function getPreviewData() { #region + preview_surfaces = [ noone, noone ]; + preview_sequence = [ noone, noone ]; + + for( var i = 0; i < 2; i++ ) { + var node = preview_node[i]; + + if(node == noone) continue; + if(!node.active) { + resetNodePreview(); + return; + } + + var value = node.getPreviewValues(); + + if(is_array(value)) { + preview_sequence[i] = value; + canvas_a = array_length(value); + } else { + preview_surfaces[i] = value; + canvas_a = 0; + } + + if(preview_sequence[i] != noone) { + if(array_length(preview_sequence[i]) == 0) return; + preview_surfaces[i] = preview_sequence[i][safe_mod(node.preview_index, array_length(preview_sequence[i]))]; + } + } + + var prevS = getNodePreviewSurface(); + + if(is_surface(prevS)) { + canvas_w = surface_get_width_safe(prevS); + canvas_h = surface_get_height_safe(prevS); + } + } #endregion + + function onFocusBegin() { PANEL_PREVIEW = self; } + + ////============ VIEW ============ + + function dragCanvas() { #region + if(canvas_dragging) { + if(!MOUSE_WRAPPING) { + var dx = mx - canvas_drag_mx; + var dy = my - canvas_drag_my; + + canvas_x += dx; + canvas_y += dy; + } + + canvas_drag_mx = mx; + canvas_drag_my = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) { + canvas_dragging = false; + view_pan_tool = false; + } + } + + if(canvas_zooming) { + if(!MOUSE_WRAPPING) { + // var mdx = mx - canvas_zoom_mx; + var mdy = my - canvas_zoom_m; + + var dd = -(mdy) / 200; + + var _s = canvas_s; + canvas_s = clamp(canvas_s * (1 + dd), 0.10, 64); + + if(_s != canvas_s) { + var dx = (canvas_s - _s) * ((canvas_zoom_mx - canvas_x) / _s); + var dy = (canvas_s - _s) * ((canvas_zoom_my - canvas_y) / _s); + canvas_x -= dx; + canvas_y -= dy; + } + } + + canvas_zoom_m = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) { + canvas_zooming = false; + view_zoom_tool = false; + } + } + + if(pHOVER && canvas_hover) { + var _doDragging = false; + var _doZooming = false; + + if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) { + _doDragging = true; + canvas_drag_key = PREFERENCES.pan_mouse_key; + + } else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) { + _doDragging = true; + canvas_drag_key = mb_left; + + } else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) { + _doZooming = true; + canvas_drag_key = mb_left; + } + + if(_doDragging) { + canvas_dragging = true; + canvas_drag_mx = mx; + canvas_drag_my = my; + canvas_drag_sx = canvas_x; + canvas_drag_sy = canvas_y; + } + + if(_doZooming) { + canvas_zooming = true; + canvas_zoom_mx = mx; + canvas_zoom_my = my; + canvas_zoom_m = my; + canvas_zoom_s = canvas_s; + } + + var _canvas_s = canvas_s; + var inc = 0.1; + if(canvas_s > 16) inc = 2; + else if(canvas_s > 8) inc = 1; + else if(canvas_s > 3) inc = 0.5; + else if(canvas_s > 1) inc = 0.25; + + if(mouse_wheel_down() && !key_mod_press_any()) canvas_s = max(round(canvas_s / inc) * inc - inc, 0.10); + if(mouse_wheel_up() && !key_mod_press_any()) canvas_s = min(round(canvas_s / inc) * inc + inc, 1024); + + if(_canvas_s != canvas_s) { + var dx = (canvas_s - _canvas_s) * ((mx - canvas_x) / _canvas_s); + var dy = (canvas_s - _canvas_s) * ((my - canvas_y) / _canvas_s); + canvas_x -= dx; + canvas_y -= dy; + } + } + + canvas_dragging_key = false; + canvas_zooming_key = false; + canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height); + } #endregion + + function dragCanvas3D() { #region + if(d3_camLerp) { + d3_view_camera.focus_angle_x = lerp_float(d3_view_camera.focus_angle_x, d3_camLerp_x, 3, 1); + d3_view_camera.focus_angle_y = lerp_float(d3_view_camera.focus_angle_y, d3_camLerp_y, 3, 1); + + if(d3_view_camera.focus_angle_x == d3_camLerp_x && d3_view_camera.focus_angle_y == d3_camLerp_y) + d3_camLerp = false; + } + + if(d3_camPanning) { + if(!MOUSE_WRAPPING) { + var dx = mx - d3_camPan_mx; + var dy = my - d3_camPan_my; + + var px = d3_view_camera.focus_angle_x; + var py = d3_view_camera.focus_angle_y; + var ax = px + dx * 0.2 * d3_pan_speed; + var ay = py + dy * 0.1 * d3_pan_speed; + + //if(py < 90 && ay >= 90) ax -= 180; + //if(py > 90 && ay <= 90) ax += 180; + + //print($"{ax},\t{ay}"); + + d3_view_camera.focus_angle_x = ax; + d3_view_camera.focus_angle_y = ay; + } + + d3_camPan_mx = mx; + d3_camPan_my = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) { + d3_camPanning = false; + view_pan_tool = false; + } + } + + if(canvas_zooming) { + if(!MOUSE_WRAPPING) { + var dy = -(my - canvas_zoom_m) / 200; + d3_view_camera.focus_dist = clamp(d3_view_camera.focus_dist + dy, 1, 1000); + } + + canvas_zoom_m = my; + setMouseWrap(); + + if(mouse_release(canvas_drag_key)) { + canvas_zooming = false; + view_zoom_tool = false; + } + } + + if(pHOVER && canvas_hover) { + var _doDragging = false; + var _doZooming = false; + + if(mouse_press(PREFERENCES.pan_mouse_key, pFOCUS)) { + _doDragging = true; + canvas_drag_key = PREFERENCES.pan_mouse_key; + + } else if(mouse_press(mb_left, pFOCUS) && canvas_dragging_key) { + + _doDragging = true; + canvas_drag_key = mb_left; + } else if(mouse_press(mb_left, pFOCUS) && canvas_zooming_key) { + + _doZooming = true; + canvas_drag_key = mb_left; + } + + if(_doDragging) { + d3_camPanning = true; + d3_camPan_mx = mx; + d3_camPan_my = my; + } + + if(_doZooming) { + canvas_zooming = true; + canvas_zoom_m = my; + } + + if(mouse_wheel_up()) d3_view_camera.focus_dist = max( 1, d3_view_camera.focus_dist * (1 - d3_zoom_speed)); + if(mouse_wheel_down()) d3_view_camera.focus_dist = min(1000, d3_view_camera.focus_dist * (1 + d3_zoom_speed)); + } + + canvas_dragging_key = false; + canvas_zooming_key = false; + canvas_hover = point_in_rectangle(mx, my, 0, toolbar_height, w, h - toolbar_height); + } #endregion + + function fullView(scale = 0) { + var bbox = noone; + + var node = getNodePreview(); + if(node != noone) bbox = node.getPreviewBoundingBox(); + if(bbox == noone) bbox = BBOX().fromWH(0, 0, PROJECT.attributes.surface_dimension[0], PROJECT.attributes.surface_dimension[1]); + + var _x = bbox.x0, _y = bbox.y0; + var _w = bbox.w, _h = bbox.h; + + if(_w == 0 || _h == 0) { + _x = 0; + _y = 0; + _w = DEF_SURF_W; + _h = DEF_SURF_H; + } + + var tl = tool_side_draw_l * 40; + var tr = tool_side_draw_r * 40; + var ss = scale == 0? min((w - 32 - tl - tr) / _w, (h - 32 - toolbar_height * 2) / _h) : scale; + + canvas_s = ss; + canvas_x = w / 2 - _w * canvas_s / 2 - _x * canvas_s + (tl - tr) / 2; + canvas_y = h / 2 - _h * canvas_s / 2 - _y * canvas_s; + } + + function drawNodeChannel(_node, _x, _y) { + if(array_length(_node.outputs) < 2) return 0; + + var chName = []; + sbChannelIndex = []; + + var currName = _node.outputs[_node.preview_channel].name; + draw_set_text(sbChannel.font, fa_center, fa_center); + var ww = 0; + var hh = TEXTBOX_HEIGHT - ui(2); + var _am = _node.getOutputJunctionAmount(); + + for( var i = 0; i < _am; i++ ) { + var _outi = _node.getOutputJunctionIndex(i); + var _outj = _node.outputs[_outi]; + + array_push(chName, _outj.name); + array_push(sbChannelIndex, _outj); + ww = max(ww, string_width(_outj.name) + ui(40)); + } + + + if(!array_empty(chName)) { + sbChannel.data_list = chName; + sbChannel.setFocusHover(pFOCUS, pHOVER); + sbChannel.draw(_x - ww, _y - hh / 2, ww, hh, currName, [mx, my], x, y); + right_menu_y += ui(40); + } + + return ww + ui(4); + } + + static onFullScreen = function() { run_in(1, fullView); } + + ////============ DRAW ============ + + function drawOnionSkin(node, psx, psy, ss) { #region + var _surf = preview_surfaces[0]; + var _rang = PROJECT.onion_skin.range; + + var _alph = PROJECT.onion_skin.alpha; + var _colr = PROJECT.onion_skin.color; + + var _step = PROJECT.onion_skin.step; + var _top = PROJECT.onion_skin.on_top; + + var fr = CURRENT_FRAME; + var st = min(_rang[0], _rang[1]); + var ed = max(_rang[0], _rang[1]); + + st = sign(st) * floor(abs(st) / _step) * _step; + ed = sign(ed) * floor(abs(ed) / _step) * _step; + + st += fr; + ed += fr; + + var surf, aa, cc; + + if(!_top) { + draw_surface_ext_safe(_surf, psx, psy, ss, ss); + BLEND_ADD + } + + for( var i = st; i <= ed; i += _step ) { + surf = node.getCacheFrame(i); + if(!is_surface(surf)) continue; + + aa = power(_alph, abs((i - fr) / _step)); + cc = c_white; + if(i < fr) cc = _colr[0]; + else if(i > fr) cc = _colr[1]; + + draw_surface_ext_safe(surf, psx, psy, ss, ss, 0, cc, aa); + } + + BLEND_NORMAL + + if(_top) draw_surface_ext_safe(_surf, psx, psy, ss, ss); + + } #endregion + + function drawNodePreview() { #region + var ss = canvas_s; + var psx = 0, psy = 0; + var psw = 0, psh = 0; + var pswd = 0, pshd = 0; + var psx1 = 0, psy1 = 0; + + var ssx = 0, ssy = 0; + var ssw = 0, ssh = 0; + + if(is_surface(preview_surfaces[0])) { + psx = canvas_x + preview_node[0].preview_x * ss; + psy = canvas_y + preview_node[0].preview_y * ss; + + psw = surface_get_width_safe(preview_surfaces[0]); + psh = surface_get_height_safe(preview_surfaces[0]); + pswd = psw * ss; + pshd = psh * ss; + + psx1 = psx + pswd; + psy1 = psy + pshd; + } + + if(is_surface(preview_surfaces[1])) { + var ssx = canvas_x + preview_node[1].preview_x * ss; + var ssy = canvas_y + preview_node[1].preview_y * ss; + + var ssw = surface_get_width_safe(preview_surfaces[1]); + var ssh = surface_get_height_safe(preview_surfaces[1]); + } + + var _node = getNodePreview(); + if(_node) title = _node.renamed? _node.display_name : _node.name; + + #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Draw Surfaces <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + var _ps0 = is_surface(preview_surfaces[0]); + var _ps1 = is_surface(preview_surfaces[1]); + + if(_ps0) { + var _sw = surface_get_width_safe(preview_surfaces[0]); + var _sh = surface_get_height_safe(preview_surfaces[0]); + + preview_surface[0] = surface_verify(preview_surface[0], _sw, _sh); + + surface_set_shader(preview_surface[0], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample); + shader_set_f("palette", PROJECT.palettes); + shader_set_i("keys", array_length(PROJECT.attributes.palette)); + shader_set_i("alpha", 1); + + draw_surface_safe(preview_surfaces[0]); + surface_reset_shader(); + } + + if(_ps1) { + var _sw = surface_get_width_safe(preview_surfaces[1]); + var _sh = surface_get_height_safe(preview_surfaces[1]); + + preview_surface[1] = surface_verify(preview_surface[1], _sw, _sh); + + surface_set_shader(preview_surface[1], PROJECT.attributes.palette_fix? sh_posterize_palette : sh_sample); + shader_set_f("palette", PROJECT.palettes); + shader_set_i("keys", array_length(PROJECT.attributes.palette)); + shader_set_i("alpha", 1); + + draw_surface_safe(preview_surfaces[1]); + surface_reset_shader(); + } + + switch(splitView) { + case 0 : + if(_ps0) { + preview_node[0].previewing = 1; + + switch(tileMode) { + case 0 : + if(PROJECT.onion_skin.enabled) drawOnionSkin(_node, psx, psy, ss); + else draw_surface_ext(preview_surface[0], psx, psy, ss, ss, 0, c_white, preview_node[0].preview_alpha); + break; + + case 1 : + tile_surface = surface_verify(tile_surface, w, surface_get_height_safe(preview_surface[0]) * ss); + surface_set_target(tile_surface); + DRAW_CLEAR + draw_surface_tiled_ext_safe(preview_surface[0], psx, 0, ss, ss, 0, c_white, 1); + surface_reset_target(); + draw_surface_safe(tile_surface, 0, psy); + break; + + case 2 : + tile_surface = surface_verify(tile_surface, surface_get_width_safe(preview_surface[0]) * ss, h); + surface_set_target(tile_surface); + DRAW_CLEAR + draw_surface_tiled_ext_safe(preview_surface[0], 0, psy, ss, ss, 0, c_white, 1); + surface_reset_target(); + draw_surface_safe(tile_surface, psx, 0); + break; + + case 3 : + draw_surface_tiled_ext_safe(preview_surface[0], psx, psy, ss, ss, 0, c_white, 1); break; + } + } + break; + case 1 : + var sp = splitPosition * w; + + if(_ps0) { + preview_node[0].previewing = 2; + var maxX = min(sp, psx1); + var sW = min(psw, (maxX - psx) / ss); + + if(sW > 0) + draw_surface_part_ext_safe(preview_surface[0], 0, 0, sW, psh, psx, psy, ss, ss, 0, c_white, 1); + } + + if(_ps1) { + preview_node[1].previewing = 3; + var minX = max(ssx, sp); + var sX = (minX - ssx) / ss; + var spx = max(sp, ssx); + + if(sX >= 0 && sX < ssw) + draw_surface_part_ext_safe(preview_surface[1], sX, 0, ssw - sX, ssh, spx, ssy, ss, ss, 0, c_white, 1); + } + break; + case 2 : + var sp = splitPosition * h; + + if(_ps0) { + preview_node[0].previewing = 4; + var maxY = min(sp, psy1); + var sH = min(psh, (maxY - psy) / ss); + + if(sH > 0) + draw_surface_part_ext_safe(preview_surface[0], 0, 0, psw, sH, psx, psy, ss, ss, 0, c_white, 1); + } + + if(_ps1) { + preview_node[1].previewing = 5; + var minY = max(ssy, sp); + var sY = (minY - ssy) / ss; + var spy = max(sp, ssy); + + if(sY >= 0 && sY < ssh) + draw_surface_part_ext_safe(preview_surface[1], 0, sY, ssw, ssh - sY, ssx, spy, ss, ss, 0, c_white, 1); + } + break; + } + #endregion + + if(!instance_exists(o_dialog_menubox)) { #region color sample + sample_color = noone; + sample_x = noone; + sample_y = noone; + + if(mouse_on_preview && (mouse_press(mb_right) || key_mod_press(CTRL))) { + var _sx = sample_x; + var _sy = sample_y; + + sample_x = floor((mx - canvas_x) / canvas_s); + sample_y = floor((my - canvas_y) / canvas_s); + var surf = getNodePreviewSurface(); + sample_color = surface_get_pixel_ext(surf, sample_x, sample_y); + + //print($"{dec_to_hex(sample_color)}: {color_get_alpha(int64(sample_color))}"); + } + } #endregion + + if(is_surface(preview_surfaces[0])) { #region outline + if(PROJECT.previewGrid.pixel && canvas_s >= 16) { + + var gw = pswd / canvas_s; + var gh = pshd / canvas_s; + + var cx = canvas_x; + var cy = canvas_y; + + draw_set_color(PROJECT.previewGrid.color); + draw_set_alpha(PROJECT.previewGrid.opacity * 0.5 * clamp((canvas_s - 16) / 16, 0, 1)); + + for( var i = 1; i < gw; i++ ) { + var _xx = cx + i * canvas_s; + draw_line(_xx, cy, _xx, cy + pshd); + } + + for( var i = 1; i < gh; i++ ) { + var _yy = cy + i * canvas_s; + draw_line(cx, _yy - 1, cx + pswd, _yy - 1); + } + + draw_set_alpha(1); + } + + if(PROJECT.previewGrid.show) { + var _gw = PROJECT.previewGrid.size[0] * canvas_s; + var _gh = PROJECT.previewGrid.size[1] * canvas_s; + + var gw = pswd / _gw; + var gh = pshd / _gh; + + var cx = canvas_x; + var cy = canvas_y; + + draw_set_color(PROJECT.previewGrid.color); + draw_set_alpha(PROJECT.previewGrid.opacity); + + for( var i = 1; i < gw; i++ ) { + var _xx = cx + i * _gw; + draw_line(_xx, cy, _xx, cy + pshd); + } + + for( var i = 1; i < gh; i++ ) { + var _yy = cy + i * _gh; + draw_line(cx, _yy, cx + pswd, _yy); + } + + draw_set_alpha(1); + } + + draw_set_color(COLORS.panel_preview_surface_outline); + draw_rectangle(psx, psy, psx + pswd - 1, psy + pshd - 1, true); + } #endregion + } #endregion + + function draw3DPolygon(_node) { #region + surface_depth_disable(false); + + _node.previewing = 1; + + d3_scene_preview = struct_has(_node, "scene")? _node.scene : d3_scene; + d3_scene_preview.camera = d3_view_camera; + + #region view + var _pos, targ, _blend = 1; + + targ = d3_camTarget; + _pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist); + + if(d3_active_transition == 1) { + var _up = new __vec3(0, 0, -1); + + d3_view_camera.position._lerp_float(_pos, 5, 0.1); + d3_view_camera.focus._lerp_float( targ, 5, 0.1); + d3_view_camera.up._lerp_float( _up, 5, 0.1); + + if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) + d3_active_transition = 0; + } else if(d3_active_transition == -1) { + var _pos = new __vec3(0, 0, 8); + var targ = new __vec3(0, 0, 0); + var _up = new __vec3(0, 1, 0); + + d3_view_camera.position._lerp_float(_pos, 5, 0.1); + d3_view_camera.focus._lerp_float( targ, 5, 0.1); + d3_view_camera.up._lerp_float( _up, 5, 0.1); + + _blend = d3_view_camera.position.distance(_pos) / 2; + _blend = clamp(_blend, 0, 1); + + if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) + d3_active_transition = 0; + } else { + d3_view_camera.position.set(_pos); + d3_view_camera.focus.set(targ); + } + + d3_view_camera.setViewSize(w, h); + d3_view_camera.setMatrix(); + #endregion + + #region background + surface_free_safe(d3_surface_bg); + + if(d3_scene_preview != d3_scene) + d3_surface_bg = d3_scene_preview.renderBackground(w, h); + #endregion + + #region shadow + if(d3_scene_preview == d3_scene) { + d3_scene_light0.shadow_map_scale = d3_view_camera.focus_dist * 2; + + var _prev_obj = _node.getPreviewObject(); + if(_prev_obj != noone) { + d3_scene_light0.submitShadow(d3_scene_preview, _prev_obj); + _prev_obj.submitShadow(d3_scene_preview, _prev_obj); + } + } + #endregion + + d3_surface = surface_verify(d3_surface, w, h); + d3_surface_normal = surface_verify(d3_surface_normal, w, h); + d3_surface_depth = surface_verify(d3_surface_depth, w, h); + d3_surface_outline = surface_verify(d3_surface_outline, w, h); + + #region defer + var _prev_obj = _node.getPreviewObject(); + if(_prev_obj) d3_deferData = d3_scene_preview.deferPass(_prev_obj, w, h, d3_deferData); + #endregion + + #region grid + surface_set_target_ext(0, d3_surface); + surface_set_target_ext(1, d3_surface_normal); + surface_set_target_ext(2, d3_surface_depth); + + draw_clear_alpha(bg_color, 0); + + d3_view_camera.applyCamera(); + + gpu_set_ztestenable(true); + gpu_set_zwriteenable(false); + + if(OS != os_macosx) { + gpu_set_cullmode(cull_noculling); + + shader_set(sh_d3d_grid_view); + var _dist = round(d3_view_camera.focus.distance(d3_view_camera.position)); + var _tx = round(d3_view_camera.focus.x); + var _ty = round(d3_view_camera.focus.y); + + var _scale = _dist * 2; + while(_scale > 32) _scale /= 2; + + shader_set_f("axisBlend", _blend); + shader_set_f("scale", _scale); + shader_set_f("shift", _tx / _dist / 2, _ty / _dist / 2); + draw_sprite_stretched(s_fx_pixel, 0, _tx - _dist, _ty - _dist, _dist * 2, _dist * 2); + shader_reset(); + } + + gpu_set_zwriteenable(true); + #endregion + + #region draw + d3_scene_preview.reset(); + gpu_set_cullmode(cull_counterclockwise); + + var _prev_obj = _node.getPreviewObjects(); + + if(d3_scene_preview == d3_scene) { + if(d3_scene_light_enabled) { + d3_scene_preview.addLightDirectional(d3_scene_light0); + d3_scene_preview.addLightDirectional(d3_scene_light1); + } + } + + for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { + var _prev = _prev_obj[i]; + if(_prev == noone) continue; + + _prev.submitShader(d3_scene_preview); + } + + d3_scene_preview.apply(d3_deferData); + + for( var i = 0, n = array_length(_prev_obj); i < n; i++ ) { + var _prev = _prev_obj[i]; + if(_prev == noone) continue; + + _prev.submitUI(d3_scene_preview); + } + + gpu_set_cullmode(cull_noculling); + surface_reset_target(); + + draw_clear(bg_color); + + switch(d3_preview_channel) { + case 0 : + if(d3_scene_preview.draw_background) + draw_surface_safe(d3_surface_bg); + + draw_surface_safe(d3_surface); + + if(is_struct(d3_deferData)) { + BLEND_MULTIPLY + draw_surface_safe(d3_deferData.ssao); + BLEND_NORMAL + } + break; + case 1 : draw_surface_safe(d3_surface_normal); break; + case 2 : draw_surface_safe(d3_surface_depth); break; + } + #endregion + + #region outline + var inspect_node = PANEL_INSPECTOR.getInspecting(); + + if(inspect_node && inspect_node.is_3D == NODE_3D.polygon) { + var _inspect_obj = inspect_node.getPreviewObjectOutline(); + + surface_set_target(d3_surface_outline); + draw_clear(c_black); + + d3_scene_preview.camera.applyCamera(); + + gpu_set_ztestenable(false); + for( var i = 0, n = array_length(_inspect_obj); i < n; i++ ) { + if(_inspect_obj[i] == noone) continue; + _inspect_obj[i].submitSel(d3_scene_preview); + } + surface_reset_target(); + + shader_set(sh_d3d_outline); + shader_set_dim("dimension", d3_surface_outline); + shader_set_color("outlineColor", COLORS._main_accent); + draw_surface_safe(d3_surface_outline); + shader_reset(); + } + #endregion + + d3_scene_preview.camera.resetCamera(); + + surface_depth_disable(true); + } #endregion + + function draw3DSdf(_node) { #region + _node.previewing = 1; + + var _env = _node.environ; + var _obj = _node.object; + + d3_scene_preview = d3_scene; + d3_scene_preview.camera = d3_view_camera; + + #region view + d3_view_camera.fov = max(1, _env.fov * 1.23); + var _pos, targ, _blend = 1; + + targ = d3_camTarget; + _pos = d3d_PolarToCart(targ.x, targ.y, targ.z, d3_view_camera.focus_angle_x, d3_view_camera.focus_angle_y, d3_view_camera.focus_dist); + + if(d3_active_transition == 1) { + var _up = new __vec3(0, 0, -1); + + d3_view_camera.position._lerp_float(_pos, 5, 0.1); + d3_view_camera.focus._lerp_float( targ, 5, 0.1); + d3_view_camera.up._lerp_float( _up, 5, 0.1); + + if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) + d3_active_transition = 0; + } else if(d3_active_transition == -1) { + var _pos = new __vec3(0, 0, 8); + var targ = new __vec3(0, 0, 0); + var _up = new __vec3(0, 1, 0); + + d3_view_camera.position._lerp_float(_pos, 5, 0.1); + d3_view_camera.focus._lerp_float( targ, 5, 0.1); + d3_view_camera.up._lerp_float( _up, 5, 0.1); + + _blend = d3_view_camera.position.distance(_pos) / 2; + _blend = clamp(_blend, 0, 1); + + if(d3_view_camera.position.equal(_pos) && d3_view_camera.focus.equal(targ)) + d3_active_transition = 0; + } else { + d3_view_camera.position.set(_pos); + d3_view_camera.focus.set(targ); + } + + d3_view_camera.setViewSize(w, h); + d3_view_camera.setMatrix(); + #endregion + + draw_clear(bg_color); + + gpu_set_texfilter(true); + shader_set(sh_rm_primitive); + var zm = 4 / d3_view_camera.focus_dist; + + shader_set_f("camRotation", [ d3_view_camera.focus_angle_y, -d3_view_camera.focus_angle_x, 0 ]); + shader_set_f("camScale", zm); + shader_set_f("camRatio", w / h); + shader_set_i("shapeAmount", 0); + + _env.apply(); + if(_obj) _obj.apply(); + + shader_set_i("drawBg", d3_drawBG); + shader_set_f("depthInt", 0); + + var _scale = zm / 2; + var _step = 1; + while(_scale > 32) { + _scale /= 2; + _step /= 2; + } + + shader_set_i("drawGrid", true); + shader_set_f("gridStep", _step); + shader_set_f("gridScale", zm / 2); + shader_set_f("axisBlend", 1.); + shader_set_f("viewRange", [ d3_view_camera.view_near, d3_view_camera.view_far ]); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, w, h); + shader_reset(); + gpu_set_texfilter(false); + + } #endregion + + function draw3D() { + var _node = getNodePreview(); + if(_node == noone) return; + + switch(d3_active) { + case NODE_3D.polygon : draw3DPolygon(_node); break; + case NODE_3D.sdf : draw3DSdf(_node); break; + } + } + + function drawPreviewOverlay() { #region + right_menu_y = toolbar_height - ui(4); + if(show_view_control == 2) { + if(d3_active) right_menu_y += ui(72); + else right_menu_y += ui(40); + } + + toolbar_draw = false; + + var _node = getNodePreview(); + + #region status texts (top right) + draw_set_text(f_p2, fa_right, fa_top, COLORS._main_text); + var _lh = line_get_height(); + + if(right_menu_x == 0) right_menu_x = w - ui(8); + + if(show_info) { + if(PANEL_PREVIEW == self) { + draw_set_color(COLORS._main_text_accent); + draw_text(right_menu_x, right_menu_y, __txt("Active")); + right_menu_y += _lh; + } + + var txt = $"{__txt("fps")} {fps}"; + if(PREFERENCES.panel_preview_show_real_fps) + txt += $" / {FPS_REAL}"; + + draw_set_color(fps >= PROJECT.animator.framerate? COLORS._main_text_sub : COLORS._main_value_negative); + draw_text(right_menu_x, right_menu_y, txt); + right_menu_y += _lh; + + draw_set_color(COLORS._main_text_sub); + draw_text(right_menu_x, right_menu_y, $"{__txt("Frame")} {CURRENT_FRAME + 1}/{TOTAL_FRAMES}"); + + if(d3_active == NODE_3D.none) { + right_menu_y += _lh; + draw_text(right_menu_x, right_menu_y, $"x{canvas_s}"); + + if(pHOVER) { + right_menu_y += _lh; + var mpx = floor((mx - canvas_x) / canvas_s); + var mpy = floor((my - canvas_y) / canvas_s); + draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]"); + + if(mouse_pos_string != "") { + right_menu_y += _lh; + draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}"); + } + } + + if(_node != noone) { + right_menu_y += _lh; + var txt = $"{canvas_w} x {canvas_h}px"; + if(canvas_a) txt = $"{canvas_a} x {txt}"; + + draw_text(right_menu_x, right_menu_y, txt); + + right_menu_x = w - ui(8); + right_menu_y += _lh; + } + } + + mouse_pos_string = ""; + } + + right_menu_x = w - ui(8); + + #endregion + + var pseq = getNodePreviewSequence(); + if(pseq == noone) return; + + if(!array_equals(pseq, _preview_sequence)) { + _preview_sequence = pseq; + preview_x = 0; + preview_x_to = 0; + } + + var prev_size = ui(48); + preview_x = lerp_float(preview_x, preview_x_to, 4); + + if(pHOVER && my > h - toolbar_height - prev_size - ui(16) && my > toolbar_height) { + canvas_hover = false; + + if(mouse_wheel_down() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to - prev_size * SCROLL_SPEED, - preview_x_max, 0); + if(mouse_wheel_up() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to + prev_size * SCROLL_SPEED, - preview_x_max, 0); + } + + #region surface array + preview_x_max = 0; + + if(array_length(pseq) > 1) { + var _xx = tool_side_draw_l * ui(40); + var xx = _xx + preview_x + ui(8); + var yy = h - toolbar_height - prev_size - ui(8); + + if(my > yy - 8) mouse_on_preview = 0; + var hoverable = pHOVER && point_in_rectangle(mx, my, _xx, ui(32), w, h - toolbar_height); + + for(var i = 0; i < array_length(pseq); i++) { + var prev = pseq[i]; + if(is_instanceof(prev, __d3dMaterial)) + prev = prev.surface; + if(!is_surface(prev)) continue; + + var prev_w = surface_get_width_safe(prev); + var prev_h = surface_get_height_safe(prev); + var ss = prev_size / max(prev_w, prev_h); + var prev_sw = prev_w * ss; + + draw_set_color(COLORS.panel_preview_surface_outline); + draw_rectangle(xx, yy, xx + prev_w * ss, yy + prev_h * ss, true); + + if(hoverable && point_in_rectangle(mx, my, xx, yy, xx + prev_sw, yy + prev_h * ss)) { + if(mouse_press(mb_left, pFOCUS)) { + _node.preview_index = i; + _node.onValueUpdate(0); + if(resetViewOnDoubleClick) + do_fullView = true; + } + draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 1); + } else { + draw_surface_ext_safe(prev, xx, yy, ss, ss, 0, c_white, 0.5); + } + + if(i == _node.preview_index) { + draw_set_color(COLORS._main_accent); + draw_rectangle(xx, yy, xx + prev_sw, yy + prev_h * ss, true); + } + + xx += prev_sw + ui(8); + preview_x_max += prev_sw + ui(8); + } + } + #endregion + + preview_x_max = max(preview_x_max - ui(100), 0); + } #endregion + + function drawViewController() { + if(!show_view_control) return; + + var _side = show_view_control == 1? 1 : -1; + var _view_x = show_view_control == 1? + tool_side_draw_l * toolbar_width + ui(8) : + w - tool_side_draw_r * toolbar_width - ui(8); + var _view_y = topbar_height + ui(8); + var _hab = pHOVER && tool_hovering == noone && !view_pan_tool && !view_zoom_tool; + view_hovering = false; + + if(d3_active) { + var d3_view_wr = ui(32); + + var _d3x = _view_x + d3_view_wr * _side; + var _d3y = _view_y + d3_view_wr; + var _hv = false; + + if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wr)) { + _hv = true; + view_hovering = true; + + if(mouse_press(mb_left, pFOCUS)) { + canvas_drag_key = mb_left; + d3_camPanning = true; + d3_camPan_mx = mx; + d3_camPan_my = my; + + view_pan_tool = true; + } + } + + if(view_pan_tool) + _hv = true; + + draw_circle_ui(_d3x, _d3y, d3_view_wr, _hv? 0 : 0.02, COLORS._main_icon, 0.3); + + var _qview = new BBMOD_Quaternion().FromEuler(d3_view_camera.focus_angle_y, -d3_view_camera.focus_angle_x, 0); + var _as = [ + new BBMOD_Vec3(-1, 0, 0), + new BBMOD_Vec3(0, 0, 1), + new BBMOD_Vec3(0, -1, 0), + ]; + + for(var i = 0; i < 3; i++) { + _as[i] = _qview.Rotate(_as[i]); + + draw_set_color(COLORS.axis[i]); + draw_line_round(_d3x, _d3y, _d3x + _as[i].X * (d3_view_wr * 0.75), _d3y + _as[i].Y * (d3_view_wr * 0.75), 3); + } + + var d3_view_wz = ui(16); + var _d3x = _view_x + (d3_view_wr * 2 + ui(20)) * _side; + var _d3y = _view_y + d3_view_wz; + var _hv = false; + + if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { + _hv = true; + view_hovering = true; + + if(mouse_press(mb_left, pFOCUS)) { + canvas_drag_key = mb_left; + canvas_zooming = true; + canvas_zoom_m = my; + view_zoom_tool = true; + } + } + + if(view_zoom_tool) + _hv = true; + + draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); + draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1); + + } else { + var d3_view_wz = ui(16); + + var _d3x = _view_x + d3_view_wz * _side; + var _d3y = _view_y + d3_view_wz; + var _hv = false; + + if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { + _hv = true; + view_hovering = true; + + if(mouse_press(mb_left, pFOCUS)) { + canvas_drag_key = mb_left; + canvas_dragging = true; + canvas_drag_mx = mx; + canvas_drag_my = my; + canvas_drag_sx = canvas_x; + canvas_drag_sy = canvas_y; + + view_pan_tool = true; + } + } + + if(view_pan_tool) + _hv = true; + + draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); + draw_sprite_ui(THEME.view_pan, 0, _d3x, _d3y, 1, 1, 0, view_pan_tool? COLORS._main_accent : COLORS._main_icon, 1); + + _d3x += (d3_view_wz + ui(4) + d3_view_wz) * _side; + _d3y = _view_y + d3_view_wz; + _hv = false; + + if(_hab && point_in_circle(mx, my, _d3x, _d3y, d3_view_wz)) { + _hv = true; + view_hovering = true; + + if(mouse_press(mb_left, pFOCUS)) { + canvas_drag_key = mb_left; + canvas_zooming = true; + canvas_zoom_mx = w / 2; + canvas_zoom_my = h / 2; + canvas_zoom_m = my; + canvas_zoom_s = canvas_s; + + view_zoom_tool = true; + } + } + + if(view_zoom_tool) + _hv = true; + + draw_circle_ui(_d3x, _d3y, d3_view_wz, _hv? 0 : 0.04, COLORS._main_icon, 0.3); + draw_sprite_ui(THEME.view_zoom, 0, _d3x, _d3y, 1, 1, 0, view_zoom_tool? COLORS._main_accent : COLORS._main_icon, 1); + } + } + + function drawNodeTools(active, _node) { #region + var _mx = mx; + var _my = my; + var overHover = pHOVER && mouse_on_preview == 1; + var tool_size = ui(32); + + var cx = canvas_x + _node.preview_x * canvas_s; + var cy = canvas_y + _node.preview_y * canvas_s; + var _snx = 0, _sny = 0; + + tool_side_draw_l = _node.tools != -1; + tool_side_draw_r = _node.rightTools != -1; + + if(_node.tools != -1 && point_in_rectangle(_mx, _my, 0, 0, toolbar_width, h)) { + overHover = false; + mouse_on_preview = 0; + } + + overHover &= !view_hovering; + overHover &= tool_hovering == noone && !overlay_hovering; + overHover &= !canvas_dragging && !canvas_zooming; + overHover &= point_in_rectangle(mx, my, (_node.tools != -1) * toolbar_width, toolbar_height, w, h - toolbar_height); + + var overActive = active && overHover; + + var params = { w, h, toolbar_height }; + var mouse_free = false; + + if(_node.is_3D == NODE_3D.none) { + if(key_mod_press(CTRL)) { + _snx = PROJECT.previewGrid.show? PROJECT.previewGrid.size[0] : 1; + _sny = PROJECT.previewGrid.show? PROJECT.previewGrid.size[1] : 1; + } else if(PROJECT.previewGrid.snap) { + _snx = PROJECT.previewGrid.size[0]; + _sny = PROJECT.previewGrid.size[1]; + } + + mouse_free = _node.drawOverlay(overHover, overActive, cx, cy, canvas_s, _mx, _my, _snx, _sny, params); + + } else { + if(key_mod_press(CTRL) || d3_tool_snap) { + _snx = d3_tool_snap_position; + _sny = d3_tool_snap_rotation; + } + + mouse_free = _node.drawOverlay3D(overActive, d3_scene, _mx, _my, _snx, _sny, params); + } + + #region node overlay + overlay_hovering = false; + + if(_node.drawPreviewToolOverlay(pHOVER, pFOCUS, _mx, _my, { x, y, w, h, toolbar_height, + x0: _node.tools == -1? 0 : ui(40), + x1: w, + y0: toolbar_height - ui(8), + y1: h - toolbar_height + })) { + canvas_hover = false; + overlay_hovering = true; + } + #endregion + + var _tool = tool_hovering; + tool_hovering = noone; + + if(_node.tools == -1) { + tool_current = noone; + return; + } + + var aa = d3_active? 0.8 : 1; + draw_sprite_stretched_ext(THEME.tool_side, 1, 0, ui(32), toolbar_width, h - toolbar_height - ui(32), c_white, aa); + + tool_y_max = 0; + tool_y = lerp_float(tool_y, tool_y_to, 5); + var xx = ui(1) + toolbar_width / 2; + var yy = ui(34) + tool_size / 2 + tool_y; + var pd = 2; + var thov = pHOVER && point_in_rectangle(mx, my, 0, toolbar_height, toolbar_width, h - toolbar_height); + if(thov) canvas_hover = false; + + for(var i = 0; i < array_length(_node.tools); i++) { #region left tools + var tool = _node.tools[i]; + var _x0 = xx - tool_size / 2; + var _y0 = yy - tool_size / 2; + var _x1 = xx + tool_size / 2; + var _y1 = yy + tool_size / 2; + + if(tool == -1) { + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); + + yy += ui(8); + tool_y_max += ui(8); + continue; + } + + if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) + tool_hovering = tool; + + if(tool.subtools > 0 && _tool == tool) { #region hovering subtools + var s_ww = tool_size * tool.subtools; + var s_hh = tool_size; + draw_sprite_stretched(THEME.s_box_r2_clr, 0, _x0 - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); + + var stool = tool.spr; + + for( var j = 0; j < array_length(stool); j++ ) { + var _sxx = xx + j * tool_size; + var _syy = yy; + + var _sx0 = _sxx - tool_size / 2; + var _sy0 = _syy - tool_size / 2; + var _sx1 = _sxx + tool_size / 2; + var _sy1 = _syy + tool_size / 2; + + if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { + TOOLTIP = tool.getDisplayName(j); + draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(j); + } + + if(tool_current == tool && tool.selecting == j) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + + draw_sprite_colored(stool[j], 0, _sxx, _syy); + } + + if(point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x0 + s_ww, _y1 - 1)) + tool_hovering = tool; + #endregion + + } else { #region single tools + if(tool_hovering == tool) { + draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2); + TOOLTIP = tool.getDisplayName(); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(); + } + + if(pFOCUS && WIDGET_CURRENT == noone) { + var _key = tool.checkHotkey(); + + if(keyboard_check_pressed(ord(string(i + 1))) || (_key != noone && _key.isPressing())) + tool.toggleKeyboard(); + } + + if(tool_current == tool) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + + if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); + else draw_sprite_colored(tool.spr, 0, xx, yy); + #endregion + } + + yy += tool_size; + tool_y_max += tool_size; + } #endregion + + var _h = _node.drawTools == noone? 0 : _node.drawTools(_mx, _my, xx, yy - tool_size / 2, tool_size, thov, pFOCUS); + yy += _h; + tool_y_max += _h; + + tool_y_max = max(0, tool_y_max - h + toolbar_height * 2); + if(thov && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_y_to = clamp(tool_y_to + ui(64) * SCROLL_SPEED, -tool_y_max, 0); + if(mouse_wheel_down()) tool_y_to = clamp(tool_y_to - ui(64) * SCROLL_SPEED, -tool_y_max, 0); + } + + if(_node.rightTools != -1) { + right_menu_x = w - toolbar_width - ui(8); + tool_ry_max = 0; + tool_ry = lerp_float(tool_ry, tool_ry_to, 5); + + var _tbx = w - toolbar_width; + var xx = _tbx + toolbar_width / 2; + var yy = ui(34) + tool_size / 2 + tool_ry; + + var _sw = -toolbar_width / sprite_get_width(THEME.tool_side); + var _sh = h - toolbar_height - ui(32) / sprite_get_height(THEME.tool_side); + + draw_sprite_ext(THEME.tool_side, 1, w + 1, ui(32), _sw, _sh, 0, c_white, aa); + + var thov = pHOVER && point_in_rectangle(mx, my, _tbx, toolbar_height, w, h - toolbar_height); + if(thov) canvas_hover = false; + + for(var i = 0; i < array_length(_node.rightTools); i++) { #region right tools + var tool = _node.rightTools[i]; + var _x0 = xx - tool_size / 2; + var _y0 = yy - tool_size / 2; + var _x1 = xx + tool_size / 2; + var _y1 = yy + tool_size / 2; + + if(tool == -1) { + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); + + yy += ui(8); + tool_ry_max += ui(8); + continue; + } + + if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) + tool_hovering = tool; + + if(tool.subtools > 0 && _tool == tool) { #region hovering subtools + + var stool = tool.spr; + var s_ww = tool_size * tool.subtools; + var s_hh = tool_size; + var tx = _x0 - s_ww + tool_size; + draw_sprite_stretched(THEME.s_box_r2_clr, 0, tx - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); + + var _am = array_length(stool); + + for( var j = 0; j < _am; j++ ) { + var _sind = _am - 1 - j; + var _sxx = tx + j * tool_size + tool_size / 2; + var _syy = yy; + + var _sx0 = _sxx - tool_size / 2; + var _sy0 = _syy - tool_size / 2; + var _sx1 = _sxx + tool_size / 2; + var _sy1 = _syy + tool_size / 2; + + draw_sprite_colored(stool[_sind], 0, _sxx, _syy); + + if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { + TOOLTIP = tool.getDisplayName(_sind); + draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(_sind); + } + + if(tool_current == tool && tool.selecting == _sind) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + } + + if(point_in_rectangle(_mx, _my, tx, _y0 + 1, tx + s_ww, _y1 - 1)) + tool_hovering = tool; + #endregion + } else { #region single tools + if(tool_hovering == tool) { + draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2); + TOOLTIP = tool.getDisplayName(); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(); + } + + if(pFOCUS && WIDGET_CURRENT == noone) { + var _key = tool.checkHotkey(); + if(keyboard_check_pressed(ord(string(i + 1))) || (_key != noone && _key.isPressing())) + tool.toggleKeyboard(); + } + + if(tool_current == tool) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + + if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); + else draw_sprite_colored(tool.spr, 0, xx, yy); + #endregion + } + + yy += tool_size; + tool_ry_max += tool_size; + } #endregion + + tool_ry_max = max(0, tool_ry_max - h + toolbar_height * 2); + if(thov && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_ry_to = clamp(tool_ry_to + ui(64) * SCROLL_SPEED, -tool_ry_max, 0); + if(mouse_wheel_down()) tool_ry_to = clamp(tool_ry_to - ui(64) * SCROLL_SPEED, -tool_ry_max, 0); + } + } + } #endregion + + function drawToolBar(_tool, _node) { + var ty = h - toolbar_height; + var aa = d3_active? 0.8 : 1; + draw_sprite_stretched_ext(THEME.toolbar, 1, 0, 0, w, topbar_height, c_white, aa); + draw_sprite_stretched_ext(THEME.toolbar, 0, 0, ty, w, toolbar_height, c_white, aa); + + if(_tool && tool_current != noone) { // tool settings + var settings = array_merge(_tool.getToolSettings(), tool_current.settings); + + tool_x = lerp_float(tool_x, tool_x_to, 5); + var tolx = tool_x + ui(8); + var toly = ui(8); + var tolw = ui(48); + var tolh = toolbar_height - ui(20); + var tol_max_w = ui(16); + + for( var i = 0, n = array_length(settings); i < n; i++ ) { + var sett = settings[i]; + var nme = sett[0]; + var wdg = sett[1]; + var key = sett[2]; + var atr = sett[3]; + + if(nme != "") { + tolx += ui(8) + bool(i == 0) * ui(8); + tol_max_w += ui(8) + bool(i == 0) * ui(8); + } + + draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub); + if(nme != "") { + draw_text(tolx, toolbar_height / 2 - ui(2), nme); + tolx += string_width(nme) + ui(8); + tol_max_w += string_width(nme) + ui(8); + } + + wdg.setFocusHover(pFOCUS, pHOVER); + var _tool_font = f_p3; + + switch(instanceof(wdg)) { + case "textBox" : + tolw = ui(40); + if(wdg.side_button != noone) tolw += tolh + ui(8); + break; + + case "buttonGroup": + case "checkBoxGroup" : + tolw = tolh * wdg.size; + break; + + case "checkBox" : + tolw = tolh; + break; + + case "scrollBox" : + tolw = ui(96); + _tool_font = f_p2; + break; + + case "buttonClass" : + tolw = wdg.text == ""? tolh : tolw; + break; + } + + var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) + params.s = tolh; + params.font = _tool_font; + + wdg.drawParam(params); + + tolx += tolw + ui(8); + tol_max_w += tolw + ui(8); + } + + tol_max_w = max(0, tol_max_w - w); + if(point_in_rectangle(mx, my, 0, 0, w, toolbar_height) && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_x_to = clamp(tool_x_to + ui(64) * SCROLL_SPEED, -tol_max_w, 0); + if(mouse_wheel_down()) tool_x_to = clamp(tool_x_to - ui(64) * SCROLL_SPEED, -tol_max_w, 0); + } + + } else { // color sampler + var cx = ui(8); + var cy = ui(8); + var cw = ui(32); + var ch = topbar_height - ui(16); + + if(sample_color != noone) { + draw_set_color(sample_color); + draw_set_alpha(1); + draw_rectangle(cx, cy, cx + cw, cy + ch, false); + } + + draw_set_color(COLORS.panel_toolbar_outline); + draw_rectangle(cx, cy, cx + cw, cy + ch, true); + + if(sample_color != noone) { + var tx = cx + cw + ui(16); + var hx = color_get_hex(sample_color); + draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + draw_text(tx, cy + ch / 2, hx); + + tx += string_width(hx) + ui(8); + draw_set_color(COLORS._main_text_sub); + draw_text(tx, cy + ch / 2, $"({color_get_alpha(sample_color)})"); + } + } + + var tbx = toolbar_height / 2; + var tby = ty + toolbar_height / 2; + + var _toolbars = toolbars; + + switch(d3_active) { + case NODE_3D.none : _toolbars = toolbars; break; + case NODE_3D.polygon : _toolbars = toolbars_3d; break; + case NODE_3D.sdf : _toolbars = toolbars_3d_sdf; break; + } + + for( var i = 0, n = array_length(_toolbars); i < n; i++ ) { + var tb = _toolbars[i]; + var tbSpr = tb[0]; + var tbInd = tb[1](); + var tbTooltip = tb[2](); + var tbActive = tb[3]; + + var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbInd); + if(b == 2) tbActive( { x: x + tbx - ui(14), y: y + tby - ui(14) } ); + + tbx += ui(32); + } + + tbx = w - toolbar_height / 2; + for( var i = 0, n = array_length(actions); i < n; i++ ) { + var tb = actions[i]; + var tbSpr = tb[0]; + var tbTooltip = tb[1]; + var tbIndex = tb[3](); + + var b = buttonInstant(THEME.button_hide, tbx - ui(14), tby - ui(14), ui(28), ui(28), [mx, my], pFOCUS, pHOVER, tbTooltip, tbSpr, tbIndex); + if(b == 2) tb[2]( { x: x + tbx - ui(14), y: y + tby - ui(14) } ); + + tbx -= ui(32); + } + + draw_set_color(COLORS.panel_toolbar_separator); + draw_line_width(tbx + ui(12), tby - toolbar_height / 2 + ui(8), tbx + ui(12), tby + toolbar_height / 2 - ui(8), 2); + + var _nodeRaw = __getNodePreview(); + if(_nodeRaw) tbx -= drawNodeChannel(_nodeRaw, tbx, tby); + } + + function drawSplitView() { #region + if(splitView == 0) return; + + draw_set_color(COLORS.panel_preview_split_line); + + if(splitViewDragging) { + if(splitView == 1) { + var cx = splitViewStart + (mx - splitViewMouse); + splitPosition = clamp(cx / w, .1, .9); + } else if(splitView == 2) { + var cy = splitViewStart + (my - splitViewMouse); + splitPosition = clamp(cy / h, .1, .9); + } + + if(mouse_release(mb_left)) + splitViewDragging = false; + } + + if(splitView == 1) { + var sx = w * splitPosition; + + if(mouse_on_preview && point_in_rectangle(mx, my, sx - ui(4), 0, sx + ui(4), h)) { + draw_line_width(sx, 0, sx, h, 2); + if(mouse_press(mb_left, pFOCUS)) { + splitViewDragging = true; + splitViewStart = sx; + splitViewMouse = mx; + } + } else + draw_line_width(sx, 0, sx, h, 1); + + draw_sprite_ui_uniform(THEME.icon_active_split, 0, splitSelection? sx + ui(16) : sx - ui(16), toolbar_height + ui(16),, COLORS._main_accent); + + if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(mx, my, 0, 0, sx, h)) + splitSelection = 0; + else if(point_in_rectangle(mx, my, sx, 0, w, h)) + splitSelection = 1; + } + } else { + var sy = h * splitPosition; + + if(mouse_on_preview && point_in_rectangle(mx, my, 0, sy - ui(4), w, sy + ui(4))) { + draw_line_width(0, sy, w, sy, 2); + if(mouse_press(mb_left, pFOCUS)) { + splitViewDragging = true; + splitViewStart = sy; + splitViewMouse = my; + } + } else + draw_line_width(0, sy, w, sy, 1); + draw_sprite_ui_uniform(THEME.icon_active_split, 0, ui(16), splitSelection? sy + ui(16) : sy - ui(16),, COLORS._main_accent); + + if(mouse_on_preview && mouse_press(mb_left, pFOCUS)) { + if(point_in_rectangle(mx, my, 0, 0, w, sy)) + splitSelection = 0; + else if(point_in_rectangle(mx, my, 0, sy, w, h)) + splitSelection = 1; + } + } + } #endregion + + function drawContent(panel) { #region >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> MAIN DRAW <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + mouse_on_preview = pHOVER && point_in_rectangle(mx, my, 0, topbar_height, w, h - toolbar_height); + + if(do_fullView) run_in(1, fullView); + do_fullView = false; + + var _prev_node = getNodePreview(); + d3_active = _prev_node == noone? NODE_3D.none : _prev_node.is_3D; + bg_color = lerp_color(bg_color, d3_active? COLORS.panel_3d_bg : COLORS.panel_bg_clear, 0.3); + + draw_clear(bg_color); + if(canvas_bg == -1) { + if(canvas_s >= 0.1) draw_sprite_tiled_ext(s_transparent, 0, canvas_x, canvas_y, canvas_s, canvas_s, COLORS.panel_preview_transparent, 1); + } else + draw_clear(canvas_bg); + + draw_set_color(COLORS._main_icon_dark); + draw_line_width(canvas_x, 0, canvas_x, h, 1); + draw_line_width(0, canvas_y, w, canvas_y, 1); + + title = __txt("Preview"); + + getPreviewData(); + + if(_prev_node) { + if(d3_active) { + dragCanvas3D(); + draw3D(); + } else { + dragCanvas(); + drawNodePreview(); + } + } else dragCanvas(); + + drawPreviewOverlay(); + + var inspect_node = PANEL_INSPECTOR.getInspecting(); + var tool = noone; + + drawViewController(); + + tool_side_draw_l = false; + tool_side_draw_r = false; + + if(PANEL_PREVIEW == self) { + if(inspect_node) { + tool = inspect_node.getTool(); + if(tool) drawNodeTools(pFOCUS, tool); + } else + tool_current = noone; + } + + if(d3_active == NODE_3D.none) drawSplitView(); + + drawToolBar(tool, _prev_node); + + if(mouse_on_preview && mouse_press(mb_right, pFOCUS) && !key_mod_press(SHIFT)) { + menuCall("preview_context_menu",,, [ + MENU_ITEMS.preview_new_preview_window, + -1, + MENU_ITEMS.preview_save_current_frame, + MENU_ITEMS.preview_save_all_current_frames, + -1, + MENU_ITEMS.preview_copy_current_frame, + MENU_ITEMS.preview_copy_color, + MENU_ITEMS.preview_copy_color_hex, + ],, getNodePreview()); + } + + ////////////////////////////////// File drop ////////////////////////////////// + + if(pHOVER) { + var _node = getNodePreview(); + + if(_node && _node.dropPath != noone) { + + if(DRAGGING && DRAGGING.type == "Asset") { + draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1); + + if(mouse_release(mb_left)) + _node.dropPath(DRAGGING.data.path); + } + + if(FILE_IS_DROPPING) + draw_sprite_stretched_ext(THEME.ui_panel_selection, 0, 8, 8, w - 16, h - 16, COLORS._main_value_positive, 1); + + if(FILE_DROPPED && !array_empty(FILE_DROPPING)) + _node.dropPath(FILE_DROPPING[0]); + } + } + + } #endregion + + ////=========== ACTION =========== + + function copyCurrentFrame() { #region + var prevS = getNodePreviewSurface(); + if(!is_surface(prevS)) return; + + var buff = buffer_create(surface_get_width_safe(prevS) * surface_get_height_safe(prevS) * 4, buffer_fixed, 1); + var s = surface_create(surface_get_width_safe(prevS), surface_get_height_safe(prevS)); + + surface_set_target(s); + shader_set(sh_BGR); + draw_surface_safe(prevS); + shader_reset(); + surface_reset_target(); + + buffer_get_surface(buff, s, 0); + surface_free(s); + + clipboard_set_bitmap(buffer_get_address(buff), surface_get_width_safe(prevS), surface_get_height_safe(prevS)); + } #endregion + + function saveCurrentFrameToFocus() { #region + var prevS = getNodePreviewSurface(); + + if(!is_surface(prevS)) return; + if(!is_struct(PANEL_FILE)) return; + + var _fileO = PANEL_FILE.file_focus; + if(_fileO == noone) return; + + var path = _fileO.path; + if(path == "") return; + + if(filename_ext(path) != ".png") path += ".png"; + + surface_save_safe(prevS, path); + _fileO.refreshThumbnail(); + } #endregion + + function saveCurrentFrame() { #region + var prevS = getNodePreviewSurface(); + var _node = getNodePreview(); + + if(_node == noone) return; + if(!is_surface(prevS)) return; + + var path = get_save_filename_pxc("image|*.png;*.jpg", _node.display_name == ""? "export" : _node.display_name, "Save surface as"); + key_release(); + + if(path == "") return; + if(filename_ext(path) != ".png") path += ".png"; + + surface_save_safe(prevS, path); + } #endregion + + function saveAllCurrentFrames() { #region + var _node = getNodePreview(); + + if(_node == noone) return; + + var path = get_save_filename_pxc("image|*.png;*.jpg", _node.display_name == ""? "export" : _node.display_name, "Save surfaces as"); + key_release(); + + if(path == "") return; + + var ext = ".png"; + var name = string_replace_all(path, ext, ""); + var ind = 0; + + var pseq = getNodePreviewSequence(); + for(var i = 0; i < array_length(pseq); i++) { + var prev = pseq[i]; + if(!is_surface(prev)) continue; + var _name = name + string(ind) + ext; + surface_save_safe(prev, _name); + ind++; + } + } #endregion + + //// =========== Serialize =========== + + static serialize = function() { + return { + name: instanceof(self), + preview_node : [ node_get_id(preview_node[0]), node_get_id(preview_node[1]) ], + + canvas_x, + canvas_y, + canvas_s, + + locked, + }; + } + + static deserialize = function(data) { + if(struct_has(data, "preview_node")) + preview_node = [ node_from_id(data.preview_node[0]), node_from_id(data.preview_node[1]) ]; + + canvas_x = struct_try_get(data, "canvas_x", canvas_x); + canvas_y = struct_try_get(data, "canvas_y", canvas_y); + canvas_s = struct_try_get(data, "canvas_s", canvas_s); + + locked = struct_try_get(data, "locked", locked); + + run_in(1, fullView) + return self; + } + } \ No newline at end of file diff --git a/scripts/panel_preview_window/panel_preview_window.gml b/scripts/panel_preview_window/panel_preview_window.gml index 377c243bb..43dc8f892 100644 --- a/scripts/panel_preview_window/panel_preview_window.gml +++ b/scripts/panel_preview_window/panel_preview_window.gml @@ -4,6 +4,12 @@ function panel_preview_window_reset() { CHECK_PANEL_PREVIEW_WINDOW CALL("preview function panel_preview_window_inspect() { CHECK_PANEL_PREVIEW_WINDOW CALL("preview_window_inspect"); PANEL_GRAPH.nodes_selecting = [ FOCUS_CONTENT.node_target ]; } function panel_preview_window_preview() { CHECK_PANEL_PREVIEW_WINDOW CALL("preview_window_preview"); PANEL_PREVIEW.setNodePreview(FOCUS_CONTENT.node_target); } +function __fnInit_Preview_Window() { + registerFunction("Preview Window", "Reset view", "", MOD_KEY.none, panel_preview_window_reset ).setMenu("preview_window_reset_view") + registerFunction("Preview Window", "Inspect", "", MOD_KEY.none, panel_preview_window_inspect ).setMenu("preview_window_inspect") + registerFunction("Preview Window", "Preview", "", MOD_KEY.none, panel_preview_window_preview ).setMenu("preview_window_preview") +} + function Panel_Preview_Window() : PanelContent() constructor { min_w = ui(64); min_h = ui(64); @@ -54,15 +60,11 @@ function Panel_Preview_Window() : PanelContent() constructor { content_surface = noone; surfaceCheck(); - registerFunction("Preview Window", "Reset view", "", MOD_KEY.none, panel_preview_window_reset); - registerFunction("Preview Window", "Inspect", "", MOD_KEY.none, panel_preview_window_inspect); - registerFunction("Preview Window", "Preview", "", MOD_KEY.none, panel_preview_window_preview); - menu = [ - menuItemAction(__txtx("reset_view", "Reset view"), panel_preview_window_reset), + MENU_ITEMS.preview_window_reset_view, -1, - menuItemAction(__txt("Inspect"), panel_preview_window_inspect), - menuItemAction(__txtx("panel_graph_send_to_preview", "Send to preview"), panel_preview_window_preview), + MENU_ITEMS.preview_window_inspect, + MENU_ITEMS.preview_window_preview, -1, ] @@ -161,7 +163,7 @@ function Panel_Preview_Window() : PanelContent() constructor { var o = node_target.outputs[i]; if(o.type != VALUE_TYPE.surface) continue; - array_push(_menu, menuItemAction(o.name, function(_dat) { changeChannel(_dat.index); })); + array_push(_menu, menuItem(o.name, function(_dat) { changeChannel(_dat.index); })); } menuCall("preview_window_menu",,, _menu,, node_target); } diff --git a/scripts/panel_workspace/panel_workspace.gml b/scripts/panel_workspace/panel_workspace.gml index 85c241cb4..010a8761d 100644 --- a/scripts/panel_workspace/panel_workspace.gml +++ b/scripts/panel_workspace/panel_workspace.gml @@ -103,9 +103,9 @@ function Panel_Workspace() : PanelContent() constructor { if(mouse_press(mb_right, pFOCUS)) { layout_selecting = str; menuCall("workspace_menu",,, [ - menuItemAction(__txt("Select"), apply_space), - menuItemAction(__txtx("workspace_replace_current", "Replace with current"), replace_space), - menuItemAction(__txt("Delete"), delete_space, THEME.cross), + menuItem(__txt("Select"), apply_space), + menuItem(__txtx("workspace_replace_current", "Replace with current"), replace_space), + menuItem(__txt("Delete"), delete_space, THEME.cross), ]); } }