diff --git a/#backups/objects/o_main/o_main.yy.backup0 b/#backups/objects/o_main/o_main.yy.backup0 new file mode 100644 index 000000000..176deb9fa --- /dev/null +++ b/#backups/objects/o_main/o_main.yy.backup0 @@ -0,0 +1,1603 @@ +// 2024-04-18 11:59:25 +#event properties (no comments/etc. here are saved) +parent_index = -1; +persistent = true; +uses_physics = false; + +#event create init +#region log + var path = "log_temp.txt"; + var f = file_text_open_append(path); + file_text_write_string(f, $"[MESSAGE] {_log_template()}session begin\n"); + file_text_close(f); + + gpu_set_tex_mip_enable(mip_off); + gc_enable(true); + gc_target_frame_time(100); +#endregion + +#region window + window_set_min_width(960); + window_set_min_height(600); + draw_set_circle_precision(64); + winManInit(); + + depth = 0; + win_wp = WIN_W; + win_hp = WIN_H; + win_resize = false; + + room_width = WIN_W; + room_height = WIN_H; + + DIALOG_DEPTH_HOVER = 0; + UPDATE = RENDER_TYPE.none; + CURSOR = cr_default; + CURSOR_LOCK = false; + CURSOR_IS_LOCK = false; + CURSOR_LOCK_X = 0; + CURSOR_LOCK_Y = 0; + TOOLTIP = ""; + DRAGGING = noone; + KEYBOARD_STRING = ""; + + RENDER_QUEUE = new Queue(); + RENDER_ORDER = []; + + globalvar AUTO_SAVE_TIMER; + AUTO_SAVE_TIMER = 0; + + _cursor = CURSOR; + dc_check = 0; + kb_time = 0; + kb_hold = false; + kb_hkey = 0; + + fpss = array_create(10); + fpsr = 0; + + _cursor_lock = false; + + watcher_surface = surface_create(1, 1); + + panelInit(); + + addHotkey("", "New file", "N", MOD_KEY.ctrl, NEW); + if(!DEMO) { + addHotkey("", "Save", "S", MOD_KEY.ctrl, SAVE); + addHotkey("", "Save as", "S", MOD_KEY.ctrl | MOD_KEY.shift, SAVE_AS); + addHotkey("", "Save all", "S", MOD_KEY.ctrl | MOD_KEY.alt, SAVE_ALL); + addHotkey("", "Open", "O", MOD_KEY.ctrl, LOAD); + } + + addHotkey("", "Undo", "Z", MOD_KEY.ctrl, UNDO); + addHotkey("", "Redo", "Z", MOD_KEY.ctrl | MOD_KEY.shift, REDO); + + addHotkey("", "Full panel", "`", MOD_KEY.none, set_focus_fullscreen); + addHotkey("", "Reset layout", vk_f10, MOD_KEY.ctrl, resetPanel); + + addHotkey("", "Open notification", vk_f12, MOD_KEY.none, function() { dialogPanelCall(new Panel_Notification()); }); + + addHotkey("", "Fullscreen", vk_f11, MOD_KEY.none, global_fullscreen); + addHotkey("", "Render all", vk_f5, MOD_KEY.none, global_render_all); + + addHotkey("", "Close file", "Q", MOD_KEY.ctrl, global_project_close); + addHotkey("", "Close program", vk_f4, MOD_KEY.alt, window_close); + addHotkey("", "Reload theme", vk_f10, MOD_KEY.ctrl | MOD_KEY.shift, global_theme_reload); + + globalvar HOTKEY_MOD, HOTKEY_BLOCK; + HOTKEY_MOD = 0; + HOTKEY_BLOCK = false; +#endregion + +#region Loader + globalvar GIF_READER; + + GIF_READER = ds_list_create(); + gif_complete_st = ds_stack_create(); +#endregion + +#region tunnel + globalvar TUNNELS_IN, TUNNELS_IN_MAP, TUNNELS_OUT; + TUNNELS_IN = ds_map_create(); + TUNNELS_IN_MAP = ds_map_create(); + TUNNELS_OUT = ds_map_create(); +#endregion + +#region add on callback + globalvar ANIMATION_PRE, ANIMATION_POST; + + ANIMATION_PRE = []; + ANIMATION_POST = []; + + function __addon_preAnim() { + for( var i = 0, n = array_length(ANIMATION_PRE); i < n; i++ ) + ANIMATION_PRE[i](); + } + + function __addon_postAnim() { + for( var i = 0, n = array_length(ANIMATION_POST); i < n; i++ ) + ANIMATION_POST[i](); + } +#endregion + +#region file drop + if(OS == os_windows) { + file_dropper_init(); + } else if(OS == os_macosx) { + file_dnd_set_hwnd(window_handle()); + file_dnd_set_enabled(true); + + _file_dnd_filelist = ""; + file_dnd_filelist = ""; + file_dnd_pattern = "*.*"; + file_dnd_allowfiles = true; + file_dnd_allowdirs = true; + file_dnd_allowmulti = true; + } + + drop_path = []; + + function load_file_path(path) { + if(!is_array(path)) path = [ path ]; + if(array_length(path) == 0) return; + + 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 = string_lower(filename_ext(p)); + + switch(ext) { + case ".txt" : + node = Node_create_Text_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".csv" : + node = Node_create_CSV_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".json" : + node = Node_create_Json_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".ase" : + case ".aseprite" : + node = Node_create_ASE_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".png" : + case ".jpg" : + case ".jpeg" : + node = Node_create_Image_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".gif" : + node = Node_create_Image_gif_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".obj" : + node = Node_create_3D_Obj_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".wav" : + node = Node_create_WAV_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".pxc" : + case ".cpxc" : + LOAD_PATH(p); + break; + case ".pxcc" : + APPEND(p); + break; + } + + if(!IS_CMD)PANEL_GRAPH.mouse_grid_y += 160; + } + + if(node && !IS_CMD) + PANEL_GRAPH.toCenterNode(); + } + } +#endregion + +#region undo + action_last_frame = []; +#endregion + +#region version + version_check = -1; + version_latest = 0; + + //if(os_is_network_connected()) { + // var version = "https://gist.githubusercontent.com/Ttanasart-pt/d9eefbda84a78863c122b8b155bc0cda/raw/version.txt"; + // version_check = http_get(version); + //} +#endregion + +#region parameter + minimized = false; + _modified = false; +#endregion + +#region dialog + globalvar DIALOGS, WIDGET_TAB_BLOCK; + DIALOGS = ds_list_create(); + WIDGET_TAB_BLOCK = false; + + instance_create(0, 0, o_dialog_textbox_autocomplete); + instance_create(0, 0, o_dialog_textbox_function_guide); +#endregion + +#region async + globalvar PORT_MAP, NETWORK_SERVERS, NETWORK_CLIENTS; + globalvar IMAGE_FETCH_MAP; + + global.FILE_LOAD_ASYNC = ds_map_create(); + PORT_MAP = ds_map_create(); + NETWORK_SERVERS = ds_map_create(); + NETWORK_CLIENTS = ds_map_create(); + + IMAGE_FETCH_MAP = ds_map_create(); + + asyncInit(); + + network_set_config(network_config_use_non_blocking_socket, 0); +#endregion + +#region steam + globalvar STEAM_ENABLED, STEAM_APP_ID, STEAM_USER_ID, STEAM_USERNAME; + globalvar STEAM_UGC_ITEM_UPLOADING, STEAM_UGC_ITEM_ID, STEAM_UGC_ITEM_FILE, STEAM_UGC_UPDATE_HANDLE; + globalvar STEAM_UGC_SUBMIT_ID, STEAM_UGC_UPDATE_MAP, STEAM_UGC_PUBLISH_ID, STEAM_UGC_UPDATE, STEAM_UGC_TYPE; + globalvar STEAM_SUB_ID; + + enum STEAM_UGC_FILE_TYPE { + collection, + project, + node_preset + } + + STEAM_UGC_TYPE = STEAM_UGC_FILE_TYPE.collection; + STEAM_SUB_ID = 0; + STEAM_USER_ID = 0; + STEAM_USERNAME = ""; + + STEAM_UGC_UPDATE_HANDLE = 0; + STEAM_UGC_ITEM_ID = 0; + STEAM_UGC_PUBLISH_ID = 0; + STEAM_UGC_SUBMIT_ID = 0; + STEAM_UGC_ITEM_UPLOADING = false; + STEAM_ENABLED = steam_initialised(); + STEAM_UGC_UPDATE = false; + STEAM_UGC_UPDATE_MAP = ds_map_create(); + + if(STEAM_ENABLED) { + STEAM_APP_ID = steam_get_app_id(); + STEAM_USER_ID = steam_get_user_account_id(); + STEAM_USERNAME = steam_get_persona_name(); + steam_set_warning_message_hook(); + } +#endregion + +#region physics + physics_world_update_iterations(100); +#endregion + +#region color selector + globalvar NODE_DROPPER_TARGET, NODE_DROPPER_TARGET_CAN, NODE_COLOR_SHOW_PALETTE; + NODE_DROPPER_TARGET = noone; + NODE_DROPPER_TARGET_CAN = false; + NODE_COLOR_SHOW_PALETTE = false; +#endregion + +#region draw + +#endregion + +#region 3D + globalvar USE_DEPTH; + _use_depth = noone; + USE_DEPTH = false; + + set3DGlobalPreview(); +#endregion + +#region debug + global.__debug_runner = 0; + __debug_animator_counter = 0; + + //instance_create(0, 0, o_video_banner, { title: "Trail effect" }); + //instance_create_depth(0, 0, -32000, FLIP_Domain); + //instance_create_depth(0, 0, -32000, FLIP_Domain); +#endregion + +#region server + globalvar TCP_SERVER, TCP_PORT, TCP_CLIENTS; + TCP_SERVER = false; + TCP_PORT = noone; + TCP_CLIENTS = []; + +#endregion + +#region arguments + #macro IS_CMD PROGRAM_ARGUMENTS._cmd + + alarm[1] = 2; + + globalvar PROGRAM_ARGUMENTS, CLI_EXPORT_AMOUNT; + + PROGRAM_ARGUMENTS = { + _path : "", + _cmd : false, + _run : false, + _rendering : false, + _exporting : [], + _persist : false, + _trusted: false, + _lua: true, + }; + + CLI_EXPORT_AMOUNT = 0; + + var paramCount = parameter_count(); + var paramType = "_path"; + var useTCP = false; + + for( var i = 0; i < paramCount; i++ ) { + var param = parameter_string(i); + //print($" >>> params {i}: {param}"); + + if(string_starts_with(param, "-")) { + switch(param) { + case "-c" : + case "--crashed" : + if(PREFERENCES.show_crash_dialog) + run_in(1, function() { dialogCall(o_dialog_crashed); }); + break; + + case "-h" : + case "--headless" : + PROGRAM_ARGUMENTS._cmd = true; + break; + + case "-p" : + case "--persist" : + PROGRAM_ARGUMENTS._persist = true; + break; + + case "-t" : + case "--trusted" : + PROGRAM_ARGUMENTS._trusted = true; + break; + + case "-s" : + case "--server" : + PROGRAM_ARGUMENTS._persist = true; + useTCP = true; + break; + + case "-sl" : + case "--skiplua" : + PROGRAM_ARGUMENTS._lua = false; + break; + + default : + paramType = string_trim(param, ["-"]); + break; + } + + } else if(paramType == "_path") { + var path = param; + path = string_replace_all(path, "\n", ""); + path = string_replace_all(path, "\"", ""); + + if(file_exists_empty(path) && (filename_ext(path) == ".pxc" || filename_ext(path) == ".cpxc")) + PROGRAM_ARGUMENTS._path = path; + + } else + PROGRAM_ARGUMENTS[$ paramType] = cmd_path(param); + } + + if(IS_CMD) { + draw_enable_drawevent(false); + log_console($"Running PixelComposer {VERSION_STRING}"); + + PROGRAM_ARGUMENTS._run = true; + PROGRAM_ARGUMENTS._rendering = true; + } + + if(file_exists_empty(PROGRAM_ARGUMENTS._path)) { + run_in(1, function() { load_file_path(PROGRAM_ARGUMENTS._path); }); + + } else if(IS_CMD) + game_end(); + + if(useTCP && struct_has(PROGRAM_ARGUMENTS, "port")) { + TCP_PORT = PROGRAM_ARGUMENTS.port; + TCP_SERVER = network_create_server_raw(network_socket_tcp, TCP_PORT, 32); + + log_console($"Open port: {TCP_PORT}"); + } +#endregion + +#event alarm1 init +#region prefload + __migration_check(); + + if(!file_exists_empty(PROGRAM_ARGUMENTS._path) && PREFERENCES.show_splash) + dialogCall(o_dialog_splash); +#endregion + +#event step init +if(winMan_isMinimized()) exit; +winManStep() + +//print("===== Step start ====="); + +if(PROJECT.active && !PROJECT.safeMode) { #region + PROJECT.animator.step(); + PROJECT.globalNode.step(); + LIVE_UPDATE = false; + + try { + if(PANEL_MAIN != 0) PANEL_MAIN.step(); + array_foreach(PROJECT.nodeArray, function(_node) { + if(!_node.active) return; + _node.triggerCheck(); + _node.step(); + }); + } catch(e) { + noti_warning("Step error: " + exception_print(e)); + } +} #endregion + +#region hotkey + HOTKEY_MOD = 0; + if(CTRL == KEYBOARD_STATUS.pressing) HOTKEY_MOD |= MOD_KEY.ctrl; + if(SHIFT == KEYBOARD_STATUS.pressing) HOTKEY_MOD |= MOD_KEY.shift; + if(ALT == KEYBOARD_STATUS.pressing) HOTKEY_MOD |= MOD_KEY.alt; + + if(!instance_exists(o_dialog_preference) && !HOTKEY_BLOCK) { + if(ds_map_exists(HOTKEYS, "")) { + var l = HOTKEYS[? ""]; + for(var i = 0; i < ds_list_size(l); i++) { + var hotkey = l[| i]; + if(hotkey.key == 0 && hotkey.modi == MOD_KEY.none) continue; + + if(key_press(hotkey.key, hotkey.modi)) { + hotkey.action(); + break; + } + } + } + + if(ds_map_exists(HOTKEYS, FOCUS_STR)) { + var list = HOTKEYS[? FOCUS_STR]; + for(var i = 0; i < ds_list_size(list); i++) { + var hotkey = list[| i]; + if(hotkey.key == 0 && hotkey.modi == MOD_KEY.none) continue; + + if(key_press(hotkey.key, hotkey.modi)) { + hotkey.action(); + break; + } + } + } + } + + HOTKEY_BLOCK = false; +#endregion + +#region GIF builder + for( var i = 0; i < ds_list_size(GIF_READER); i++ ) { + var _reader = GIF_READER[| i]; + + var _reading = _reader[0].reading(); + if(_reading) { + var ret = _reader[2]; + ret(new __gif_sprite_builder(_reader[0])); + ds_stack_push(gif_complete_st, i); + } + } + + while(!ds_stack_empty(gif_complete_st)) { + var i = ds_stack_pop(gif_complete_st); + buffer_delete(GIF_READER[| i][1]); + delete GIF_READER[| i][0]; + ds_list_delete(GIF_READER, i); + } +#endregion + +#region file drop + if(OS == os_windows) { + if(array_length(drop_path)) { + load_file_path(drop_path); + drop_path = []; + } + } else if(OS == os_macosx) { + file_dnd_set_files(file_dnd_pattern, file_dnd_allowfiles, file_dnd_allowdirs, file_dnd_allowmulti); + file_dnd_filelist = file_dnd_get_files(); + + if(file_dnd_filelist != "" && _file_dnd_filelist != file_dnd_filelist) { + var path = string_trim(file_dnd_filelist); + load_file_path(string_splice(path, "\n")); + } + + _file_dnd_filelist = file_dnd_filelist; + } +#endregion + +#region window + if(_modified != PROJECT.modified) { + _modified = PROJECT.modified; + + var cap = ""; + if(PROJECT.safeMode) cap += "[SAFE MODE] "; + if(PROJECT.readonly) cap += "[READ ONLY] "; + cap += PROJECT.path + (PROJECT.modified? "*" : "") + " - Pixel Composer"; + + window_set_caption(cap); + } +#endregion + +#region notification + if(!ds_list_empty(WARNING)) { + var rem = ds_stack_create(); + + for( var i = 0; i < ds_list_size(WARNING); i++ ) { + var w = WARNING[| i]; + if(--w.life <= 0) + ds_stack_push(rem, w); + } + + while(!ds_stack_empty(rem)) { + ds_list_delete(WARNING, ds_stack_pop(rem)); + } + + ds_stack_destroy(rem); + } +#endregion + +#region steam + steam_update(); + + if(STEAM_ENABLED) { + if (steam_is_screenshot_requested()) { + var file = "PixelComposer_" + string(irandom_range(100_000, 999_999)) + ".png"; + screen_save(file); + steam_send_screenshot(file, window_get_width(), window_get_height()); + } + } +#endregion + +#event step_begin init +global.__debug_runner++; +global.cache_call = 0; +global.cache_hit = 0; + +HOVERING_ELEMENT = _HOVERING_ELEMENT; +_HOVERING_ELEMENT = noone; + +#region minimize + if(winMan_isMinimized()) { + if(!minimized) game_set_speed(1, gamespeed_fps); + minimized = true; + exit; + } else if(!minimized) + window_preminimize_rect = [ window_get_x(), window_get_y(), window_get_width(), window_get_height() ]; + + if(minimized) { + game_set_speed(PREFERENCES.ui_framerate, gamespeed_fps); + window_set_rectangle(window_preminimize_rect[0], window_preminimize_rect[1], window_preminimize_rect[2], window_preminimize_rect[3]); + + minimized = false; + } +#endregion + +#region fpss + if(fpsr++ % 5 == 0) { + var ff = 0; + for( var i = 1; i < 10; i++ ) { + fpss[i] = fpss[i - 1] + ff += fpss[i]; + } + fpss[0] = fps_real; + ff += fps_real; + FPS_REAL = round(ff / 10); + } +#endregion + +#region window & mouse + //if(keyboard_check_pressed(vk_f12)) DEBUG = !DEBUG; + + if(_cursor != CURSOR) { + window_set_cursor(CURSOR); + _cursor = CURSOR; + } + CURSOR = cr_default; + + if(_cursor_lock != CURSOR_LOCK) { + window_mouse_set_locked(CURSOR_LOCK); + if(!CURSOR_LOCK) window_mouse_set(CURSOR_LOCK_X, CURSOR_LOCK_Y); + } + + _cursor_lock = CURSOR_LOCK; + CURSOR_IS_LOCK = CURSOR_LOCK; + CURSOR_LOCK = false; + + if(!is_surface(watcher_surface)) { + RENDER_ALL + watcher_surface = surface_create(1, 1); + } + + PEN_USE = false; + PEN_RELEASED = false; + PEN_RIGHT_PRESS = false; + PEN_RIGHT_RELEASE = false; + + if(!IS_CMD) tabletstuff_perform_event(id, ev_other, ev_user10); + + //print($"{PEN_RIGHT_CLICK} | {PEN_RIGHT_PRESS}, {PEN_RIGHT_RELEASE}"); + //print($"{mouse_x}, {mouse_y}"); +#endregion + +#region focus + if(mouse_release(mb_any)) DIALOG_CLICK = true; + + HOVER = noone; + with(_p_dialog) checkMouse(); + + if(PANEL_MAIN != 0) PANEL_MAIN.stepBegin(); + + DIALOG_DEPTH_HOVER = 0; + + with(_p_dialog) checkFocus(); + with(_p_dialog) checkDepth(); + + with(_p_dialog) doDrag(); + with(_p_dialog) doResize(); +#endregion + +#region auto save + AUTO_SAVE_TIMER += delta_time / 1_000_000; + + if(PROJECT.modified && PREFERENCES.auto_save_time > 0 && AUTO_SAVE_TIMER > PREFERENCES.auto_save_time) { + AUTO_SAVE_TIMER = 0; + var loc = DIRECTORY + "Autosave/"; + directory_verify(loc); + + var fname = string_replace(filename_name(PROJECT.path), filename_ext(PROJECT.path), "") + + "_autosave" + string(current_year) + "-" + + string_lead_zero(current_month, 2) + "-" + + string_lead_zero(current_day, 2) + "T" + + string_lead_zero(current_hour, 2) + + string_lead_zero(current_minute, 2) + + string_lead_zero(current_second, 2) + filename_ext(PROJECT.path); + + try { SAVE_AT(PROJECT, loc + fname, "Autosaved "); } + catch(e) { print(exception_print(e)); } + } +#endregion + +#region animation & render + DEF_SURFACE_RESET(); + + if(!PROJECT.safeMode && UPDATE_RENDER_ORDER) { + ResetAllNodesRender(); + NodeTopoSort(); + } + + if(LIVE_UPDATE) + Render(); + else if(!PROJECT.safeMode) { + UPDATE_RENDER_ORDER = false; + + if(PROJECT.active) { + PROJECT.animator.is_simulating = false; + array_foreach(PROJECT.nodeArray, function(_node) { if(!_node.active) return; _node.stepBegin(); }); + + if(PROGRAM_ARGUMENTS._run) { + if(PROJECT != noone && PROJECT.path != "") { + exportAll(); + PROGRAM_ARGUMENTS._run = false; + } + + } else if(IS_PLAYING || IS_RENDERING) { + if(PROJECT.animator.frame_progress) { + __addon_preAnim(); + + if(IS_FIRST_FRAME) + ResetAllNodesRender(); + + if(IS_CMD) Render(false); + else Render(true); + + __addon_postAnim(); + } + PROJECT.animator.frame_progress = false; + + } else { + if(UPDATE & RENDER_TYPE.full) + Render(); + + else if(UPDATE & RENDER_TYPE.partial) + Render(true); + + } + } + } + + if(PROGRAM_ARGUMENTS._rendering && PROGRAM_ARGUMENTS._run == false && array_empty(PROGRAM_ARGUMENTS._exporting)) { + log_console($"Export {CLI_EXPORT_AMOUNT} {CLI_EXPORT_AMOUNT > 1? "files" : "file"} completed"); + + if(PROGRAM_ARGUMENTS._persist) { + PROGRAM_ARGUMENTS._rendering = false; + cli_wait(); + } else + game_end(); + } + + UPDATE = RENDER_TYPE.none; +#endregion + +#region clicks + DOUBLE_CLICK = false; + if(mouse_press(mb_left)) { + if(dc_check > 0) { + if(point_distance(mouse_mx, mouse_my, DOUBLE_CLICK_POS[0], DOUBLE_CLICK_POS[1]) < 8) + DOUBLE_CLICK = true; + dc_check = 0; + } else { + dc_check = PREFERENCES.double_click_delay; + DOUBLE_CLICK_POS = [ mouse_mx, mouse_my ]; + } + } + + dc_check -= DELTA_TIME; +#endregion + +#region step + if(array_length(action_last_frame) > 0) { + ds_stack_push(UNDO_STACK, action_last_frame); + ds_stack_clear(REDO_STACK); + } + action_last_frame = []; +#endregion + +#region modifiers + if(CTRL == KEYBOARD_STATUS.up) + CTRL = KEYBOARD_STATUS.idle; + if(SHIFT == KEYBOARD_STATUS.up) + SHIFT = KEYBOARD_STATUS.idle; + if(ALT == KEYBOARD_STATUS.up) + ALT = KEYBOARD_STATUS.idle; + + if(CTRL == KEYBOARD_STATUS.pressing && !keyboard_check(vk_control)) + CTRL = KEYBOARD_STATUS.up; + + if(SHIFT == KEYBOARD_STATUS.pressing && !keyboard_check(vk_shift)) + SHIFT = KEYBOARD_STATUS.up; + + if(ALT == KEYBOARD_STATUS.pressing && !keyboard_check(vk_alt)) + ALT = KEYBOARD_STATUS.up; + + if(CTRL == KEYBOARD_STATUS.down) + CTRL = KEYBOARD_STATUS.pressing; + + if(SHIFT == KEYBOARD_STATUS.down) + SHIFT = KEYBOARD_STATUS.pressing; + + if(ALT == KEYBOARD_STATUS.down) + ALT = KEYBOARD_STATUS.pressing; + + if(keyboard_check_pressed(vk_control)) + CTRL = KEYBOARD_STATUS.down; + if(keyboard_check_pressed(vk_shift)) + SHIFT = KEYBOARD_STATUS.down; + if(keyboard_check_pressed(vk_alt)) + ALT = KEYBOARD_STATUS.down; + + if(keyboard_check_released(vk_control)) + CTRL = KEYBOARD_STATUS.up; + if(keyboard_check_released(vk_shift)) + SHIFT = KEYBOARD_STATUS.up; + if(keyboard_check_released(vk_alt)) + ALT = KEYBOARD_STATUS.up; +#endregion + +#region mouse wrap + MOUSE_WRAPPING = max(0, MOUSE_WRAPPING - 1); + + if(MOUSE_WRAP) { + var _pad = 2; + + if(mouse_mx < _pad) { + window_mouse_set(window_get_width() - _pad, mouse_my); + MOUSE_WRAPPING = 2; + } else if(mouse_mx > window_get_width() - _pad) { + window_mouse_set(_pad, mouse_my); + MOUSE_WRAPPING = 2; + } + + if(mouse_my < _pad) { + window_mouse_set(mouse_mx, window_get_height() - _pad); + MOUSE_WRAPPING = 2; + } else if(mouse_my > window_get_height() - _pad) { + window_mouse_set(mouse_mx, _pad); + MOUSE_WRAPPING = 2; + } + } + MOUSE_WRAP = false; +#endregion + +#region depth + if(_use_depth != USE_DEPTH) { + _use_depth = USE_DEPTH; + surface_depth_disable(!USE_DEPTH); + } + + USE_DEPTH = false; +#endregion + +#region cmd + var _resPath = program_directory + "in"; + + if(file_exists(_resPath)) { + var cmd = file_read_all(_resPath); + cmd_submit(cmd); + file_delete(_resPath); + } +#endregion + +//if(global.cache_call) print($"CACHE called: {global.cache_call} | hit: {global.cache_hit} ({global.cache_hit / global.cache_call * 100}%)"); +//if(!is_struct(FOCUS)) print(FOCUS); + +#event keyboard:vk_anykey +var trigger = false; + +KEYBOARD_PRESSED = vk_nokey; +kb_time += DELTA_TIME; +if(kb_hold && kb_time >= PREFERENCES.keyboard_repeat_speed) { + trigger = true; + kb_time = 0; +} else if(!kb_hold && kb_time >= PREFERENCES.keyboard_repeat_start) { + trigger = true; + kb_time = 0; + kb_hold = true; +} + +if(!trigger) exit; + +KEYBOARD_PRESSED = kb_hkey; + +if(keyboard_check(vk_backspace)) + KEYBOARD_STRING = string_copy(KEYBOARD_STRING, 1, string_length(KEYBOARD_STRING) - 1); +else + KEYBOARD_STRING += keyboard_lastchar; + +if(WIDGET_CURRENT && is_instanceof(WIDGET_CURRENT, textInput)) + WIDGET_CURRENT.onKey(KEYBOARD_PRESSED); + +#event other_game_start main directory, parameter +//print("===== Game Start Begin ====="); + +#region directory + globalvar DIRECTORY, APP_DIRECTORY, APP_LOCATION, PRESIST_PREF; + DIRECTORY = ""; + PRESIST_PREF = { + path: "" + }; + + APP_DIRECTORY = env_user(); + show_debug_message($"App directory: {APP_DIRECTORY}"); + + directory_verify(APP_DIRECTORY); + + var perstPath = APP_DIRECTORY + "persistPreference.json"; + if(file_exists_empty(perstPath)) { + struct_override(PRESIST_PREF, json_load_struct(perstPath)); + DIRECTORY = struct_has(PRESIST_PREF, "path")? PRESIST_PREF.path : ""; + } + + if(DIRECTORY != "") { + var _ch = string_char_last(DIRECTORY); + if(_ch != "\\" && _ch != "/") DIRECTORY += "\\"; + + show_debug_message($"Env directory: {DIRECTORY}"); + var dir_valid = DIRECTORY != "" && directory_exists(DIRECTORY); + var tmp = file_text_open_write(DIRECTORY + "val_check.txt"); + + if(tmp == -1) { + dir_valid = false; + show_message($"WARNING: Inaccessible main directory ({DIRECTORY}) this may be caused by non existing folder, or Pixel Composer has no permission to open the folder."); + } else { + file_text_close(tmp); + file_delete($"{DIRECTORY}val_check.txt"); + } + + if(!dir_valid) { + show_debug_message("Invalid directory revert back to default %APPDATA%"); + DIRECTORY = APP_DIRECTORY; + } + } else + DIRECTORY = APP_DIRECTORY; + + directory_verify(DIRECTORY); + + APP_LOCATION = program_directory; + if(OS == os_macosx) + APP_LOCATION = string_replace(APP_LOCATION, "/Contents/MacOS/", "/Contents/Resources/"); + if(string_pos("GameMakerStudio2\\Cache\\runtimes", APP_LOCATION)) + APP_LOCATION = working_directory; + print($"===================== WORKING DIRECTORIES =====================\n\t{working_directory}\n\t{DIRECTORY}"); +#endregion + +#region Set up + var t = current_time; + PREF_LOAD(); + + var dir = string(DIRECTORY) + "log"; + directory_verify(dir); + + log_clear(); + log_newline(); + log_message("SESSION", "Begin"); + log_message("DIRECTORY", DIRECTORY); + + PREF_APPLY(); + var t0 = get_timer(); + var t = get_timer(); + var _lua = PROGRAM_ARGUMENTS._lua; + + __initKeys() + __initPatreon(); log_message("SESSION", $"> init Patreon | complete in {get_timer() - t}"); t = get_timer(); + if(!IS_CMD) { __initTheme(); log_message("SESSION", $"> init Theme | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initLocale(); log_message("SESSION", $"> init Locale | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { loadFonts(); log_message("SESSION", $"> init Font | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initProject(); log_message("SESSION", $"> init Project | complete in {get_timer() - t}"); t = get_timer(); } + + if(!IS_CMD) { __initAction(); log_message("SESSION", $"> init Action | complete in {get_timer() - t}"); t = get_timer(); } + __initSurfaceFormat(); log_message("SESSION", $"> init SurfaceFormat | complete in {get_timer() - t}"); t = get_timer(); + if(!IS_CMD) { __initCollection(); log_message("SESSION", $"> init Collection | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initAssets(); log_message("SESSION", $"> init Assets | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initPresets(); log_message("SESSION", $"> init Presets | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initFontFolder(); log_message("SESSION", $"> init FontFolder | complete in {get_timer() - t}"); t = get_timer(); } + if(_lua) { __initLua(); log_message("SESSION", $"> init Lua | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initNodeData(); log_message("SESSION", $"> init NodeData | complete in {get_timer() - t}"); t = get_timer(); } + __initNodes(); log_message("SESSION", $"> init Nodes | complete in {get_timer() - t}"); t = get_timer(); + if(!IS_CMD) { __initSteamUGC(); log_message("SESSION", $"> init SteamUGC | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initAddon(); log_message("SESSION", $"> init Addon | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initPalette(); log_message("SESSION", $"> init Palette | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initGradient(); log_message("SESSION", $"> init Gradient | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initPen(); log_message("SESSION", $"> init Pen | complete in {get_timer() - t}"); t = get_timer(); } + + if(!IS_CMD) { loadAddon(); log_message("SESSION", $"> init Addons | complete in {get_timer() - t}"); t = get_timer(); } + + if(!IS_CMD) { LOAD_SAMPLE(); log_message("SESSION", $"> init sample | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { INIT_FOLDERS(); log_message("SESSION", $"> init folders | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { RECENT_LOAD(); log_message("SESSION", $"> init recents | complete in {get_timer() - t}"); t = get_timer(); } + + log_message("SESSION", $">> Initialization complete in {get_timer() - t0}"); + + if(!IS_CMD) { + __initPanel(); + + if(file_exists_empty("icon.png")) + file_copy("icon.png", DIRECTORY + "icon.png"); + + var cmd = ".pxc=\"" + string(program_directory) + "PixelComposer.exe\""; + shell_execute_async("assoc", cmd); + + var cmd = ".pxcc=\"" + string(program_directory) + "PixelComposer.exe\""; + shell_execute_async("assoc", cmd); + } + + directory_set_current_working(DIRECTORY); +#endregion + +#region lua + //lua_error_handler = _lua_error; +#endregion + +//print("===== Game Start End ====="); + +#event other_game_end +#region log + log_message("SESSION", "Ended"); + PREF_SAVE(); +#endregion + +#region steam + if(STEAM_ENABLED) + steam_shutdown(); +#endregion + +#event other_room_start init +PROJECT.modified = false; + +#region reset data + ds_stack_clear(UNDO_STACK); + ds_stack_clear(REDO_STACK); +#endregion + +#event other_user10 Pen tablet event + +var e; e = tabletstuff_get_event_data(); +if (!ds_map_exists(e, "pointer_info_pen")) exit; +PEN_USE = true; + +/* + See: + https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-pointer_pen_info + for flags and constants in the fields. +*/ + +var f = e[? "pointer_info_flags"]; + +var pp = e[? "pointer_info_pen_pressure"]; +var pr = e[? "pointer_info_pen_rotation"]; +var px = e[? "pointer_info_pixel_location_x"] - window_get_x(); +var py = e[? "pointer_info_pixel_location_y"] - window_get_y(); +var pb = e[? "pointer_info_button_change_type"]; + +var tx = e[? "pointer_info_pen_tilt_x"]; +var ty = e[? "pointer_info_pen_tilt_y"]; + +PEN_X_DELTA = px - PEN_X; +PEN_Y_DELTA = px - PEN_Y; + +PEN_X = px; +PEN_Y = py; + +PEN_PRESSURE = pp; + +var contact = bool(f & 0x4); +if(PEN_CONTACT && !contact) + PEN_RELEASED = true; +PEN_CONTACT = contact; + +var b1 = bool(f & 0x10); // POINTER_FLAG_FIRSTBUTTON +var b2 = bool(f & 0x20); // POINTER_FLAG_SECONDBUTTON + +if(!PEN_RIGHT_CLICK && b2) PEN_RIGHT_PRESS = true; +if(PEN_RIGHT_CLICK && !b2) PEN_RIGHT_RELEASE = true; + +PEN_RIGHT_CLICK = b2; + +//print($"{PEN_RIGHT_CLICK} | {PEN_RIGHT_PRESS}, {PEN_RIGHT_RELEASE}"); + + +#event async_image +if(!ds_map_exists(IMAGE_FETCH_MAP, async_load[? "id"])) exit; + +var _callback = IMAGE_FETCH_MAP[? async_load[? "id"]]; +_callback(async_load); + +#event async_http network +if(ds_map_exists(global.FILE_LOAD_ASYNC, async_load[? "id"])) { + var cb = global.FILE_LOAD_ASYNC[? async_load[? "id"]]; + var callback = cb[0]; + var arguments = cb[1]; + + callback(arguments); +} + +asyncLoad(async_load); + +#event async_network +var _id = async_load[? "id"]; + +if(_id == TCP_SERVER) { + var t = async_load[? "type"]; + + if (t == network_type_connect) { + var sock = ds_map_find_value(async_load, "socket"); + array_push(TCP_CLIENTS, sock); + log_console($"Client connected: {sock}"); + + } else if (t == network_type_disconnect) { + var sock = ds_map_find_value(async_load, "socket"); + array_remove(TCP_CLIENTS, sock); + log_console($"Client disconnected: {sock}"); + + } else if (t == network_type_data) { + var _buffer = ds_map_find_value(async_load, "buffer"); + var cmd_type = buffer_read(_buffer, buffer_string ); + cmd_submit(cmd_type); + } + + exit; +} + +if(!ds_map_exists(PORT_MAP, _id)) exit; +var nodeTarget = PORT_MAP[? _id]; +nodeTarget.asyncPackets(async_load); + +#event async_steam +var ev_id = async_load[? "id"]; +var ev_type = async_load[? "event_type"]; + +if(string(ev_id) == string(STEAM_UGC_ITEM_ID) && ev_type == "ugc_create_item") { + STEAM_UGC_PUBLISH_ID = async_load[? "published_file_id"]; + STEAM_UGC_UPDATE_HANDLE = steam_ugc_start_item_update(STEAM_APP_ID, STEAM_UGC_PUBLISH_ID); + + steam_ugc_set_item_title(STEAM_UGC_UPDATE_HANDLE, STEAM_UGC_ITEM_FILE.name); + steam_ugc_set_item_description(STEAM_UGC_UPDATE_HANDLE, STEAM_UGC_ITEM_FILE.meta.description); + steam_ugc_set_item_visibility(STEAM_UGC_UPDATE_HANDLE, ugc_visibility_public); + + var tgs = array_clone(STEAM_UGC_ITEM_FILE.meta.tags); + switch(STEAM_UGC_TYPE) { + case STEAM_UGC_FILE_TYPE.collection : array_insert_unique(tgs, 0, "Collection"); break; + case STEAM_UGC_FILE_TYPE.project : array_insert_unique(tgs, 0, "Project"); break; + case STEAM_UGC_FILE_TYPE.node_preset : array_insert_unique(tgs, 0, "Node preset"); break; + } + + array_push_unique(tgs, VERSION_STRING); + + steam_ugc_set_item_tags(STEAM_UGC_UPDATE_HANDLE, tgs); + steam_ugc_set_item_preview(STEAM_UGC_UPDATE_HANDLE, TEMPDIR + "steamUGCthumbnail.png"); + steam_ugc_set_item_content(STEAM_UGC_UPDATE_HANDLE, DIRECTORY + "steamUGC"); + + STEAM_UGC_SUBMIT_ID = steam_ugc_submit_item_update(STEAM_UGC_UPDATE_HANDLE, "Initial upload"); + exit; +} + +if(string(ev_id) == string(STEAM_UGC_SUBMIT_ID)) { + STEAM_UGC_ITEM_UPLOADING = false; + + var type = ""; + switch(STEAM_UGC_TYPE) { + case STEAM_UGC_FILE_TYPE.collection : type = "Collection"; break; + case STEAM_UGC_FILE_TYPE.project : type = "Project"; break; + case STEAM_UGC_FILE_TYPE.node_preset : type = "Node preset"; break; + } + + if(async_load[? "result"] == ugc_result_success) { + if(STEAM_UGC_UPDATE) { + log_message("WORKSHOP", type + " updated", THEME.workshop_update); + PANEL_MENU.setNotiIcon(THEME.workshop_update); + } else { + log_message("WORKSHOP", type + " uploaded", THEME.workshop_upload); + PANEL_MENU.setNotiIcon(THEME.workshop_upload); + } + + STEAM_SUB_ID = steam_ugc_subscribe_item(STEAM_UGC_PUBLISH_ID); + exit; + } + + switch(async_load[? "result"]) { #region error + case 2: log_warning("WORKSHOP", "Generic failure."); break; + case 3: log_warning("WORKSHOP", "Your Steam client doesn't have a connection to the back-end."); break; + case 5: log_warning("WORKSHOP", "Password/ticket is invalid."); break; + case 6: log_warning("WORKSHOP", "The user is logged in elsewhere."); break; + case 7: log_warning("WORKSHOP", "Protocol version is incorrect."); break; + case 8: log_warning("WORKSHOP", "A parameter is incorrect."); break; + case 9: log_warning("WORKSHOP", "File was not found."); break; + case 10: log_warning("WORKSHOP", "Called method is busy - action not taken."); break; + case 11: log_warning("WORKSHOP", "Called object was in an invalid state."); break; + case 12: log_warning("WORKSHOP", "The name was invalid."); break; + case 13: log_warning("WORKSHOP", "The email was invalid."); break; + case 14: log_warning("WORKSHOP", "The name is not unique."); break; + case 15: log_warning("WORKSHOP", "Access is denied."); break; + case 16: log_warning("WORKSHOP", "Operation timed out."); break; + case 17: log_warning("WORKSHOP", "The user is VAC2 banned."); break; + case 18: log_warning("WORKSHOP", "Account not found."); break; + case 19: log_warning("WORKSHOP", "The Steam ID was invalid."); break; + case 20: log_warning("WORKSHOP", "The requested service is currently unavailable."); break; + case 21: log_warning("WORKSHOP", "The user is not logged on."); break; + case 22: log_warning("WORKSHOP", "Request is pending, it may be in process or waiting on third party."); break; + case 23: log_warning("WORKSHOP", "Encryption or Decryption failed."); break; + case 24: log_warning("WORKSHOP", "Insufficient privilege."); break; + case 25: log_warning("WORKSHOP", "Too much of a good thing."); break; + case 26: log_warning("WORKSHOP", "Access has been revoked (used for revoked guest passes.)"); break; + case 27: log_warning("WORKSHOP", "License/Guest pass the user is trying to access is expired."); break; + case 28: log_warning("WORKSHOP", "Guest pass has already been redeemed by account, cannot be used again."); break; + case 29: log_warning("WORKSHOP", "The request is a duplicate and the action has already occurred in the past, ignored this time."); break; + case 30: log_warning("WORKSHOP", "All the games in this guest pass redemption request are already owned by the user."); break; + case 31: log_warning("WORKSHOP", "IP address not found."); break; + case 32: log_warning("WORKSHOP", "Failed to write change to the data store."); break; + case 33: log_warning("WORKSHOP", "Failed to acquire access lock for this operation."); break; + case 34: log_warning("WORKSHOP", "The logon session has been replaced."); break; + case 35: log_warning("WORKSHOP", "Failed to connect."); break; + case 36: log_warning("WORKSHOP", "The authentication handshake has failed."); break; + case 37: log_warning("WORKSHOP", "There has been a generic IO failure."); break; + case 38: log_warning("WORKSHOP", "The remote server has disconnected."); break; + case 39: log_warning("WORKSHOP", "Failed to find the shopping cart requested."); break; + case 40: log_warning("WORKSHOP", "A user blocked the action."); break; + case 41: log_warning("WORKSHOP", "The target is ignoring sender."); break; + case 42: log_warning("WORKSHOP", "Nothing matching the request found."); break; + case 43: log_warning("WORKSHOP", "The account is disabled."); break; + case 44: log_warning("WORKSHOP", "This service is not accepting content changes right now."); break; + case 45: log_warning("WORKSHOP", "Account doesn't have value, so this feature isn't available."); break; + case 46: log_warning("WORKSHOP", "Allowed to take this action, but only because requester is admin."); break; + case 47: log_warning("WORKSHOP", "A Version mismatch in content transmitted within the Steam protocol."); break; + case 48: log_warning("WORKSHOP", "The current CM can't service the user making a request, user should try another."); break; + case 49: log_warning("WORKSHOP", "You are already logged in elsewhere, this cached credential login has failed."); break; + case 50: log_warning("WORKSHOP", "The user is logged in elsewhere. (Use k_EResultLoggedInElsewhere instead!)"); break; + case 51: log_warning("WORKSHOP", "Long running operation has suspended/paused. (eg. content download.)"); break; + case 52: log_warning("WORKSHOP", "Operation has been canceled, typically by user. (eg. a content download.)"); break; + case 53: log_warning("WORKSHOP", "Operation canceled because data is ill formed or unrecoverable."); break; + case 54: log_warning("WORKSHOP", "Operation canceled - not enough disk space."); break; + case 55: log_warning("WORKSHOP", "The remote or IPC call has failed."); break; + case 56: log_warning("WORKSHOP", "Password could not be verified as it's unset server side."); break; + case 57: log_warning("WORKSHOP", "External account (PSN, Facebook...) is not linked to a Steam account."); break; + case 58: log_warning("WORKSHOP", "PSN ticket was invalid."); break; + case 59: log_warning("WORKSHOP", "External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first."); break; + case 60: log_warning("WORKSHOP", "The sync cannot resume due to a conflict between the local and remote files."); break; + case 61: log_warning("WORKSHOP", "The requested new password is not allowed."); break; + case 62: log_warning("WORKSHOP", "New value is the same as the old one. This is used for secret question and answer."); break; + case 63: log_warning("WORKSHOP", "Account login denied due to 2nd factor authentication failure."); break; + case 64: log_warning("WORKSHOP", "The requested new password is not legal."); break; + case 65: log_warning("WORKSHOP", "Account login denied due to auth code invalid."); break; + case 66: log_warning("WORKSHOP", "Account login denied due to 2nd factor auth failure - and no mail has been sent."); break; + case 67: log_warning("WORKSHOP", "The users hardware does not support Intel's Identity Protection Technology (IPT)."); break; + case 68: log_warning("WORKSHOP", "Intel's Identity Protection Technology (IPT) has failed to initialize."); break; + case 69: log_warning("WORKSHOP", "Operation failed due to parental control restrictions for current user."); break; + case 70: log_warning("WORKSHOP", "Facebook query returned an error."); break; + case 71: log_warning("WORKSHOP", "Account login denied due to an expired auth code."); break; + case 72: log_warning("WORKSHOP", "The login failed due to an IP restriction."); break; + case 73: log_warning("WORKSHOP", "The current users account is currently locked for use. This is likely due to a hijacking and pending ownership verification."); break; + case 74: log_warning("WORKSHOP", "The logon failed because the accounts email is not verified."); break; + case 75: log_warning("WORKSHOP", "There is no URL matching the provided values."); break; + case 76: log_warning("WORKSHOP", "Bad Response due to a Parse failure, missing field, etc."); break; + case 77: log_warning("WORKSHOP", "The user cannot complete the action until they re-enter their password."); break; + case 78: log_warning("WORKSHOP", "The value entered is outside the acceptable range."); break; + case 79: log_warning("WORKSHOP", "Something happened that we didn't expect to ever happen."); break; + case 80: log_warning("WORKSHOP", "The requested service has been configured to be unavailable."); break; + case 81: log_warning("WORKSHOP", "The files submitted to the CEG server are not valid."); break; + case 82: log_warning("WORKSHOP", "The device being used is not allowed to perform this action."); break; + case 83: log_warning("WORKSHOP", "The action could not be complete because it is region restricted."); break; + case 84: log_warning("WORKSHOP", "Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent."); break; + case 85: log_warning("WORKSHOP", "Need two-factor code to login."); break; + case 86: log_warning("WORKSHOP", "The thing we're trying to access has been deleted."); break; + case 87: log_warning("WORKSHOP", "Login attempt failed, try to throttle response to possible attacker."); break; + case 88: log_warning("WORKSHOP", "Two factor authentication (Steam Guard) code is incorrect."); break; + case 89: log_warning("WORKSHOP", "The activation code for two-factor authentication (Steam Guard) didn't match."); break; + case 90: log_warning("WORKSHOP", "The current account has been associated with multiple partners."); break; + case 91: log_warning("WORKSHOP", "The data has not been modified."); break; + case 92: log_warning("WORKSHOP", "The account does not have a mobile device associated with it."); break; + case 93: log_warning("WORKSHOP", "The time presented is out of range or tolerance."); break; + case 94: log_warning("WORKSHOP", "SMS code failure - no match, none pending, etc."); break; + case 95: log_warning("WORKSHOP", "Too many accounts access this resource."); break; + case 96: log_warning("WORKSHOP", "Too many changes to this account."); break; + case 97: log_warning("WORKSHOP", "Too many changes to this phone."); break; + case 98: log_warning("WORKSHOP", "Cannot refund to payment method, must use wallet."); break; + case 99: log_warning("WORKSHOP", "Cannot send an email."); break; + case 100: log_warning("WORKSHOP", "Can't perform operation until payment has settled."); break; + case 101: log_warning("WORKSHOP", "The user needs to provide a valid captcha."); break; + case 102: log_warning("WORKSHOP", "A game server login token owned by this token's owner has been banned."); break; + case 103: log_warning("WORKSHOP", "Game server owner is denied for some other reason such as account locked, community ban, vac ban, missing phone, etc."); break; + case 104: log_warning("WORKSHOP", "The type of thing we were requested to act on is invalid."); break; + case 105: log_warning("WORKSHOP", "The IP address has been banned from taking this action."); break; + case 106: log_warning("WORKSHOP", "This Game Server Login Token (GSLT) has expired from disuse; it can be reset for use."); break; + case 107: log_warning("WORKSHOP", "user doesn't have enough wallet funds to complete the action"); break; + case 108: log_warning("WORKSHOP", "There are too many of this thing pending already"); break; + } #endregion +} + +#event async_social Firebase + +if (async_load[? "type"] == "FirebaseFirestore_Collection_Query") { + PATREON_MAIL_CALLBACK(async_load); + exit; +} + +#event async_system +var ev_id = async_load[? "id"]; +var ev_type = async_load[? "event_type"]; + +if(ev_type == "file_drop") { + dropping = async_load[?"filename"]; + array_push(drop_path, dropping); +} + +#event draw_gui init +if(winMan_isMinimized()) exit; + +_MOUSE_BLOCK = MOUSE_BLOCK; +MOUSE_BLOCK = false; + +if(APP_SURF_OVERRIDE) { + APP_SURF = surface_verify(APP_SURF, WIN_W, WIN_H); + PRE_APP_SURF = surface_verify(PRE_APP_SURF, WIN_W, WIN_H); + POST_APP_SURF = surface_verify(POST_APP_SURF, WIN_W, WIN_H); + + surface_set_target(APP_SURF); +} + +draw_clear(COLORS.bg); + +#region widget scroll + if(!WIDGET_TAB_BLOCK) { + if(keyboard_check_pressed(vk_tab)) { + if(key_mod_press(SHIFT)) widget_previous(); + else widget_next(); + } + + if(keyboard_check_pressed(vk_enter)) + widget_trigger(); + + if(keyboard_check_pressed(vk_escape)) + widget_clear(); + } + + WIDGET_TAB_BLOCK = false; +#endregion + +#region register UI element + WIDGET_ACTIVE = []; +#endregion + +#region panels + if(PANEL_MAIN == 0) resetPanel(); + + var surf = surface_get_target(); + try { + PANEL_MAIN.draw(); + } catch(e) { + while(surface_get_target() != surf) + surface_reset_target(); + + noti_warning(exception_print(e)); + } + + panelDraw(); +#endregion + +#region notes + for( var i = 0, n = array_length(PROJECT.notes); i < n; i++ ) + PROJECT.notes[i].draw(); +#endregion + +#region window + winManDraw(); +#endregion + +if(APP_SURF_OVERRIDE) { #region + surface_reset_target(); + draw_surface(POST_APP_SURF, 0, 0); + + surface_set_target(PRE_APP_SURF); + draw_surface(APP_SURF, 0, 0); + surface_reset_target(); + + surface_set_target(POST_APP_SURF); + draw_surface(APP_SURF, 0, 0); + surface_reset_target(); +} #endregion + +#event draw_gui_end tooltip filedrop +if(winMan_isMinimized()) exit; + +#region tooltip + if(is_struct(TOOLTIP)) { + if(struct_has(TOOLTIP, "drawTooltip")) + TOOLTIP.drawTooltip(); + + } else if(is_array(TOOLTIP)) { + var content = TOOLTIP[0]; + var type = TOOLTIP[1]; + + if(is_method(content)) content = content(); + + switch(type) { + case VALUE_TYPE.float : + case VALUE_TYPE.integer : + case VALUE_TYPE.text : + case VALUE_TYPE.struct : + case VALUE_TYPE.path : + draw_tooltip_text(string_real(content)); + break; + + case VALUE_TYPE.boolean : + draw_tooltip_text(printBool(content)); + break; + + case VALUE_TYPE.curve : + draw_tooltip_text("[" + __txt("Curve Object") + "]"); + break; + + case VALUE_TYPE.color : + draw_tooltip_color(content); + break; + + case VALUE_TYPE.gradient : + draw_tooltip_gradient(content); + break; + + case VALUE_TYPE.d3object : + draw_tooltip_text("[" + __txt("3D Object") + "]"); + break; + + case VALUE_TYPE.object : + draw_tooltip_text("[" + __txt("Object") + "]"); + break; + + case VALUE_TYPE.surface : + draw_tooltip_surface(content); + break; + + case VALUE_TYPE.rigid : + draw_tooltip_text("[" + __txt("Rigidbody Object") + " (id: " + string(content[$ "object"]) + ")]"); + break; + + case VALUE_TYPE.particle : + var txt = "[" + + __txt("Particle Object") + + " (size: " + string(array_length(content)) + ") " + + "]"; + draw_tooltip_text(txt); + break; + + case VALUE_TYPE.pathnode : + draw_tooltip_text("[" + __txt("Path Object") + "]"); + break; + + case VALUE_TYPE.sdomain : + draw_tooltip_text("[" + __txt("Domain") + " (id: " + string(content) + ")]"); + break; + + case VALUE_TYPE.strands : + var txt = __txt("Strands Object"); + if(is_struct(content)) + txt += " (strands: " + string(array_length(content.hairs)) + ")"; + draw_tooltip_text("[" + txt + "]"); + break; + + case VALUE_TYPE.mesh : + var txt = __txt("Mesh Object"); + if(is_struct(content)) + txt += " (triangles: " + string(array_length(content.triangles)) + ")"; + draw_tooltip_text("[" + txt + "]"); + break; + + case VALUE_TYPE.d3vertex : + var txt = __txt("3D Vertex"); + txt += " (groups: " + string(array_length(content)) + ")"; + draw_tooltip_text("[" + txt + "]"); + break; + + case VALUE_TYPE.buffer : + draw_tooltip_buffer(content); + break; + + case "sprite" : + draw_tooltip_sprite(content); + break; + + default : + var tt = ""; + if(is_struct(content)) tt = $"[{instanceof(content)}] {content}"; + else tt = string(content); + + draw_tooltip_text(tt); + } + } else if(TOOLTIP != "") + draw_tooltip_text(TOOLTIP); + TOOLTIP = ""; +#endregion + +#region dragging + if(DRAGGING != noone) { + switch(DRAGGING.type) { + case "Color" : + draw_sprite_stretched_ext(THEME.color_picker_box, 1, mouse_mx + ui(-16), mouse_my + ui(-16), ui(32), ui(32), DRAGGING.data, 0.5); + break; + + case "Palette" : + drawPalette(DRAGGING.data, mouse_mx - ui(64), mouse_my - ui(12), ui(128), ui(24), 0.5); + break; + + case "Gradient" : + DRAGGING.data.draw(mouse_mx - ui(64), mouse_my - ui(12), ui(128), ui(24), 0.5); + break; + + case "Bool" : + draw_set_alpha(0.5); + draw_set_text(f_h3, fa_center, fa_center, COLORS._main_text); + draw_text_bbox({ xc: mouse_mx, yc: mouse_my, w: ui(128), h: ui(24) }, __txt(DRAGGING.data? "True" : "False")); + draw_set_alpha(1); + break; + + case "Asset" : + case "Project" : + case "Collection" : + if(DRAGGING.data.spr) { + var ss = ui(48) / max(sprite_get_width(DRAGGING.data.spr), sprite_get_height(DRAGGING.data.spr)) + draw_sprite_ext(DRAGGING.data.spr, 0, mouse_mx + ui(8), mouse_my + ui(8), ss, ss, 0, c_white, 0.5); + } + break; + + default: + draw_set_alpha(0.5); + draw_set_text(f_h3, fa_center, fa_center, COLORS._main_text); + draw_text_bbox({ xc: mouse_mx, yc: mouse_my, w: ui(128), h: ui(24) }, DRAGGING.data); + draw_set_alpha(1); + } + + if(mouse_release(mb_left)) + DRAGGING = noone; + } +#endregion + +#region safe mode + if(PROJECT.safeMode) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, 0, 0, WIN_W, WIN_H, COLORS._main_value_negative, 1); + draw_set_text(f_h1, fa_right, fa_bottom, COLORS._main_value_negative); + draw_set_alpha(0.25); + draw_text(WIN_W - ui(16), WIN_H - ui(8), __txtx("safe_mode", "SAFE MODE")); + draw_set_alpha(1); + } +#endregion + +#region draw gui top + PANEL_MAIN.drawGUI(); + + if(NODE_DROPPER_TARGET != noone) { + draw_sprite_ui(THEME.node_dropper, 0, mouse_x + ui(20), mouse_y + ui(20)); + if(mouse_press(mb_left, NODE_DROPPER_TARGET_CAN)) + NODE_DROPPER_TARGET = noone; + NODE_DROPPER_TARGET_CAN = true; + } else + NODE_DROPPER_TARGET_CAN = false; + + panelDisplayDraw(); +#endregion + +#region debug + if(global.FLAG[$ "hover_element"]) { + draw_set_text(f_p0, fa_right, fa_bottom, COLORS._main_text); + if(HOVERING_ELEMENT) + draw_text(WIN_W, WIN_H, $"[{instanceof(HOVERING_ELEMENT)}]"); + } +#endregion + +#region frame + draw_set_color(merge_color(COLORS._main_icon, COLORS._main_icon_dark, 0.95)); + draw_rectangle(1, 1, WIN_W - 2, WIN_H - 2, true); +#endregion + +#event keypress:vk_anykey +kb_hkey = keyboard_key == 0? keyboard_lastkey : keyboard_key; +kb_time = 0; +kb_hold = false; + +KEYBOARD_PRESSED = kb_hkey; + +if(keyboard_check(vk_backspace)) + KEYBOARD_STRING = string_copy(KEYBOARD_STRING, 1, string_length(KEYBOARD_STRING) - 1); +else + KEYBOARD_STRING += keyboard_lastchar; + +if(KEYBOARD_PRESSED == -1) { + for( var i = 0, n = array_length(global.KEYS_VK); i < n; i++ ) { + if(keyboard_check(global.KEYS_VK[i])) + KEYBOARD_PRESSED = global.KEYS_VK[i]; + } +} + +#event keyrelease:vk_anykey +kb_time = 0; +kb_hold = false; +keyboard_lastchar = ""; + +kb_hkey = vk_nokey; +KEYBOARD_PRESSED = vk_nokey; \ No newline at end of file diff --git a/#backups/objects/o_main/o_main.yy.backup1 b/#backups/objects/o_main/o_main.yy.backup1 new file mode 100644 index 000000000..d04f2a3b4 --- /dev/null +++ b/#backups/objects/o_main/o_main.yy.backup1 @@ -0,0 +1,1605 @@ +// 2024-04-18 11:59:03 +#event properties (no comments/etc. here are saved) +parent_index = -1; +persistent = true; +uses_physics = false; + +#event create init +#region log + var path = "log_temp.txt"; + var f = file_text_open_append(path); + file_text_write_string(f, $"[MESSAGE] {_log_template()}session begin\n"); + file_text_close(f); + + gpu_set_tex_mip_enable(mip_off); + gc_enable(true); + gc_target_frame_time(100); +#endregion + +#region window + window_set_min_width(960); + window_set_min_height(600); + draw_set_circle_precision(64); + winManInit(); + + depth = 0; + win_wp = WIN_W; + win_hp = WIN_H; + win_resize = false; + + room_width = WIN_W; + room_height = WIN_H; + + DIALOG_DEPTH_HOVER = 0; + UPDATE = RENDER_TYPE.none; + CURSOR = cr_default; + CURSOR_LOCK = false; + CURSOR_IS_LOCK = false; + CURSOR_LOCK_X = 0; + CURSOR_LOCK_Y = 0; + TOOLTIP = ""; + DRAGGING = noone; + KEYBOARD_STRING = ""; + + RENDER_QUEUE = new Queue(); + RENDER_ORDER = []; + + globalvar AUTO_SAVE_TIMER; + AUTO_SAVE_TIMER = 0; + + _cursor = CURSOR; + dc_check = 0; + kb_time = 0; + kb_hold = false; + kb_hkey = 0; + + fpss = array_create(10); + fpsr = 0; + + _cursor_lock = false; + + watcher_surface = surface_create(1, 1); + + panelInit(); + + addHotkey("", "New file", "N", MOD_KEY.ctrl, NEW); + if(!DEMO) { + addHotkey("", "Save", "S", MOD_KEY.ctrl, SAVE); + addHotkey("", "Save as", "S", MOD_KEY.ctrl | MOD_KEY.shift, SAVE_AS); + addHotkey("", "Save all", "S", MOD_KEY.ctrl | MOD_KEY.alt, SAVE_ALL); + addHotkey("", "Open", "O", MOD_KEY.ctrl, LOAD); + } + + addHotkey("", "Undo", "Z", MOD_KEY.ctrl, UNDO); + addHotkey("", "Redo", "Z", MOD_KEY.ctrl | MOD_KEY.shift, REDO); + + addHotkey("", "Full panel", "`", MOD_KEY.none, set_focus_fullscreen); + addHotkey("", "Reset layout", vk_f10, MOD_KEY.ctrl, resetPanel); + + addHotkey("", "Open notification", vk_f12, MOD_KEY.none, function() { dialogPanelCall(new Panel_Notification()); }); + + addHotkey("", "Fullscreen", vk_f11, MOD_KEY.none, global_fullscreen); + addHotkey("", "Render all", vk_f5, MOD_KEY.none, global_render_all); + + addHotkey("", "Close file", "Q", MOD_KEY.ctrl, global_project_close); + addHotkey("", "Close program", vk_f4, MOD_KEY.alt, window_close); + addHotkey("", "Reload theme", vk_f10, MOD_KEY.ctrl | MOD_KEY.shift, global_theme_reload); + + globalvar HOTKEY_MOD, HOTKEY_BLOCK; + HOTKEY_MOD = 0; + HOTKEY_BLOCK = false; +#endregion + +#region Loader + globalvar GIF_READER; + + GIF_READER = ds_list_create(); + gif_complete_st = ds_stack_create(); +#endregion + +#region tunnel + globalvar TUNNELS_IN, TUNNELS_IN_MAP, TUNNELS_OUT; + TUNNELS_IN = ds_map_create(); + TUNNELS_IN_MAP = ds_map_create(); + TUNNELS_OUT = ds_map_create(); +#endregion + +#region add on callback + globalvar ANIMATION_PRE, ANIMATION_POST; + + ANIMATION_PRE = []; + ANIMATION_POST = []; + + function __addon_preAnim() { + for( var i = 0, n = array_length(ANIMATION_PRE); i < n; i++ ) + ANIMATION_PRE[i](); + } + + function __addon_postAnim() { + for( var i = 0, n = array_length(ANIMATION_POST); i < n; i++ ) + ANIMATION_POST[i](); + } +#endregion + +#region file drop + if(OS == os_windows) { + file_dropper_init(); + } else if(OS == os_macosx) { + file_dnd_set_hwnd(window_handle()); + file_dnd_set_enabled(true); + + _file_dnd_filelist = ""; + file_dnd_filelist = ""; + file_dnd_pattern = "*.*"; + file_dnd_allowfiles = true; + file_dnd_allowdirs = true; + file_dnd_allowmulti = true; + } + + drop_path = []; + + function load_file_path(path) { + if(!is_array(path)) path = [ path ]; + if(array_length(path) == 0) return; + + 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 = string_lower(filename_ext(p)); + + switch(ext) { + case ".txt" : + node = Node_create_Text_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".csv" : + node = Node_create_CSV_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".json" : + node = Node_create_Json_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".ase" : + case ".aseprite" : + node = Node_create_ASE_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".png" : + case ".jpg" : + case ".jpeg" : + node = Node_create_Image_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".gif" : + node = Node_create_Image_gif_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".obj" : + node = Node_create_3D_Obj_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".wav" : + node = Node_create_WAV_File_Read_path(PANEL_GRAPH.mouse_grid_x, PANEL_GRAPH.mouse_grid_y, p); + break; + case ".pxc" : + case ".cpxc" : + LOAD_PATH(p); + break; + case ".pxcc" : + APPEND(p); + break; + } + + if(!IS_CMD)PANEL_GRAPH.mouse_grid_y += 160; + } + + if(node && !IS_CMD) + PANEL_GRAPH.toCenterNode(); + } + } +#endregion + +#region undo + action_last_frame = []; +#endregion + +#region version + version_check = -1; + version_latest = 0; + + //if(os_is_network_connected()) { + // var version = "https://gist.githubusercontent.com/Ttanasart-pt/d9eefbda84a78863c122b8b155bc0cda/raw/version.txt"; + // version_check = http_get(version); + //} +#endregion + +#region parameter + minimized = false; + _modified = false; +#endregion + +#region dialog + globalvar DIALOGS, WIDGET_TAB_BLOCK; + DIALOGS = ds_list_create(); + WIDGET_TAB_BLOCK = false; + + instance_create(0, 0, o_dialog_textbox_autocomplete); + instance_create(0, 0, o_dialog_textbox_function_guide); +#endregion + +#region async + globalvar PORT_MAP, NETWORK_SERVERS, NETWORK_CLIENTS; + globalvar IMAGE_FETCH_MAP; + + global.FILE_LOAD_ASYNC = ds_map_create(); + PORT_MAP = ds_map_create(); + NETWORK_SERVERS = ds_map_create(); + NETWORK_CLIENTS = ds_map_create(); + + IMAGE_FETCH_MAP = ds_map_create(); + + asyncInit(); + + network_set_config(network_config_use_non_blocking_socket, 0); +#endregion + +#region steam + globalvar STEAM_ENABLED, STEAM_APP_ID, STEAM_USER_ID, STEAM_USERNAME; + globalvar STEAM_UGC_ITEM_UPLOADING, STEAM_UGC_ITEM_ID, STEAM_UGC_ITEM_FILE, STEAM_UGC_UPDATE_HANDLE; + globalvar STEAM_UGC_SUBMIT_ID, STEAM_UGC_UPDATE_MAP, STEAM_UGC_PUBLISH_ID, STEAM_UGC_UPDATE, STEAM_UGC_TYPE; + globalvar STEAM_SUB_ID; + + enum STEAM_UGC_FILE_TYPE { + collection, + project, + node_preset + } + + STEAM_UGC_TYPE = STEAM_UGC_FILE_TYPE.collection; + STEAM_SUB_ID = 0; + STEAM_USER_ID = 0; + STEAM_USERNAME = ""; + + STEAM_UGC_UPDATE_HANDLE = 0; + STEAM_UGC_ITEM_ID = 0; + STEAM_UGC_PUBLISH_ID = 0; + STEAM_UGC_SUBMIT_ID = 0; + STEAM_UGC_ITEM_UPLOADING = false; + STEAM_ENABLED = steam_initialised(); + STEAM_UGC_UPDATE = false; + STEAM_UGC_UPDATE_MAP = ds_map_create(); + + if(STEAM_ENABLED) { + STEAM_APP_ID = steam_get_app_id(); + STEAM_USER_ID = steam_get_user_account_id(); + STEAM_USERNAME = steam_get_persona_name(); + steam_set_warning_message_hook(); + } +#endregion + +#region physics + physics_world_update_iterations(100); +#endregion + +#region color selector + globalvar NODE_DROPPER_TARGET, NODE_DROPPER_TARGET_CAN, NODE_COLOR_SHOW_PALETTE; + NODE_DROPPER_TARGET = noone; + NODE_DROPPER_TARGET_CAN = false; + NODE_COLOR_SHOW_PALETTE = false; +#endregion + +#region draw + +#endregion + +#region 3D + globalvar USE_DEPTH; + _use_depth = noone; + USE_DEPTH = false; + + set3DGlobalPreview(); +#endregion + +#region debug + global.__debug_runner = 0; + __debug_animator_counter = 0; + + //instance_create(0, 0, o_video_banner, { title: "Trail effect" }); + //instance_create_depth(0, 0, -32000, FLIP_Domain); + //instance_create_depth(0, 0, -32000, FLIP_Domain); +#endregion + +#region server + globalvar TCP_SERVER, TCP_PORT, TCP_CLIENTS; + TCP_SERVER = false; + TCP_PORT = noone; + TCP_CLIENTS = []; + +#endregion + +#region arguments + #macro IS_CMD PROGRAM_ARGUMENTS._cmd + + alarm[1] = 2; + + globalvar PROGRAM_ARGUMENTS, CLI_EXPORT_AMOUNT; + + PROGRAM_ARGUMENTS = { + _path : "", + _cmd : false, + _run : false, + _rendering : false, + _exporting : [], + _persist : false, + _trusted: false, + _lua: true, + }; + + CLI_EXPORT_AMOUNT = 0; + + var paramCount = parameter_count(); + var paramType = "_path"; + var useTCP = false; + + for( var i = 0; i < paramCount; i++ ) { + var param = parameter_string(i); + //print($" >>> params {i}: {param}"); + + if(string_starts_with(param, "-")) { + switch(param) { + case "-c" : + case "--crashed" : + if(PREFERENCES.show_crash_dialog) + run_in(1, function() { dialogCall(o_dialog_crashed); }); + break; + + case "-h" : + case "--headless" : + PROGRAM_ARGUMENTS._cmd = true; + break; + + case "-p" : + case "--persist" : + PROGRAM_ARGUMENTS._persist = true; + break; + + case "-t" : + case "--trusted" : + PROGRAM_ARGUMENTS._trusted = true; + break; + + case "-s" : + case "--server" : + PROGRAM_ARGUMENTS._persist = true; + useTCP = true; + break; + + case "-sl" : + case "--skiplua" : + PROGRAM_ARGUMENTS._lua = false; + break; + + default : + paramType = string_trim(param, ["-"]); + break; + } + + } else if(paramType == "_path") { + var path = param; + path = string_replace_all(path, "\n", ""); + path = string_replace_all(path, "\"", ""); + + if(file_exists_empty(path) && (filename_ext(path) == ".pxc" || filename_ext(path) == ".cpxc")) + PROGRAM_ARGUMENTS._path = path; + + } else + PROGRAM_ARGUMENTS[$ paramType] = cmd_path(param); + } + + if(IS_CMD) { + draw_enable_drawevent(false); + log_console($"Running PixelComposer {VERSION_STRING}"); + + PROGRAM_ARGUMENTS._run = true; + PROGRAM_ARGUMENTS._rendering = true; + } + + if(file_exists_empty(PROGRAM_ARGUMENTS._path)) { + run_in(1, function() { load_file_path(PROGRAM_ARGUMENTS._path); }); + + } else if(IS_CMD) + game_end(); + + if(useTCP && struct_has(PROGRAM_ARGUMENTS, "port")) { + TCP_PORT = PROGRAM_ARGUMENTS.port; + TCP_SERVER = network_create_server_raw(network_socket_tcp, TCP_PORT, 32); + + log_console($"Open port: {TCP_PORT}"); + } +#endregion + +#event alarm1 init +#region prefload + __migration_check(); + + if(!file_exists_empty(PROGRAM_ARGUMENTS._path) && PREFERENCES.show_splash) + dialogCall(o_dialog_splash); +#endregion + +#event step init +if(winMan_isMinimized()) exit; +winManStep() + +//print("===== Step start ====="); + +if(PROJECT.active && !PROJECT.safeMode) { #region + PROJECT.animator.step(); + PROJECT.globalNode.step(); + LIVE_UPDATE = false; + + try { + if(PANEL_MAIN != 0) PANEL_MAIN.step(); + array_foreach(PROJECT.nodeArray, function(_node) { + if(!_node.active) return; + _node.triggerCheck(); + _node.step(); + }); + } catch(e) { + noti_warning("Step error: " + exception_print(e)); + } +} #endregion + +#region hotkey + HOTKEY_MOD = 0; + if(CTRL == KEYBOARD_STATUS.pressing) HOTKEY_MOD |= MOD_KEY.ctrl; + if(SHIFT == KEYBOARD_STATUS.pressing) HOTKEY_MOD |= MOD_KEY.shift; + if(ALT == KEYBOARD_STATUS.pressing) HOTKEY_MOD |= MOD_KEY.alt; + + if(!instance_exists(o_dialog_preference) && !HOTKEY_BLOCK) { + if(ds_map_exists(HOTKEYS, "")) { + var l = HOTKEYS[? ""]; + for(var i = 0; i < ds_list_size(l); i++) { + var hotkey = l[| i]; + if(hotkey.key == 0 && hotkey.modi == MOD_KEY.none) continue; + + if(key_press(hotkey.key, hotkey.modi)) { + hotkey.action(); + break; + } + } + } + + if(ds_map_exists(HOTKEYS, FOCUS_STR)) { + var list = HOTKEYS[? FOCUS_STR]; + for(var i = 0; i < ds_list_size(list); i++) { + var hotkey = list[| i]; + if(hotkey.key == 0 && hotkey.modi == MOD_KEY.none) continue; + + if(key_press(hotkey.key, hotkey.modi)) { + hotkey.action(); + break; + } + } + } + } + + HOTKEY_BLOCK = false; +#endregion + +#region GIF builder + for( var i = 0; i < ds_list_size(GIF_READER); i++ ) { + var _reader = GIF_READER[| i]; + + var _reading = _reader[0].reading(); + if(_reading) { + var ret = _reader[2]; + ret(new __gif_sprite_builder(_reader[0])); + ds_stack_push(gif_complete_st, i); + } + } + + while(!ds_stack_empty(gif_complete_st)) { + var i = ds_stack_pop(gif_complete_st); + buffer_delete(GIF_READER[| i][1]); + delete GIF_READER[| i][0]; + ds_list_delete(GIF_READER, i); + } +#endregion + +#region file drop + if(OS == os_windows) { + if(array_length(drop_path)) { + load_file_path(drop_path); + drop_path = []; + } + } else if(OS == os_macosx) { + file_dnd_set_files(file_dnd_pattern, file_dnd_allowfiles, file_dnd_allowdirs, file_dnd_allowmulti); + file_dnd_filelist = file_dnd_get_files(); + + if(file_dnd_filelist != "" && _file_dnd_filelist != file_dnd_filelist) { + var path = string_trim(file_dnd_filelist); + load_file_path(string_splice(path, "\n")); + } + + _file_dnd_filelist = file_dnd_filelist; + } +#endregion + +#region window + if(_modified != PROJECT.modified) { + _modified = PROJECT.modified; + + var cap = ""; + if(PROJECT.safeMode) cap += "[SAFE MODE] "; + if(PROJECT.readonly) cap += "[READ ONLY] "; + cap += PROJECT.path + (PROJECT.modified? "*" : "") + " - Pixel Composer"; + + window_set_caption(cap); + } +#endregion + +#region notification + if(!ds_list_empty(WARNING)) { + var rem = ds_stack_create(); + + for( var i = 0; i < ds_list_size(WARNING); i++ ) { + var w = WARNING[| i]; + if(--w.life <= 0) + ds_stack_push(rem, w); + } + + while(!ds_stack_empty(rem)) { + ds_list_delete(WARNING, ds_stack_pop(rem)); + } + + ds_stack_destroy(rem); + } +#endregion + +#region steam + steam_update(); + + if(STEAM_ENABLED) { + if (steam_is_screenshot_requested()) { + var file = "PixelComposer_" + string(irandom_range(100_000, 999_999)) + ".png"; + screen_save(file); + steam_send_screenshot(file, window_get_width(), window_get_height()); + } + } +#endregion + +#event step_begin init +global.__debug_runner++; +global.cache_call = 0; +global.cache_hit = 0; + +HOVERING_ELEMENT = _HOVERING_ELEMENT; +_HOVERING_ELEMENT = noone; + +#region minimize + if(winMan_isMinimized()) { + if(!minimized) game_set_speed(1, gamespeed_fps); + minimized = true; + exit; + } else if(!minimized) + window_preminimize_rect = [ window_get_x(), window_get_y(), window_get_width(), window_get_height() ]; + + if(minimized) { + game_set_speed(PREFERENCES.ui_framerate, gamespeed_fps); + window_set_rectangle(window_preminimize_rect[0], window_preminimize_rect[1], window_preminimize_rect[2], window_preminimize_rect[3]); + + minimized = false; + } +#endregion + +#region fpss + if(fpsr++ % 5 == 0) { + var ff = 0; + for( var i = 1; i < 10; i++ ) { + fpss[i] = fpss[i - 1] + ff += fpss[i]; + } + fpss[0] = fps_real; + ff += fps_real; + FPS_REAL = round(ff / 10); + } +#endregion + +#region window & mouse + //if(keyboard_check_pressed(vk_f12)) DEBUG = !DEBUG; + + if(_cursor != CURSOR) { + window_set_cursor(CURSOR); + _cursor = CURSOR; + } + CURSOR = cr_default; + + if(_cursor_lock != CURSOR_LOCK) { + window_mouse_set_locked(CURSOR_LOCK); + if(!CURSOR_LOCK) window_mouse_set(CURSOR_LOCK_X, CURSOR_LOCK_Y); + } + + _cursor_lock = CURSOR_LOCK; + CURSOR_IS_LOCK = CURSOR_LOCK; + CURSOR_LOCK = false; + + if(!is_surface(watcher_surface)) { + RENDER_ALL + watcher_surface = surface_create(1, 1); + } + + PEN_USE = false; + PEN_RELEASED = false; + PEN_RIGHT_PRESS = false; + PEN_RIGHT_RELEASE = false; + + if(!IS_CMD) tabletstuff_perform_event(id, ev_other, ev_user10); + + //print($"{PEN_RIGHT_CLICK} | {PEN_RIGHT_PRESS}, {PEN_RIGHT_RELEASE}"); + //print($"{mouse_x}, {mouse_y}"); +#endregion + +#region focus + if(mouse_release(mb_any)) DIALOG_CLICK = true; + + HOVER = noone; + with(_p_dialog) checkMouse(); + + if(PANEL_MAIN != 0) PANEL_MAIN.stepBegin(); + + DIALOG_DEPTH_HOVER = 0; + + with(_p_dialog) checkFocus(); + with(_p_dialog) checkDepth(); + + with(_p_dialog) doDrag(); + with(_p_dialog) doResize(); +#endregion + +#region auto save + AUTO_SAVE_TIMER += delta_time / 1_000_000; + + if(PROJECT.modified && PREFERENCES.auto_save_time > 0 && AUTO_SAVE_TIMER > PREFERENCES.auto_save_time) { + AUTO_SAVE_TIMER = 0; + var loc = DIRECTORY + "Autosave/"; + directory_verify(loc); + + var fname = string_replace(filename_name(PROJECT.path), filename_ext(PROJECT.path), "") + + "_autosave" + string(current_year) + "-" + + string_lead_zero(current_month, 2) + "-" + + string_lead_zero(current_day, 2) + "T" + + string_lead_zero(current_hour, 2) + + string_lead_zero(current_minute, 2) + + string_lead_zero(current_second, 2) + filename_ext(PROJECT.path); + + try { SAVE_AT(PROJECT, loc + fname, "Autosaved "); } + catch(e) { print(exception_print(e)); } + } +#endregion + +#region animation & render + DEF_SURFACE_RESET(); + + if(!PROJECT.safeMode && UPDATE_RENDER_ORDER) { + ResetAllNodesRender(); + NodeTopoSort(); + } + + if(LIVE_UPDATE) + Render(); + else if(!PROJECT.safeMode) { + UPDATE_RENDER_ORDER = false; + + if(PROJECT.active) { + PROJECT.animator.is_simulating = false; + array_foreach(PROJECT.nodeArray, function(_node) { if(!_node.active) return; _node.stepBegin(); }); + + if(PROGRAM_ARGUMENTS._run) { + if(PROJECT != noone && PROJECT.path != "") { + exportAll(); + PROGRAM_ARGUMENTS._run = false; + } + + } else if(IS_PLAYING || IS_RENDERING) { + if(PROJECT.animator.frame_progress) { + __addon_preAnim(); + + if(IS_FIRST_FRAME) + ResetAllNodesRender(); + + if(IS_CMD) Render(false); + else Render(true); + + __addon_postAnim(); + } + PROJECT.animator.frame_progress = false; + + } else { + if(UPDATE & RENDER_TYPE.full) + Render(); + + else if(UPDATE & RENDER_TYPE.partial) + Render(true); + + } + } + } + + if(PROGRAM_ARGUMENTS._rendering && PROGRAM_ARGUMENTS._run == false && array_empty(PROGRAM_ARGUMENTS._exporting)) { + log_console($"Export {CLI_EXPORT_AMOUNT} {CLI_EXPORT_AMOUNT > 1? "files" : "file"} completed"); + + if(PROGRAM_ARGUMENTS._persist) { + PROGRAM_ARGUMENTS._rendering = false; + cli_wait(); + } else + game_end(); + } + + UPDATE = RENDER_TYPE.none; +#endregion + +#region clicks + DOUBLE_CLICK = false; + if(mouse_press(mb_left)) { + if(dc_check > 0) { + if(point_distance(mouse_mx, mouse_my, DOUBLE_CLICK_POS[0], DOUBLE_CLICK_POS[1]) < 8) + DOUBLE_CLICK = true; + dc_check = 0; + } else { + dc_check = PREFERENCES.double_click_delay; + DOUBLE_CLICK_POS = [ mouse_mx, mouse_my ]; + } + } + + dc_check -= DELTA_TIME; +#endregion + +#region step + if(array_length(action_last_frame) > 0) { + ds_stack_push(UNDO_STACK, action_last_frame); + ds_stack_clear(REDO_STACK); + } + action_last_frame = []; +#endregion + +#region modifiers + if(CTRL == KEYBOARD_STATUS.up) + CTRL = KEYBOARD_STATUS.idle; + if(SHIFT == KEYBOARD_STATUS.up) + SHIFT = KEYBOARD_STATUS.idle; + if(ALT == KEYBOARD_STATUS.up) + ALT = KEYBOARD_STATUS.idle; + + if(CTRL == KEYBOARD_STATUS.pressing && !keyboard_check(vk_control)) + CTRL = KEYBOARD_STATUS.up; + + if(SHIFT == KEYBOARD_STATUS.pressing && !keyboard_check(vk_shift)) + SHIFT = KEYBOARD_STATUS.up; + + if(ALT == KEYBOARD_STATUS.pressing && !keyboard_check(vk_alt)) + ALT = KEYBOARD_STATUS.up; + + if(CTRL == KEYBOARD_STATUS.down) + CTRL = KEYBOARD_STATUS.pressing; + + if(SHIFT == KEYBOARD_STATUS.down) + SHIFT = KEYBOARD_STATUS.pressing; + + if(ALT == KEYBOARD_STATUS.down) + ALT = KEYBOARD_STATUS.pressing; + + if(keyboard_check_pressed(vk_control)) + CTRL = KEYBOARD_STATUS.down; + if(keyboard_check_pressed(vk_shift)) + SHIFT = KEYBOARD_STATUS.down; + if(keyboard_check_pressed(vk_alt)) + ALT = KEYBOARD_STATUS.down; + + if(keyboard_check_released(vk_control)) + CTRL = KEYBOARD_STATUS.up; + if(keyboard_check_released(vk_shift)) + SHIFT = KEYBOARD_STATUS.up; + if(keyboard_check_released(vk_alt)) + ALT = KEYBOARD_STATUS.up; +#endregion + +#region mouse wrap + MOUSE_WRAPPING = max(0, MOUSE_WRAPPING - 1); + + if(MOUSE_WRAP) { + var _pad = 2; + + if(mouse_mx < _pad) { + window_mouse_set(window_get_width() - _pad, mouse_my); + MOUSE_WRAPPING = 2; + } else if(mouse_mx > window_get_width() - _pad) { + window_mouse_set(_pad, mouse_my); + MOUSE_WRAPPING = 2; + } + + if(mouse_my < _pad) { + window_mouse_set(mouse_mx, window_get_height() - _pad); + MOUSE_WRAPPING = 2; + } else if(mouse_my > window_get_height() - _pad) { + window_mouse_set(mouse_mx, _pad); + MOUSE_WRAPPING = 2; + } + } + MOUSE_WRAP = false; +#endregion + +#region depth + if(_use_depth != USE_DEPTH) { + _use_depth = USE_DEPTH; + surface_depth_disable(!USE_DEPTH); + } + + USE_DEPTH = false; +#endregion + +#region cmd + var _resPath = program_directory + "in"; + + if(file_exists(_resPath)) { + var cmd = file_read_all(_resPath); + cmd_submit(cmd); + file_delete(_resPath); + } +#endregion + +//if(global.cache_call) print($"CACHE called: {global.cache_call} | hit: {global.cache_hit} ({global.cache_hit / global.cache_call * 100}%)"); +//if(!is_struct(FOCUS)) print(FOCUS); + +#event keyboard:vk_anykey +var trigger = false; + +KEYBOARD_PRESSED = vk_nokey; +kb_time += DELTA_TIME; +if(kb_hold && kb_time >= PREFERENCES.keyboard_repeat_speed) { + trigger = true; + kb_time = 0; +} else if(!kb_hold && kb_time >= PREFERENCES.keyboard_repeat_start) { + trigger = true; + kb_time = 0; + kb_hold = true; +} + +if(!trigger) exit; + +KEYBOARD_PRESSED = kb_hkey; + +if(keyboard_check(vk_backspace)) + KEYBOARD_STRING = string_copy(KEYBOARD_STRING, 1, string_length(KEYBOARD_STRING) - 1); +else + KEYBOARD_STRING += keyboard_lastchar; + +if(WIDGET_CURRENT && is_instanceof(WIDGET_CURRENT, textInput)) + WIDGET_CURRENT.onKey(KEYBOARD_PRESSED); + +#event other_game_start main directory, parameter +//print("===== Game Start Begin ====="); + +#region directory + globalvar DIRECTORY, APP_DIRECTORY, APP_LOCATION, PRESIST_PREF; + DIRECTORY = ""; + PRESIST_PREF = { + path: "" + }; + + APP_DIRECTORY = env_user(); + show_debug_message($"App directory: {APP_DIRECTORY}"); + + directory_verify(APP_DIRECTORY); + + var perstPath = APP_DIRECTORY + "persistPreference.json"; + if(file_exists_empty(perstPath)) { + struct_override(PRESIST_PREF, json_load_struct(perstPath)); + DIRECTORY = struct_has(PRESIST_PREF, "path")? PRESIST_PREF.path : ""; + } + + if(DIRECTORY != "") { + var _ch = string_char_last(DIRECTORY); + if(_ch != "\\" && _ch != "/") DIRECTORY += "\\"; + + show_debug_message($"Env directory: {DIRECTORY}"); + var dir_valid = DIRECTORY != "" && directory_exists(DIRECTORY); + var tmp = file_text_open_write(DIRECTORY + "val_check.txt"); + + if(tmp == -1) { + dir_valid = false; + show_message($"WARNING: Inaccessible main directory ({DIRECTORY}) this may be caused by non existing folder, or Pixel Composer has no permission to open the folder."); + } else { + file_text_close(tmp); + file_delete($"{DIRECTORY}val_check.txt"); + } + + if(!dir_valid) { + show_debug_message("Invalid directory revert back to default %APPDATA%"); + DIRECTORY = APP_DIRECTORY; + } + } else + DIRECTORY = APP_DIRECTORY; + + directory_verify(DIRECTORY); + + APP_LOCATION = program_directory; + if(OS == os_macosx) + APP_LOCATION = string_replace(APP_LOCATION, "/Contents/MacOS/", "/Contents/Resources/"); + if(string_pos("GameMakerStudio2\\Cache\\runtimes", APP_LOCATION)) + APP_LOCATION = working_directory; + print($"===================== WORKING DIRECTORIES =====================\n\t{working_directory}\n\t{DIRECTORY}"); +#endregion + +#region Set up + var t = current_time; + PREF_LOAD(); + + var dir = string(DIRECTORY) + "log"; + directory_verify(dir); + + log_clear(); + log_newline(); + log_message("SESSION", "Begin"); + log_message("DIRECTORY", DIRECTORY); + + PREF_APPLY(); + var t0 = get_timer(); + var t = get_timer(); + var _lua = PROGRAM_ARGUMENTS._lua; + + __initKeys() + __initPatreon(); log_message("SESSION", $"> init Patreon | complete in {get_timer() - t}"); t = get_timer(); + if(!IS_CMD) { __initTheme(); log_message("SESSION", $"> init Theme | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initLocale(); log_message("SESSION", $"> init Locale | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { loadFonts(); log_message("SESSION", $"> init Font | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initProject(); log_message("SESSION", $"> init Project | complete in {get_timer() - t}"); t = get_timer(); } + + if(!IS_CMD) { __initAction(); log_message("SESSION", $"> init Action | complete in {get_timer() - t}"); t = get_timer(); } + __initSurfaceFormat(); log_message("SESSION", $"> init SurfaceFormat | complete in {get_timer() - t}"); t = get_timer(); + if(!IS_CMD) { __initCollection(); log_message("SESSION", $"> init Collection | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initAssets(); log_message("SESSION", $"> init Assets | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initPresets(); log_message("SESSION", $"> init Presets | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initFontFolder(); log_message("SESSION", $"> init FontFolder | complete in {get_timer() - t}"); t = get_timer(); } + if(_lua) { __initLua(); log_message("SESSION", $"> init Lua | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initNodeData(); log_message("SESSION", $"> init NodeData | complete in {get_timer() - t}"); t = get_timer(); } + __initNodes(); log_message("SESSION", $"> init Nodes | complete in {get_timer() - t}"); t = get_timer(); + if(!IS_CMD) { __initSteamUGC(); log_message("SESSION", $"> init SteamUGC | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initAddon(); log_message("SESSION", $"> init Addon | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initPalette(); log_message("SESSION", $"> init Palette | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initGradient(); log_message("SESSION", $"> init Gradient | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { __initPen(); log_message("SESSION", $"> init Pen | complete in {get_timer() - t}"); t = get_timer(); } + + if(!IS_CMD) { loadAddon(); log_message("SESSION", $"> init Addons | complete in {get_timer() - t}"); t = get_timer(); } + + if(!IS_CMD) { LOAD_SAMPLE(); log_message("SESSION", $"> init sample | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { INIT_FOLDERS(); log_message("SESSION", $"> init folders | complete in {get_timer() - t}"); t = get_timer(); } + if(!IS_CMD) { RECENT_LOAD(); log_message("SESSION", $"> init recents | complete in {get_timer() - t}"); t = get_timer(); } + + log_message("SESSION", $">> Initialization complete in {get_timer() - t0}"); + + if(!IS_CMD) { + __initPanel(); + + if(file_exists_empty("icon.png")) + file_copy("icon.png", DIRECTORY + "icon.png"); + + var cmd = ".pxc=\"" + string(program_directory) + "PixelComposer.exe\""; + shell_execute_async("assoc", cmd); + + var cmd = ".pxcc=\"" + string(program_directory) + "PixelComposer.exe\""; + shell_execute_async("assoc", cmd); + } + + directory_set_current_working(DIRECTORY); +#endregion + +#region lua + //lua_error_handler = _lua_error; +#endregion + +//print("===== Game Start End ====="); + +#event other_game_end +#region log + log_message("SESSION", "Ended"); + PREF_SAVE(); +#endregion + +#region steam + if(STEAM_ENABLED) + steam_shutdown(); +#endregion + +#event other_room_start init +PROJECT.modified = false; + +#region reset data + ds_stack_clear(UNDO_STACK); + ds_stack_clear(REDO_STACK); +#endregion + +#event other_user10 Pen tablet event + +var e; e = tabletstuff_get_event_data(); +if (!ds_map_exists(e, "pointer_info_pen")) exit; +PEN_USE = true; + +/* + See: + https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-pointer_pen_info + for flags and constants in the fields. +*/ + +var f = e[? "pointer_info_flags"]; + +var pp = e[? "pointer_info_pen_pressure"]; +var pr = e[? "pointer_info_pen_rotation"]; +var px = e[? "pointer_info_pixel_location_x"] - window_get_x(); +var py = e[? "pointer_info_pixel_location_y"] - window_get_y(); +var pb = e[? "pointer_info_button_change_type"]; + +var tx = e[? "pointer_info_pen_tilt_x"]; +var ty = e[? "pointer_info_pen_tilt_y"]; + +PEN_X_DELTA = px - PEN_X; +PEN_Y_DELTA = px - PEN_Y; + +//print($"{PEN_X_DELTA}, {PEN_Y_DELTA}"); + +PEN_X = px; +PEN_Y = py; + +PEN_PRESSURE = pp; + +var contact = bool(f & 0x4); +if(PEN_CONTACT && !contact) + PEN_RELEASED = true; +PEN_CONTACT = contact; + +var b1 = bool(f & 0x10); // POINTER_FLAG_FIRSTBUTTON +var b2 = bool(f & 0x20); // POINTER_FLAG_SECONDBUTTON + +if(!PEN_RIGHT_CLICK && b2) PEN_RIGHT_PRESS = true; +if(PEN_RIGHT_CLICK && !b2) PEN_RIGHT_RELEASE = true; + +PEN_RIGHT_CLICK = b2; + +//print($"{PEN_RIGHT_CLICK} | {PEN_RIGHT_PRESS}, {PEN_RIGHT_RELEASE}"); + + +#event async_image +if(!ds_map_exists(IMAGE_FETCH_MAP, async_load[? "id"])) exit; + +var _callback = IMAGE_FETCH_MAP[? async_load[? "id"]]; +_callback(async_load); + +#event async_http network +if(ds_map_exists(global.FILE_LOAD_ASYNC, async_load[? "id"])) { + var cb = global.FILE_LOAD_ASYNC[? async_load[? "id"]]; + var callback = cb[0]; + var arguments = cb[1]; + + callback(arguments); +} + +asyncLoad(async_load); + +#event async_network +var _id = async_load[? "id"]; + +if(_id == TCP_SERVER) { + var t = async_load[? "type"]; + + if (t == network_type_connect) { + var sock = ds_map_find_value(async_load, "socket"); + array_push(TCP_CLIENTS, sock); + log_console($"Client connected: {sock}"); + + } else if (t == network_type_disconnect) { + var sock = ds_map_find_value(async_load, "socket"); + array_remove(TCP_CLIENTS, sock); + log_console($"Client disconnected: {sock}"); + + } else if (t == network_type_data) { + var _buffer = ds_map_find_value(async_load, "buffer"); + var cmd_type = buffer_read(_buffer, buffer_string ); + cmd_submit(cmd_type); + } + + exit; +} + +if(!ds_map_exists(PORT_MAP, _id)) exit; +var nodeTarget = PORT_MAP[? _id]; +nodeTarget.asyncPackets(async_load); + +#event async_steam +var ev_id = async_load[? "id"]; +var ev_type = async_load[? "event_type"]; + +if(string(ev_id) == string(STEAM_UGC_ITEM_ID) && ev_type == "ugc_create_item") { + STEAM_UGC_PUBLISH_ID = async_load[? "published_file_id"]; + STEAM_UGC_UPDATE_HANDLE = steam_ugc_start_item_update(STEAM_APP_ID, STEAM_UGC_PUBLISH_ID); + + steam_ugc_set_item_title(STEAM_UGC_UPDATE_HANDLE, STEAM_UGC_ITEM_FILE.name); + steam_ugc_set_item_description(STEAM_UGC_UPDATE_HANDLE, STEAM_UGC_ITEM_FILE.meta.description); + steam_ugc_set_item_visibility(STEAM_UGC_UPDATE_HANDLE, ugc_visibility_public); + + var tgs = array_clone(STEAM_UGC_ITEM_FILE.meta.tags); + switch(STEAM_UGC_TYPE) { + case STEAM_UGC_FILE_TYPE.collection : array_insert_unique(tgs, 0, "Collection"); break; + case STEAM_UGC_FILE_TYPE.project : array_insert_unique(tgs, 0, "Project"); break; + case STEAM_UGC_FILE_TYPE.node_preset : array_insert_unique(tgs, 0, "Node preset"); break; + } + + array_push_unique(tgs, VERSION_STRING); + + steam_ugc_set_item_tags(STEAM_UGC_UPDATE_HANDLE, tgs); + steam_ugc_set_item_preview(STEAM_UGC_UPDATE_HANDLE, TEMPDIR + "steamUGCthumbnail.png"); + steam_ugc_set_item_content(STEAM_UGC_UPDATE_HANDLE, DIRECTORY + "steamUGC"); + + STEAM_UGC_SUBMIT_ID = steam_ugc_submit_item_update(STEAM_UGC_UPDATE_HANDLE, "Initial upload"); + exit; +} + +if(string(ev_id) == string(STEAM_UGC_SUBMIT_ID)) { + STEAM_UGC_ITEM_UPLOADING = false; + + var type = ""; + switch(STEAM_UGC_TYPE) { + case STEAM_UGC_FILE_TYPE.collection : type = "Collection"; break; + case STEAM_UGC_FILE_TYPE.project : type = "Project"; break; + case STEAM_UGC_FILE_TYPE.node_preset : type = "Node preset"; break; + } + + if(async_load[? "result"] == ugc_result_success) { + if(STEAM_UGC_UPDATE) { + log_message("WORKSHOP", type + " updated", THEME.workshop_update); + PANEL_MENU.setNotiIcon(THEME.workshop_update); + } else { + log_message("WORKSHOP", type + " uploaded", THEME.workshop_upload); + PANEL_MENU.setNotiIcon(THEME.workshop_upload); + } + + STEAM_SUB_ID = steam_ugc_subscribe_item(STEAM_UGC_PUBLISH_ID); + exit; + } + + switch(async_load[? "result"]) { #region error + case 2: log_warning("WORKSHOP", "Generic failure."); break; + case 3: log_warning("WORKSHOP", "Your Steam client doesn't have a connection to the back-end."); break; + case 5: log_warning("WORKSHOP", "Password/ticket is invalid."); break; + case 6: log_warning("WORKSHOP", "The user is logged in elsewhere."); break; + case 7: log_warning("WORKSHOP", "Protocol version is incorrect."); break; + case 8: log_warning("WORKSHOP", "A parameter is incorrect."); break; + case 9: log_warning("WORKSHOP", "File was not found."); break; + case 10: log_warning("WORKSHOP", "Called method is busy - action not taken."); break; + case 11: log_warning("WORKSHOP", "Called object was in an invalid state."); break; + case 12: log_warning("WORKSHOP", "The name was invalid."); break; + case 13: log_warning("WORKSHOP", "The email was invalid."); break; + case 14: log_warning("WORKSHOP", "The name is not unique."); break; + case 15: log_warning("WORKSHOP", "Access is denied."); break; + case 16: log_warning("WORKSHOP", "Operation timed out."); break; + case 17: log_warning("WORKSHOP", "The user is VAC2 banned."); break; + case 18: log_warning("WORKSHOP", "Account not found."); break; + case 19: log_warning("WORKSHOP", "The Steam ID was invalid."); break; + case 20: log_warning("WORKSHOP", "The requested service is currently unavailable."); break; + case 21: log_warning("WORKSHOP", "The user is not logged on."); break; + case 22: log_warning("WORKSHOP", "Request is pending, it may be in process or waiting on third party."); break; + case 23: log_warning("WORKSHOP", "Encryption or Decryption failed."); break; + case 24: log_warning("WORKSHOP", "Insufficient privilege."); break; + case 25: log_warning("WORKSHOP", "Too much of a good thing."); break; + case 26: log_warning("WORKSHOP", "Access has been revoked (used for revoked guest passes.)"); break; + case 27: log_warning("WORKSHOP", "License/Guest pass the user is trying to access is expired."); break; + case 28: log_warning("WORKSHOP", "Guest pass has already been redeemed by account, cannot be used again."); break; + case 29: log_warning("WORKSHOP", "The request is a duplicate and the action has already occurred in the past, ignored this time."); break; + case 30: log_warning("WORKSHOP", "All the games in this guest pass redemption request are already owned by the user."); break; + case 31: log_warning("WORKSHOP", "IP address not found."); break; + case 32: log_warning("WORKSHOP", "Failed to write change to the data store."); break; + case 33: log_warning("WORKSHOP", "Failed to acquire access lock for this operation."); break; + case 34: log_warning("WORKSHOP", "The logon session has been replaced."); break; + case 35: log_warning("WORKSHOP", "Failed to connect."); break; + case 36: log_warning("WORKSHOP", "The authentication handshake has failed."); break; + case 37: log_warning("WORKSHOP", "There has been a generic IO failure."); break; + case 38: log_warning("WORKSHOP", "The remote server has disconnected."); break; + case 39: log_warning("WORKSHOP", "Failed to find the shopping cart requested."); break; + case 40: log_warning("WORKSHOP", "A user blocked the action."); break; + case 41: log_warning("WORKSHOP", "The target is ignoring sender."); break; + case 42: log_warning("WORKSHOP", "Nothing matching the request found."); break; + case 43: log_warning("WORKSHOP", "The account is disabled."); break; + case 44: log_warning("WORKSHOP", "This service is not accepting content changes right now."); break; + case 45: log_warning("WORKSHOP", "Account doesn't have value, so this feature isn't available."); break; + case 46: log_warning("WORKSHOP", "Allowed to take this action, but only because requester is admin."); break; + case 47: log_warning("WORKSHOP", "A Version mismatch in content transmitted within the Steam protocol."); break; + case 48: log_warning("WORKSHOP", "The current CM can't service the user making a request, user should try another."); break; + case 49: log_warning("WORKSHOP", "You are already logged in elsewhere, this cached credential login has failed."); break; + case 50: log_warning("WORKSHOP", "The user is logged in elsewhere. (Use k_EResultLoggedInElsewhere instead!)"); break; + case 51: log_warning("WORKSHOP", "Long running operation has suspended/paused. (eg. content download.)"); break; + case 52: log_warning("WORKSHOP", "Operation has been canceled, typically by user. (eg. a content download.)"); break; + case 53: log_warning("WORKSHOP", "Operation canceled because data is ill formed or unrecoverable."); break; + case 54: log_warning("WORKSHOP", "Operation canceled - not enough disk space."); break; + case 55: log_warning("WORKSHOP", "The remote or IPC call has failed."); break; + case 56: log_warning("WORKSHOP", "Password could not be verified as it's unset server side."); break; + case 57: log_warning("WORKSHOP", "External account (PSN, Facebook...) is not linked to a Steam account."); break; + case 58: log_warning("WORKSHOP", "PSN ticket was invalid."); break; + case 59: log_warning("WORKSHOP", "External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first."); break; + case 60: log_warning("WORKSHOP", "The sync cannot resume due to a conflict between the local and remote files."); break; + case 61: log_warning("WORKSHOP", "The requested new password is not allowed."); break; + case 62: log_warning("WORKSHOP", "New value is the same as the old one. This is used for secret question and answer."); break; + case 63: log_warning("WORKSHOP", "Account login denied due to 2nd factor authentication failure."); break; + case 64: log_warning("WORKSHOP", "The requested new password is not legal."); break; + case 65: log_warning("WORKSHOP", "Account login denied due to auth code invalid."); break; + case 66: log_warning("WORKSHOP", "Account login denied due to 2nd factor auth failure - and no mail has been sent."); break; + case 67: log_warning("WORKSHOP", "The users hardware does not support Intel's Identity Protection Technology (IPT)."); break; + case 68: log_warning("WORKSHOP", "Intel's Identity Protection Technology (IPT) has failed to initialize."); break; + case 69: log_warning("WORKSHOP", "Operation failed due to parental control restrictions for current user."); break; + case 70: log_warning("WORKSHOP", "Facebook query returned an error."); break; + case 71: log_warning("WORKSHOP", "Account login denied due to an expired auth code."); break; + case 72: log_warning("WORKSHOP", "The login failed due to an IP restriction."); break; + case 73: log_warning("WORKSHOP", "The current users account is currently locked for use. This is likely due to a hijacking and pending ownership verification."); break; + case 74: log_warning("WORKSHOP", "The logon failed because the accounts email is not verified."); break; + case 75: log_warning("WORKSHOP", "There is no URL matching the provided values."); break; + case 76: log_warning("WORKSHOP", "Bad Response due to a Parse failure, missing field, etc."); break; + case 77: log_warning("WORKSHOP", "The user cannot complete the action until they re-enter their password."); break; + case 78: log_warning("WORKSHOP", "The value entered is outside the acceptable range."); break; + case 79: log_warning("WORKSHOP", "Something happened that we didn't expect to ever happen."); break; + case 80: log_warning("WORKSHOP", "The requested service has been configured to be unavailable."); break; + case 81: log_warning("WORKSHOP", "The files submitted to the CEG server are not valid."); break; + case 82: log_warning("WORKSHOP", "The device being used is not allowed to perform this action."); break; + case 83: log_warning("WORKSHOP", "The action could not be complete because it is region restricted."); break; + case 84: log_warning("WORKSHOP", "Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent."); break; + case 85: log_warning("WORKSHOP", "Need two-factor code to login."); break; + case 86: log_warning("WORKSHOP", "The thing we're trying to access has been deleted."); break; + case 87: log_warning("WORKSHOP", "Login attempt failed, try to throttle response to possible attacker."); break; + case 88: log_warning("WORKSHOP", "Two factor authentication (Steam Guard) code is incorrect."); break; + case 89: log_warning("WORKSHOP", "The activation code for two-factor authentication (Steam Guard) didn't match."); break; + case 90: log_warning("WORKSHOP", "The current account has been associated with multiple partners."); break; + case 91: log_warning("WORKSHOP", "The data has not been modified."); break; + case 92: log_warning("WORKSHOP", "The account does not have a mobile device associated with it."); break; + case 93: log_warning("WORKSHOP", "The time presented is out of range or tolerance."); break; + case 94: log_warning("WORKSHOP", "SMS code failure - no match, none pending, etc."); break; + case 95: log_warning("WORKSHOP", "Too many accounts access this resource."); break; + case 96: log_warning("WORKSHOP", "Too many changes to this account."); break; + case 97: log_warning("WORKSHOP", "Too many changes to this phone."); break; + case 98: log_warning("WORKSHOP", "Cannot refund to payment method, must use wallet."); break; + case 99: log_warning("WORKSHOP", "Cannot send an email."); break; + case 100: log_warning("WORKSHOP", "Can't perform operation until payment has settled."); break; + case 101: log_warning("WORKSHOP", "The user needs to provide a valid captcha."); break; + case 102: log_warning("WORKSHOP", "A game server login token owned by this token's owner has been banned."); break; + case 103: log_warning("WORKSHOP", "Game server owner is denied for some other reason such as account locked, community ban, vac ban, missing phone, etc."); break; + case 104: log_warning("WORKSHOP", "The type of thing we were requested to act on is invalid."); break; + case 105: log_warning("WORKSHOP", "The IP address has been banned from taking this action."); break; + case 106: log_warning("WORKSHOP", "This Game Server Login Token (GSLT) has expired from disuse; it can be reset for use."); break; + case 107: log_warning("WORKSHOP", "user doesn't have enough wallet funds to complete the action"); break; + case 108: log_warning("WORKSHOP", "There are too many of this thing pending already"); break; + } #endregion +} + +#event async_social Firebase + +if (async_load[? "type"] == "FirebaseFirestore_Collection_Query") { + PATREON_MAIL_CALLBACK(async_load); + exit; +} + +#event async_system +var ev_id = async_load[? "id"]; +var ev_type = async_load[? "event_type"]; + +if(ev_type == "file_drop") { + dropping = async_load[?"filename"]; + array_push(drop_path, dropping); +} + +#event draw_gui init +if(winMan_isMinimized()) exit; + +_MOUSE_BLOCK = MOUSE_BLOCK; +MOUSE_BLOCK = false; + +if(APP_SURF_OVERRIDE) { + APP_SURF = surface_verify(APP_SURF, WIN_W, WIN_H); + PRE_APP_SURF = surface_verify(PRE_APP_SURF, WIN_W, WIN_H); + POST_APP_SURF = surface_verify(POST_APP_SURF, WIN_W, WIN_H); + + surface_set_target(APP_SURF); +} + +draw_clear(COLORS.bg); + +#region widget scroll + if(!WIDGET_TAB_BLOCK) { + if(keyboard_check_pressed(vk_tab)) { + if(key_mod_press(SHIFT)) widget_previous(); + else widget_next(); + } + + if(keyboard_check_pressed(vk_enter)) + widget_trigger(); + + if(keyboard_check_pressed(vk_escape)) + widget_clear(); + } + + WIDGET_TAB_BLOCK = false; +#endregion + +#region register UI element + WIDGET_ACTIVE = []; +#endregion + +#region panels + if(PANEL_MAIN == 0) resetPanel(); + + var surf = surface_get_target(); + try { + PANEL_MAIN.draw(); + } catch(e) { + while(surface_get_target() != surf) + surface_reset_target(); + + noti_warning(exception_print(e)); + } + + panelDraw(); +#endregion + +#region notes + for( var i = 0, n = array_length(PROJECT.notes); i < n; i++ ) + PROJECT.notes[i].draw(); +#endregion + +#region window + winManDraw(); +#endregion + +if(APP_SURF_OVERRIDE) { #region + surface_reset_target(); + draw_surface(POST_APP_SURF, 0, 0); + + surface_set_target(PRE_APP_SURF); + draw_surface(APP_SURF, 0, 0); + surface_reset_target(); + + surface_set_target(POST_APP_SURF); + draw_surface(APP_SURF, 0, 0); + surface_reset_target(); +} #endregion + +#event draw_gui_end tooltip filedrop +if(winMan_isMinimized()) exit; + +#region tooltip + if(is_struct(TOOLTIP)) { + if(struct_has(TOOLTIP, "drawTooltip")) + TOOLTIP.drawTooltip(); + + } else if(is_array(TOOLTIP)) { + var content = TOOLTIP[0]; + var type = TOOLTIP[1]; + + if(is_method(content)) content = content(); + + switch(type) { + case VALUE_TYPE.float : + case VALUE_TYPE.integer : + case VALUE_TYPE.text : + case VALUE_TYPE.struct : + case VALUE_TYPE.path : + draw_tooltip_text(string_real(content)); + break; + + case VALUE_TYPE.boolean : + draw_tooltip_text(printBool(content)); + break; + + case VALUE_TYPE.curve : + draw_tooltip_text("[" + __txt("Curve Object") + "]"); + break; + + case VALUE_TYPE.color : + draw_tooltip_color(content); + break; + + case VALUE_TYPE.gradient : + draw_tooltip_gradient(content); + break; + + case VALUE_TYPE.d3object : + draw_tooltip_text("[" + __txt("3D Object") + "]"); + break; + + case VALUE_TYPE.object : + draw_tooltip_text("[" + __txt("Object") + "]"); + break; + + case VALUE_TYPE.surface : + draw_tooltip_surface(content); + break; + + case VALUE_TYPE.rigid : + draw_tooltip_text("[" + __txt("Rigidbody Object") + " (id: " + string(content[$ "object"]) + ")]"); + break; + + case VALUE_TYPE.particle : + var txt = "[" + + __txt("Particle Object") + + " (size: " + string(array_length(content)) + ") " + + "]"; + draw_tooltip_text(txt); + break; + + case VALUE_TYPE.pathnode : + draw_tooltip_text("[" + __txt("Path Object") + "]"); + break; + + case VALUE_TYPE.sdomain : + draw_tooltip_text("[" + __txt("Domain") + " (id: " + string(content) + ")]"); + break; + + case VALUE_TYPE.strands : + var txt = __txt("Strands Object"); + if(is_struct(content)) + txt += " (strands: " + string(array_length(content.hairs)) + ")"; + draw_tooltip_text("[" + txt + "]"); + break; + + case VALUE_TYPE.mesh : + var txt = __txt("Mesh Object"); + if(is_struct(content)) + txt += " (triangles: " + string(array_length(content.triangles)) + ")"; + draw_tooltip_text("[" + txt + "]"); + break; + + case VALUE_TYPE.d3vertex : + var txt = __txt("3D Vertex"); + txt += " (groups: " + string(array_length(content)) + ")"; + draw_tooltip_text("[" + txt + "]"); + break; + + case VALUE_TYPE.buffer : + draw_tooltip_buffer(content); + break; + + case "sprite" : + draw_tooltip_sprite(content); + break; + + default : + var tt = ""; + if(is_struct(content)) tt = $"[{instanceof(content)}] {content}"; + else tt = string(content); + + draw_tooltip_text(tt); + } + } else if(TOOLTIP != "") + draw_tooltip_text(TOOLTIP); + TOOLTIP = ""; +#endregion + +#region dragging + if(DRAGGING != noone) { + switch(DRAGGING.type) { + case "Color" : + draw_sprite_stretched_ext(THEME.color_picker_box, 1, mouse_mx + ui(-16), mouse_my + ui(-16), ui(32), ui(32), DRAGGING.data, 0.5); + break; + + case "Palette" : + drawPalette(DRAGGING.data, mouse_mx - ui(64), mouse_my - ui(12), ui(128), ui(24), 0.5); + break; + + case "Gradient" : + DRAGGING.data.draw(mouse_mx - ui(64), mouse_my - ui(12), ui(128), ui(24), 0.5); + break; + + case "Bool" : + draw_set_alpha(0.5); + draw_set_text(f_h3, fa_center, fa_center, COLORS._main_text); + draw_text_bbox({ xc: mouse_mx, yc: mouse_my, w: ui(128), h: ui(24) }, __txt(DRAGGING.data? "True" : "False")); + draw_set_alpha(1); + break; + + case "Asset" : + case "Project" : + case "Collection" : + if(DRAGGING.data.spr) { + var ss = ui(48) / max(sprite_get_width(DRAGGING.data.spr), sprite_get_height(DRAGGING.data.spr)) + draw_sprite_ext(DRAGGING.data.spr, 0, mouse_mx + ui(8), mouse_my + ui(8), ss, ss, 0, c_white, 0.5); + } + break; + + default: + draw_set_alpha(0.5); + draw_set_text(f_h3, fa_center, fa_center, COLORS._main_text); + draw_text_bbox({ xc: mouse_mx, yc: mouse_my, w: ui(128), h: ui(24) }, DRAGGING.data); + draw_set_alpha(1); + } + + if(mouse_release(mb_left)) + DRAGGING = noone; + } +#endregion + +#region safe mode + if(PROJECT.safeMode) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, 0, 0, WIN_W, WIN_H, COLORS._main_value_negative, 1); + draw_set_text(f_h1, fa_right, fa_bottom, COLORS._main_value_negative); + draw_set_alpha(0.25); + draw_text(WIN_W - ui(16), WIN_H - ui(8), __txtx("safe_mode", "SAFE MODE")); + draw_set_alpha(1); + } +#endregion + +#region draw gui top + PANEL_MAIN.drawGUI(); + + if(NODE_DROPPER_TARGET != noone) { + draw_sprite_ui(THEME.node_dropper, 0, mouse_x + ui(20), mouse_y + ui(20)); + if(mouse_press(mb_left, NODE_DROPPER_TARGET_CAN)) + NODE_DROPPER_TARGET = noone; + NODE_DROPPER_TARGET_CAN = true; + } else + NODE_DROPPER_TARGET_CAN = false; + + panelDisplayDraw(); +#endregion + +#region debug + if(global.FLAG[$ "hover_element"]) { + draw_set_text(f_p0, fa_right, fa_bottom, COLORS._main_text); + if(HOVERING_ELEMENT) + draw_text(WIN_W, WIN_H, $"[{instanceof(HOVERING_ELEMENT)}]"); + } +#endregion + +#region frame + draw_set_color(merge_color(COLORS._main_icon, COLORS._main_icon_dark, 0.95)); + draw_rectangle(1, 1, WIN_W - 2, WIN_H - 2, true); +#endregion + +#event keypress:vk_anykey +kb_hkey = keyboard_key == 0? keyboard_lastkey : keyboard_key; +kb_time = 0; +kb_hold = false; + +KEYBOARD_PRESSED = kb_hkey; + +if(keyboard_check(vk_backspace)) + KEYBOARD_STRING = string_copy(KEYBOARD_STRING, 1, string_length(KEYBOARD_STRING) - 1); +else + KEYBOARD_STRING += keyboard_lastchar; + +if(KEYBOARD_PRESSED == -1) { + for( var i = 0, n = array_length(global.KEYS_VK); i < n; i++ ) { + if(keyboard_check(global.KEYS_VK[i])) + KEYBOARD_PRESSED = global.KEYS_VK[i]; + } +} + +#event keyrelease:vk_anykey +kb_time = 0; +kb_hold = false; +keyboard_lastchar = ""; + +kb_hkey = vk_nokey; +KEYBOARD_PRESSED = vk_nokey; \ No newline at end of file diff --git a/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup0 b/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup0 index e41e97e99..316ece633 100644 --- a/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup0 +++ b/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-14 12:48:00 +// 2024-04-18 12:06:16 function canvas_brush() constructor { brush_sizing = false; brush_sizing_s = 0; diff --git a/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup1 b/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup1 index 9634571c6..e41e97e99 100644 --- a/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup1 +++ b/#backups/scripts/__canvas_brush/__canvas_brush.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-14 10:09:02 +// 2024-04-14 12:48:00 function canvas_brush() constructor { brush_sizing = false; brush_sizing_s = 0; diff --git a/#backups/scripts/__initPen/__initPen.gml.backup0 b/#backups/scripts/__initPen/__initPen.gml.backup0 new file mode 100644 index 000000000..7ccc88d17 --- /dev/null +++ b/#backups/scripts/__initPen/__initPen.gml.backup0 @@ -0,0 +1,25 @@ +// 2024-04-18 12:09:37 +globalvar PEN_USE, PEN_CONTACT, PEN_RELEASED, PEN_PRESSURE; +globalvar PEN_X, PEN_Y, PEN_X_DELTA, PEN_Y_DELTA; +globalvar PEN_RIGHT_CLICK, PEN_RIGHT_PRESS, PEN_RIGHT_RELEASE; + +PEN_USE = false; + +PEN_X = 0; +PEN_Y = 0; + +PEN_X_DELTA = 0; +PEN_Y_DELTA = 0; + +PEN_CONTACT = false; +PEN_PRESSURE = 0; + +PEN_RIGHT_CLICK = false; +PEN_RIGHT_PRESS = false; +PEN_RIGHT_RELEASE = false; + +function __initPen() { + var c = tabletstuff_get_init_error_code(); + if (c != tabletstuff_error_none) + show_error("Unable to initialize TabletStuff. Code=" + tabletstuff_error_to_string(c), true); +} \ No newline at end of file diff --git a/#backups/scripts/__initPen/__initPen.gml.backup1 b/#backups/scripts/__initPen/__initPen.gml.backup1 new file mode 100644 index 000000000..65986ca03 --- /dev/null +++ b/#backups/scripts/__initPen/__initPen.gml.backup1 @@ -0,0 +1,25 @@ +// 2024-04-18 11:51:43 +globalvar PEN_USE, PEN_CONTACT, PEN_RELEASED, PEN_PRESSURE; +globalvar PEN_X, PEN_Y, PEN_X_DELTA, PEN_Y_DELTA; +globalvar PEN_RIGHT_CLICK, PEN_RIGHT_PRESS, PEN_RIGHT_RELEASE; + +PEN_USE = false; + +PEN_X = 0; +PEN_Y = 0; + +PEN_X_DELTA = 0; +PEN_Y_DELTA = 0; + +PEN_CONTACT = false; +PEN_PRESSURE = 0; + +PEN_RIGHT_CLICK = false; +PEN_RIGHT_PRESS = false; +PEN_RIGHT_RELEASE = false; + +function __initPen() { + var c = tabletstuff_get_init_error_code(); + if (c != tabletstuff_error_none) + show_error("Unable to initialize TabletStuff. Code=" + tabletstuff_error_to_string(c), true); +} \ No newline at end of file diff --git a/#backups/scripts/buttonGroup/buttonGroup.gml.backup0 b/#backups/scripts/buttonGroup/buttonGroup.gml.backup0 new file mode 100644 index 000000000..a762e967e --- /dev/null +++ b/#backups/scripts/buttonGroup/buttonGroup.gml.backup0 @@ -0,0 +1,133 @@ +// 2024-04-18 12:09:27 +function buttonGroup(_data, _onClick) : widget() constructor { + data = _data; + onClick = _onClick; + + display_button = false; + buttonSpr = [ THEME.button_left, THEME.button_middle, THEME.button_right ]; + fColor = COLORS._main_text; + + current_selecting = 0; + tooltips = []; + + for(var i = 0; i < array_length(data); i++) + buttons[i] = button(-1); + + sb_small = new scrollBox(data, _onClick); + + static setFont = function(font) { + self.font = font; + return self; + } + + static setTooltips = function(tt) { tooltips = tt; return self; } + + static trigger = function() { + if(current_selecting + 1 >= array_length(data)) + onClick(0); + else + onClick(current_selecting + 1); + } + + static setInteract = function(interactable = noone) { + self.interactable = interactable; + for(var i = 0; i < array_length(data); i++) + buttons[i].interactable = interactable; + sb_small.interactable = interactable; + } + + static register = function(parent = noone) { + if(display_button) { + array_push(WIDGET_ACTIVE, self); + self.parent = parent; + } else + sb_small.register(parent); + } + + static drawParam = function(params) { + setParam(params); + sb_small.setParam(params); + + return draw(params.x, params.y, params.w, params.h, params.data, params.m, params.rx, params.ry); + } + + static draw = function(_x, _y, _w, _h, _selecting, _m, _rx = 0, _ry = 0) { + x = _x; + y = _y; + w = _w; + h = _h; + current_selecting = _selecting; + while(is_array(current_selecting)) + current_selecting = array_safe_get_fast(current_selecting, 0); + hovering = hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + var amo = array_length(data); + var ww = _w / amo; + + var total_width = 0; + draw_set_font(font); + for(var i = 0; i < amo; i++) { + if(is_string(data[i])) + total_width += string_width(data[i]) + ui(32); + } + + display_button = total_width < _w; + + if(display_button) { + var bx = _x; + var draw_sel = noone; + + for(var i = 0; i < amo; i++) { + buttons[i].setFocusHover(active, hover); + buttons[i].tooltip = array_safe_get(tooltips, i, ""); + + var spr = i == 0 ? buttonSpr[0] : (i == amo - 1? buttonSpr[2] : buttonSpr[1]); + + if(_selecting == i) { + draw_sprite_stretched(spr, 2, floor(bx), _y, ceil(ww), _h); + draw_sel = [spr, bx]; + } else { + buttons[i].draw(floor(bx), _y, ceil(ww), _h, _m, spr); + if(buttons[i].clicked) onClick(i); + } + + if(is_string(data[i])) { + draw_set_text(font, fa_center, fa_center, fColor); + draw_text(bx + ww / 2, _y + _h / 2, data[i]); + } else if(sprite_exists(data[i])) { + draw_sprite_ui_uniform(data[i], i, bx + ww / 2, _y + _h / 2); + } + + bx += ww; + } + + if(draw_sel != noone) + draw_sprite_stretched_ext(draw_sel[0], 3, draw_sel[1], _y, ww, _h, COLORS._main_accent, 1); + + if(point_in_rectangle(_m[0], _m[1], _x, _y, _x + w, _y + _h)) { + if(is_array(data) && key_mod_press(SHIFT)) { + var len = array_length(data); + if(len) { + if(mouse_wheel_down()) onClick(safe_mod(_selecting + 1 + len, len)); + if(mouse_wheel_up()) onClick(safe_mod(_selecting - 1 + len, len)); + } + } + } + } else { + sb_small.setFocusHover(active, hover); + sb_small.draw(_x, _y, _w, _h, data[_selecting], _m, _rx, _ry); + } + + if(WIDGET_CURRENT == self) + draw_sprite_stretched_ext(THEME.widget_selecting, 0, x - ui(3), y - ui(3), w + ui(6), h + ui(6), COLORS._main_accent, 1); + + resetFocus(); + + return h; + } + + static clone = function() { #region + var cln = new buttonGroup(data, onClick); + return cln; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/buttonGroup/buttonGroup.gml.backup1 b/#backups/scripts/buttonGroup/buttonGroup.gml.backup1 new file mode 100644 index 000000000..8ae3973bb --- /dev/null +++ b/#backups/scripts/buttonGroup/buttonGroup.gml.backup1 @@ -0,0 +1,133 @@ +// 2024-04-18 08:59:10 +function buttonGroup(_data, _onClick) : widget() constructor { + data = _data; + onClick = _onClick; + + display_button = false; + buttonSpr = [ THEME.button_left, THEME.button_middle, THEME.button_right ]; + fColor = COLORS._main_text; + + current_selecting = 0; + tooltips = []; + + for(var i = 0; i < array_length(data); i++) + buttons[i] = button(-1); + + sb_small = new scrollBox(data, _onClick); + + static setFont = function(font) { + self.font = font; + return self; + } + + static setTooltips = function(tt) { tooltips = tt; return self; } + + static trigger = function() { + if(current_selecting + 1 >= array_length(data)) + onClick(0); + else + onClick(current_selecting + 1); + } + + static setInteract = function(interactable = noone) { + self.interactable = interactable; + for(var i = 0; i < array_length(data); i++) + buttons[i].interactable = interactable; + sb_small.interactable = interactable; + } + + static register = function(parent = noone) { + if(display_button) { + array_push(WIDGET_ACTIVE, self); + self.parent = parent; + } else + sb_small.register(parent); + } + + static drawParam = function(params) { + setParam(params); + sb_small.setParam(params); + + return draw(params.x, params.y, params.w, params.h, params.data, params.m, params.rx, params.ry); + } + + static draw = function(_x, _y, _w, _h, _selecting, _m, _rx = 0, _ry = 0) { + x = _x; + y = _y; + w = _w; + h = _h; + current_selecting = _selecting; + while(is_array(current_selecting)) + current_selecting = array_safe_get_fast(current_selecting, 0); + hovering = hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + var amo = array_length(data); + var ww = _w / amo; + + var total_width = 0; + draw_set_font(font); + for(var i = 0; i < amo; i++) { + if(is_string(data[i])) + total_width += string_width(data[i]) + ui(32); + } + + display_button = total_width < _w; + + if(display_button) { + var bx = _x; + var draw_sel = noone; + + for(var i = 0; i < amo; i++) { + buttons[i].setFocusHover(active, hover); + buttons[i].tooltip = array_safe_get(tooltips, i, ""); + + var spr = i == 0 ? buttonSpr[0] : (i == amo - 1? buttonSpr[2] : buttonSpr[1]); + + if(_selecting == i) { + draw_sprite_stretched(spr, 2, floor(bx), _y, ceil(ww), _h); + draw_sel = [spr, bx]; + } else { + buttons[i].draw(floor(bx), _y, ceil(ww), _h, _m, spr); + if(buttons[i].clicked) onClick(i); + } + + if(is_string(data[i])) { + draw_set_text(font, fa_center, fa_center, fColor); + draw_text(bx + ww / 2, _y + _h / 2, data[i]); + } else if(sprite_exists(data[i])) { + draw_sprite_ui_uniform(data[i], i, bx + ww / 2, _y + _h / 2); + } + + bx += ww; + } + + if(draw_sel != noone) + draw_sprite_stretched_ext(draw_sel[0], 3, draw_sel[1], _y, ww, _h, COLORS._main_accent, 1); + + if(point_in_rectangle(_m[0], _m[1], _x, _y, _x + w, _y + _h)) { + if(is_array(data) && key_mod_press(SHIFT)) { + var len = array_length(data); + if(len) { + if(mouse_wheel_down()) onClick(safe_mod(_selecting + 1 + len, len)); + if(mouse_wheel_up()) onClick(safe_mod(_selecting - 1 + len, len)); + } + } + } + } else { + sb_small.setFocusHover(active, hover); + sb_small.draw(_x, _y, _w, _h, data[_selecting], _m, _rx, _ry); + } + + if(WIDGET_CURRENT == self) + draw_sprite_stretched_ext(THEME.widget_selecting, 0, x - ui(3), y - ui(3), w + ui(6), h + ui(6), COLORS._main_accent, 1); + + resetFocus(); + + return h; + } + + static clone = function() { #region + var cln = new buttonGroup(data, onClick); + return cln; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 index 7ff9b4316..9da23409e 100644 --- a/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 +++ b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-15 17:50:18 +// 2024-04-18 12:09:16 function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region if(brush.brush_surface == noone) { @@ -136,15 +136,32 @@ function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region return; } - var _min_x = min(_x0, _x1) - 1; - var _max_x = max(_x0, _x1); - var _min_y = min(_y0, _y1) - 1; - var _max_y = max(_y0, _y1); + draw_set_circle_precision(64); + var _min_x = min(_x0, _x1) - 0.5; + var _max_x = max(_x0, _x1) - 0.5; + var _min_y = min(_y0, _y1) - 0.5; + var _max_y = max(_y0, _y1) - 0.5; - if(_fill) { - draw_set_circle_precision(64); - draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + if(brush.brush_surface == noone) { + if(_fill) draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + + if(brush.brush_size == 1) { + draw_ellipse(_min_x, _min_y, _max_x, _max_y, 1); + + } else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_ellipse(_min_x + fx[i][0], _min_y + fx[i][1], _max_x + fx[i][0], _max_y + fx[i][1], 1); + + } else { + draw_ellipse(_min_x, _min_y, _max_x, _max_y, brush.brush_size); + + } + return; } + + if(_fill) draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); var samp = 64; var cx = (_min_x + _max_x) / 2; diff --git a/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 index cf6c95a8f..dbfc1639f 100644 --- a/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 +++ b/#backups/scripts/canvas_draw_functions/canvas_draw_functions.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-15 17:50:17 +// 2024-04-18 08:58:48 function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region if(brush.brush_surface == noone) { @@ -136,15 +136,32 @@ function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region return; } - var _min_x = min(_x0, _x1) - 1; - var _max_x = max(_x0, _x1); - var _min_y = min(_y0, _y1) - 1; - var _max_y = max(_y0, _y1); + draw_set_circle_precision(64); + var _min_x = min(_x0, _x1) - 0.5; + var _max_x = max(_x0, _x1) - 0.5; + var _min_y = min(_y0, _y1) - 0.5; + var _max_y = max(_y0, _y1) - 0.5; - if(_fill) { - draw_set_circle_precision(64); - draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + if(brush.brush_surface == noone) { + if(_fill) draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + + if(brush.brush_size == 1) { + draw_ellipse(_min_x, _min_y, _max_x, _max_y, 1); + + } else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_ellipse(_min_x + fx[i][0], _min_y + fx[i][1], _max_x + fx[i][0], _max_y + fx[i][1], 1); + + } else { + draw_ellipse(_min_x, _min_y, _max_x, _max_y, brush.brush_size); + + } + return; } + + if(_fill) draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); var samp = 64; var cx = (_min_x + _max_x) / 2; diff --git a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 index eccb4747c..5f888dbdb 100644 --- a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 +++ b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-16 15:02:26 +// 2024-04-18 12:08:52 function canvas_tool_node(canvas, node) : canvas_tool() constructor { self.canvas = canvas; @@ -23,25 +23,34 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { surface_reset_shader(); static destroy = function() { - noti_warning("Selected node has no surface output."); - if(applySelection) canvas.tool_selection.apply(); canvas.nodeTool = noone; - surface_free_safe(maskedSurface); - cleanUp(); } static cleanUp = function() { surface_free_safe(targetSurface); surface_free_safe(maskedSurface); - nodeObject.destroy(); + + if(is_struct(nodeObject)) { + if(is_instanceof(nodeObject, Node)) + nodeObject.destroy(); + + else { + var keys = struct_get_names(nodeObject); + for (var i = 0, n = array_length(keys); i < n; i++) + if(is_instanceof(nodeObject[$ keys[i]], Node)) + nodeObject[$ keys[i]].destroy(); + } + } + } nodeObject = node.build(0, 0); if(nodeObject == noone || !is_instanceof(nodeObject, Node)) { + noti_warning("Not tools only allows a single node."); destroy(); return; } @@ -66,6 +75,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { } if(outputJunction == noone) { + noti_warning("Selected node has no surface output."); destroy(); return; } diff --git a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 index b03cbccf0..20ec1d1e2 100644 --- a/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 +++ b/#backups/scripts/canvas_tool_node/canvas_tool_node.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-16 15:02:19 +// 2024-04-17 08:13:29 function canvas_tool_node(canvas, node) : canvas_tool() constructor { self.canvas = canvas; @@ -23,25 +23,34 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { surface_reset_shader(); static destroy = function() { - noti_warning("Selected node has no surface output."); - if(applySelection) canvas.tool_selection.apply(); canvas.nodeTool = noone; - surface_free_safe(maskedSurface); - cleanUp(); } static cleanUp = function() { surface_free_safe(targetSurface); surface_free_safe(maskedSurface); - nodeObject.destroy(); + + if(is_struct(nodeObject)) { + if(is_instanceof(nodeObject, Node)) + nodeObject.destroy(); + + else { + var keys = struct_get_names(nodeObject); + for (var i = 0, n = array_length(keys); i < n; i++) + if(is_instanceof(nodeObject[$ keys[i]], Node)) + nodeObject[$ keys[i]].destroy(); + } + } + } nodeObject = node.build(0, 0); if(nodeObject == noone || !is_instanceof(nodeObject, Node)) { + noti_warning("Not tools only allows a single node."); destroy(); return; } @@ -66,6 +75,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { } if(outputJunction == noone) { + noti_warning("Selected node has no surface output."); destroy(); return; } diff --git a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 index b843559b4..2d0e18313 100644 --- a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 +++ b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-15 19:18:42 +// 2024-04-18 12:08:45 function canvas_tool_selection(selector = noone) : canvas_tool() constructor { self.selector = selector; @@ -230,15 +230,18 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { selection_sy = pos_y; selection_mx = mouse_cur_x; selection_my = mouse_cur_y; + } } if(key_press(vk_delete)) { is_selected = false; surface_free(selection_surface); - } - - if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); + + } else if(key_press(vk_escape)) { + apply(); + + } else if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); } #endregion function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region diff --git a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 index 6245b0570..035ac0c1b 100644 --- a/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 +++ b/#backups/scripts/canvas_tool_selection/canvas_tool_selection.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-15 19:18:37 +// 2024-04-18 09:09:57 function canvas_tool_selection(selector = noone) : canvas_tool() constructor { self.selector = selector; @@ -230,15 +230,18 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { selection_sy = pos_y; selection_mx = mouse_cur_x; selection_my = mouse_cur_y; + } } if(key_press(vk_delete)) { is_selected = false; surface_free(selection_surface); - } - - if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); + + } else if(key_press(vk_escape)) { + apply(); + + } else if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); } #endregion function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region diff --git a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 index a99435b94..f89882dfb 100644 --- a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 +++ b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup0 @@ -1,8 +1,10 @@ -// 2024-04-16 10:03:25 +// 2024-04-18 12:08:38 function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor { self.tool_attribute = toolAttr; + selecting = false; + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { mouse_cur_x = round((_mx - _x) / _s - 0.5); @@ -14,7 +16,7 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection var _fill_type = tool_attribute.fill8; if(!selector.is_select_drag && mouse_press(mb_left, active)) { - + selecting = true; canvas_buffer = node.canvas_buffer; preview_index = node.preview_index; @@ -58,7 +60,8 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection if(node.selection_tool_after != noone) node.selection_tool_after.toggle(); node.selection_tool_after = noone; - } + } else + selector.apply(); } } diff --git a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 index 91cb9ae24..ed48052b9 100644 --- a/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 +++ b/#backups/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml.backup1 @@ -1,8 +1,10 @@ -// 2024-04-16 10:03:18 +// 2024-04-18 09:15:40 function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor { self.tool_attribute = toolAttr; + selecting = false; + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { mouse_cur_x = round((_mx - _x) / _s - 0.5); @@ -14,7 +16,7 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection var _fill_type = tool_attribute.fill8; if(!selector.is_select_drag && mouse_press(mb_left, active)) { - + selecting = true; canvas_buffer = node.canvas_buffer; preview_index = node.preview_index; @@ -58,7 +60,8 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection if(node.selection_tool_after != noone) node.selection_tool_after.toggle(); node.selection_tool_after = noone; - } + } else + selector.apply(); } } diff --git a/#backups/scripts/checkboxGroup/checkboxGroup.gml.backup0 b/#backups/scripts/checkboxGroup/checkboxGroup.gml.backup0 new file mode 100644 index 000000000..c36c26997 --- /dev/null +++ b/#backups/scripts/checkboxGroup/checkboxGroup.gml.backup0 @@ -0,0 +1,81 @@ +// 2024-04-18 12:08:32 +function checkBoxGroup(sprs, _onClick) : widget() constructor { + self.sprs = sprs; + self.size = sprite_get_number(sprs); + onClick = _onClick; + + holding = noone; + tooltips = []; + + static trigger = function(ind, val) { onClick(ind, val); } + static setTooltips = function(tt) { tooltips = tt; return self; } + + static drawParam = function(params) { + setParam(params); + + return draw(params.x, params.y, params.data, params.m, params.s); + } + + static draw = function(_x, _y, _value, _m, ss = ui(28), halign = fa_left, valign = fa_top) { + x = _x; + y = _y; + w = ss * size; + h = ss; + + var _dx, _dy; + switch(halign) { + case fa_left: _dx = _x; break; + case fa_center: _dx = _x - ss / 2; break; + case fa_right: _dx = _x - ss; break; + } + + switch(valign) { + case fa_top: _dy = _y; break; + case fa_center: _dy = _y - ss / 2; break; + case fa_bottom: _dy = _y - ss; break; + } + + if(mouse_release(mb_left)) + holding = noone; + + var aa = interactable * 0.25 + 0.75; + for( var i = 0; i < size; i++ ) { + var spr = i == 0 ? THEME.button_left : (i == size - 1? THEME.button_right : THEME.button_middle); + var ind = _value[i] * 2; + + if(hover && point_in_rectangle(_m[0], _m[1], _dx, _dy, _dx + ss, _dy + ss)) { + ind = 1 + TOOLTIP = array_safe_get(tooltips, i, ""); + + if(holding != noone) + trigger(i, holding); + + if(mouse_press(mb_left, active)) { + trigger(i, !_value[i]); + holding = _value[i]; + } + } else + if(mouse_press(mb_left)) deactivate(); + + draw_sprite_stretched_ext(spr, ind, _dx, _dy, ss, ss, c_white, aa); + if(_value[i]) + draw_sprite_stretched_ext(spr, 3, _dx, _dy, ss, ss, COLORS._main_accent, 1); + draw_sprite_ext(sprs, i, _dx + ss / 2, _dy + ss / 2, 1, 1, 0, c_white, 0.5 + _value[i] * 0.5); + + _dx += ss; + } + + if(WIDGET_CURRENT == self) + draw_sprite_stretched_ext(THEME.widget_selecting, 0, _dx - ui(3), _dy - ui(3), ss + ui(6), ss + ui(6), COLORS._main_accent, 1); + + resetFocus(); + + return h; + } + + static clone = function() { #region + var cln = new checkBoxGroup(sprs, onClick); + + return cln; + } #endregion +} diff --git a/#backups/scripts/checkboxGroup/checkboxGroup.gml.backup1 b/#backups/scripts/checkboxGroup/checkboxGroup.gml.backup1 new file mode 100644 index 000000000..587948ef9 --- /dev/null +++ b/#backups/scripts/checkboxGroup/checkboxGroup.gml.backup1 @@ -0,0 +1,81 @@ +// 2024-04-18 08:59:03 +function checkBoxGroup(sprs, _onClick) : widget() constructor { + self.sprs = sprs; + self.size = sprite_get_number(sprs); + onClick = _onClick; + + holding = noone; + tooltips = []; + + static trigger = function(ind, val) { onClick(ind, val); } + static setTooltips = function(tt) { tooltips = tt; return self; } + + static drawParam = function(params) { + setParam(params); + + return draw(params.x, params.y, params.data, params.m, params.s); + } + + static draw = function(_x, _y, _value, _m, ss = ui(28), halign = fa_left, valign = fa_top) { + x = _x; + y = _y; + w = ss * size; + h = ss; + + var _dx, _dy; + switch(halign) { + case fa_left: _dx = _x; break; + case fa_center: _dx = _x - ss / 2; break; + case fa_right: _dx = _x - ss; break; + } + + switch(valign) { + case fa_top: _dy = _y; break; + case fa_center: _dy = _y - ss / 2; break; + case fa_bottom: _dy = _y - ss; break; + } + + if(mouse_release(mb_left)) + holding = noone; + + var aa = interactable * 0.25 + 0.75; + for( var i = 0; i < size; i++ ) { + var spr = i == 0 ? THEME.button_left : (i == size - 1? THEME.button_right : THEME.button_middle); + var ind = _value[i] * 2; + + if(hover && point_in_rectangle(_m[0], _m[1], _dx, _dy, _dx + ss, _dy + ss)) { + ind = 1 + TOOLTIP = array_safe_get(tooltips, i, ""); + + if(holding != noone) + trigger(i, holding); + + if(mouse_press(mb_left, active)) { + trigger(i, !_value[i]); + holding = _value[i]; + } + } else + if(mouse_press(mb_left)) deactivate(); + + draw_sprite_stretched_ext(spr, ind, _dx, _dy, ss, ss, c_white, aa); + if(_value[i]) + draw_sprite_stretched_ext(spr, 3, _dx, _dy, ss, ss, COLORS._main_accent, 1); + draw_sprite_ext(sprs, i, _dx + ss / 2, _dy + ss / 2, 1, 1, 0, c_white, 0.5 + _value[i] * 0.5); + + _dx += ss; + } + + if(WIDGET_CURRENT == self) + draw_sprite_stretched_ext(THEME.widget_selecting, 0, _dx - ui(3), _dy - ui(3), ss + ui(6), ss + ui(6), COLORS._main_accent, 1); + + resetFocus(); + + return h; + } + + static clone = function() { #region + var cln = new checkBoxGroup(sprs, onClick); + + return cln; + } #endregion +} diff --git a/#backups/scripts/globals/globals.gml.backup0 b/#backups/scripts/globals/globals.gml.backup0 index 21ea44562..24c94b177 100644 --- a/#backups/scripts/globals/globals.gml.backup0 +++ b/#backups/scripts/globals/globals.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-16 08:32:52 +// 2024-04-18 12:08:21 #region save globalvar LOADING, CLONING, CLONING_GROUP; globalvar CONNECTION_CONFLICT, LOADING_VERSION; @@ -39,7 +39,7 @@ LATEST_VERSION = 11600; VERSION = 11700; SAVE_VERSION = 11690; - VERSION_STRING = "1.17.rc1"; + VERSION_STRING = "1.17.rc3"; BUILD_NUMBER = 11700; globalvar HOTKEYS, HOTKEY_CONTEXT; diff --git a/#backups/scripts/globals/globals.gml.backup1 b/#backups/scripts/globals/globals.gml.backup1 index 2b71aad65..03fd9f50b 100644 --- a/#backups/scripts/globals/globals.gml.backup1 +++ b/#backups/scripts/globals/globals.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-15 17:50:18 +// 2024-04-18 12:08:17 #region save globalvar LOADING, CLONING, CLONING_GROUP; globalvar CONNECTION_CONFLICT, LOADING_VERSION; @@ -39,7 +39,7 @@ LATEST_VERSION = 11600; VERSION = 11700; SAVE_VERSION = 11690; - VERSION_STRING = "1.17.rc1"; + VERSION_STRING = "1.17.rc3"; BUILD_NUMBER = 11700; globalvar HOTKEYS, HOTKEY_CONTEXT; diff --git a/#backups/scripts/load_function/load_function.gml.backup0 b/#backups/scripts/load_function/load_function.gml.backup0 new file mode 100644 index 000000000..cdb498602 --- /dev/null +++ b/#backups/scripts/load_function/load_function.gml.backup0 @@ -0,0 +1,341 @@ +// 2024-04-18 12:08:08 +function LOAD(safe = false) { #region + if(DEMO) return false; + + var path = get_open_filename("Pixel Composer project (.pxc)|*.pxc;*.cpxc", ""); + key_release(); + if(path == "") return; + if(filename_ext(path) != ".json" && filename_ext(path) != ".pxc") return; + + gc_collect(); + var proj = LOAD_PATH(path, false, safe); +} #endregion + +function TEST_PATH(path) { #region + TESTING = true; + TEST_ERROR = true; + + PROJECT.cleanup(); + PROJECT = new Project(); + PANEL_GRAPH.setProject(PROJECT); + + LOAD_AT(path); +} #endregion + +function LOAD_PATH(path, readonly = false, safe_mode = false) { #region + for( var i = 0, n = array_length(PROJECTS); i < n; i++ ) + if(PROJECTS[i].path == path) return; + + var _PROJECT = PROJECT; + PROJECT = new Project(); + + if(_PROJECT == noone) { + PROJECTS = [ PROJECT ]; + + } else if(_PROJECT.path == "" && !_PROJECT.modified) { + var ind = array_find(PROJECTS, _PROJECT); + if(ind == -1) ind = 0; + PROJECTS[ind] = PROJECT; + + if(!IS_CMD) PANEL_GRAPH.setProject(PROJECT); + + } else { + if(!IS_CMD) { + var graph = new Panel_Graph(PROJECT); + PANEL_GRAPH.panel.setContent(graph, true); + PANEL_GRAPH = graph; + } + array_push(PROJECTS, PROJECT); + } + + var res = LOAD_AT(path, readonly); + if(!res) return false; + + PROJECT.safeMode = safe_mode; + if(!IS_CMD) + setFocus(PANEL_GRAPH.panel); + + return PROJECT; +} #endregion + +function LOAD_AT(path, readonly = false, override = false) { #region + static log = false; + + CALL("load"); + + printIf(log, $"========== Loading {path} =========="); var t0 = get_timer(), t1 = get_timer(); + + if(DEMO) return false; + + if(!file_exists_empty(path)) { + log_warning("LOAD", $"File not found: {path}"); + return false; + } + + if(filename_ext(path) != ".json" && filename_ext(path) != ".pxc" && filename_ext(path) != ".cpxc") { + log_warning("LOAD", "File not a valid PROJECT"); + return false; + } + + LOADING = true; + + if(override) { + nodeCleanUp(); + clearPanel(); + setPanel(); + if(!TESTING) + instance_destroy(_p_dialog); + ds_list_clear(ERRORS); + } + + printIf(log, $" > Check file : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + var temp_path = TEMPDIR; + directory_verify(temp_path); + + var temp_file_path = TEMPDIR + string(UUID_generate(6)); + if(file_exists_empty(temp_file_path)) file_delete(temp_file_path); + file_copy(path, temp_file_path); + + PROJECT.readonly = readonly; + SET_PATH(PROJECT, path); + + printIf(log, $" > Create temp : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + var _load_content; + var _ext = filename_ext(path); + var s; + + if(_ext == ".pxc") { + var f = file_text_open_read(path); + s = file_text_read_all(f); + file_text_close(f); + + } else if(_ext == ".cpxc") { + var b = buffer_decompress(buffer_load(path)); + s = buffer_read(b, buffer_string); + } + + _load_content = json_try_parse(s); + + printIf(log, $" > Load struct : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(struct_has(_load_content, "version")) { + var _v = _load_content.version; + + PROJECT.version = _v; + LOADING_VERSION = _v; + + if(PREFERENCES.notify_load_version && floor(_v) != floor(SAVE_VERSION)) { + var warn = $"File version mismatch : loading file version {_v} to Pixel Composer {SAVE_VERSION}"; + log_warning("LOAD", warn); + } + } else { + var warn = $"File version mismatch : loading old format to Pixel Composer {SAVE_VERSION}"; + log_warning("LOAD", warn); + } + + printIf(log, $" > Load meta : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + var create_list = ds_list_create(); + if(struct_has(_load_content, "nodes")) { + try { + var _node_list = _load_content.nodes; + for(var i = 0, n = array_length(_node_list); i < n; i++) { + var _node = nodeLoad(_node_list[i]); + if(_node) ds_list_add(create_list, _node); + } + } catch(e) { + log_warning("LOAD", exception_print(e)); + } + } + + printIf(log, $" > Load nodes : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + if(struct_has(_load_content, "animator")) { + var _anim_map = _load_content.animator; + PROJECT.animator.frames_total = struct_try_get(_anim_map, "frames_total", 30); + PROJECT.animator.framerate = struct_try_get(_anim_map, "framerate", 30); + PROJECT.animator.frame_range = struct_try_get(_anim_map, "frame_range", noone); + } + } catch(e) { + log_warning("LOAD, animator", exception_print(e)); + } + + if(struct_has(_load_content, "onion_skin")) + struct_override(PROJECT.onion_skin, _load_content.onion_skin); + + if(struct_has(_load_content, "previewGrid")) + struct_override(PROJECT.previewGrid, _load_content.previewGrid); + + if(struct_has(_load_content, "graphGrid")) + struct_override(PROJECT.graphGrid, _load_content.graphGrid); + + if(struct_has(_load_content, "attributes")) + struct_override(PROJECT.attributes, _load_content.attributes); + PROJECT.setPalette(); + + if(struct_has(_load_content, "notes")) { + PROJECT.notes = array_create(array_length(_load_content.notes)); + for( var i = 0, n = array_length(_load_content.notes); i < n; i++ ) + PROJECT.notes[i] = new Note.deserialize(_load_content.notes[i]); + } + + try { + if(struct_has(_load_content, "metadata")) + PROJECT.meta.deserialize(_load_content.metadata); + } catch(e) { + log_warning("LOAD, metadata", exception_print(e)); + } + + PROJECT.globalNode = new Node_Global(); + try { + if(struct_has(_load_content, "global")) + PROJECT.globalNode.deserialize(_load_content.global); + else if(struct_has(_load_content, "global_node")) + PROJECT.globalNode.deserialize(_load_content.global_node); + } catch(e) { + log_warning("LOAD, global", exception_print(e)); + } + + try { + if(struct_has(_load_content, "addon")) { + var _addon = _load_content.addon; + PROJECT.addons = _addon; + struct_foreach(_addon, function(_name, _value) { addonLoad(_name, false); }); + } else + PROJECT.addons = {}; + } catch(e) { + log_warning("LOAD, addon", exception_print(e)); + } + + printIf(log, $" > Load data : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + ds_queue_clear(CONNECTION_CONFLICT); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].loadGroup(); + } catch(e) { + log_warning("LOAD, group", exception_print(e)); + return false; + } + + printIf(log, $" > Load group : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].postDeserialize(); + } catch(e) { + log_warning("LOAD, deserialize", exception_print(e)); + } + + printIf(log, $" > Deserialize: {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].applyDeserialize(); + } catch(e) { + log_warning("LOAD, apply deserialize", exception_print(e)); + } + + printIf(log, $" > Apply deserialize : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].preConnect(); + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].connect(); + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].postConnect(); + } catch(e) { + log_warning("LOAD, connect", exception_print(e)); + } + + printIf(log, $" > Connect : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(!ds_queue_empty(CONNECTION_CONFLICT)) { + var pass = 0; + + try { + while(++pass < 4 && !ds_queue_empty(CONNECTION_CONFLICT)) { + var size = ds_queue_size(CONNECTION_CONFLICT); + log_message("LOAD", $"[Connect] {size} Connection conflict(s) detected (pass: {pass})"); + repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).connect(); + repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).postConnect(); + Render(); + } + + if(!ds_queue_empty(CONNECTION_CONFLICT)) + log_warning("LOAD", "Some connection(s) is unsolved. This may caused by render node not being update properly, or image path is broken."); + } catch(e) { + log_warning("LOAD, connect solver", exception_print(e)); + } + } + + printIf(log, $" > Conflict : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].postLoad(); + } catch(e) { + log_warning("LOAD, connect", exception_print(e)); + } + + printIf(log, $" > Post load : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].clearInputCache(); + } catch(e) { + log_warning("LOAD, connect", exception_print(e)); + } + + printIf(log, $" > Clear cache : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + RENDER_ALL_REORDER + + LOADING = false; + PROJECT.modified = false; + + log_message("FILE", "load " + path, THEME.noti_icon_file_load); + log_console("Loaded project: " + path); + + if(!IS_CMD) PANEL_MENU.setNotiIcon(THEME.noti_icon_file_load); + + refreshNodeMap(); + + printIf(log, $" > Refresh map : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(struct_has(_load_content, "timelines") && !array_empty(_load_content.timelines.contents)) + PROJECT.timelines.deserialize(_load_content.timelines); + + printIf(log, $" > Timeline : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(!IS_CMD) run_in(1, PANEL_GRAPH.toCenterNode); + + printIf(log, $"========== Load {ds_map_size(PROJECT.nodeMap)} nodes completed in {(get_timer() - t0) / 1000} ms =========="); + + return true; +} #endregion + +function __IMPORT_ZIP() { #region + var path = get_open_filename("Pixel Composer portable project (.zip)|*.zip", ""); + + var _fname = filename_name_only(path); + var _fext = filename_ext(path); + if(_fext != ".zip") return false; + + directory_verify(TEMPDIR + "proj/"); + var _dir = TEMPDIR + "proj/" + _fname; + directory_create(_dir); + zip_unzip(path, _dir); + + var _f = file_find_first(_dir + "/*.pxc", fa_none); + var _proj = $"{_dir}/{_f}"; + print(_proj); + if(!file_exists_empty(_proj)) return false; + + LOAD_PATH(_proj, true); +} #endregion \ No newline at end of file diff --git a/#backups/scripts/load_function/load_function.gml.backup1 b/#backups/scripts/load_function/load_function.gml.backup1 new file mode 100644 index 000000000..93562b8b0 --- /dev/null +++ b/#backups/scripts/load_function/load_function.gml.backup1 @@ -0,0 +1,341 @@ +// 2024-04-18 11:54:26 +function LOAD(safe = false) { #region + if(DEMO) return false; + + var path = get_open_filename("Pixel Composer project (.pxc)|*.pxc;*.cpxc", ""); + key_release(); + if(path == "") return; + if(filename_ext(path) != ".json" && filename_ext(path) != ".pxc") return; + + gc_collect(); + var proj = LOAD_PATH(path, false, safe); +} #endregion + +function TEST_PATH(path) { #region + TESTING = true; + TEST_ERROR = true; + + PROJECT.cleanup(); + PROJECT = new Project(); + PANEL_GRAPH.setProject(PROJECT); + + LOAD_AT(path); +} #endregion + +function LOAD_PATH(path, readonly = false, safe_mode = false) { #region + for( var i = 0, n = array_length(PROJECTS); i < n; i++ ) + if(PROJECTS[i].path == path) return; + + var _PROJECT = PROJECT; + PROJECT = new Project(); + + if(_PROJECT == noone) { + PROJECTS = [ PROJECT ]; + + } else if(_PROJECT.path == "" && !_PROJECT.modified) { + var ind = array_find(PROJECTS, _PROJECT); + if(ind == -1) ind = 0; + PROJECTS[ind] = PROJECT; + + if(!IS_CMD) PANEL_GRAPH.setProject(PROJECT); + + } else { + if(!IS_CMD) { + var graph = new Panel_Graph(PROJECT); + PANEL_GRAPH.panel.setContent(graph, true); + PANEL_GRAPH = graph; + } + array_push(PROJECTS, PROJECT); + } + + var res = LOAD_AT(path, readonly); + if(!res) return false; + + PROJECT.safeMode = safe_mode; + if(!IS_CMD) + setFocus(PANEL_GRAPH.panel); + + return PROJECT; +} #endregion + +function LOAD_AT(path, readonly = false, override = false) { #region + static log = false; + + CALL("load"); + + printIf(log, $"========== Loading {path} =========="); var t0 = get_timer(), t1 = get_timer(); + + if(DEMO) return false; + + if(!file_exists_empty(path)) { + log_warning("LOAD", $"File not found: {path}"); + return false; + } + + if(filename_ext(path) != ".json" && filename_ext(path) != ".pxc" && filename_ext(path) != ".cpxc") { + log_warning("LOAD", "File not a valid PROJECT"); + return false; + } + + LOADING = true; + + if(override) { + nodeCleanUp(); + clearPanel(); + setPanel(); + if(!TESTING) + instance_destroy(_p_dialog); + ds_list_clear(ERRORS); + } + + printIf(log, $" > Check file : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + var temp_path = TEMPDIR; + directory_verify(temp_path); + + var temp_file_path = TEMPDIR + string(UUID_generate(6)); + if(file_exists_empty(temp_file_path)) file_delete(temp_file_path); + file_copy(path, temp_file_path); + + PROJECT.readonly = readonly; + SET_PATH(PROJECT, path); + + printIf(log, $" > Create temp : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + var _load_content; + var _ext = filename_ext(path); + var s; + + if(_ext == ".pxc") { + var f = file_text_open_read(path); + s = file_text_read_all(f); + file_text_close(f); + + } else if(_ext == ".cpxc") { + var b = buffer_decompress(buffer_load(path)); + s = buffer_read(b, buffer_string); + } + + _load_content = json_try_parse(s); + + printIf(log, $" > Load struct : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(struct_has(_load_content, "version")) { + var _v = _load_content.version; + + PROJECT.version = _v; + LOADING_VERSION = _v; + + if(PREFERENCES.notify_load_version && floor(_v) != floor(SAVE_VERSION)) { + var warn = $"File version mismatch : loading file version {_v} to Pixel Composer {SAVE_VERSION}"; + log_warning("LOAD", warn); + } + } else { + var warn = $"File version mismatch : loading old format to Pixel Composer {SAVE_VERSION}"; + log_warning("LOAD", warn); + } + + printIf(log, $" > Load meta : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + var create_list = ds_list_create(); + if(struct_has(_load_content, "nodes")) { + try { + var _node_list = _load_content.nodes; + for(var i = 0, n = array_length(_node_list); i < n; i++) { + var _node = nodeLoad(_node_list[i]); + if(_node) ds_list_add(create_list, _node); + } + } catch(e) { + log_warning("LOAD", exception_print(e)); + } + } + + printIf(log, $" > Load nodes : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + if(struct_has(_load_content, "animator")) { + var _anim_map = _load_content.animator; + PROJECT.animator.frames_total = struct_try_get(_anim_map, "frames_total", 30); + PROJECT.animator.framerate = struct_try_get(_anim_map, "framerate", 30); + PROJECT.animator.frame_range = struct_try_get(_anim_map, "frame_range", noone); + } + } catch(e) { + log_warning("LOAD, animator", exception_print(e)); + } + + if(struct_has(_load_content, "onion_skin")) + struct_override(PROJECT.onion_skin, _load_content.onion_skin); + + if(struct_has(_load_content, "previewGrid")) + struct_override(PROJECT.previewGrid, _load_content.previewGrid); + + if(struct_has(_load_content, "graphGrid")) + struct_override(PROJECT.graphGrid, _load_content.graphGrid); + + if(struct_has(_load_content, "attributes")) + struct_override(PROJECT.attributes, _load_content.attributes); + PROJECT.setPalette(); + + if(struct_has(_load_content, "notes")) { + PROJECT.notes = array_create(array_length(_load_content.notes)); + for( var i = 0, n = array_length(_load_content.notes); i < n; i++ ) + PROJECT.notes[i] = new Note.deserialize(_load_content.notes[i]); + } + + try { + if(struct_has(_load_content, "metadata")) + PROJECT.meta.deserialize(_load_content.metadata); + } catch(e) { + log_warning("LOAD, metadata", exception_print(e)); + } + + PROJECT.globalNode = new Node_Global(); + try { + if(struct_has(_load_content, "global")) + PROJECT.globalNode.deserialize(_load_content.global); + else if(struct_has(_load_content, "global_node")) + PROJECT.globalNode.deserialize(_load_content.global_node); + } catch(e) { + log_warning("LOAD, global", exception_print(e)); + } + + try { + if(struct_has(_load_content, "addon")) { + var _addon = _load_content.addon; + PROJECT.addons = _addon; + struct_foreach(_addon, function(_name, _value) { addonLoad(_name, false); }); + } else + PROJECT.addons = {}; + } catch(e) { + log_warning("LOAD, addon", exception_print(e)); + } + + printIf(log, $" > Load data : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + ds_queue_clear(CONNECTION_CONFLICT); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].loadGroup(); + } catch(e) { + log_warning("LOAD, group", exception_print(e)); + return false; + } + + printIf(log, $" > Load group : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].postDeserialize(); + } catch(e) { + log_warning("LOAD, deserialize", exception_print(e)); + } + + printIf(log, $" > Deserialize: {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].applyDeserialize(); + } catch(e) { + log_warning("LOAD, apply deserialize", exception_print(e)); + } + + printIf(log, $" > Apply deserialize : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].preConnect(); + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].connect(); + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].postConnect(); + } catch(e) { + log_warning("LOAD, connect", exception_print(e)); + } + + printIf(log, $" > Connect : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(!ds_queue_empty(CONNECTION_CONFLICT)) { + var pass = 0; + + try { + while(++pass < 4 && !ds_queue_empty(CONNECTION_CONFLICT)) { + var size = ds_queue_size(CONNECTION_CONFLICT); + log_message("LOAD", $"[Connect] {size} Connection conflict(s) detected (pass: {pass})"); + repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).connect(); + repeat(size) ds_queue_dequeue(CONNECTION_CONFLICT).postConnect(); + Render(); + } + + if(!ds_queue_empty(CONNECTION_CONFLICT)) + log_warning("LOAD", "Some connection(s) is unsolved. This may caused by render node not being update properly, or image path is broken."); + } catch(e) { + log_warning("LOAD, connect solver", exception_print(e)); + } + } + + printIf(log, $" > Conflict : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].postLoad(); + } catch(e) { + log_warning("LOAD, connect", exception_print(e)); + } + + printIf(log, $" > Post load : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + try { + for(var i = 0; i < ds_list_size(create_list); i++) + create_list[| i].clearInputCache(); + } catch(e) { + log_warning("LOAD, connect", exception_print(e)); + } + + printIf(log, $" > Clear cache : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + RENDER_ALL_REORDER + + LOADING = false; + PROJECT.modified = false; + + log_message("FILE", "load " + path, THEME.noti_icon_file_load); + log_console("Loaded project: " + path); + + if(!IS_CMD) PANEL_MENU.setNotiIcon(THEME.noti_icon_file_load); + + refreshNodeMap(); + + printIf(log, $" > Refresh map : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(struct_has(_load_content, "timelines") && !array_empty(_load_content.timelines.contents)) + PROJECT.timelines.deserialize(_load_content.timelines); + + printIf(log, $" > Timeline : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); + + if(!IS_CMD) run_in(1, PANEL_GRAPH.toCenterNode); + + printIf(log, $"========== Load {ds_map_size(PROJECT.nodeMap)} nodes completed in {(get_timer() - t0) / 1000} ms =========="); + + return true; +} #endregion + +function __IMPORT_ZIP() { #region + var path = get_open_filename("Pixel Composer portable project (.zip)|*.zip", ""); + + var _fname = filename_name_only(path); + var _fext = filename_ext(path); + if(_fext != ".zip") return false; + + directory_verify(TEMPDIR + "proj/"); + var _dir = TEMPDIR + "proj/" + _fname; + directory_create(_dir); + zip_unzip(path, _dir); + + var _f = file_find_first(_dir + "/*.pxc", fa_none); + var _proj = $"{_dir}/{_f}"; + print(_proj); + if(!file_exists_empty(_proj)) return false; + + LOAD_PATH(_proj, true); +} #endregion \ No newline at end of file diff --git a/#backups/scripts/node_atlas/node_atlas.gml.backup0 b/#backups/scripts/node_atlas/node_atlas.gml.backup0 new file mode 100644 index 000000000..1c8415569 --- /dev/null +++ b/#backups/scripts/node_atlas/node_atlas.gml.backup0 @@ -0,0 +1,74 @@ +// 2024-04-18 08:44:11 +function Node_Atlas(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Pixel Expand"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 1; + + inputs[| 2] = nodeValue("Method", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Radial", "Scan" ]); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 1, 0, 2 ]; + + temp_surface = array_create(2); + + attribute_surface_depth(); + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _surf = _data[0]; + var _meth = _data[2]; + var _dim = surface_get_dimension(_data[0]); + + for( var i = 0; i < 2; i++ ) temp_surface[i] = surface_verify(temp_surface[i], _dim[0], _dim[1]); + + if(_meth == 0) { + var _bg = 0; + var _itr = ceil(max(_dim[0], _dim[1]) / 64); + + surface_set_shader(temp_surface[!_bg]); + draw_surface_safe(_surf); + surface_reset_shader(); + + repeat(_itr) { + surface_set_shader(temp_surface[_bg], sh_atlas); + shader_set_f("dimension", _dim); + draw_surface(temp_surface[!_bg], 0, 0); + surface_reset_shader(); + + _bg = !_bg; + } + + surface_set_shader(_outSurf); + draw_surface_safe(temp_surface[!_bg]); + surface_reset_shader(); + + } else if(_meth == 1) { + + surface_set_shader(temp_surface[0], sh_atlas_scan); + shader_set_f("dimension", _dim); + shader_set_f("iteration", _dim[0]); + shader_set_i("axis", 0); + + draw_surface_safe(_surf); + surface_reset_shader(); + + surface_set_shader(temp_surface[1], sh_atlas_scan); + shader_set_f("dimension", _dim); + shader_set_f("iteration", _dim[1]); + shader_set_i("axis", 1); + + draw_surface_safe(temp_surface[0]); + surface_reset_shader(); + + surface_set_shader(_outSurf); + draw_surface_safe(temp_surface[1]); + surface_reset_shader(); + } + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_atlas/node_atlas.gml.backup1 b/#backups/scripts/node_atlas/node_atlas.gml.backup1 new file mode 100644 index 000000000..3c6937ff1 --- /dev/null +++ b/#backups/scripts/node_atlas/node_atlas.gml.backup1 @@ -0,0 +1,74 @@ +// 2024-04-18 08:40:55 +function Node_Atlas(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Pixel Expand"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 1; + + inputs[| 2] = nodeValue("Method", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Radial", "Scan" ]); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 1, 0, 2 ]; + + temp_surface = array_create(2); + + attribute_surface_depth(); + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _surf = _data[0]; + var _meth = _data[2]; + var _dim = surface_get_dimension(_data[0]); + + for( var i = 0; i < 2; i++ ) temp_surface[i] = surface_verify(temp_surface[i], _dim[0], _dim[1]); + + if(_meth == 0) { + var _bg = 0; + var _itr = ceil(max(_dim[0], _dim[1]) / 64); + + surface_set_shader(temp_surface[!_bg]); + draw_surface_safe(_surf); + surface_reset_shader(); + + repeat(_itr) { + surface_set_shader(temp_surface[_bg], sh_atlas); + shader_set_f("dimension", _dim); + draw_surface(temp_surface[!_bg], 0, 0); + surface_reset_shader(); + + _bg = !_bg; + } + + surface_set_shader(_outSurf); + draw_surface_safe(temp_surface[!_bg]); + surface_reset_shader(); + + } else if(_meth == 1) { + + surface_set_shader(temp_surface[0], sh_atlas_scan); + shader_set_f("dimension", _dim); + shader_set_f("iteration", _dim[0]); + shader_set_i("axis", 0); + + draw_surface_safe(_surf); + surface_reset_shader(); + + surface_set_shader(temp_surface[1], sh_atlas_scan); + shader_set_f("dimension", _dim); + shader_set_f("iteration", _dim[1]); + shader_set_i("axis", 1); + + draw_surface_safe(temp_surface[0]); + surface_reset_shader(); + + surface_set_shader(_outSurf); + draw_surface_safe(temp_surface[1]); + surface_reset_shader(); + } + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_canvas/node_canvas.gml.backup0 b/#backups/scripts/node_canvas/node_canvas.gml.backup0 index ec529ddd7..a2af80392 100644 --- a/#backups/scripts/node_canvas/node_canvas.gml.backup0 +++ b/#backups/scripts/node_canvas/node_canvas.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-16 14:17:00 +// 2024-04-18 12:08:01 function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Canvas"; color = COLORS.node_blend_canvas; @@ -215,10 +215,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.drawLayer = 0; tool_attribute.pickColor = c_white; - tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); + tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }) + .setTooltips( [ "Draw on top", "Draw behind", "Draw inside" ] ); tool_attribute.mirror = [ false, false, false ]; - tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }); + tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }) + .setTooltips( [ "Toggle diagonal", "", "" ] ); tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ], [ "", tool_drawLayer_edit, "drawLayer", tool_attribute ], @@ -513,12 +515,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_clear(drawing_surface); } #endregion - function surface_store_buffers(index = preview_index) { #region + static surface_store_buffers = function(index = preview_index) { #region for( var i = 0; i < attributes.frames; i++ ) surface_store_buffer(i); } #endregion - function surface_store_buffer(index = preview_index) { #region + static surface_store_buffer = function(index = preview_index) { #region if(index >= attributes.frames) return; buffer_delete(canvas_buffer[index]); @@ -817,6 +819,42 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor shader_set_f("dimension", _sw, _sh); draw_surface_ext_safe(preview_draw_mask, 0, 0, 1, 1, 0, c_white, 1); shader_reset(); + + draw_set_color(COLORS._main_accent); + if(tool_selection.is_selected) { + var _spx = tool_selection.selection_position[0]; + var _spy = tool_selection.selection_position[1]; + var _spw = tool_selection.selection_size[0]; + var _sph = tool_selection.selection_size[1]; + + var _x0 = _x + _spx * _s; + var _x1 = _x + (_spx + _spw) * _s; + var _xc = _x + (_spx + _spw / 2) * _s; + + var _y0 = _y + _spy * _s; + var _y1 = _y + (_spy + _sph) * _s; + var _yc = _y + (_spy + _sph / 2) * _s; + + if(tool_attribute.mirror[1]) draw_line(_xc, _y0, _xc, _y1); + if(tool_attribute.mirror[2]) draw_line(_x0, _yc, _x1, _yc); + + } else { + var _x0 = _x; + var _x1 = _x + _dim[0] * _s; + var _xc = _x + _dim[0] / 2 * _s; + + var _y0 = _y; + var _y1 = _y + _dim[1] * _s; + var _yc = _y + _dim[1] / 2 * _s; + + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_line(_xc, _y0, _xc, _y1); + if(tool_attribute.mirror[2]) draw_line(_x0, _yc, _x1, _yc); + } else { + if(tool_attribute.mirror[1]) draw_line(_x0, _y1, _x1, _y0); + if(tool_attribute.mirror[2]) draw_line(_x0, _y0, _x1, _y1); + } + } if(_tool) _tool.drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); @@ -917,8 +955,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } } #endregion - static getPreviewValues = function() { return nodeTool == noone || nodeTool.applySelection? output_surface : noone; } - static doSerialize = function(_map) { #region surface_store_buffers(); var _buff = array_create(attributes.frames); diff --git a/#backups/scripts/node_canvas/node_canvas.gml.backup1 b/#backups/scripts/node_canvas/node_canvas.gml.backup1 index c75b03c06..4c748c27f 100644 --- a/#backups/scripts/node_canvas/node_canvas.gml.backup1 +++ b/#backups/scripts/node_canvas/node_canvas.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-16 14:16:53 +// 2024-04-18 10:49:51 function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Canvas"; color = COLORS.node_blend_canvas; @@ -215,10 +215,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.drawLayer = 0; tool_attribute.pickColor = c_white; - tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); + tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }) + .setTooltips( [ "Draw on top", "Draw behind", "Draw inside" ] ); tool_attribute.mirror = [ false, false, false ]; - tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }); + tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }) + .setTooltips( [ "Toggle diagonal", "", "" ] ); tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ], [ "", tool_drawLayer_edit, "drawLayer", tool_attribute ], @@ -513,12 +515,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_clear(drawing_surface); } #endregion - function surface_store_buffers(index = preview_index) { #region + static surface_store_buffers = function(index = preview_index) { #region for( var i = 0; i < attributes.frames; i++ ) surface_store_buffer(i); } #endregion - function surface_store_buffer(index = preview_index) { #region + static surface_store_buffer = function(index = preview_index) { #region if(index >= attributes.frames) return; buffer_delete(canvas_buffer[index]); @@ -817,6 +819,42 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor shader_set_f("dimension", _sw, _sh); draw_surface_ext_safe(preview_draw_mask, 0, 0, 1, 1, 0, c_white, 1); shader_reset(); + + draw_set_color(COLORS._main_accent); + if(tool_selection.is_selected) { + var _spx = tool_selection.selection_position[0]; + var _spy = tool_selection.selection_position[1]; + var _spw = tool_selection.selection_size[0]; + var _sph = tool_selection.selection_size[1]; + + var _x0 = _x + _spx * _s; + var _x1 = _x + (_spx + _spw) * _s; + var _xc = _x + (_spx + _spw / 2) * _s; + + var _y0 = _y + _spy * _s; + var _y1 = _y + (_spy + _sph) * _s; + var _yc = _y + (_spy + _sph / 2) * _s; + + if(tool_attribute.mirror[1]) draw_line(_xc, _y0, _xc, _y1); + if(tool_attribute.mirror[2]) draw_line(_x0, _yc, _x1, _yc); + + } else { + var _x0 = _x; + var _x1 = _x + _dim[0] * _s; + var _xc = _x + _dim[0] / 2 * _s; + + var _y0 = _y; + var _y1 = _y + _dim[1] * _s; + var _yc = _y + _dim[1] / 2 * _s; + + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_line(_xc, _y0, _xc, _y1); + if(tool_attribute.mirror[2]) draw_line(_x0, _yc, _x1, _yc); + } else { + if(tool_attribute.mirror[1]) draw_line(_x0, _y1, _x1, _y0); + if(tool_attribute.mirror[2]) draw_line(_x0, _y0, _x1, _y1); + } + } if(_tool) _tool.drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); @@ -917,8 +955,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } } #endregion - static getPreviewValues = function() { return nodeTool == noone || nodeTool.applySelection? output_surface : noone; } - static doSerialize = function(_map) { #region surface_store_buffers(); var _buff = array_create(attributes.frames); diff --git a/#backups/scripts/node_outline/node_outline.gml.backup0 b/#backups/scripts/node_outline/node_outline.gml.backup0 new file mode 100644 index 000000000..602c677fd --- /dev/null +++ b/#backups/scripts/node_outline/node_outline.gml.backup0 @@ -0,0 +1,110 @@ +// 2024-04-18 12:07:51 +function Node_Outline(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Outline"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Width", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setMappable(15); + + inputs[| 2] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white); + + inputs[| 3] = nodeValue("Blend", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, 0, "Blend outline color with the original color."); + + inputs[| 4] = nodeValue("Blend alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider) + .setMappable(16); + + inputs[| 5] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) + .setDisplay(VALUE_DISPLAY.enum_button, ["Inside", "Outside"]); + + inputs[| 6] = nodeValue("Anti aliasing", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, 0); + + inputs[| 7] = nodeValue("Oversample mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture.") + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Clamp", "Repeat" ]); + + inputs[| 8] = nodeValue("Start", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "Shift outline inside, outside the shape.") + .setMappable(17); + + inputs[| 9] = nodeValue("Mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 10] = nodeValue("Mix", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider); + + inputs[| 11] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 11; + + inputs[| 12] = nodeValue("Crop border", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + __init_mask_modifier(9); // inputs 13, 14 + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + inputs[| 15] = nodeValueMap("Width map", self); + + inputs[| 16] = nodeValueMap("Blend alpha map", self); + + inputs[| 17] = nodeValueMap("Start map", self); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Outline", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 11, + ["Surfaces", true], 0, 9, 10, 13, 14, + ["Outline", false], 1, 15, 5, 8, 17, 12, + ["Render", false], 2, 6, + ["Blend", true, 3], 4, 16, + ]; + + attribute_surface_depth(); + attribute_oversample(); + + static step = function() { #region + var _side = getInputData(5); + + inputs[| 12].setVisible(_side == 0); + + __step_mask_modifier(); + + inputs[| 1].mappableStep(); + inputs[| 4].mappableStep(); + inputs[| 8].mappableStep(); + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var ww = surface_get_width_safe(_data[0]); + var hh = surface_get_height_safe(_data[0]); + var cl = _data[2]; + + var blend = _data[3]; + var side = _data[5]; + var aa = _data[6]; + var sam = struct_try_get(attributes, "oversample"); + var _crop = _data[12]; + + surface_set_shader(_outSurf, sh_outline); + shader_set_f("dimension", ww, hh); + shader_set_f_map("borderSize", _data[1], _data[15], inputs[| 1]); + shader_set_f_map("borderStart", _data[8], _data[17], inputs[| 8]); + shader_set_color("borderColor", cl); + + shader_set_i("side", side); + shader_set_i("is_aa", aa); + shader_set_i("outline_only", _output_index); + shader_set_i("is_blend", blend); + shader_set_f_map("blend_alpha", _data[4], _data[16], inputs[| 4]); + shader_set_i("sampleMode", sam); + shader_set_i("crop_border", _crop); + + draw_surface_safe(_data[0]); + surface_reset_shader(); + + __process_mask_modifier(_data); + _outSurf = mask_apply(_data[0], _outSurf, _data[9], _data[10]); + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_outline/node_outline.gml.backup1 b/#backups/scripts/node_outline/node_outline.gml.backup1 new file mode 100644 index 000000000..27283c7f2 --- /dev/null +++ b/#backups/scripts/node_outline/node_outline.gml.backup1 @@ -0,0 +1,110 @@ +// 2024-04-17 19:15:17 +function Node_Outline(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Outline"; + + inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 1] = nodeValue("Width", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setMappable(15); + + inputs[| 2] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white); + + inputs[| 3] = nodeValue("Blend", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, 0, "Blend outline color with the original color."); + + inputs[| 4] = nodeValue("Blend alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider) + .setMappable(16); + + inputs[| 5] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) + .setDisplay(VALUE_DISPLAY.enum_button, ["Inside", "Outside"]); + + inputs[| 6] = nodeValue("Anti-aliasing", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, 0); + + inputs[| 7] = nodeValue("Oversample mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture.") + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Clamp", "Repeat" ]); + + inputs[| 8] = nodeValue("Start", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "Shift outline inside, outside the shape.") + .setMappable(17); + + inputs[| 9] = nodeValue("Mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); + + inputs[| 10] = nodeValue("Mix", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) + .setDisplay(VALUE_DISPLAY.slider); + + inputs[| 11] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + active_index = 11; + + inputs[| 12] = nodeValue("Crop border", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + __init_mask_modifier(9); // inputs 13, 14 + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + inputs[| 15] = nodeValueMap("Width map", self); + + inputs[| 16] = nodeValueMap("Blend alpha map", self); + + inputs[| 17] = nodeValueMap("Start map", self); + + ////////////////////////////////////////////////////////////////////////////////////////////////// + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + outputs[| 1] = nodeValue("Outline", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ 11, + ["Surfaces", true], 0, 9, 10, 13, 14, + ["Outline", false], 1, 15, 5, 8, 17, 12, + ["Render", false], 2, 6, + ["Blend", true, 3], 4, 16, + ]; + + attribute_surface_depth(); + attribute_oversample(); + + static step = function() { #region + var _side = getInputData(5); + + inputs[| 12].setVisible(_side == 0); + + __step_mask_modifier(); + + inputs[| 1].mappableStep(); + inputs[| 4].mappableStep(); + inputs[| 8].mappableStep(); + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var ww = surface_get_width_safe(_data[0]); + var hh = surface_get_height_safe(_data[0]); + var cl = _data[2]; + + var blend = _data[3]; + var side = _data[5]; + var aa = _data[6]; + var sam = struct_try_get(attributes, "oversample"); + var _crop = _data[12]; + + surface_set_shader(_outSurf, sh_outline); + shader_set_f("dimension", ww, hh); + shader_set_f_map("borderSize", _data[1], _data[15], inputs[| 1]); + shader_set_f_map("borderStart", _data[8], _data[17], inputs[| 8]); + shader_set_color("borderColor", cl); + + shader_set_i("side", side); + shader_set_i("is_aa", aa); + shader_set_i("outline_only", _output_index); + shader_set_i("is_blend", blend); + shader_set_f_map("blend_alpha", _data[4], _data[16], inputs[| 4]); + shader_set_i("sampleMode", sam); + shader_set_i("crop_border", _crop); + + draw_surface_safe(_data[0]); + surface_reset_shader(); + + __process_mask_modifier(_data); + _outSurf = mask_apply(_data[0], _outSurf, _data[9], _data[10]); + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_shape/node_shape.gml.backup0 b/#backups/scripts/node_shape/node_shape.gml.backup0 new file mode 100644 index 000000000..fdcb522d3 --- /dev/null +++ b/#backups/scripts/node_shape/node_shape.gml.backup0 @@ -0,0 +1,356 @@ +// 2024-04-18 12:07:41 +enum NODE_SHAPE_TYPE { rectangle, elipse, regular, star, arc, teardrop, cross, leaf, crescent, donut } + +#region create + global.node_shape_keys = [ "rectangle", "ellipse", "regular polygon", "star", "arc", "teardrop", "cross", "leaf", "crescent", "donut" ]; + array_append(global.node_shape_keys, [ "square", "circle", "triangle", "pentagon", "hexagon", "ring" ]); + + function Node_create_Shape(_x, _y, _group = noone, _param = {}) { #region + var query = struct_try_get(_param, "query", ""); + var node = new Node_Shape(_x, _y, _group); + var ind = -1; + + switch(query) { + case "square" : ind = 0; break; + case "circle" : ind = 1; break; + case "triangle" : ind = 2; node.inputs[| 4].setValue(3); break; + case "pentagon" : ind = 2; node.inputs[| 4].setValue(5); break; + case "hexagon" : ind = 2; node.inputs[| 4].setValue(6); break; + case "ring" : ind = 9; break; + + default : ind = array_find(global.node_shape_keys, query); + } + + if(ind >= 0) node.inputs[| 2].setValue(ind); + + return node; + } + +#endregion + +function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Shape"; + + onSurfaceSize = function() { return getInputData(0, DEF_SURF); }; + + inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF ) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 1] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + var _types = [ "Rectangle", "Ellipse", "Regular polygon", "Star", "Arc", "Teardrop", "Cross", "Leaf", "Crescent", "Donut" ]; + for( var i = 0, n = array_length(_types); i < n; i++ ) + _types[i] = new scrollItem(_types[i], s_node_shape_type, i); + + inputs[| 2] = nodeValue("Shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, _types); + + inputs[| 3] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, DEF_AREA_REF) + .setUnitRef(onSurfaceSize, VALUE_UNIT.reference) + .setDisplay(VALUE_DISPLAY.area, { onSurfaceSize, useShape : false }); + + inputs[| 4] = nodeValue("Sides", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 3) + .setVisible(false); + + inputs[| 5] = nodeValue("Inner radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.5) + .setDisplay(VALUE_DISPLAY.slider) + .setVisible(false); + + inputs[| 6] = nodeValue("Anti-aliasing", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 7] = nodeValue("Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.rotation); + + inputs[| 8] = nodeValue("Angle range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 180 ]) + .setDisplay(VALUE_DISPLAY.rotation_range); + + inputs[| 9] = nodeValue("Corner radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.slider, { range: [0, 0.5, 0.01] }); + + inputs[| 10] = nodeValue("Shape color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white); + + inputs[| 11] = nodeValue("Background color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_black); + + inputs[| 12] = nodeValue("Height", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 13] = nodeValue("Start radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.1) + .setDisplay(VALUE_DISPLAY.slider) + .setVisible(false); + + inputs[| 14] = nodeValue("Shape path", self, JUNCTION_CONNECT.input, VALUE_TYPE.pathnode, noone) + .setVisible(true, true); + + inputs[| 15] = nodeValue("Positioning Mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Area", "Center + Scale", "Full Image" ]) + + inputs[| 16] = nodeValue("Center", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2 ] ) + .setDisplay(VALUE_DISPLAY.vector) + .setUnitRef(onSurfaceSize); + + inputs[| 17] = nodeValue("Half Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2 ] ) + .setDisplay(VALUE_DISPLAY.vector) + .setUnitRef(onSurfaceSize); + + inputs[| 18] = nodeValue("Tile", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 19] = nodeValue("Shape Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.rotation); + + inputs[| 20] = nodeValue("Level", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 1 ]) + .setDisplay(VALUE_DISPLAY.slider_range); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ + ["Output", false], 0, 6, + ["Transform", false], 15, 3, 16, 17, 19, + ["Shape", false], 14, 2, 9, 4, 13, 5, 7, 8, + ["Render", true], 10, 12, 20, 18, + ["Background", true, 1], 11, + ]; + + temp_surface = [ noone ]; + + attribute_surface_depth(); + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var _path = getInputData(14); + if(_path != noone && struct_has(_path, "getPointRatio")) return; + + var _type = getInputData(15); + + if(_type == 0) { + inputs[| 3].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + } else if(_type == 1) { + var _pos = getInputData(16); + var _px = _x + _pos[0] * _s; + var _py = _y + _pos[1] * _s; + + inputs[| 16].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + inputs[| 17].drawOverlay(hover, active, _px, _py, _s, _mx, _my, _snx, _sny); + } + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _dim = _data[0]; + var _bg = _data[1]; + var _shape = _data[2]; + var _aa = _data[6]; + var _corner = _data[9]; + var _color = _data[10]; + var _df = _data[12]; + var _path = _data[14]; + var _bgC = _data[11]; + var _bgcol = _bg? colToVec4(_data[11]) : [0, 0, 0, 0]; + + var _posTyp = _data[15]; + var _tile = _data[18]; + var _rotat = _data[19]; + var _level = _data[20]; + + var _center = [ 0, 0 ]; + var _scale = [ 0, 0 ]; + + switch(_posTyp) { + case 0 : + var _area = _data[3]; + + _center = [ _area[0] / _dim[0], _area[1] / _dim[1] ]; + _scale = [ _area[2] / _dim[0], _area[3] / _dim[1] ]; + break; + case 1 : + var _posit = _data[16]; + var _scal = _data[17]; + + _center = [ _posit[0] / _dim[0], _posit[1] / _dim[1] ]; + _scale = [ _scal[0] / _dim[0], _scal[1] / _dim[1] ]; + break; + case 2 : + _center = [ 0.5, 0.5 ]; + _scale = [ 0.5, 0.5 ]; + break; + } + + inputs[| 3].setVisible(_posTyp == 0); + inputs[| 16].setVisible(_posTyp == 1); + inputs[| 17].setVisible(_posTyp == 1); + + inputs[| 4].setVisible(true); + inputs[| 5].setVisible(true); + inputs[| 6].setVisible(_path == noone); + inputs[| 7].setVisible(true); + inputs[| 8].setVisible(true); + inputs[| 9].setVisible(true); + inputs[| 13].setVisible(true); + inputs[| 15].setVisible(true); + + _outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth()); + + if(_path != noone && struct_has(_path, "getPointRatio")) { #region + inputs[| 3].setVisible(false); + inputs[| 4].setVisible(false); + inputs[| 5].setVisible(false); + inputs[| 7].setVisible(false); + inputs[| 8].setVisible(false); + inputs[| 9].setVisible(false); + inputs[| 13].setVisible(false); + inputs[| 15].setVisible(false); + + surface_set_target(_outSurf); + if(_bg) draw_clear_alpha(0, 1); + else DRAW_CLEAR + + var points = []; + var segCount = _path.getSegmentCount(); + if(segCount) { + var quality = 8; + var sample = quality * segCount; + + for( var i = 0; i < sample; i++ ) { + var t = i / sample; + var pos = _path.getPointRatio(t); + + array_push(points, pos); + } + + var triangles = polygon_triangulate(points); + + draw_set_color(_color); + draw_primitive_begin(pr_trianglelist); + for( var i = 0, n = array_length(triangles); i < n; i++ ) { + var tri = triangles[i]; + var p0 = tri[0]; + var p1 = tri[1]; + var p2 = tri[2]; + + draw_vertex(p0.x, p0.y); + draw_vertex(p1.x, p1.y); + draw_vertex(p2.x, p2.y); + } + draw_primitive_end(); + } + surface_reset_target(); + + return _outSurf; + } #endregion + + surface_set_shader(_outSurf, sh_shape); + if(_bg) draw_clear_alpha(0, 1); + else DRAW_CLEAR + + inputs[| 4].setVisible(false); + inputs[| 5].setVisible(false); + inputs[| 7].setVisible(false); + inputs[| 8].setVisible(false); + inputs[| 9].setVisible(false); + inputs[| 13].setVisible(false); + inputs[| 18].setVisible( true); + + switch(_shape) { #region + case NODE_SHAPE_TYPE.rectangle : + inputs[| 9].setVisible( true); + inputs[| 18].setVisible(false); + break; + case NODE_SHAPE_TYPE.elipse : + break; + case NODE_SHAPE_TYPE.regular : + inputs[| 4].setVisible(true); + inputs[| 7].setVisible(true); + inputs[| 9].setVisible(true); + + shader_set_i("sides", _data[4]); + shader_set_f("angle", degtorad(_data[7])); + break; + case NODE_SHAPE_TYPE.star : + inputs[| 4].setVisible(true); + inputs[| 5].setVisible(true); + inputs[| 7].setVisible(true); + inputs[| 9].setVisible(true); + + inputs[| 5].name = "Inner radius"; + + shader_set_i("sides", _data[4]); + shader_set_f("angle", degtorad(_data[7])); + shader_set_f("inner", _data[5]); + break; + case NODE_SHAPE_TYPE.arc : + inputs[| 5].setVisible(true); + inputs[| 8].setVisible(true); + + inputs[| 5].name = "Inner radius"; + + var ar = _data[8]; + var center = degtorad(ar[0] + ar[1]) / 2; + var range = degtorad(ar[0] - ar[1]) / 2; + shader_set_f("angle", center); + shader_set_f("angle_range", [ sin(range), cos(range) ] ); + shader_set_f("inner", _data[5] / 2); + break; + case NODE_SHAPE_TYPE.teardrop : + inputs[| 5].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "End radius"; + inputs[| 13].name = "Start radius"; + + shader_set_f("edRad", _data[ 5]); + shader_set_f("stRad", _data[13]); + break; + case NODE_SHAPE_TYPE.cross : + inputs[| 9].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 13].name = "Outer radius"; + + shader_set_f("outer", _data[13]); + break; + case NODE_SHAPE_TYPE.leaf : + inputs[| 5].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "Inner radius"; + inputs[| 13].name = "Outer radius"; + + shader_set_f("inner", _data[ 5]); + shader_set_f("outer", _data[13]); + break; + case NODE_SHAPE_TYPE.crescent : + inputs[| 5].setVisible(true); + inputs[| 7].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "Shift"; + inputs[| 13].name = "Inner circle"; + + shader_set_f("outer", _data[ 5]); + shader_set_f("angle", -degtorad(_data[7])); + shader_set_f("inner", _data[13]); + break; + case NODE_SHAPE_TYPE.donut : + inputs[| 13].setVisible(true); + + inputs[| 13].name = "Inner circle"; + + shader_set_f("inner", _data[13]); + break; + } #endregion + + shader_set_f("dimension", _dim); + shader_set_i("shape", _shape); + shader_set_f("bgColor", _bgcol); + shader_set_i("aa", _aa); + shader_set_i("drawDF", _df); + shader_set_f("dfLevel", _level); + shader_set_i("tile", _tile); + shader_set_f("corner", _corner); + + shader_set_f("center", _center); + shader_set_f("scale", _scale ); + shader_set_f("rotation", degtorad(_rotat)); + + draw_sprite_stretched_ext(s_fx_pixel, 0, 0, 0, _dim[0], _dim[1], _color, _color_get_alpha(_color)); + surface_reset_shader(); + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/node_shape/node_shape.gml.backup1 b/#backups/scripts/node_shape/node_shape.gml.backup1 new file mode 100644 index 000000000..26c79f414 --- /dev/null +++ b/#backups/scripts/node_shape/node_shape.gml.backup1 @@ -0,0 +1,356 @@ +// 2024-04-17 19:15:10 +enum NODE_SHAPE_TYPE { rectangle, elipse, regular, star, arc, teardrop, cross, leaf, crescent, donut } + +#region create + global.node_shape_keys = [ "rectangle", "ellipse", "regular polygon", "star", "arc", "teardrop", "cross", "leaf", "crescent", "donut" ]; + array_append(global.node_shape_keys, [ "square", "circle", "triangle", "pentagon", "hexagon", "ring" ]); + + function Node_create_Shape(_x, _y, _group = noone, _param = {}) { #region + var query = struct_try_get(_param, "query", ""); + var node = new Node_Shape(_x, _y, _group); + var ind = -1; + + switch(query) { + case "square" : ind = 0; break; + case "circle" : ind = 1; break; + case "triangle" : ind = 2; node.inputs[| 4].setValue(3); break; + case "pentagon" : ind = 2; node.inputs[| 4].setValue(5); break; + case "hexagon" : ind = 2; node.inputs[| 4].setValue(6); break; + case "ring" : ind = 9; break; + + default : ind = array_find(global.node_shape_keys, query); + } + + if(ind >= 0) node.inputs[| 2].setValue(ind); + + return node; + } + +#endregion + +function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { + name = "Shape"; + + onSurfaceSize = function() { return getInputData(0, DEF_SURF); }; + + inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF ) + .setDisplay(VALUE_DISPLAY.vector); + + inputs[| 1] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + var _types = [ "Rectangle", "Ellipse", "Regular polygon", "Star", "Arc", "Teardrop", "Cross", "Leaf", "Crescent", "Donut" ]; + for( var i = 0, n = array_length(_types); i < n; i++ ) + _types[i] = new scrollItem(_types[i], s_node_shape_type, i); + + inputs[| 2] = nodeValue("Shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, _types); + + inputs[| 3] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, DEF_AREA_REF) + .setUnitRef(onSurfaceSize, VALUE_UNIT.reference) + .setDisplay(VALUE_DISPLAY.area, { onSurfaceSize, useShape : false }); + + inputs[| 4] = nodeValue("Sides", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 3) + .setVisible(false); + + inputs[| 5] = nodeValue("Inner radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.5) + .setDisplay(VALUE_DISPLAY.slider) + .setVisible(false); + + inputs[| 6] = nodeValue("Anti-aliasing", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 7] = nodeValue("Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.rotation); + + inputs[| 8] = nodeValue("Angle range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 180 ]) + .setDisplay(VALUE_DISPLAY.rotation_range); + + inputs[| 9] = nodeValue("Corner radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.slider, { range: [0, 0.5, 0.01] }); + + inputs[| 10] = nodeValue("Shape color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white); + + inputs[| 11] = nodeValue("Background color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_black); + + inputs[| 12] = nodeValue("Height", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 13] = nodeValue("Start radius", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.1) + .setDisplay(VALUE_DISPLAY.slider) + .setVisible(false); + + inputs[| 14] = nodeValue("Shape path", self, JUNCTION_CONNECT.input, VALUE_TYPE.pathnode, noone) + .setVisible(true, true); + + inputs[| 15] = nodeValue("Positioning Mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Area", "Center + Scale", "Full Image" ]) + + inputs[| 16] = nodeValue("Center", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2 ] ) + .setDisplay(VALUE_DISPLAY.vector) + .setUnitRef(onSurfaceSize); + + inputs[| 17] = nodeValue("Half Size", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ DEF_SURF_W / 2, DEF_SURF_H / 2 ] ) + .setDisplay(VALUE_DISPLAY.vector) + .setUnitRef(onSurfaceSize); + + inputs[| 18] = nodeValue("Tile", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + + inputs[| 19] = nodeValue("Shape Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.rotation); + + inputs[| 20] = nodeValue("Level", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 1 ]) + .setDisplay(VALUE_DISPLAY.slider_range); + + outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); + + input_display_list = [ + ["Output", false], 0, 6, + ["Transform", false], 15, 3, 16, 17, 19, + ["Shape", false], 14, 2, 9, 4, 13, 5, 7, 8, + ["Render", true], 10, 12, 20, 18, + ["Background", true, 1], 11, + ]; + + temp_surface = [ noone ]; + + attribute_surface_depth(); + + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var _path = getInputData(14); + if(_path != noone && struct_has(_path, "getPointRatio")) return; + + var _type = getInputData(15); + + if(_type == 0) { + inputs[| 3].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + } else if(_type == 1) { + var _pos = getInputData(16); + var _px = _x + _pos[0] * _s; + var _py = _y + _pos[1] * _s; + + inputs[| 16].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + inputs[| 17].drawOverlay(hover, active, _px, _py, _s, _mx, _my, _snx, _sny); + } + } #endregion + + static processData = function(_outSurf, _data, _output_index, _array_index) { #region + var _dim = _data[0]; + var _bg = _data[1]; + var _shape = _data[2]; + var _aa = _data[6]; + var _corner = _data[9]; + var _color = _data[10]; + var _df = _data[12]; + var _path = _data[14]; + var _bgC = _data[11]; + var _bgcol = _bg? colToVec4(_data[11]) : [0, 0, 0, 0]; + + var _posTyp = _data[15]; + var _tile = _data[18]; + var _rotat = _data[19]; + var _level = _data[20]; + + var _center = [ 0, 0 ]; + var _scale = [ 0, 0 ]; + + switch(_posTyp) { + case 0 : + var _area = _data[3]; + + _center = [ _area[0] / _dim[0], _area[1] / _dim[1] ]; + _scale = [ _area[2] / _dim[0], _area[3] / _dim[1] ]; + break; + case 1 : + var _posit = _data[16]; + var _scal = _data[17]; + + _center = [ _posit[0] / _dim[0], _posit[1] / _dim[1] ]; + _scale = [ _scal[0] / _dim[0], _scal[1] / _dim[1] ]; + break; + case 2 : + _center = [ 0.5, 0.5 ]; + _scale = [ 0.5, 0.5 ]; + break; + } + + inputs[| 3].setVisible(_posTyp == 0); + inputs[| 16].setVisible(_posTyp == 1); + inputs[| 17].setVisible(_posTyp == 1); + + inputs[| 4].setVisible(true); + inputs[| 5].setVisible(true); + inputs[| 6].setVisible(_path == noone); + inputs[| 7].setVisible(true); + inputs[| 8].setVisible(true); + inputs[| 9].setVisible(true); + inputs[| 13].setVisible(true); + inputs[| 15].setVisible(true); + + _outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth()); + + if(_path != noone && struct_has(_path, "getPointRatio")) { #region + inputs[| 3].setVisible(false); + inputs[| 4].setVisible(false); + inputs[| 5].setVisible(false); + inputs[| 7].setVisible(false); + inputs[| 8].setVisible(false); + inputs[| 9].setVisible(false); + inputs[| 13].setVisible(false); + inputs[| 15].setVisible(false); + + surface_set_target(_outSurf); + if(_bg) draw_clear_alpha(0, 1); + else DRAW_CLEAR + + var points = []; + var segCount = _path.getSegmentCount(); + if(segCount) { + var quality = 8; + var sample = quality * segCount; + + for( var i = 0; i < sample; i++ ) { + var t = i / sample; + var pos = _path.getPointRatio(t); + + array_push(points, pos); + } + + var triangles = polygon_triangulate(points); + + draw_set_color(_color); + draw_primitive_begin(pr_trianglelist); + for( var i = 0, n = array_length(triangles); i < n; i++ ) { + var tri = triangles[i]; + var p0 = tri[0]; + var p1 = tri[1]; + var p2 = tri[2]; + + draw_vertex(p0.x, p0.y); + draw_vertex(p1.x, p1.y); + draw_vertex(p2.x, p2.y); + } + draw_primitive_end(); + } + surface_reset_target(); + + return _outSurf; + } #endregion + + surface_set_shader(_outSurf, sh_shape); + if(_bg) draw_clear_alpha(0, 1); + else DRAW_CLEAR + + inputs[| 4].setVisible(false); + inputs[| 5].setVisible(false); + inputs[| 7].setVisible(false); + inputs[| 8].setVisible(false); + inputs[| 9].setVisible(false); + inputs[| 13].setVisible(false); + inputs[| 18].setVisible( true); + + switch(_shape) { #region + case NODE_SHAPE_TYPE.rectangle : + inputs[| 9].setVisible( true); + inputs[| 18].setVisible(false); + break; + case NODE_SHAPE_TYPE.elipse : + break; + case NODE_SHAPE_TYPE.regular : + inputs[| 4].setVisible(true); + inputs[| 7].setVisible(true); + inputs[| 9].setVisible(true); + + shader_set_i("sides", _data[4]); + shader_set_f("angle", degtorad(_data[7])); + break; + case NODE_SHAPE_TYPE.star : + inputs[| 4].setVisible(true); + inputs[| 5].setVisible(true); + inputs[| 7].setVisible(true); + inputs[| 9].setVisible(true); + + inputs[| 5].name = "Inner radius"; + + shader_set_i("sides", _data[4]); + shader_set_f("angle", degtorad(_data[7])); + shader_set_f("inner", _data[5]); + break; + case NODE_SHAPE_TYPE.arc : + inputs[| 5].setVisible(true); + inputs[| 8].setVisible(true); + + inputs[| 5].name = "Inner radius"; + + var ar = _data[8]; + var center = degtorad(ar[0] + ar[1]) / 2; + var range = degtorad(ar[0] - ar[1]) / 2; + shader_set_f("angle", center); + shader_set_f("angle_range", [ sin(range), cos(range) ] ); + shader_set_f("inner", _data[5] / 2); + break; + case NODE_SHAPE_TYPE.teardrop : + inputs[| 5].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "End radius"; + inputs[| 13].name = "Start radius"; + + shader_set_f("edRad", _data[ 5]); + shader_set_f("stRad", _data[13]); + break; + case NODE_SHAPE_TYPE.cross : + inputs[| 9].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 13].name = "Outer radius"; + + shader_set_f("outer", _data[13]); + break; + case NODE_SHAPE_TYPE.leaf : + inputs[| 5].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "Inner radius"; + inputs[| 13].name = "Outer radius"; + + shader_set_f("inner", _data[ 5]); + shader_set_f("outer", _data[13]); + break; + case NODE_SHAPE_TYPE.crescent : + inputs[| 5].setVisible(true); + inputs[| 7].setVisible(true); + inputs[| 13].setVisible(true); + + inputs[| 5].name = "Shift"; + inputs[| 13].name = "Inner circle"; + + shader_set_f("outer", _data[ 5]); + shader_set_f("angle", -degtorad(_data[7])); + shader_set_f("inner", _data[13]); + break; + case NODE_SHAPE_TYPE.donut : + inputs[| 13].setVisible(true); + + inputs[| 13].name = "Inner circle"; + + shader_set_f("inner", _data[13]); + break; + } #endregion + + shader_set_f("dimension", _dim); + shader_set_i("shape", _shape); + shader_set_f("bgColor", _bgcol); + shader_set_i("aa", _aa); + shader_set_i("drawDF", _df); + shader_set_f("dfLevel", _level); + shader_set_i("tile", _tile); + shader_set_f("corner", _corner); + + shader_set_f("center", _center); + shader_set_f("scale", _scale ); + shader_set_f("rotation", degtorad(_rotat)); + + draw_sprite_stretched_ext(s_fx_pixel, 0, 0, 0, _dim[0], _dim[1], _color, _color_get_alpha(_color)); + surface_reset_shader(); + + return _outSurf; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/preferences/preferences.gml.backup0 b/#backups/scripts/preferences/preferences.gml.backup0 index ab10f08f0..86e8b6141 100644 --- a/#backups/scripts/preferences/preferences.gml.backup0 +++ b/#backups/scripts/preferences/preferences.gml.backup0 @@ -1,4 +1,4 @@ -// 2024-04-15 17:50:18 +// 2024-04-17 07:56:45 #region preference globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA; PREFERENCES = {}; diff --git a/#backups/scripts/preferences/preferences.gml.backup1 b/#backups/scripts/preferences/preferences.gml.backup1 index ab7c66f84..ab10f08f0 100644 --- a/#backups/scripts/preferences/preferences.gml.backup1 +++ b/#backups/scripts/preferences/preferences.gml.backup1 @@ -1,4 +1,4 @@ -// 2024-04-15 17:50:17 +// 2024-04-15 17:50:18 #region preference globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA; PREFERENCES = {}; diff --git a/#backups/scripts/textBox/textBox.gml.backup0 b/#backups/scripts/textBox/textBox.gml.backup0 new file mode 100644 index 000000000..412246f91 --- /dev/null +++ b/#backups/scripts/textBox/textBox.gml.backup0 @@ -0,0 +1,749 @@ +// 2024-04-18 12:07:15 +enum TEXTBOX_INPUT { + text, + number +} + +function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { + onRelease = noone; + + align = _input == TEXTBOX_INPUT.number? fa_center : fa_left; + hide = false; + color = COLORS._main_text; + boxColor = c_white; + format = TEXT_AREA_FORMAT._default; + precision = 5; + + suffix = ""; + + no_empty = true; + auto_update = false; + + slidable = false; + sliding = false; + slide_delta = 0; + slide_int = false; + slide_speed = 1 / 10; + slide_snap = 0; + slide_range = noone; + curr_range = [ 0, 1 ]; + + slider_def_val = 0; + slider_cur_val = 0; + + label = ""; + + starting_char = 1; + + _current_text = ""; + _input_text = ""; + _last_text = ""; + current_value = ""; + _disp_text = ""; + + cursor = 0; + cursor_pos = 0; + cursor_pos_y = 0; + cursor_pos_to = 0; + cursor_select = -1; + + disp_x = 0; + disp_x_to = 0; + disp_x_min = 0; + disp_x_max = 0; + + click_block = 0; + + use_range = false; + range_min = 0; + range_max = 0; + + disp_text_fx = []; + + sprite_index = -1; + + text_surface = surface_create(1, 1); + + shake_amount = 0; + + static setOnRelease = function(release) { onRelease = release; return self; } + + static modifyValue = function(value) { #region + if(input == TEXTBOX_INPUT.number) { + if(use_range) value = clamp(value, range_min, range_max); + } + + onModify(value); + } #endregion + + static setSlidable = function(slideStep = slide_speed, _slide_int = false, _slide_range = noone) { #region + slidable = true; + slide_speed = is_array(slideStep)? slideStep[0] : slideStep; + slide_snap = is_array(slideStep)? slideStep[1] : 0; + slide_int = _slide_int; + slide_range = _slide_range; + + return self; + } #endregion + + static setRange = function(_rng_min, _rng_max) { #region + use_range = true; + range_min = _rng_min; + range_max = _rng_max; + + return self; + } #endregion + + static setFont = function(font) { #region + self.font = font; + return self; + } #endregion + + static setLabel = function(label) { #region + self.label = label; + return self; + } #endregion + + static setPrecision = function(precision) { #region + self.precision = precision; + return self; + } #endregion + + static setEmpty = function() { #region + no_empty = false; + return self; + } #endregion + + static activate = function() { #region + WIDGET_CURRENT = self; + WIDGET_CURRENT_SCROLL = parent; + parentFocus(); + + _input_text = _current_text; + _last_text = _current_text; + + cursor = string_length(_current_text); + cursor_select = 0; + click_block = 1; + + KEYBOARD_STRING = ""; + keyboard_lastkey = -1; + + if(PEN_USE) keyboard_virtual_show(input == TEXTBOX_INPUT.number? kbv_type_numbers : kbv_type_default, kbv_returnkey_default, kbv_autocapitalize_none, true); + } #endregion + + static deactivate = function() { #region + if(WIDGET_CURRENT != self) return; + + apply(); + if(is_callable(onRelease)) + apply(true); + + WIDGET_CURRENT = noone; + UNDO_HOLDING = false; + + if(PEN_USE) keyboard_virtual_hide(); + } #endregion + + static onKey = function(key) { #region + if(KEYBOARD_PRESSED == vk_left) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else if(cursor_select != -1) + cursor_select = -1; + + move_cursor(-1); + } + + if(KEYBOARD_PRESSED == vk_right) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else if(cursor_select != -1) + cursor_select = -1; + + move_cursor(1); + } + } #endregion + + static apply = function(release = false) { #region + var _input_text_current = _input_text; + disp_x_to = 0; + + if(input == TEXTBOX_INPUT.number) + _input_text_current = evaluateFunction(_input_text); + + if(no_empty && _input_text_current == "") + _input_text_current = _last_text; + current_value = _input_text_current; + + if(release) { + if(is_callable(onRelease)) { + var _modi = onRelease(_input_text_current); + if(_modi && IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; + return _modi; + } + } else { + if(is_callable(onModify)) { + var _modi = onModify(_input_text_current); + if(_modi && IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; + return _modi; + } + } + + if(IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; + return false; + } #endregion + + static move_cursor = function(delta) { #region + var ll = string_length(_input_text) + 1; + cursor = safe_mod(cursor + delta + ll, ll); + } #endregion + + static editText = function() { #region + var edited = false; + + #region text editor + if(key_mod_press(CTRL) && keyboard_check_pressed(ord("A"))) { + cursor_select = 0; + cursor = string_length(_input_text); + } else if(key_mod_press(CTRL) && (keyboard_check_pressed(ord("C")) || keyboard_check_pressed(ord("X")))) { + if(cursor_select != -1) { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + clipboard_set_text(string_copy(_input_text, minc + 1, maxc - minc)); + } + } else { + if(key_mod_press(CTRL) && keyboard_check_pressed(ord("V"))) { + KEYBOARD_STRING = clipboard_get_text(); + edited = true; + } + + if(keyboard_check_pressed(vk_escape) || keyboard_check_pressed(vk_enter)) { + } else if(KEYBOARD_PRESSED == vk_backspace) { + if(cursor_select == -1) { + var str_before, str_after; + + if(key_mod_press(CTRL)) { + var _c = cursor - 1; + while(_c > 0) { + var ch = string_char_at(_input_text, _c); + if(breakCharacter(ch)) break; + _c--; + } + + str_before = string_copy(_input_text, 1, _c); + str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor); + cursor = _c + 1; + } else { + str_before = string_copy(_input_text, 1, cursor - 1); + str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor); + } + + _input_text = str_before + str_after; + } else { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + + var str_before = string_copy(_input_text, 1, minc); + var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc); + + cursor = minc + 1; + _input_text = str_before + str_after; + } + + edited = true; + cursor_select = -1; + move_cursor(-1); + } else if(KEYBOARD_PRESSED == vk_delete || (keyboard_check_pressed(ord("X")) && key_mod_press(CTRL) && cursor_select != -1)) { + if(cursor_select == -1) { + var str_before = string_copy(_input_text, 1, cursor); + var str_after = string_copy(_input_text, cursor + 2, string_length(_input_text) - cursor - 1); + + _input_text = str_before + str_after; + } else { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + + var str_before = string_copy(_input_text, 1, minc); + var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc); + + cursor = minc; + _input_text = str_before + str_after; + } + + edited = true; + cursor_select = -1; + } else if(KEYBOARD_STRING != "") { + var ch = KEYBOARD_STRING; + + if(cursor_select == -1) { + var str_before = string_copy(_input_text, 1, cursor); + var str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor); + + _input_text = str_before + ch + str_after; + move_cursor(string_length(ch)); + } else { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + + var str_before = string_copy(_input_text, 1, minc); + var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc); + + _input_text = str_before + ch + str_after; + cursor = minc + string_length(ch); + } + + edited = true; + cursor_select = -1; + } + } + + KEYBOARD_STRING = ""; + keyboard_lastkey = -1; + #endregion + + if(keyboard_check_pressed(vk_left)) onKey(vk_left); + if(keyboard_check_pressed(vk_right)) onKey(vk_right); + + if(input == TEXTBOX_INPUT.number) { + var _inc = 1; + if(key_mod_press(CTRL)) _inc *= 10; + if(key_mod_press(ALT)) _inc /= 10; + + if(KEYBOARD_PRESSED == vk_up || keyboard_check_pressed(vk_up)) { _input_text = string(toNumber(_input_text) + _inc); apply(); } + if(KEYBOARD_PRESSED == vk_down || keyboard_check_pressed(vk_down)) { _input_text = string(toNumber(_input_text) - _inc); apply(); } + } + + if(edited) { + typing = 100; + + if(IS_PATREON) { + shake_amount = PREFERENCES.textbox_shake; + repeat(PREFERENCES.textbox_particle) spawn_particle(rx + cursor_pos, ry + cursor_pos_y + random(16), 8); + } + } + + if(keyboard_check_pressed(vk_home)) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else + cursor_select = -1; + move_cursor(-cursor); + + } else if(keyboard_check_pressed(vk_end)) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else + cursor_select = -1; + move_cursor(string_length(_input_text) - cursor); + + } else if(keyboard_check_pressed(vk_escape)) { + _input_text = _last_text; + deactivate(); + + } else if(keyboard_check_pressed(vk_enter)) { + deactivate(); + + } else if(auto_update && (edited || keyboard_check_pressed(vk_anykey))) { + apply(); + } + } #endregion + + static display_text = function(_x, _y, _text, _w, _m = -1) { #region + draw_set_alpha(0.5 + 0.5 * interactable); + _y += ui(1); //Huh? + + var cc = color; + if(sliding == 2) cc = COLORS._main_accent + + draw_set_text(font, fa_left, fa_top, cc); + draw_text_add(_x + disp_x, _y, _text + suffix); + draw_set_alpha(1); + + _disp_text = _text; + + var _xx = _x + disp_x; + var _mm = _m; + var target = -999; + + if(!sliding && selecting) { + for( var i = 1; i <= string_length(_text); i++ ) { + var _ch = string_char_at(_text, i); + var _chw = string_width(_ch); + + if(_mm < _xx + _chw / 2) { + target = i - 1; + break; + } else if(_mm < _xx + _chw) { + target = i; + break; + } + + _xx += _chw; + } + + if(target != -999) { + if(!click_block) { + if(mouse_press(mb_left, active)) { + cursor_select = target; + cursor = target; + } else if(mouse_click(mb_left, active) && cursor != target) + cursor = target; + } + } + + if(mouse_release(mb_left, active)) + click_block = false; + } + } #endregion + + static drawParam = function(params) { #region + setParam(params); + + return draw(params.x, params.y, params.w, params.h, params.data, params.m, params.halign, params.valign); + } #endregion + + static draw = function(_x, _y, _w, _h, _text = "", _m = mouse_ui, halign = fa_left, valign = fa_top) { #region + x = _x; + y = _y; + w = _w; + h = _h; + + hovering = false; + if(shake_amount != 0) { + _x += irandom_range(-shake_amount, shake_amount); + _y += irandom_range(-shake_amount, shake_amount); + if(shake_amount) shake_amount--; + } + + var drawText = selecting || _h >= line_get_height(font); + + switch(halign) { + case fa_left: _x = _x; break; + case fa_center: _x = _x - _w / 2; break; + case fa_right: _x = _x - _w; break; + } + + switch(valign) { + case fa_top: _y = _y; break; + case fa_center: _y = _y - _h / 2; break; + case fa_bottom: _y = _y - _h; break; + } + + var _bs = min(h, ui(32)); + + if(_w - _bs > ui(100) && side_button) { + side_button.setFocusHover(active, hover); + side_button.draw(_x + _w - _bs, _y + _h / 2 - _bs / 2, _bs, _bs, _m, THEME.button_hide); + _w -= _bs + ui(4); + } + + var _raw_text = _text; + _text = string_real(_text); + _current_text = _text; + + var tb_surf_x = _x + ui(8); + var tb_surf_y = _y; + + var tx = _x; + switch(align) { + case fa_left : tx = _x + ui(8); break; + case fa_center : tx = _x + _w / 2; break; + case fa_right : tx = _x + _w - ui(8); break; + } + + if(drawText) { + var _update = !surface_valid(text_surface, _w - ui(16), _h); + if(_update) text_surface = surface_verify(text_surface, _w - ui(16), _h); + } + + if(!hide) { + draw_sprite_stretched_ext(THEME.textbox, 3, _x, _y, _w, _h, boxColor, 1); + + if(slide_range != noone) { + var _minn = slide_range[0]; + var _maxx = slide_range[1]; + var _rang = abs(_maxx - _minn); + var _currVal = toNumber(_current_text); + + if(sliding != 2) { + curr_range[0] = (_currVal >= _minn)? _minn : _minn - ceil(abs(_currVal - _minn) / _rang) * _rang; + curr_range[1] = (_currVal <= _maxx)? _maxx : _maxx + ceil(abs(_currVal - _maxx) / _rang) * _rang; + } + + var lw = _w * (_currVal - curr_range[0]) / (curr_range[1] - curr_range[0]); + draw_sprite_stretched_ext(THEME.textbox, 4, _x, _y, lw, _h, boxColor, 1); + } + } + + if(_w > ui(48)) { + if(sliding == 2) { + var _ax0 = _x + ui(10); + var _ax1 = _x + _w - ui(10); + var _ay = _y + _h / 2; + + draw_sprite_ui_uniform(THEME.arrow, 2, _ax0, _ay, 1, COLORS._main_accent, 1); + draw_sprite_ui_uniform(THEME.arrow, 0, _ax1, _ay, 1, COLORS._main_accent, 1); + + } else if(label != "") { + draw_set_text(font, fa_left, fa_center, COLORS._main_text_sub); + + draw_set_alpha(0.5); + draw_text_add(_x + ui(8), _y + _h / 2, label); + draw_set_alpha(1); + } + } + + disp_x = lerp_float(disp_x, disp_x_to, 5); + + var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + if(sliding > 0) { #region slide + slide_delta += PEN_USE? PEN_X_DELTA : window_mouse_get_delta_x(); + slide_delta += PEN_USE? PEN_Y_DELTA : window_mouse_get_delta_y(); + + if(sliding == 1 && abs(slide_delta) > 8) { + deactivate(); + var _defval = toNumber(_current_text); + slider_def_val = _defval; + slider_cur_val = _defval; + + CURSOR_LOCK_X = mouse_mx; + CURSOR_LOCK_Y = mouse_my; + + sliding = 2; + } + + if(sliding == 2) { + MOUSE_BLOCK = true; + CURSOR_LOCK = true; + + if(mouse_check_button_pressed(mb_right)) { + _input_text = string_real(slider_def_val); + sliding = 0; + apply(); + deactivate(); + + UNDO_HOLDING = false; + + } else { + var _s = slide_speed; + + var _mdx = PEN_USE? PEN_X_DELTA : window_mouse_get_delta_x(); + var _mdy = PEN_USE? PEN_Y_DELTA : window_mouse_get_delta_y(); + + var _dx = abs(_mdx) > abs(_mdy)? _mdx : -_mdy; + + if(key_mod_press(CTRL) && !slide_snap) _s *= 10; + if(key_mod_press(ALT)) _s /= 10; + + slider_cur_val += _dx * _s; + + if(slide_range != noone) + slider_cur_val = clamp(slider_cur_val, curr_range[0], curr_range[1]); + + var _val = value_snap(slider_cur_val, _s); + + if(key_mod_press(CTRL) && slide_snap) _val = value_snap(slider_cur_val, slide_snap); + if(slide_int) _val = round(_val); + + if(abs(_val) < _s * 4) _val = 0; + + _input_text = string_real(_val); + if(apply()) UNDO_HOLDING = true; + } + + if(mouse_release(mb_left)) { + deactivate(); + if(onRelease != noone) apply(true); + } + } + + if(mouse_release(mb_left)) { + sliding = 0; + _update = true; + UNDO_HOLDING = false; + } + } #endregion + + if(selecting) { + if(sprite_index == -1) draw_sprite_stretched_ext(THEME.textbox, 2, _x, _y, _w, _h, COLORS._main_accent, 1); + else draw_sprite_stretched(THEME.textbox, sprite_index, _x, _y, _w, _h); + + editText(); + + #region multiplier + if(_w > ui(80) && input == TEXTBOX_INPUT.number) { + draw_set_alpha(0.5); + + if(hover && point_in_rectangle(_m[0], _m[1], _x + _w - ui(32), _y, _x + _w, _y + _h)) { + draw_set_alpha(1); + + if(mouse_press(mb_left, active)) { + if(key_mod_press(ALT)) _input_text = string_real(toNumber(_input_text) / 2); + else _input_text = string_real(toNumber(_input_text) * 2); + apply(); + + if(IS_PATREON) shake_amount = PREFERENCES.textbox_shake; + } + } + + draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); + if(key_mod_press(ALT)) draw_text_add(_x + _w - ui(16), _y + _h / 2, "/2"); + else draw_text_add(_x + _w - ui(16), _y + _h / 2, "x2"); + draw_set_alpha(1); + } + #endregion + + #region draw + var txt = _input_text; + draw_set_text(font, fa_left, fa_top); + var tw = string_width(txt); + var th = string_height(txt == ""? "l" : txt); + + var cs = string_copy(txt, 1, cursor); + var c_w = string_width(cs); + var c_y0 = _y + _h / 2 - th / 2; + var c_y1 = _y + _h / 2 + th / 2; + + switch(align) { + case fa_left : + disp_x_min = -max(0, tw - _w + ui(16 + 8)); + disp_x_max = 0; + break; + case fa_center : + disp_x_min = -max(0, tw - _w + ui(16 + 8)) / 2; + disp_x_max = max(0, tw - _w + ui(16 + 8)) / 2; + tx -= tw / 2; + break; + case fa_right : + disp_x_min = 0; + disp_x_max = max(0, tw - _w + ui(16 + 8)); + tx -= tw; + break; + } + + cursor_pos_to = disp_x + tx + c_w; + if(cursor_pos_to < _x) + disp_x_to += _w - ui(16); + if(cursor_pos_to > _x + _w - ui(16)) + disp_x_to -= _w - ui(16); + + cursor_pos_y = c_y0; + cursor_pos = cursor_pos == 0? cursor_pos_to : lerp_float(cursor_pos, cursor_pos_to, 2); + + if(cursor_select > -1) { //draw highlight + draw_set_color(COLORS.widget_text_highlight); + var c_x1 = tx + disp_x + string_width(string_copy(txt, 1, cursor_select)); + var _rx0 = clamp(min(cursor_pos, c_x1), tx, tx + _w); + var _rx1 = clamp(max(cursor_pos, c_x1), tx, tx + _w); + + draw_roundrect_ext(_rx0, c_y0, _rx1, c_y1, THEME_VALUE.highlight_corner_radius, THEME_VALUE.highlight_corner_radius, 0); + } + + var _mx = -1; + var _my = -1; + if(hover && hoverRect) { + _mx = _m[0]; + _my = _m[1]; + } + + var _display_text = string_real(txt); + if(_update || _display_text != _disp_text) { + surface_set_shader(text_surface, noone, true, BLEND.add); + display_text(tx - tb_surf_x, _h / 2 - th / 2, _display_text, _w - ui(4), _mx - tb_surf_x); + surface_reset_shader(); + } + + BLEND_ALPHA + draw_surface(text_surface, tb_surf_x, tb_surf_y); + BLEND_NORMAL + + draw_set_color(COLORS._main_text_accent); + draw_set_alpha(typing || current_time % (PREFERENCES.caret_blink * 2000) > PREFERENCES.caret_blink * 1000); + draw_line_width(cursor_pos, c_y0, cursor_pos, c_y1, 2); + draw_set_alpha(1); + + if(typing) typing--; + #endregion + + disp_x_to = clamp(disp_x_to, disp_x_min, disp_x_max); + + if(!hoverRect && mouse_press(mb_left)) + deactivate(); + + } else { + + if(hover && hoverRect) { + hovering = true; + draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, _h, boxColor, 0.5 + (0.5 * interactable)); + + if(mouse_press(mb_left, active)) + activate(); + + if(input == TEXTBOX_INPUT.number && key_mod_press(SHIFT)) { + var amo = slide_speed; + if(key_mod_press(CTRL)) amo *= 10; + if(key_mod_press(ALT)) amo /= 10; + + if(mouse_wheel_down()) modifyValue(toNumber(_text) + amo * SCROLL_SPEED); + if(mouse_wheel_up()) modifyValue(toNumber(_text) - amo * SCROLL_SPEED); + } + + if(slidable && mouse_press(mb_left, active)) { + sliding = 1; + slide_delta = 0; + + slide_mx = _m[0]; + slide_my = _m[1]; + } + + } else if(!hide) + draw_sprite_stretched_ext(THEME.textbox, 0, _x, _y, _w, _h, boxColor, 0.5 + 0.5 * interactable); + + if(drawText) { + draw_set_text(font, fa_left, fa_center); + var _display_text = _raw_text; + + if(input == TEXTBOX_INPUT.number) { + var dig = floor(_w / string_width("0")) - 3; + _display_text = string_real(_display_text, dig, precision); + } + + var tw = string_width(_display_text); + var th = string_height(_display_text); + + switch(align) { + case fa_left : break; + case fa_center : tx -= tw / 2; break; + case fa_right : tx -= tw; break; + } + + if(_update || _display_text != _disp_text) { + surface_set_shader(text_surface, noone, true, BLEND.add); + display_text(tx - tb_surf_x, _h / 2 - th / 2, _display_text, _w - ui(4)); + surface_reset_shader(); + } + + BLEND_ALPHA + draw_surface(text_surface, tb_surf_x, tb_surf_y); + BLEND_NORMAL + } + } + + if(DRAGGING && (DRAGGING.type == "Text" || DRAGGING.type == "Number") && hover && hoverRect) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, _y, _w, _h, COLORS._main_value_positive, 1); + if(mouse_release(mb_left)) + onModify(DRAGGING.data); + } + + selecting = self == WIDGET_CURRENT; + resetFocus(); + sprite_index = -1; + return _h; + } #endregion +} \ No newline at end of file diff --git a/#backups/scripts/textBox/textBox.gml.backup1 b/#backups/scripts/textBox/textBox.gml.backup1 new file mode 100644 index 000000000..6c9b7f7e1 --- /dev/null +++ b/#backups/scripts/textBox/textBox.gml.backup1 @@ -0,0 +1,749 @@ +// 2024-04-18 12:00:32 +enum TEXTBOX_INPUT { + text, + number +} + +function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { + onRelease = noone; + + align = _input == TEXTBOX_INPUT.number? fa_center : fa_left; + hide = false; + color = COLORS._main_text; + boxColor = c_white; + format = TEXT_AREA_FORMAT._default; + precision = 5; + + suffix = ""; + + no_empty = true; + auto_update = false; + + slidable = false; + sliding = false; + slide_delta = 0; + slide_int = false; + slide_speed = 1 / 10; + slide_snap = 0; + slide_range = noone; + curr_range = [ 0, 1 ]; + + slider_def_val = 0; + slider_cur_val = 0; + + label = ""; + + starting_char = 1; + + _current_text = ""; + _input_text = ""; + _last_text = ""; + current_value = ""; + _disp_text = ""; + + cursor = 0; + cursor_pos = 0; + cursor_pos_y = 0; + cursor_pos_to = 0; + cursor_select = -1; + + disp_x = 0; + disp_x_to = 0; + disp_x_min = 0; + disp_x_max = 0; + + click_block = 0; + + use_range = false; + range_min = 0; + range_max = 0; + + disp_text_fx = []; + + sprite_index = -1; + + text_surface = surface_create(1, 1); + + shake_amount = 0; + + static setOnRelease = function(release) { onRelease = release; return self; } + + static modifyValue = function(value) { #region + if(input == TEXTBOX_INPUT.number) { + if(use_range) value = clamp(value, range_min, range_max); + } + + onModify(value); + } #endregion + + static setSlidable = function(slideStep = slide_speed, _slide_int = false, _slide_range = noone) { #region + slidable = true; + slide_speed = is_array(slideStep)? slideStep[0] : slideStep; + slide_snap = is_array(slideStep)? slideStep[1] : 0; + slide_int = _slide_int; + slide_range = _slide_range; + + return self; + } #endregion + + static setRange = function(_rng_min, _rng_max) { #region + use_range = true; + range_min = _rng_min; + range_max = _rng_max; + + return self; + } #endregion + + static setFont = function(font) { #region + self.font = font; + return self; + } #endregion + + static setLabel = function(label) { #region + self.label = label; + return self; + } #endregion + + static setPrecision = function(precision) { #region + self.precision = precision; + return self; + } #endregion + + static setEmpty = function() { #region + no_empty = false; + return self; + } #endregion + + static activate = function() { #region + WIDGET_CURRENT = self; + WIDGET_CURRENT_SCROLL = parent; + parentFocus(); + + _input_text = _current_text; + _last_text = _current_text; + + cursor = string_length(_current_text); + cursor_select = 0; + click_block = 1; + + KEYBOARD_STRING = ""; + keyboard_lastkey = -1; + + if(PEN_USE) keyboard_virtual_show(input == TEXTBOX_INPUT.number? kbv_type_numbers : kbv_type_default, kbv_returnkey_default, kbv_autocapitalize_none, true); + } #endregion + + static deactivate = function() { #region + if(WIDGET_CURRENT != self) return; + + apply(); + if(is_callable(onRelease)) + apply(true); + + WIDGET_CURRENT = noone; + UNDO_HOLDING = false; + + if(PEN_USE) keyboard_virtual_hide(); + } #endregion + + static onKey = function(key) { #region + if(KEYBOARD_PRESSED == vk_left) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else if(cursor_select != -1) + cursor_select = -1; + + move_cursor(-1); + } + + if(KEYBOARD_PRESSED == vk_right) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else if(cursor_select != -1) + cursor_select = -1; + + move_cursor(1); + } + } #endregion + + static apply = function(release = false) { #region + var _input_text_current = _input_text; + disp_x_to = 0; + + if(input == TEXTBOX_INPUT.number) + _input_text_current = evaluateFunction(_input_text); + + if(no_empty && _input_text_current == "") + _input_text_current = _last_text; + current_value = _input_text_current; + + if(release) { + if(is_callable(onRelease)) { + var _modi = onRelease(_input_text_current); + if(_modi && IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; + return _modi; + } + } else { + if(is_callable(onModify)) { + var _modi = onModify(_input_text_current); + if(_modi && IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; + return _modi; + } + } + + if(IS_PATREON) shake_amount = PREFERENCES.textbox_shake / 4; + return false; + } #endregion + + static move_cursor = function(delta) { #region + var ll = string_length(_input_text) + 1; + cursor = safe_mod(cursor + delta + ll, ll); + } #endregion + + static editText = function() { #region + var edited = false; + + #region text editor + if(key_mod_press(CTRL) && keyboard_check_pressed(ord("A"))) { + cursor_select = 0; + cursor = string_length(_input_text); + } else if(key_mod_press(CTRL) && (keyboard_check_pressed(ord("C")) || keyboard_check_pressed(ord("X")))) { + if(cursor_select != -1) { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + clipboard_set_text(string_copy(_input_text, minc + 1, maxc - minc)); + } + } else { + if(key_mod_press(CTRL) && keyboard_check_pressed(ord("V"))) { + KEYBOARD_STRING = clipboard_get_text(); + edited = true; + } + + if(keyboard_check_pressed(vk_escape) || keyboard_check_pressed(vk_enter)) { + } else if(KEYBOARD_PRESSED == vk_backspace) { + if(cursor_select == -1) { + var str_before, str_after; + + if(key_mod_press(CTRL)) { + var _c = cursor - 1; + while(_c > 0) { + var ch = string_char_at(_input_text, _c); + if(breakCharacter(ch)) break; + _c--; + } + + str_before = string_copy(_input_text, 1, _c); + str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor); + cursor = _c + 1; + } else { + str_before = string_copy(_input_text, 1, cursor - 1); + str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor); + } + + _input_text = str_before + str_after; + } else { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + + var str_before = string_copy(_input_text, 1, minc); + var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc); + + cursor = minc + 1; + _input_text = str_before + str_after; + } + + edited = true; + cursor_select = -1; + move_cursor(-1); + } else if(KEYBOARD_PRESSED == vk_delete || (keyboard_check_pressed(ord("X")) && key_mod_press(CTRL) && cursor_select != -1)) { + if(cursor_select == -1) { + var str_before = string_copy(_input_text, 1, cursor); + var str_after = string_copy(_input_text, cursor + 2, string_length(_input_text) - cursor - 1); + + _input_text = str_before + str_after; + } else { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + + var str_before = string_copy(_input_text, 1, minc); + var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc); + + cursor = minc; + _input_text = str_before + str_after; + } + + edited = true; + cursor_select = -1; + } else if(KEYBOARD_STRING != "") { + var ch = KEYBOARD_STRING; + + if(cursor_select == -1) { + var str_before = string_copy(_input_text, 1, cursor); + var str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor); + + _input_text = str_before + ch + str_after; + move_cursor(string_length(ch)); + } else { + var minc = min(cursor, cursor_select); + var maxc = max(cursor, cursor_select); + + var str_before = string_copy(_input_text, 1, minc); + var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc); + + _input_text = str_before + ch + str_after; + cursor = minc + string_length(ch); + } + + edited = true; + cursor_select = -1; + } + } + + KEYBOARD_STRING = ""; + keyboard_lastkey = -1; + #endregion + + if(keyboard_check_pressed(vk_left)) onKey(vk_left); + if(keyboard_check_pressed(vk_right)) onKey(vk_right); + + if(input == TEXTBOX_INPUT.number) { + var _inc = 1; + if(key_mod_press(CTRL)) _inc *= 10; + if(key_mod_press(ALT)) _inc /= 10; + + if(KEYBOARD_PRESSED == vk_up || keyboard_check_pressed(vk_up)) { _input_text = string(toNumber(_input_text) + _inc); apply(); } + if(KEYBOARD_PRESSED == vk_down || keyboard_check_pressed(vk_down)) { _input_text = string(toNumber(_input_text) - _inc); apply(); } + } + + if(edited) { + typing = 100; + + if(IS_PATREON) { + shake_amount = PREFERENCES.textbox_shake; + repeat(PREFERENCES.textbox_particle) spawn_particle(rx + cursor_pos, ry + cursor_pos_y + random(16), 8); + } + } + + if(keyboard_check_pressed(vk_home)) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else + cursor_select = -1; + move_cursor(-cursor); + + } else if(keyboard_check_pressed(vk_end)) { + if(key_mod_press(SHIFT)) { + if(cursor_select == -1) + cursor_select = cursor; + } else + cursor_select = -1; + move_cursor(string_length(_input_text) - cursor); + + } else if(keyboard_check_pressed(vk_escape)) { + _input_text = _last_text; + deactivate(); + + } else if(keyboard_check_pressed(vk_enter)) { + deactivate(); + + } else if(auto_update && (edited || keyboard_check_pressed(vk_anykey))) { + apply(); + } + } #endregion + + static display_text = function(_x, _y, _text, _w, _m = -1) { #region + draw_set_alpha(0.5 + 0.5 * interactable); + _y += ui(1); //Huh? + + var cc = color; + if(sliding == 2) cc = COLORS._main_accent + + draw_set_text(font, fa_left, fa_top, cc); + draw_text_add(_x + disp_x, _y, _text + suffix); + draw_set_alpha(1); + + _disp_text = _text; + + var _xx = _x + disp_x; + var _mm = _m; + var target = -999; + + if(!sliding && selecting) { + for( var i = 1; i <= string_length(_text); i++ ) { + var _ch = string_char_at(_text, i); + var _chw = string_width(_ch); + + if(_mm < _xx + _chw / 2) { + target = i - 1; + break; + } else if(_mm < _xx + _chw) { + target = i; + break; + } + + _xx += _chw; + } + + if(target != -999) { + if(!click_block) { + if(mouse_press(mb_left, active)) { + cursor_select = target; + cursor = target; + } else if(mouse_click(mb_left, active) && cursor != target) + cursor = target; + } + } + + if(mouse_release(mb_left, active)) + click_block = false; + } + } #endregion + + static drawParam = function(params) { #region + setParam(params); + + return draw(params.x, params.y, params.w, params.h, params.data, params.m, params.halign, params.valign); + } #endregion + + static draw = function(_x, _y, _w, _h, _text = "", _m = mouse_ui, halign = fa_left, valign = fa_top) { #region + x = _x; + y = _y; + w = _w; + h = _h; + + hovering = false; + if(shake_amount != 0) { + _x += irandom_range(-shake_amount, shake_amount); + _y += irandom_range(-shake_amount, shake_amount); + if(shake_amount) shake_amount--; + } + + var drawText = selecting || _h >= line_get_height(font); + + switch(halign) { + case fa_left: _x = _x; break; + case fa_center: _x = _x - _w / 2; break; + case fa_right: _x = _x - _w; break; + } + + switch(valign) { + case fa_top: _y = _y; break; + case fa_center: _y = _y - _h / 2; break; + case fa_bottom: _y = _y - _h; break; + } + + var _bs = min(h, ui(32)); + + if(_w - _bs > ui(100) && side_button) { + side_button.setFocusHover(active, hover); + side_button.draw(_x + _w - _bs, _y + _h / 2 - _bs / 2, _bs, _bs, _m, THEME.button_hide); + _w -= _bs + ui(4); + } + + var _raw_text = _text; + _text = string_real(_text); + _current_text = _text; + + var tb_surf_x = _x + ui(8); + var tb_surf_y = _y; + + var tx = _x; + switch(align) { + case fa_left : tx = _x + ui(8); break; + case fa_center : tx = _x + _w / 2; break; + case fa_right : tx = _x + _w - ui(8); break; + } + + if(drawText) { + var _update = !surface_valid(text_surface, _w - ui(16), _h); + if(_update) text_surface = surface_verify(text_surface, _w - ui(16), _h); + } + + if(!hide) { + draw_sprite_stretched_ext(THEME.textbox, 3, _x, _y, _w, _h, boxColor, 1); + + if(slide_range != noone) { + var _minn = slide_range[0]; + var _maxx = slide_range[1]; + var _rang = abs(_maxx - _minn); + var _currVal = toNumber(_current_text); + + if(sliding != 2) { + curr_range[0] = (_currVal >= _minn)? _minn : _minn - ceil(abs(_currVal - _minn) / _rang) * _rang; + curr_range[1] = (_currVal <= _maxx)? _maxx : _maxx + ceil(abs(_currVal - _maxx) / _rang) * _rang; + } + + var lw = _w * (_currVal - curr_range[0]) / (curr_range[1] - curr_range[0]); + draw_sprite_stretched_ext(THEME.textbox, 4, _x, _y, lw, _h, boxColor, 1); + } + } + + if(_w > ui(48)) { + if(sliding == 2) { + var _ax0 = _x + ui(10); + var _ax1 = _x + _w - ui(10); + var _ay = _y + _h / 2; + + draw_sprite_ui_uniform(THEME.arrow, 2, _ax0, _ay, 1, COLORS._main_accent, 1); + draw_sprite_ui_uniform(THEME.arrow, 0, _ax1, _ay, 1, COLORS._main_accent, 1); + + } else if(label != "") { + draw_set_text(font, fa_left, fa_center, COLORS._main_text_sub); + + draw_set_alpha(0.5); + draw_text_add(_x + ui(8), _y + _h / 2, label); + draw_set_alpha(1); + } + } + + disp_x = lerp_float(disp_x, disp_x_to, 5); + + var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + + if(sliding > 0) { #region slide + slide_delta += PEN_USE? PEN_X_DELTA : window_mouse_get_delta_x(); + slide_delta += PEN_USE? PEN_Y_DELTA : window_mouse_get_delta_y(); + + if(sliding == 1 && abs(slide_delta) > 8) { + deactivate(); + var _defval = toNumber(_current_text); + slider_def_val = _defval; + slider_cur_val = _defval; + + CURSOR_LOCK_X = mouse_mx; + CURSOR_LOCK_Y = mouse_my; + + sliding = 2; + } + + if(sliding == 2) { + MOUSE_BLOCK = true; + CURSOR_LOCK = true; + + if(mouse_check_button_pressed(mb_right)) { + _input_text = string_real(slider_def_val); + sliding = 0; + apply(); + deactivate(); + + UNDO_HOLDING = false; + + } else { + var _s = slide_speed; + + var _mdx = PEN_USE? PEN_X_DELTA : window_mouse_get_delta_x(); + var _mdy = PEN_USE? PEN_Y_DELTA : window_mouse_get_delta_y(); + + var _dx = abs(_mdx) > abs(_mdy)? _mdx : -_mdy; + + if(key_mod_press(CTRL) && !slide_snap) _s *= 10; + if(key_mod_press(ALT)) _s /= 10; + + slider_cur_val += _dx * _s; + + if(slide_range != noone) + slider_cur_val = clamp(slider_cur_val, curr_range[0], curr_range[1]); + + var _val = value_snap(slider_cur_val, _s); + + if(key_mod_press(CTRL) && slide_snap) _val = value_snap(slider_cur_val, slide_snap); + if(slide_int) _val = round(_val); + + if(abs(_val) < _s * 4) _val = 0; + + _input_text = string_real(_val); + if(apply()) UNDO_HOLDING = true; + } + + if(mouse_release(mb_left)) { + deactivate(); + if(onRelease != noone) apply(true); + } + } + + if(mouse_release(mb_left)) { + sliding = 0; + _update = true; + UNDO_HOLDING = false; + } + } #endregion + + if(selecting) { + if(sprite_index == -1) draw_sprite_stretched_ext(THEME.textbox, 2, _x, _y, _w, _h, COLORS._main_accent, 1); + else draw_sprite_stretched(THEME.textbox, sprite_index, _x, _y, _w, _h); + + editText(); + + #region multiplier + if(_w > ui(80) && input == TEXTBOX_INPUT.number) { + draw_set_alpha(0.5); + + if(hover && point_in_rectangle(_m[0], _m[1], _x + _w - ui(32), _y, _x + _w, _y + _h)) { + draw_set_alpha(1); + + if(mouse_press(mb_left, active)) { + if(key_mod_press(ALT)) _input_text = string_real(toNumber(_input_text) / 2); + else _input_text = string_real(toNumber(_input_text) * 2); + apply(); + + if(IS_PATREON) shake_amount = PREFERENCES.textbox_shake; + } + } + + draw_set_text(f_p0b, fa_center, fa_center, COLORS._main_text_sub); + if(key_mod_press(ALT)) draw_text_add(_x + _w - ui(16), _y + _h / 2, "/2"); + else draw_text_add(_x + _w - ui(16), _y + _h / 2, "x2"); + draw_set_alpha(1); + } + #endregion + + #region draw + var txt = _input_text; + draw_set_text(font, fa_left, fa_top); + var tw = string_width(txt); + var th = string_height(txt == ""? "l" : txt); + + var cs = string_copy(txt, 1, cursor); + var c_w = string_width(cs); + var c_y0 = _y + _h / 2 - th / 2; + var c_y1 = _y + _h / 2 + th / 2; + + switch(align) { + case fa_left : + disp_x_min = -max(0, tw - _w + ui(16 + 8)); + disp_x_max = 0; + break; + case fa_center : + disp_x_min = -max(0, tw - _w + ui(16 + 8)) / 2; + disp_x_max = max(0, tw - _w + ui(16 + 8)) / 2; + tx -= tw / 2; + break; + case fa_right : + disp_x_min = 0; + disp_x_max = max(0, tw - _w + ui(16 + 8)); + tx -= tw; + break; + } + + cursor_pos_to = disp_x + tx + c_w; + if(cursor_pos_to < _x) + disp_x_to += _w - ui(16); + if(cursor_pos_to > _x + _w - ui(16)) + disp_x_to -= _w - ui(16); + + cursor_pos_y = c_y0; + cursor_pos = cursor_pos == 0? cursor_pos_to : lerp_float(cursor_pos, cursor_pos_to, 2); + + if(cursor_select > -1) { //draw highlight + draw_set_color(COLORS.widget_text_highlight); + var c_x1 = tx + disp_x + string_width(string_copy(txt, 1, cursor_select)); + var _rx0 = clamp(min(cursor_pos, c_x1), tx, tx + _w); + var _rx1 = clamp(max(cursor_pos, c_x1), tx, tx + _w); + + draw_roundrect_ext(_rx0, c_y0, _rx1, c_y1, THEME_VALUE.highlight_corner_radius, THEME_VALUE.highlight_corner_radius, 0); + } + + var _mx = -1; + var _my = -1; + if(hover && hoverRect) { + _mx = _m[0]; + _my = _m[1]; + } + + var _display_text = string_real(txt); + if(_update || _display_text != _disp_text) { + surface_set_shader(text_surface, noone, true, BLEND.add); + display_text(tx - tb_surf_x, _h / 2 - th / 2, _display_text, _w - ui(4), _mx - tb_surf_x); + surface_reset_shader(); + } + + BLEND_ALPHA + draw_surface(text_surface, tb_surf_x, tb_surf_y); + BLEND_NORMAL + + draw_set_color(COLORS._main_text_accent); + draw_set_alpha(typing || current_time % (PREFERENCES.caret_blink * 2000) > PREFERENCES.caret_blink * 1000); + draw_line_width(cursor_pos, c_y0, cursor_pos, c_y1, 2); + draw_set_alpha(1); + + if(typing) typing--; + #endregion + + disp_x_to = clamp(disp_x_to, disp_x_min, disp_x_max); + + if(!hoverRect && mouse_press(mb_left)) + deactivate(); + + } else { + + if(hover && hoverRect) { + hovering = true; + draw_sprite_stretched_ext(THEME.textbox, 1, _x, _y, _w, _h, boxColor, 0.5 + (0.5 * interactable)); + + if(mouse_press(mb_left, active)) + activate(); + + if(input == TEXTBOX_INPUT.number && key_mod_press(SHIFT)) { + var amo = slide_speed; + if(key_mod_press(CTRL)) amo *= 10; + if(key_mod_press(ALT)) amo /= 10; + + if(mouse_wheel_down()) modifyValue(toNumber(_text) + amo * SCROLL_SPEED); + if(mouse_wheel_up()) modifyValue(toNumber(_text) - amo * SCROLL_SPEED); + } + + if(slidable && mouse_press(mb_left, active)) { + sliding = 1; + slide_delta = 0; + + slide_mx = _m[0]; + slide_my = _m[1]; + } + + } else if(!hide) + draw_sprite_stretched_ext(THEME.textbox, 0, _x, _y, _w, _h, boxColor, 0.5 + 0.5 * interactable); + + if(drawText) { + draw_set_text(font, fa_left, fa_center); + var _display_text = _raw_text; + + if(input == TEXTBOX_INPUT.number) { + var dig = floor(_w / string_width("0")) - 3; + _display_text = string_real(_display_text, dig, precision); + } + + var tw = string_width(_display_text); + var th = string_height(_display_text); + + switch(align) { + case fa_left : break; + case fa_center : tx -= tw / 2; break; + case fa_right : tx -= tw; break; + } + + if(_update || _display_text != _disp_text) { + surface_set_shader(text_surface, noone, true, BLEND.add); + display_text(tx - tb_surf_x, _h / 2 - th / 2, _display_text, _w - ui(4)); + surface_reset_shader(); + } + + BLEND_ALPHA + draw_surface(text_surface, tb_surf_x, tb_surf_y); + BLEND_NORMAL + } + } + + if(DRAGGING && (DRAGGING.type == "Text" || DRAGGING.type == "Number") && hover && hoverRect) { + draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, _y, _w, _h, COLORS._main_value_positive, 1); + if(mouse_release(mb_left)) + onModify(DRAGGING.data); + } + + selecting = self == WIDGET_CURRENT; + resetFocus(); + sprite_index = -1; + return _h; + } #endregion +} \ No newline at end of file diff --git a/#backups/shaders/sh_atlas/sh_atlas.fsh.backup0 b/#backups/shaders/sh_atlas/sh_atlas.fsh.backup0 new file mode 100644 index 000000000..f734dd315 --- /dev/null +++ b/#backups/shaders/sh_atlas/sh_atlas.fsh.backup0 @@ -0,0 +1,38 @@ +// 2024-04-18 08:42:38 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; + +#define TAU 6.283185307179586 + +void main() { + vec2 tx = 1. / dimension; + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = col; + + if(col.a == 1.) + return; + + for(float i = 1.; i <= 64.; i++) { + float base = 1.; + float top = 0.; + + for(float j = 0.; j <= 64.; j++) { + float ang = top / base * TAU; + top += 2.; + if(top >= base) { + top = 1.; + base *= 2.; + } + + vec2 pxs = v_vTexcoord + vec2( cos(ang), sin(ang)) * i * tx; + vec4 sam = texture2D( gm_BaseTexture, pxs ); + + if(sam.a < 1.) continue; + + gl_FragColor = sam; + return; + } + } +} diff --git a/#backups/shaders/sh_atlas/sh_atlas.fsh.backup1 b/#backups/shaders/sh_atlas/sh_atlas.fsh.backup1 new file mode 100644 index 000000000..07bfc44ac --- /dev/null +++ b/#backups/shaders/sh_atlas/sh_atlas.fsh.backup1 @@ -0,0 +1,38 @@ +// 2024-04-18 08:42:35 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; + +#define TAU 6.283185307179586 + +void main() { + vec2 tx = 1. / dimension; + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = col; + + if(col.a == 1.) + return; + + for(float i = 1.; i <= 64.; i++) { + float base = 1.; + float top = 0.; + + for(float j = 0.; j <= 64.; j++) { + float ang = top / base * TAU; + top += 2.; + if(top >= base) { + top = 1.; + base *= 2.; + } + + vec2 pxs = v_vTexcoord + vec2( cos(ang), sin(ang)) * i * tx; + vec4 sam = texture2D( gm_BaseTexture, pxs ); + + if(sam.a < 1.) continue; + + gl_FragColor = sam; + return; + } + } +} diff --git a/#backups/shaders/sh_atlas_scan/sh_atlas_scan.fsh.backup0 b/#backups/shaders/sh_atlas_scan/sh_atlas_scan.fsh.backup0 new file mode 100644 index 000000000..b57dabcc6 --- /dev/null +++ b/#backups/shaders/sh_atlas_scan/sh_atlas_scan.fsh.backup0 @@ -0,0 +1,49 @@ +// 2024-04-18 08:38:57 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform int axis; +uniform float iteration; + +void main() { + vec2 tx = 1. / dimension; + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = col; + + if(col.a == 1.) + return; + + float _min, _cmp; + vec2 _str, _axs; + + if(axis == 0) { + _min = dimension.x; + _cmp = _min * v_vTexcoord.x; + + _str = vec2(0., v_vTexcoord.y); + _axs = vec2(tx.x, 0.); + + } else { + _min = dimension.y; + _cmp = _min * v_vTexcoord.y; + + _str = vec2(v_vTexcoord.x, 0.); + _axs = vec2(0., tx.y); + + } + + for(float i = 1.; i < 2048.; i++) { + if(i > iteration) break; + + vec2 sx = _str + _axs * i; + vec4 ss = texture2D( gm_BaseTexture, sx ); + + if(ss.a == 1. && abs(i - _cmp) < _min) { + _min = abs(i - _cmp); + col = ss; + } + } + + gl_FragColor = col; +} diff --git a/#backups/shaders/sh_atlas_scan/sh_atlas_scan.fsh.backup1 b/#backups/shaders/sh_atlas_scan/sh_atlas_scan.fsh.backup1 new file mode 100644 index 000000000..b57dabcc6 --- /dev/null +++ b/#backups/shaders/sh_atlas_scan/sh_atlas_scan.fsh.backup1 @@ -0,0 +1,49 @@ +// 2024-04-18 08:38:57 +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform int axis; +uniform float iteration; + +void main() { + vec2 tx = 1. / dimension; + vec4 col = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = col; + + if(col.a == 1.) + return; + + float _min, _cmp; + vec2 _str, _axs; + + if(axis == 0) { + _min = dimension.x; + _cmp = _min * v_vTexcoord.x; + + _str = vec2(0., v_vTexcoord.y); + _axs = vec2(tx.x, 0.); + + } else { + _min = dimension.y; + _cmp = _min * v_vTexcoord.y; + + _str = vec2(v_vTexcoord.x, 0.); + _axs = vec2(0., tx.y); + + } + + for(float i = 1.; i < 2048.; i++) { + if(i > iteration) break; + + vec2 sx = _str + _axs * i; + vec4 ss = texture2D( gm_BaseTexture, sx ); + + if(ss.a == 1. && abs(i - _cmp) < _min) { + _min = abs(i - _cmp); + col = ss; + } + } + + gl_FragColor = col; +} diff --git a/objects/o_main/Other_20.gml b/objects/o_main/Other_20.gml index 3271947b4..404a3707f 100644 --- a/objects/o_main/Other_20.gml +++ b/objects/o_main/Other_20.gml @@ -21,6 +21,9 @@ var pb = e[? "pointer_info_button_change_type"]; var tx = e[? "pointer_info_pen_tilt_x"]; var ty = e[? "pointer_info_pen_tilt_y"]; +PEN_X_DELTA = px - PEN_X; +PEN_Y_DELTA = px - PEN_Y; + PEN_X = px; PEN_Y = py; diff --git a/scripts/__initPen/__initPen.gml b/scripts/__initPen/__initPen.gml index 1c34e43d2..a8c9e7bb3 100644 --- a/scripts/__initPen/__initPen.gml +++ b/scripts/__initPen/__initPen.gml @@ -1,4 +1,5 @@ -globalvar PEN_USE, PEN_CONTACT, PEN_RELEASED, PEN_PRESSURE, PEN_X, PEN_Y; +globalvar PEN_USE, PEN_CONTACT, PEN_RELEASED, PEN_PRESSURE; +globalvar PEN_X, PEN_Y, PEN_X_DELTA, PEN_Y_DELTA; globalvar PEN_RIGHT_CLICK, PEN_RIGHT_PRESS, PEN_RIGHT_RELEASE; PEN_USE = false; @@ -6,6 +7,9 @@ PEN_USE = false; PEN_X = 0; PEN_Y = 0; +PEN_X_DELTA = 0; +PEN_Y_DELTA = 0; + PEN_CONTACT = false; PEN_PRESSURE = 0; diff --git a/scripts/buttonGroup/buttonGroup.gml b/scripts/buttonGroup/buttonGroup.gml index 18debd7ae..f111eb87c 100644 --- a/scripts/buttonGroup/buttonGroup.gml +++ b/scripts/buttonGroup/buttonGroup.gml @@ -7,6 +7,7 @@ function buttonGroup(_data, _onClick) : widget() constructor { fColor = COLORS._main_text; current_selecting = 0; + tooltips = []; for(var i = 0; i < array_length(data); i++) buttons[i] = button(-1); @@ -18,6 +19,8 @@ function buttonGroup(_data, _onClick) : widget() constructor { return self; } + static setTooltips = function(tt) { tooltips = tt; return self; } + static trigger = function() { if(current_selecting + 1 >= array_length(data)) onClick(0); @@ -75,6 +78,7 @@ function buttonGroup(_data, _onClick) : widget() constructor { for(var i = 0; i < amo; i++) { buttons[i].setFocusHover(active, hover); + buttons[i].tooltip = array_safe_get(tooltips, i, ""); var spr = i == 0 ? buttonSpr[0] : (i == amo - 1? buttonSpr[2] : buttonSpr[1]); diff --git a/scripts/canvas_draw_functions/canvas_draw_functions.gml b/scripts/canvas_draw_functions/canvas_draw_functions.gml index db3528ac6..f13278e32 100644 --- a/scripts/canvas_draw_functions/canvas_draw_functions.gml +++ b/scripts/canvas_draw_functions/canvas_draw_functions.gml @@ -135,15 +135,32 @@ function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region return; } - var _min_x = min(_x0, _x1) - 1; - var _max_x = max(_x0, _x1); - var _min_y = min(_y0, _y1) - 1; - var _max_y = max(_y0, _y1); + draw_set_circle_precision(64); + var _min_x = min(_x0, _x1) - 0.5; + var _max_x = max(_x0, _x1) - 0.5; + var _min_y = min(_y0, _y1) - 0.5; + var _max_y = max(_y0, _y1) - 0.5; - if(_fill) { - draw_set_circle_precision(64); - draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + if(brush.brush_surface == noone) { + if(_fill) draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); + + if(brush.brush_size == 1) { + draw_ellipse(_min_x, _min_y, _max_x, _max_y, 1); + + } else if(brush.brush_size < global.FIX_POINTS_AMOUNT) { + + var fx = global.FIX_POINTS[brush.brush_size]; + for( var i = 0, n = array_length(fx); i < n; i++ ) + draw_ellipse(_min_x + fx[i][0], _min_y + fx[i][1], _max_x + fx[i][0], _max_y + fx[i][1], 1); + + } else { + draw_ellipse(_min_x, _min_y, _max_x, _max_y, brush.brush_size); + + } + return; } + + if(_fill) draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); var samp = 64; var cx = (_min_x + _max_x) / 2; diff --git a/scripts/canvas_tool_node/canvas_tool_node.gml b/scripts/canvas_tool_node/canvas_tool_node.gml index 270906245..ba225f2f8 100644 --- a/scripts/canvas_tool_node/canvas_tool_node.gml +++ b/scripts/canvas_tool_node/canvas_tool_node.gml @@ -22,25 +22,34 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { surface_reset_shader(); static destroy = function() { - noti_warning("Selected node has no surface output."); - if(applySelection) canvas.tool_selection.apply(); canvas.nodeTool = noone; - surface_free_safe(maskedSurface); - cleanUp(); } static cleanUp = function() { surface_free_safe(targetSurface); surface_free_safe(maskedSurface); - nodeObject.destroy(); + + if(is_struct(nodeObject)) { + if(is_instanceof(nodeObject, Node)) + nodeObject.destroy(); + + else { + var keys = struct_get_names(nodeObject); + for (var i = 0, n = array_length(keys); i < n; i++) + if(is_instanceof(nodeObject[$ keys[i]], Node)) + nodeObject[$ keys[i]].destroy(); + } + } + } nodeObject = node.build(0, 0); if(nodeObject == noone || !is_instanceof(nodeObject, Node)) { + noti_warning("Not tools only allows a single node."); destroy(); return; } @@ -65,6 +74,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor { } if(outputJunction == noone) { + noti_warning("Selected node has no surface output."); destroy(); return; } diff --git a/scripts/canvas_tool_selection/canvas_tool_selection.gml b/scripts/canvas_tool_selection/canvas_tool_selection.gml index 156718ed2..658445ffd 100644 --- a/scripts/canvas_tool_selection/canvas_tool_selection.gml +++ b/scripts/canvas_tool_selection/canvas_tool_selection.gml @@ -229,15 +229,18 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { selection_sy = pos_y; selection_mx = mouse_cur_x; selection_my = mouse_cur_y; + } } if(key_press(vk_delete)) { is_selected = false; surface_free(selection_surface); - } - - if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); + + } else if(key_press(vk_escape)) { + apply(); + + } else if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); } #endregion function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region diff --git a/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml b/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml index bbf3fd4b3..d02afdd97 100644 --- a/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml +++ b/scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.gml @@ -2,6 +2,8 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection self.tool_attribute = toolAttr; + selecting = false; + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { mouse_cur_x = round((_mx - _x) / _s - 0.5); @@ -13,7 +15,7 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection var _fill_type = tool_attribute.fill8; if(!selector.is_select_drag && mouse_press(mb_left, active)) { - + selecting = true; canvas_buffer = node.canvas_buffer; preview_index = node.preview_index; @@ -57,7 +59,8 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection if(node.selection_tool_after != noone) node.selection_tool_after.toggle(); node.selection_tool_after = noone; - } + } else + selector.apply(); } } diff --git a/scripts/checkboxGroup/checkboxGroup.gml b/scripts/checkboxGroup/checkboxGroup.gml index 51c987f96..73cf58171 100644 --- a/scripts/checkboxGroup/checkboxGroup.gml +++ b/scripts/checkboxGroup/checkboxGroup.gml @@ -4,10 +4,10 @@ function checkBoxGroup(sprs, _onClick) : widget() constructor { onClick = _onClick; holding = noone; + tooltips = []; - static trigger = function(ind, val) { - onClick(ind, val); - } + static trigger = function(ind, val) { onClick(ind, val); } + static setTooltips = function(tt) { tooltips = tt; return self; } static drawParam = function(params) { setParam(params); @@ -44,6 +44,7 @@ function checkBoxGroup(sprs, _onClick) : widget() constructor { if(hover && point_in_rectangle(_m[0], _m[1], _dx, _dy, _dx + ss, _dy + ss)) { ind = 1 + TOOLTIP = array_safe_get(tooltips, i, ""); if(holding != noone) trigger(i, holding); diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index 4ccb7621c..661d67624 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -38,7 +38,7 @@ LATEST_VERSION = 11600; VERSION = 11700; SAVE_VERSION = 11690; - VERSION_STRING = "1.17.rc1"; + VERSION_STRING = "1.17.rc3"; BUILD_NUMBER = 11700; globalvar HOTKEYS, HOTKEY_CONTEXT; diff --git a/scripts/load_function/load_function.gml b/scripts/load_function/load_function.gml index 34bb46ca6..4045bc6b9 100644 --- a/scripts/load_function/load_function.gml +++ b/scripts/load_function/load_function.gml @@ -115,7 +115,7 @@ function LOAD_AT(path, readonly = false, override = false) { #region s = buffer_read(b, buffer_string); } - _load_content = json_parse(s); + _load_content = json_try_parse(s); printIf(log, $" > Load struct : {(get_timer() - t1) / 1000} ms"); t1 = get_timer(); diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index c8878ca67..e3b2a037d 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -214,10 +214,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.drawLayer = 0; tool_attribute.pickColor = c_white; - tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); + tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }) + .setTooltips( [ "Draw on top", "Draw behind", "Draw inside" ] ); tool_attribute.mirror = [ false, false, false ]; - tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }); + tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; }) + .setTooltips( [ "Toggle diagonal", "", "" ] ); tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ], [ "", tool_drawLayer_edit, "drawLayer", tool_attribute ], @@ -512,12 +514,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_clear(drawing_surface); } #endregion - function surface_store_buffers(index = preview_index) { #region + static surface_store_buffers = function(index = preview_index) { #region for( var i = 0; i < attributes.frames; i++ ) surface_store_buffer(i); } #endregion - function surface_store_buffer(index = preview_index) { #region + static surface_store_buffer = function(index = preview_index) { #region if(index >= attributes.frames) return; buffer_delete(canvas_buffer[index]); @@ -816,6 +818,42 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor shader_set_f("dimension", _sw, _sh); draw_surface_ext_safe(preview_draw_mask, 0, 0, 1, 1, 0, c_white, 1); shader_reset(); + + draw_set_color(COLORS._main_accent); + if(tool_selection.is_selected) { + var _spx = tool_selection.selection_position[0]; + var _spy = tool_selection.selection_position[1]; + var _spw = tool_selection.selection_size[0]; + var _sph = tool_selection.selection_size[1]; + + var _x0 = _x + _spx * _s; + var _x1 = _x + (_spx + _spw) * _s; + var _xc = _x + (_spx + _spw / 2) * _s; + + var _y0 = _y + _spy * _s; + var _y1 = _y + (_spy + _sph) * _s; + var _yc = _y + (_spy + _sph / 2) * _s; + + if(tool_attribute.mirror[1]) draw_line(_xc, _y0, _xc, _y1); + if(tool_attribute.mirror[2]) draw_line(_x0, _yc, _x1, _yc); + + } else { + var _x0 = _x; + var _x1 = _x + _dim[0] * _s; + var _xc = _x + _dim[0] / 2 * _s; + + var _y0 = _y; + var _y1 = _y + _dim[1] * _s; + var _yc = _y + _dim[1] / 2 * _s; + + if(tool_attribute.mirror[0] == false) { + if(tool_attribute.mirror[1]) draw_line(_xc, _y0, _xc, _y1); + if(tool_attribute.mirror[2]) draw_line(_x0, _yc, _x1, _yc); + } else { + if(tool_attribute.mirror[1]) draw_line(_x0, _y1, _x1, _y0); + if(tool_attribute.mirror[2]) draw_line(_x0, _y0, _x1, _y1); + } + } if(_tool) _tool.drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); @@ -916,8 +954,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } } #endregion - static getPreviewValues = function() { return nodeTool == noone || nodeTool.applySelection? output_surface : noone; } - static doSerialize = function(_map) { #region surface_store_buffers(); var _buff = array_create(attributes.frames); diff --git a/scripts/node_outline/node_outline.gml b/scripts/node_outline/node_outline.gml index 75b5918d3..46a7fa3aa 100644 --- a/scripts/node_outline/node_outline.gml +++ b/scripts/node_outline/node_outline.gml @@ -17,7 +17,7 @@ function Node_Outline(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c inputs[| 5] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) .setDisplay(VALUE_DISPLAY.enum_button, ["Inside", "Outside"]); - inputs[| 6] = nodeValue("Anti alising", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, 0); + inputs[| 6] = nodeValue("Anti aliasing", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, 0); inputs[| 7] = nodeValue("Oversample mode", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "How to deal with pixel outside the surface.\n - Empty: Use empty pixel\n - Clamp: Repeat edge pixel\n - Repeat: Repeat texture.") .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Empty", "Clamp", "Repeat" ]); diff --git a/scripts/node_shape/node_shape.gml b/scripts/node_shape/node_shape.gml index bca4dce54..7563b35ae 100644 --- a/scripts/node_shape/node_shape.gml +++ b/scripts/node_shape/node_shape.gml @@ -55,7 +55,7 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con .setDisplay(VALUE_DISPLAY.slider) .setVisible(false); - inputs[| 6] = nodeValue("Anti alising", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); + inputs[| 6] = nodeValue("Anti-aliasing", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false); inputs[| 7] = nodeValue("Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) .setDisplay(VALUE_DISPLAY.rotation); diff --git a/scripts/textBox/textBox.gml b/scripts/textBox/textBox.gml index 398383508..1384c06d2 100644 --- a/scripts/textBox/textBox.gml +++ b/scripts/textBox/textBox.gml @@ -397,7 +397,6 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { if(mouse_release(mb_left, active)) click_block = false; - } } #endregion @@ -502,9 +501,9 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); - if(sliding > 0) { #region - slide_delta += window_mouse_get_delta_x(); - slide_delta += window_mouse_get_delta_y(); + if(sliding > 0) { #region slide + slide_delta += PEN_USE? PEN_X_DELTA : window_mouse_get_delta_x(); + slide_delta += PEN_USE? PEN_Y_DELTA : window_mouse_get_delta_y(); if(sliding == 1 && abs(slide_delta) > 8) { deactivate(); @@ -514,7 +513,7 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { CURSOR_LOCK_X = mouse_mx; CURSOR_LOCK_Y = mouse_my; - + sliding = 2; } @@ -532,8 +531,10 @@ function textBox(_input, _onModify) : textInput(_input, _onModify) constructor { } else { var _s = slide_speed; - var _mdx = window_mouse_get_delta_x(); - var _mdy = window_mouse_get_delta_y(); + + var _mdx = PEN_USE? PEN_X_DELTA : window_mouse_get_delta_x(); + var _mdy = PEN_USE? PEN_Y_DELTA : window_mouse_get_delta_y(); + var _dx = abs(_mdx) > abs(_mdy)? _mdx : -_mdy; if(key_mod_press(CTRL) && !slide_snap) _s *= 10;