mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-23 21:46:17 +01:00
palette alpha fix
This commit is contained in:
parent
a768e60f21
commit
dce6a37919
35 changed files with 6962 additions and 1918 deletions
442
#backups/objects/o_dialog_palette/o_dialog_palette.yy.backup0
Normal file
442
#backups/objects/o_dialog_palette/o_dialog_palette.yy.backup0
Normal file
|
@ -0,0 +1,442 @@
|
|||
// 2024-04-20 10:00:16
|
||||
#event properties (no comments/etc. here are saved)
|
||||
parent_index = _p_dialog_undo_block;
|
||||
uses_physics = false;
|
||||
|
||||
#event create init
|
||||
event_inherited();
|
||||
|
||||
#region data
|
||||
dialog_w = ui(812);
|
||||
dialog_h = ui(440);
|
||||
title_height = 52;
|
||||
destroy_on_click_out = true;
|
||||
|
||||
name = __txtx("palette_editor_title", "Palette editor");
|
||||
palette = 0;
|
||||
|
||||
index_selecting = 0;
|
||||
index_dragging = -1;
|
||||
interactable = true;
|
||||
|
||||
index_drag_x = 0; index_drag_x_to = 0;
|
||||
index_drag_y = 0; index_drag_y_to = 0;
|
||||
index_drag_w = 0; index_drag_w_to = 0;
|
||||
index_drag_h = 0; index_drag_h_to = 0;
|
||||
|
||||
setColor = function(color) {
|
||||
if(index_selecting == -1 || palette == 0) return;
|
||||
palette[index_selecting] = color;
|
||||
|
||||
if(onApply == noone) return;
|
||||
onApply(palette);
|
||||
}
|
||||
|
||||
onApply = noone;
|
||||
selector = new colorSelector(setColor);
|
||||
selector.dropper_close = false;
|
||||
selector.discretize_pal = false;
|
||||
|
||||
previous_palette = c_black;
|
||||
|
||||
function setDefault(pal) {
|
||||
setPalette(pal);
|
||||
previous_palette = array_clone(pal);
|
||||
}
|
||||
|
||||
b_cancel = button(function() {
|
||||
onApply(previous_palette);
|
||||
instance_destroy();
|
||||
}).setIcon(THEME.undo, 0, COLORS._main_icon)
|
||||
.setTooltip(__txtx("dialog_revert_and_exit", "Revert and exit"));
|
||||
|
||||
b_apply = button(function() {
|
||||
onApply(palette);
|
||||
instance_destroy();
|
||||
}).setIcon(THEME.accept, 0, COLORS._main_icon_dark);
|
||||
|
||||
function setPalette(pal) {
|
||||
palette = pal;
|
||||
index_selecting = 0;
|
||||
if(array_length(palette) > 0)
|
||||
selector.setColor(palette[0]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region presets
|
||||
hovering_name = "";
|
||||
|
||||
sp_preset_w = ui(240 - 32 - 16);
|
||||
sp_presets = new scrollPane(sp_preset_w, dialog_h - ui(62), function(_y, _m) {
|
||||
var ww = sp_preset_w - ui(40);
|
||||
var hh = ui(32);
|
||||
var yy = _y + ui(8);
|
||||
var hg = ui(52);
|
||||
draw_clear_alpha(COLORS.panel_bg_clear, 0);
|
||||
|
||||
for(var i = -1; i < array_length(PALETTES); i++) {
|
||||
var pal = i == -1? {
|
||||
name: "project",
|
||||
palette: PROJECT.attributes.palette,
|
||||
path: ""
|
||||
} : PALETTES[i];
|
||||
var isHover = sHOVER && sp_presets.hover && point_in_rectangle(_m[0], _m[1], ui(4), yy, ui(4) + sp_preset_w - ui(16), yy + hg);
|
||||
draw_sprite_stretched(THEME.ui_panel_bg, 3, ui(4), yy, sp_preset_w - ui(16), hg);
|
||||
if(isHover)
|
||||
draw_sprite_stretched_ext(THEME.node_active, 1, ui(4), yy, sp_preset_w - ui(16), hg, COLORS._main_accent, 1);
|
||||
|
||||
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
|
||||
draw_text(ui(16), yy + ui(8), pal.name);
|
||||
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(16));
|
||||
|
||||
if(isHover) {
|
||||
if(mouse_press(mb_left, interactable && sFOCUS)) {
|
||||
palette = array_clone(pal.palette);
|
||||
onApply(palette);
|
||||
|
||||
index_selecting = 0;
|
||||
selector.setColor(palette[index_selecting], false);
|
||||
}
|
||||
|
||||
if(i >= 0 && mouse_press(mb_right, interactable && sFOCUS)) {
|
||||
hovering = pal;
|
||||
|
||||
menuCall("palette_window_preset_menu",,, [
|
||||
menuItem(__txtx("palette_editor_set_default", "Set as default"), function() {
|
||||
DEF_PALETTE = array_clone(hovering.palette);
|
||||
}),
|
||||
menuItem(__txtx("palette_editor_delete", "Delete palette"), function() {
|
||||
file_delete(hovering.path);
|
||||
__initPalette();
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
yy += hg + ui(4);
|
||||
hh += hg + ui(4);
|
||||
}
|
||||
|
||||
return hh;
|
||||
});
|
||||
|
||||
sp_presets.always_scroll = true;
|
||||
#endregion
|
||||
|
||||
#region tools
|
||||
function sortPalette(sortFunc) {
|
||||
array_sort(palette, sortFunc);
|
||||
onApply(palette);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region action
|
||||
onResize = function() {
|
||||
sp_presets.resize(sp_preset_w, dialog_h - ui(62));
|
||||
}
|
||||
|
||||
function checkMouse() {}
|
||||
#endregion
|
||||
|
||||
#event step_begin init
|
||||
if !ready exit;
|
||||
|
||||
#region destroy
|
||||
selector.interactable = interactable;
|
||||
if(!selector.dropper_active) {
|
||||
if(sHOVER && !point_in_rectangle(mouse_mx, mouse_my, dialog_x, dialog_y, dialog_x + dialog_w, dialog_y + dialog_h)) {
|
||||
if(destroy_on_click_out && mouse_press(mb_left))
|
||||
instance_destroy(self);
|
||||
}
|
||||
doDrag();
|
||||
}
|
||||
|
||||
if(sFOCUS && WIDGET_CURRENT == noone) {
|
||||
if(keyboard_check_pressed(vk_enter)) {
|
||||
onApply(palette);
|
||||
instance_destroy();
|
||||
}
|
||||
|
||||
if(keyboard_check_pressed(vk_escape)) {
|
||||
onApply(previous_palette);
|
||||
instance_destroy();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region resize
|
||||
if(_dialog_h != dialog_h || _dialog_w != dialog_w) {
|
||||
_dialog_h = dialog_h;
|
||||
_dialog_w = dialog_w;
|
||||
|
||||
if(onResize != -1) onResize();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#event draw_gui init
|
||||
if !ready exit;
|
||||
if palette == 0 exit;
|
||||
|
||||
#region dropper
|
||||
selector.interactable = interactable;
|
||||
if(selector.dropper_active) {
|
||||
selector.drawDropper(self);
|
||||
exit;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region base UI
|
||||
var presets_x = dialog_x;
|
||||
var presets_w = ui(240);
|
||||
|
||||
var content_x = dialog_x + presets_w + ui(16);
|
||||
var content_w = dialog_w - presets_w - ui(16);
|
||||
|
||||
var p = DIALOG_PAD;
|
||||
var p2 = DIALOG_PAD * 2;
|
||||
|
||||
draw_sprite_stretched(THEME.dialog_bg, 0, presets_x - p, dialog_y - p, presets_w + p2, dialog_h + p2);
|
||||
if(sFOCUS) draw_sprite_stretched_ext(THEME.dialog_active, 0, presets_x - p, dialog_y - p, presets_w + p2, dialog_h + p2, COLORS._main_accent, 1);
|
||||
|
||||
draw_sprite_stretched(THEME.dialog_bg, 0, content_x - p, dialog_y - p, content_w + p2, dialog_h + p2);
|
||||
if(sFOCUS) draw_sprite_stretched_ext(THEME.dialog_active, 0, content_x - p, dialog_y - p, content_w + p2, dialog_h + p2, COLORS._main_accent, 1);
|
||||
|
||||
draw_set_text(f_p0, fa_left, fa_top, COLORS._main_text);
|
||||
draw_text(presets_x + ui(24), dialog_y + ui(16), __txt("Presets"));
|
||||
draw_text(content_x + (!interactable * ui(32)) + ui(24), dialog_y + ui(16), name);
|
||||
if(!interactable)
|
||||
draw_sprite_ui(THEME.lock, 0, content_x + ui(24 + 12), dialog_y + ui(16 + 12),,,, COLORS._main_icon);
|
||||
#endregion
|
||||
|
||||
#region presets
|
||||
draw_sprite_stretched(THEME.ui_panel_bg, 1, presets_x + ui(16), dialog_y + ui(44), ui(240 - 32), dialog_h - ui(60));
|
||||
|
||||
sp_presets.setFocusHover(sFOCUS, sHOVER);
|
||||
sp_presets.draw(presets_x + ui(24), dialog_y + ui(44));
|
||||
|
||||
var bx = presets_x + presets_w - ui(44);
|
||||
var by = dialog_y + ui(12);
|
||||
var bs = ui(28);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txtx("add_preset", "Add to preset"), THEME.add_20) == 2) {
|
||||
var dia = dialogCall(o_dialog_file_name, mouse_mx + ui(8), mouse_my + ui(8));
|
||||
dia.onModify = function (txt) {
|
||||
var file = file_text_open_write(txt + ".hex");
|
||||
for(var i = 0; i < array_length(palette); i++) {
|
||||
var cc = palette[i];
|
||||
var r = number_to_hex(color_get_red(cc));
|
||||
var g = number_to_hex(color_get_green(cc));
|
||||
var b = number_to_hex(color_get_blue(cc));
|
||||
var a = number_to_hex(color_get_alpha(cc));
|
||||
|
||||
file_text_write_string(file, $"{r}{g}{b}{a}\n");
|
||||
}
|
||||
file_text_close(file);
|
||||
__initPalette();
|
||||
};
|
||||
dia.path = DIRECTORY + "Palettes/"
|
||||
}
|
||||
bx -= ui(32);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txt("Refresh"), THEME.refresh_20) == 2)
|
||||
__initPalette();
|
||||
bx -= ui(32);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txtx("color_selector_open_palette", "Open palette folder"), THEME.path_open_20) == 2) {
|
||||
var _realpath = DIRECTORY + "Palettes";
|
||||
shellOpenExplorer(_realpath)
|
||||
}
|
||||
draw_sprite_ui_uniform(THEME.path_open_20, 1, bx + bs / 2, by + bs / 2, 1, c_white);
|
||||
bx -= ui(32);
|
||||
#endregion
|
||||
|
||||
#region palette
|
||||
var pl_x = content_x + ui(60);
|
||||
var pl_y = dialog_y + ui(54);
|
||||
var pl_w = content_w - ui(154);
|
||||
var pl_h = ui(24);
|
||||
|
||||
var max_col = 8;
|
||||
var col = min(array_length(palette), max_col);
|
||||
var row = ceil(array_length(palette) / col);
|
||||
var ww = round(pl_w / col);
|
||||
var hh = (pl_h + ui(6)) * row;
|
||||
dialog_h = ui(408) + hh;
|
||||
|
||||
draw_sprite_stretched(THEME.textbox, 3, pl_x - ui(6), pl_y - ui(6), pl_w + ui(12), hh + ui(6));
|
||||
draw_sprite_stretched(THEME.textbox, 0, pl_x - ui(6), pl_y - ui(6), pl_w + ui(12), hh + ui(6));
|
||||
|
||||
#region tools
|
||||
var bx = content_x + content_w - ui(50);
|
||||
var by = dialog_y + ui(16);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_sort", "Sort color"), THEME.sort) == 2) {
|
||||
menuCall("palette_window_sort_menu", bx + ui(32), by, [
|
||||
menuItem(__txtx("palette_editor_sort_brighter", "Brighter"), function() { sortPalette(__sortBright); }),
|
||||
menuItem(__txtx("palette_editor_sort_darker", "Darker"), function() { sortPalette(__sortDark); }),
|
||||
-1,
|
||||
menuItem(__txtx("palette_editor_sort_hue", "Hue"), function() { sortPalette(__sortHue); }),
|
||||
menuItem(__txtx("palette_editor_sort_sat", "Saturation"), function() { sortPalette(__sortSat); }),
|
||||
menuItem(__txtx("palette_editor_sort_val", "Value"), function() { sortPalette(__sortVal); }),
|
||||
],, palette);
|
||||
}
|
||||
bx -= ui(32);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_reverse", "Reverse palette"), THEME.reverse) == 2) {
|
||||
palette = array_reverse(palette);
|
||||
onApply(palette);
|
||||
}
|
||||
bx -= ui(32);
|
||||
#endregion
|
||||
|
||||
var hover = -1, hvx, hvy;
|
||||
var _pd = ui(5);
|
||||
|
||||
for(var i = 0; i < row; i++)
|
||||
for(var j = 0; j < col; j++) {
|
||||
var index = i * col + j;
|
||||
if(index >= array_length(palette)) break;
|
||||
|
||||
var _p = palette[index];
|
||||
var _pa = _color_get_alpha(_p);
|
||||
var _kx = pl_x + j * ww;
|
||||
var _ky = pl_y + i * (pl_h + ui(6));
|
||||
|
||||
var _px = _kx + ui(2);
|
||||
var _py = _ky;
|
||||
var _pw = ww - ui(4);
|
||||
var _ph = pl_h;
|
||||
|
||||
if(index == index_dragging) {
|
||||
index_drag_x_to = _px;
|
||||
index_drag_y_to = _py;
|
||||
index_drag_w_to = _pw;
|
||||
index_drag_h_to = _ph;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(_pa < 1) {
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph - ui(8), _p, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw, ui(6), c_black, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw * _pa, ui(6), c_white, 1);
|
||||
} else
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph, _p, 1);
|
||||
|
||||
if(index == index_selecting)
|
||||
draw_sprite_stretched_ext(THEME.palette_selecting, 0, _px - _pd, _py - _pd, _pw + _pd * 2, _ph + _pd * 2, c_white, 1);
|
||||
|
||||
if(sHOVER && point_in_rectangle(mouse_mx, mouse_my, _kx, _ky, _kx + ww, _ky + pl_h)) {
|
||||
hover = index;
|
||||
hvx = _kx;
|
||||
hvy = _ky;
|
||||
}
|
||||
}
|
||||
|
||||
if(index_dragging > -1) {
|
||||
index_drag_x = index_drag_x == 0? index_drag_x_to : lerp_float(index_drag_x, index_drag_x_to, 5);
|
||||
index_drag_y = index_drag_y == 0? index_drag_y_to : lerp_float(index_drag_y, index_drag_y_to, 5);
|
||||
index_drag_w = index_drag_w == 0? index_drag_w_to : lerp_float(index_drag_w, index_drag_w_to, 5);
|
||||
index_drag_h = index_drag_h == 0? index_drag_h_to : lerp_float(index_drag_h, index_drag_h_to, 5);
|
||||
|
||||
_px = index_drag_x;
|
||||
_py = index_drag_y;
|
||||
_pw = index_drag_w;
|
||||
_ph = index_drag_h;
|
||||
_p = palette[index_dragging];
|
||||
_pa = _color_get_alpha(_p);
|
||||
|
||||
if(_pa < 1) {
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph - ui(8), _p, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw, ui(6), c_black, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw * _pa, ui(6), c_white, 1);
|
||||
} else
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph, _p, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_selecting, 0, _px - _pd, _py - _pd, _pw + _pd * 2, _ph + _pd * 2, c_white, 1);
|
||||
|
||||
if(hover > -1 && hover != index_dragging) {
|
||||
draw_set_color(COLORS.dialog_palette_divider);
|
||||
var sx = hvx;
|
||||
if(hover >= index_dragging) sx += ww;
|
||||
|
||||
var tt = palette[index_dragging];
|
||||
|
||||
array_delete(palette, index_dragging, 1);
|
||||
array_insert(palette, hover, tt);
|
||||
index_selecting = hover;
|
||||
index_dragging = hover;
|
||||
|
||||
onApply(palette);
|
||||
}
|
||||
|
||||
if(mouse_release(mb_left))
|
||||
index_dragging = -1;
|
||||
} else {
|
||||
index_drag_x = 0;
|
||||
index_drag_y = 0;
|
||||
index_drag_w = 0;
|
||||
index_drag_h = 0;
|
||||
}
|
||||
|
||||
if(mouse_press(mb_left, sFOCUS) && hover > -1) {
|
||||
index_selecting = hover;
|
||||
if(interactable)
|
||||
index_dragging = hover;
|
||||
selector.setColor(palette[hover]);
|
||||
}
|
||||
|
||||
var bx = content_x + content_w - ui(50);
|
||||
var by = pl_y - ui(2);
|
||||
|
||||
if(array_length(palette) > 1) {
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.minus) == 2) {
|
||||
array_delete(palette, index_selecting, 1);
|
||||
index_selecting = clamp(index_selecting - 1, 0, array_length(palette) - 1);
|
||||
onApply(palette);
|
||||
}
|
||||
} else {
|
||||
draw_sprite_ui_uniform(THEME.minus, 0, bx + ui(14), by + ui(14), 1, COLORS._main_icon, 0.5);
|
||||
}
|
||||
|
||||
bx -= ui(32);
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.add) == 2) {
|
||||
index_selecting = array_length(palette);
|
||||
palette[array_length(palette)] = c_black;
|
||||
onApply(palette);
|
||||
}
|
||||
|
||||
bx = content_x + ui(18);
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_load", "Load palette file") + " (.hex)", THEME.file) == 2) {
|
||||
var path = get_open_filename("HEX palette|*.hex", "");
|
||||
key_release();
|
||||
|
||||
if(isPaletteFile(path)) {
|
||||
palette = loadPalette(path);
|
||||
onApply(palette);
|
||||
}
|
||||
}
|
||||
draw_sprite_ui_uniform(THEME.file, 0, bx + ui(14), by + ui(14), 1, COLORS._main_icon);
|
||||
#endregion
|
||||
|
||||
#region selector
|
||||
var col_x = content_x + ui(20);
|
||||
var col_y = dialog_y + ui(70) + hh;
|
||||
|
||||
selector.draw(col_x, col_y, sFOCUS, sHOVER);
|
||||
#endregion
|
||||
|
||||
#region controls
|
||||
var bx = content_x + content_w - ui(36);
|
||||
var by = dialog_y + dialog_h - ui(36);
|
||||
|
||||
b_apply.register();
|
||||
b_apply.setFocusHover(sFOCUS, sHOVER);
|
||||
b_apply.draw(bx - ui(18), by - ui(18), ui(36), ui(36), mouse_ui, THEME.button_lime);
|
||||
|
||||
bx -= ui(48);
|
||||
b_cancel.register();
|
||||
b_cancel.setFocusHover(sFOCUS, sHOVER);
|
||||
b_cancel.draw(bx - ui(18), by - ui(18), ui(36), ui(36), mouse_ui, THEME.button_hide);
|
||||
#endregion
|
||||
|
||||
#event draw_gui_end
|
||||
selector.colorPicker();
|
442
#backups/objects/o_dialog_palette/o_dialog_palette.yy.backup1
Normal file
442
#backups/objects/o_dialog_palette/o_dialog_palette.yy.backup1
Normal file
|
@ -0,0 +1,442 @@
|
|||
// 2024-04-20 09:59:48
|
||||
#event properties (no comments/etc. here are saved)
|
||||
parent_index = _p_dialog_undo_block;
|
||||
uses_physics = false;
|
||||
|
||||
#event create init
|
||||
event_inherited();
|
||||
|
||||
#region data
|
||||
dialog_w = ui(812);
|
||||
dialog_h = ui(440);
|
||||
title_height = 52;
|
||||
destroy_on_click_out = true;
|
||||
|
||||
name = __txtx("palette_editor_title", "Palette editor");
|
||||
palette = 0;
|
||||
|
||||
index_selecting = 0;
|
||||
index_dragging = -1;
|
||||
interactable = true;
|
||||
|
||||
index_drag_x = 0; index_drag_x_to = 0;
|
||||
index_drag_y = 0; index_drag_y_to = 0;
|
||||
index_drag_w = 0; index_drag_w_to = 0;
|
||||
index_drag_h = 0; index_drag_h_to = 0;
|
||||
|
||||
setColor = function(color) {
|
||||
if(index_selecting == -1 || palette == 0) return;
|
||||
palette[index_selecting] = color;
|
||||
|
||||
if(onApply == noone) return;
|
||||
onApply(palette);
|
||||
}
|
||||
|
||||
onApply = noone;
|
||||
selector = new colorSelector(setColor);
|
||||
selector.dropper_close = false;
|
||||
selector.discretize_pal = false;
|
||||
|
||||
previous_palette = c_black;
|
||||
|
||||
function setDefault(pal) {
|
||||
setPalette(pal);
|
||||
previous_palette = array_clone(pal);
|
||||
}
|
||||
|
||||
b_cancel = button(function() {
|
||||
onApply(previous_palette);
|
||||
instance_destroy();
|
||||
}).setIcon(THEME.undo, 0, COLORS._main_icon)
|
||||
.setTooltip(__txtx("dialog_revert_and_exit", "Revert and exit"));
|
||||
|
||||
b_apply = button(function() {
|
||||
onApply(palette);
|
||||
instance_destroy();
|
||||
}).setIcon(THEME.accept, 0, COLORS._main_icon_dark);
|
||||
|
||||
function setPalette(pal) {
|
||||
palette = pal;
|
||||
index_selecting = 0;
|
||||
if(array_length(palette) > 0)
|
||||
selector.setColor(palette[0]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region presets
|
||||
hovering_name = "";
|
||||
|
||||
sp_preset_w = ui(240 - 32 - 16);
|
||||
sp_presets = new scrollPane(sp_preset_w, dialog_h - ui(62), function(_y, _m) {
|
||||
var ww = sp_preset_w - ui(40);
|
||||
var hh = ui(32);
|
||||
var yy = _y + ui(8);
|
||||
var hg = ui(52);
|
||||
draw_clear_alpha(COLORS.panel_bg_clear, 0);
|
||||
|
||||
for(var i = -1; i < array_length(PALETTES); i++) {
|
||||
var pal = i == -1? {
|
||||
name: "project",
|
||||
palette: PROJECT.attributes.palette,
|
||||
path: ""
|
||||
} : PALETTES[i];
|
||||
var isHover = sHOVER && sp_presets.hover && point_in_rectangle(_m[0], _m[1], ui(4), yy, ui(4) + sp_preset_w - ui(16), yy + hg);
|
||||
draw_sprite_stretched(THEME.ui_panel_bg, 3, ui(4), yy, sp_preset_w - ui(16), hg);
|
||||
if(isHover)
|
||||
draw_sprite_stretched_ext(THEME.node_active, 1, ui(4), yy, sp_preset_w - ui(16), hg, COLORS._main_accent, 1);
|
||||
|
||||
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
|
||||
draw_text(ui(16), yy + ui(8), pal.name);
|
||||
drawPalette(pal.palette, ui(16), yy + ui(28), ww, ui(16));
|
||||
|
||||
if(isHover) {
|
||||
if(mouse_press(mb_left, interactable && sFOCUS)) {
|
||||
palette = array_clone(pal.palette);
|
||||
onApply(palette);
|
||||
|
||||
index_selecting = 0;
|
||||
selector.setColor(palette[index_selecting], false);
|
||||
}
|
||||
|
||||
if(i >= 0 && mouse_press(mb_right, interactable && sFOCUS)) {
|
||||
hovering = pal;
|
||||
|
||||
menuCall("palette_window_preset_menu",,, [
|
||||
menuItem(__txtx("palette_editor_set_default", "Set as default"), function() {
|
||||
DEF_PALETTE = array_clone(hovering.palette);
|
||||
}),
|
||||
menuItem(__txtx("palette_editor_delete", "Delete palette"), function() {
|
||||
file_delete(hovering.path);
|
||||
__initPalette();
|
||||
}),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
yy += hg + ui(4);
|
||||
hh += hg + ui(4);
|
||||
}
|
||||
|
||||
return hh;
|
||||
});
|
||||
|
||||
sp_presets.always_scroll = true;
|
||||
#endregion
|
||||
|
||||
#region tools
|
||||
function sortPalette(sortFunc) {
|
||||
array_sort(palette, sortFunc);
|
||||
onApply(palette);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region action
|
||||
onResize = function() {
|
||||
sp_presets.resize(sp_preset_w, dialog_h - ui(62));
|
||||
}
|
||||
|
||||
function checkMouse() {}
|
||||
#endregion
|
||||
|
||||
#event step_begin init
|
||||
if !ready exit;
|
||||
|
||||
#region destroy
|
||||
selector.interactable = interactable;
|
||||
if(!selector.dropper_active) {
|
||||
if(sHOVER && !point_in_rectangle(mouse_mx, mouse_my, dialog_x, dialog_y, dialog_x + dialog_w, dialog_y + dialog_h)) {
|
||||
if(destroy_on_click_out && mouse_press(mb_left))
|
||||
instance_destroy(self);
|
||||
}
|
||||
doDrag();
|
||||
}
|
||||
|
||||
if(sFOCUS && WIDGET_CURRENT == noone) {
|
||||
if(keyboard_check_pressed(vk_enter)) {
|
||||
onApply(palette);
|
||||
instance_destroy();
|
||||
}
|
||||
|
||||
if(keyboard_check_pressed(vk_escape)) {
|
||||
onApply(previous_palette);
|
||||
instance_destroy();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region resize
|
||||
if(_dialog_h != dialog_h || _dialog_w != dialog_w) {
|
||||
_dialog_h = dialog_h;
|
||||
_dialog_w = dialog_w;
|
||||
|
||||
if(onResize != -1) onResize();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#event draw_gui init
|
||||
if !ready exit;
|
||||
if palette == 0 exit;
|
||||
|
||||
#region dropper
|
||||
selector.interactable = interactable;
|
||||
if(selector.dropper_active) {
|
||||
selector.drawDropper(self);
|
||||
exit;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region base UI
|
||||
var presets_x = dialog_x;
|
||||
var presets_w = ui(240);
|
||||
|
||||
var content_x = dialog_x + presets_w + ui(16);
|
||||
var content_w = dialog_w - presets_w - ui(16);
|
||||
|
||||
var p = DIALOG_PAD;
|
||||
var p2 = DIALOG_PAD * 2;
|
||||
|
||||
draw_sprite_stretched(THEME.dialog_bg, 0, presets_x - p, dialog_y - p, presets_w + p2, dialog_h + p2);
|
||||
if(sFOCUS) draw_sprite_stretched_ext(THEME.dialog_active, 0, presets_x - p, dialog_y - p, presets_w + p2, dialog_h + p2, COLORS._main_accent, 1);
|
||||
|
||||
draw_sprite_stretched(THEME.dialog_bg, 0, content_x - p, dialog_y - p, content_w + p2, dialog_h + p2);
|
||||
if(sFOCUS) draw_sprite_stretched_ext(THEME.dialog_active, 0, content_x - p, dialog_y - p, content_w + p2, dialog_h + p2, COLORS._main_accent, 1);
|
||||
|
||||
draw_set_text(f_p0, fa_left, fa_top, COLORS._main_text);
|
||||
draw_text(presets_x + ui(24), dialog_y + ui(16), __txt("Presets"));
|
||||
draw_text(content_x + (!interactable * ui(32)) + ui(24), dialog_y + ui(16), name);
|
||||
if(!interactable)
|
||||
draw_sprite_ui(THEME.lock, 0, content_x + ui(24 + 12), dialog_y + ui(16 + 12),,,, COLORS._main_icon);
|
||||
#endregion
|
||||
|
||||
#region presets
|
||||
draw_sprite_stretched(THEME.ui_panel_bg, 1, presets_x + ui(16), dialog_y + ui(44), ui(240 - 32), dialog_h - ui(60));
|
||||
|
||||
sp_presets.setFocusHover(sFOCUS, sHOVER);
|
||||
sp_presets.draw(presets_x + ui(24), dialog_y + ui(44));
|
||||
|
||||
var bx = presets_x + presets_w - ui(44);
|
||||
var by = dialog_y + ui(12);
|
||||
var bs = ui(28);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txtx("add_preset", "Add to preset"), THEME.add_20) == 2) {
|
||||
var dia = dialogCall(o_dialog_file_name, mouse_mx + ui(8), mouse_my + ui(8));
|
||||
dia.onModify = function (txt) {
|
||||
var file = file_text_open_write(txt + ".hex");
|
||||
for(var i = 0; i < array_length(palette); i++) {
|
||||
var cc = palette[i];
|
||||
var r = number_to_hex(color_get_red(cc));
|
||||
var g = number_to_hex(color_get_green(cc));
|
||||
var b = number_to_hex(color_get_blue(cc));
|
||||
var a = number_to_hex(color_get_alpha(cc));
|
||||
|
||||
file_text_write_string(file, $"{r}{g}{b}{a}\n");
|
||||
}
|
||||
file_text_close(file);
|
||||
__initPalette();
|
||||
};
|
||||
dia.path = DIRECTORY + "Palettes/"
|
||||
}
|
||||
bx -= ui(32);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txt("Refresh"), THEME.refresh_20) == 2)
|
||||
__initPalette();
|
||||
bx -= ui(32);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, bs, bs, mouse_ui, sFOCUS, sHOVER, __txtx("color_selector_open_palette", "Open palette folder"), THEME.path_open_20) == 2) {
|
||||
var _realpath = DIRECTORY + "Palettes";
|
||||
shellOpenExplorer(_realpath)
|
||||
}
|
||||
draw_sprite_ui_uniform(THEME.path_open_20, 1, bx + bs / 2, by + bs / 2, 1, c_white);
|
||||
bx -= ui(32);
|
||||
#endregion
|
||||
|
||||
#region palette
|
||||
var pl_x = content_x + ui(60);
|
||||
var pl_y = dialog_y + ui(54);
|
||||
var pl_w = content_w - ui(154);
|
||||
var pl_h = ui(24);
|
||||
|
||||
var max_col = 8;
|
||||
var col = min(array_length(palette), max_col);
|
||||
var row = ceil(array_length(palette) / col);
|
||||
var ww = round(pl_w / col);
|
||||
var hh = (pl_h + ui(6)) * row;
|
||||
dialog_h = ui(408) + hh;
|
||||
|
||||
draw_sprite_stretched(THEME.textbox, 3, pl_x - ui(6), pl_y - ui(6), pl_w + ui(12), hh + ui(6));
|
||||
draw_sprite_stretched(THEME.textbox, 0, pl_x - ui(6), pl_y - ui(6), pl_w + ui(12), hh + ui(6));
|
||||
|
||||
#region tools
|
||||
var bx = content_x + content_w - ui(50);
|
||||
var by = dialog_y + ui(16);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_sort", "Sort color"), THEME.sort) == 2) {
|
||||
menuCall("palette_window_sort_menu", bx + ui(32), by, [
|
||||
menuItem(__txtx("palette_editor_sort_brighter", "Brighter"), function() { sortPalette(__sortBright); }),
|
||||
menuItem(__txtx("palette_editor_sort_darker", "Darker"), function() { sortPalette(__sortDark); }),
|
||||
-1,
|
||||
menuItem(__txtx("palette_editor_sort_hue", "Hue"), function() { sortPalette(__sortHue); }),
|
||||
menuItem(__txtx("palette_editor_sort_sat", "Saturation"), function() { sortPalette(__sortSat); }),
|
||||
menuItem(__txtx("palette_editor_sort_val", "Value"), function() { sortPalette(__sortVal); }),
|
||||
],, palette);
|
||||
}
|
||||
bx -= ui(32);
|
||||
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_reverse", "Reverse palette"), THEME.reverse) == 2) {
|
||||
palette = array_reverse(palette);
|
||||
onApply(palette);
|
||||
}
|
||||
bx -= ui(32);
|
||||
#endregion
|
||||
|
||||
var hover = -1, hvx, hvy;
|
||||
var _pd = ui(5);
|
||||
|
||||
for(var i = 0; i < row; i++)
|
||||
for(var j = 0; j < col; j++) {
|
||||
var index = i * col + j;
|
||||
if(index >= array_length(palette)) break;
|
||||
|
||||
var _p = palette[index];
|
||||
var _pa = _color_get_alpha(_p);
|
||||
var _kx = pl_x + j * ww;
|
||||
var _ky = pl_y + i * (pl_h + ui(6));
|
||||
|
||||
var _px = _kx + ui(2);
|
||||
var _py = _ky;
|
||||
var _pw = ww - ui(4);
|
||||
var _ph = pl_h;
|
||||
|
||||
if(index == index_dragging) {
|
||||
index_drag_x_to = _px;
|
||||
index_drag_y_to = _py;
|
||||
index_drag_w_to = _pw;
|
||||
index_drag_h_to = _ph;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(_pa < 1) {
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph - ui(8), _p, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw, ui(6), c_black, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw * _pa, ui(6), c_white, 1);
|
||||
} else
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph, _p, 1);
|
||||
|
||||
if(index == index_selecting)
|
||||
draw_sprite_stretched_ext(THEME.palette_selecting, 0, _px - _pd, _py - _pd, _pw + _pd * 2, _ph + _pd * 2, c_white, 1);
|
||||
|
||||
if(sHOVER && point_in_rectangle(mouse_mx, mouse_my, _kx, _ky, _kx + ww, _ky + pl_h)) {
|
||||
hover = index;
|
||||
hvx = _kx;
|
||||
hvy = _ky;
|
||||
}
|
||||
}
|
||||
|
||||
if(index_dragging > -1) {
|
||||
index_drag_x = index_drag_x == 0? index_drag_x_to : lerp_float(index_drag_x, index_drag_x_to, 5);
|
||||
index_drag_y = index_drag_y == 0? index_drag_y_to : lerp_float(index_drag_y, index_drag_y_to, 5);
|
||||
index_drag_w = index_drag_w == 0? index_drag_w_to : lerp_float(index_drag_w, index_drag_w_to, 5);
|
||||
index_drag_h = index_drag_h == 0? index_drag_h_to : lerp_float(index_drag_h, index_drag_h_to, 5);
|
||||
|
||||
_px = index_drag_x;
|
||||
_py = index_drag_y;
|
||||
_pw = index_drag_w;
|
||||
_ph = index_drag_h;
|
||||
_p = palette[index_dragging];
|
||||
_pa = _color_get_alpha(_p);
|
||||
|
||||
if(_pa < 1) {
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph - ui(8), _p, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw, ui(6), c_black, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py + _ph - ui(6), _pw * _pa, ui(6), c_white, 1);
|
||||
} else
|
||||
draw_sprite_stretched_ext(THEME.palette_mask, 1, _px, _py, _pw, _ph, _p, 1);
|
||||
draw_sprite_stretched_ext(THEME.palette_selecting, 0, _px - _pd, _py - _pd, _pw + _pd * 2, _ph + _pd * 2, c_white, 1);
|
||||
|
||||
if(hover > -1 && hover != index_dragging) {
|
||||
draw_set_color(COLORS.dialog_palette_divider);
|
||||
var sx = hvx;
|
||||
if(hover >= index_dragging) sx += ww;
|
||||
|
||||
var tt = palette[index_dragging];
|
||||
|
||||
array_delete(palette, index_dragging, 1);
|
||||
array_insert(palette, hover, tt);
|
||||
index_selecting = hover;
|
||||
index_dragging = hover;
|
||||
|
||||
onApply(palette);
|
||||
}
|
||||
|
||||
if(mouse_release(mb_left))
|
||||
index_dragging = -1;
|
||||
} else {
|
||||
index_drag_x = 0;
|
||||
index_drag_y = 0;
|
||||
index_drag_w = 0;
|
||||
index_drag_h = 0;
|
||||
}
|
||||
|
||||
if(mouse_press(mb_left, sFOCUS) && hover > -1) {
|
||||
index_selecting = hover;
|
||||
if(interactable)
|
||||
index_dragging = hover;
|
||||
selector.setColor(palette[hover]);
|
||||
}
|
||||
|
||||
var bx = content_x + content_w - ui(50);
|
||||
var by = pl_y - ui(2);
|
||||
|
||||
if(array_length(palette) > 1) {
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.minus) == 2) {
|
||||
array_delete(palette, index_selecting, 1);
|
||||
index_selecting = clamp(index_selecting - 1, 0, array_length(palette) - 1);
|
||||
onApply(palette);
|
||||
}
|
||||
} else {
|
||||
draw_sprite_ui_uniform(THEME.minus, 0, bx + ui(14), by + ui(14), 1, COLORS._main_icon, 0.5);
|
||||
}
|
||||
|
||||
bx -= ui(32);
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, "", THEME.add) == 2) {
|
||||
index_selecting = array_length(palette);
|
||||
palette[array_length(palette)] = c_black;
|
||||
onApply(palette);
|
||||
}
|
||||
|
||||
bx = content_x + ui(18);
|
||||
if(buttonInstant(THEME.button_hide, bx, by, ui(28), ui(28), mouse_ui, interactable && sFOCUS, sHOVER, __txtx("palette_editor_load", "Load palette file") + " (.hex)", THEME.file) == 2) {
|
||||
var path = get_open_filename("HEX palette|*.hex", "");
|
||||
key_release();
|
||||
|
||||
if(isPaletteFile(path)) {
|
||||
palette = loadPalette(path);
|
||||
onApply(palette);
|
||||
}
|
||||
}
|
||||
draw_sprite_ui_uniform(THEME.file, 0, bx + ui(14), by + ui(14), 1, COLORS._main_icon);
|
||||
#endregion
|
||||
|
||||
#region selector
|
||||
var col_x = content_x + ui(20);
|
||||
var col_y = dialog_y + ui(70) + hh;
|
||||
|
||||
selector.draw(col_x, col_y, sFOCUS, sHOVER);
|
||||
#endregion
|
||||
|
||||
#region controls
|
||||
var bx = content_x + content_w - ui(36);
|
||||
var by = dialog_y + dialog_h - ui(36);
|
||||
|
||||
b_apply.register();
|
||||
b_apply.setFocusHover(sFOCUS, sHOVER);
|
||||
b_apply.draw(bx - ui(18), by - ui(18), ui(36), ui(36), mouse_ui, THEME.button_lime);
|
||||
|
||||
bx -= ui(48);
|
||||
b_cancel.register();
|
||||
b_cancel.setFocusHover(sFOCUS, sHOVER);
|
||||
b_cancel.draw(bx - ui(18), by - ui(18), ui(36), ui(36), mouse_ui, THEME.button_hide);
|
||||
#endregion
|
||||
|
||||
#event draw_gui_end
|
||||
selector.colorPicker();
|
|
@ -1,4 +1,4 @@
|
|||
// 2024-04-19 07:55:21
|
||||
// 2024-04-20 08:26:31
|
||||
function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
||||
name = "Canvas";
|
||||
color = COLORS.node_blend_canvas;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// 2024-04-18 18:31:59
|
||||
// 2024-04-20 08:25:39
|
||||
function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
|
||||
name = "Canvas";
|
||||
color = COLORS.node_blend_canvas;
|
||||
|
|
305
#backups/scripts/node_functions/node_functions.gml.backup0
Normal file
305
#backups/scripts/node_functions/node_functions.gml.backup0
Normal file
|
@ -0,0 +1,305 @@
|
|||
// 2024-04-20 08:21:26
|
||||
#macro DEF_SURF_W PROJECT.attributes.surface_dimension[0]
|
||||
#macro DEF_SURF_H PROJECT.attributes.surface_dimension[1]
|
||||
#macro DEF_SURF PROJECT.attributes.surface_dimension
|
||||
|
||||
#macro DEF_PALETTE PROJECT.attributes.palette
|
||||
|
||||
#region
|
||||
function node_draw_transform_init() {
|
||||
drag_type = -1;
|
||||
dragging_sx = 0;
|
||||
dragging_sy = 0;
|
||||
dragging_mx = 0;
|
||||
dragging_my = 0;
|
||||
rot_anc_x = 0;
|
||||
rot_anc_y = 0;
|
||||
}
|
||||
|
||||
function node_draw_transform_box(active, _x, _y, _s, _mx, _my, _snx, _sny, _posInd, _rotInd, _scaInd, _scaUnit = false) {
|
||||
var _pos = getInputData(_posInd);
|
||||
var _rot = getInputData(_rotInd);
|
||||
var _sca = getInputData(_scaInd);
|
||||
|
||||
if(drag_type > -1) {
|
||||
if(drag_type == 0) {
|
||||
var _dx = (_mx - dragging_mx) / _s;
|
||||
var _dy = (_my - dragging_my) / _s;
|
||||
|
||||
if(key_mod_press(SHIFT)) {
|
||||
if(abs(_dx) > abs(_dy) + ui(16))
|
||||
_dy = 0;
|
||||
else if(abs(_dy) > abs(_dx) + ui(16))
|
||||
_dx = 0;
|
||||
else {
|
||||
_dx = max(_dx, _dy);
|
||||
_dy = _dx;
|
||||
}
|
||||
}
|
||||
|
||||
_pos[0] = value_snap(dragging_sx + _dx, _snx);
|
||||
_pos[1] = value_snap(dragging_sy + _dy, _sny);
|
||||
|
||||
if(inputs[| _posInd].setValue(_pos))
|
||||
UNDO_HOLDING = true;
|
||||
|
||||
if(inputs[| _posInd].unit.mode == VALUE_UNIT.reference) {
|
||||
var p = [ _pos[0], _pos[1] ];
|
||||
_pos = inputs[| _posInd].unit.apply(p);
|
||||
}
|
||||
} else if(drag_type == 1) {
|
||||
var aa = point_direction(rot_anc_x, rot_anc_y, _mx, _my);
|
||||
var da = angle_difference(dragging_mx, aa);
|
||||
|
||||
if(key_mod_press(CTRL))
|
||||
_rot = round((dragging_sx - da) / 15) * 15;
|
||||
else
|
||||
_rot = dragging_sx - da;
|
||||
|
||||
if(inputs[| _rotInd].setValue(_rot))
|
||||
UNDO_HOLDING = true;
|
||||
} else if(drag_type == 2) {
|
||||
var _p = point_rotate(_mx - dragging_mx, _my - dragging_my, 0, 0, -_rot);
|
||||
_sca[0] = _p[0] / _s;
|
||||
_sca[1] = _p[1] / _s;
|
||||
|
||||
if(key_mod_press(SHIFT)) {
|
||||
_sca[0] = min(_sca[0], _sca[1]);
|
||||
_sca[1] = min(_sca[0], _sca[1]);
|
||||
}
|
||||
|
||||
if(inputs[| _scaInd].setValue(_sca))
|
||||
UNDO_HOLDING = true;
|
||||
|
||||
if(_scaUnit && inputs[| _scaInd].unit.mode == VALUE_UNIT.reference) {
|
||||
var s = [ _sca[0], _sca[1] ];
|
||||
_sca = inputs[| _scaInd].unit.apply(s);
|
||||
}
|
||||
}
|
||||
|
||||
if(mouse_release(mb_left)) {
|
||||
drag_type = -1;
|
||||
UNDO_HOLDING = false;
|
||||
}
|
||||
}
|
||||
|
||||
var p0 = point_rotate(-_sca[0], -_sca[1], 0, 0, _rot);
|
||||
var p1 = point_rotate( _sca[0], -_sca[1], 0, 0, _rot);
|
||||
var p2 = point_rotate(-_sca[0], _sca[1], 0, 0, _rot);
|
||||
var p3 = point_rotate( _sca[0], _sca[1], 0, 0, _rot);
|
||||
var pr = point_rotate( 0, -_sca[1] - 1, 0, 0, _rot);
|
||||
|
||||
var pd0x = _x + (p0[0] + _pos[0]) * _s; var pd0y = _y + (p0[1] + _pos[1]) * _s;
|
||||
var pd1x = _x + (p1[0] + _pos[0]) * _s; var pd1y = _y + (p1[1] + _pos[1]) * _s;
|
||||
var pd2x = _x + (p2[0] + _pos[0]) * _s; var pd2y = _y + (p2[1] + _pos[1]) * _s;
|
||||
var pd3x = _x + (p3[0] + _pos[0]) * _s; var pd3y = _y + (p3[1] + _pos[1]) * _s;
|
||||
var prx = _x + (pr[0] + _pos[0]) * _s; var pry = _y + (pr[1] + _pos[1]) * _s;
|
||||
|
||||
var hovering = -1;
|
||||
|
||||
if(drag_type == -1) {
|
||||
if(point_in_rectangle_points(_mx, _my, pd0x, pd0y, pd1x, pd1y, pd2x, pd2y, pd3x, pd3y))
|
||||
hovering = 0;
|
||||
if(point_in_circle(_mx, _my, prx, pry, 12))
|
||||
hovering = 1;
|
||||
if(point_in_circle(_mx, _my, pd3x, pd3y, 12))
|
||||
hovering = 2;
|
||||
}
|
||||
|
||||
draw_set_color(COLORS._main_accent);
|
||||
draw_line_width(pd0x, pd0y, pd1x, pd1y, hovering == 0? 2 : 1);
|
||||
draw_line_width(pd0x, pd0y, pd2x, pd2y, hovering == 0? 2 : 1);
|
||||
draw_line_width(pd3x, pd3y, pd1x, pd1y, hovering == 0? 2 : 1);
|
||||
draw_line_width(pd3x, pd3y, pd2x, pd2y, hovering == 0? 2 : 1);
|
||||
|
||||
draw_sprite_colored(THEME.anchor_rotate, hovering == 1, prx, pry,, _rot);
|
||||
draw_sprite_colored(THEME.anchor_scale, hovering == 2, pd3x, pd3y,, _rot);
|
||||
|
||||
if(hovering == -1) return;
|
||||
if(drag_type > -1) return;
|
||||
|
||||
if(mouse_press(mb_left, active)) {
|
||||
drag_type = hovering;
|
||||
if(hovering == 0) {
|
||||
dragging_sx = _pos[0];
|
||||
dragging_sy = _pos[1];
|
||||
dragging_mx = _mx;
|
||||
dragging_my = _my;
|
||||
} else if(hovering == 1) { //rot
|
||||
dragging_sx = _rot;
|
||||
rot_anc_x = _x + _pos[0] * _s;
|
||||
rot_anc_y = _y + _pos[1] * _s;
|
||||
dragging_mx = point_direction(rot_anc_x, rot_anc_y, _mx, _my);
|
||||
} else if(hovering == 2) { //sca
|
||||
dragging_sx = _sca[0];
|
||||
dragging_sy = _sca[1];
|
||||
dragging_mx = _x + _pos[0] * _s;
|
||||
dragging_my = _y + _pos[1] * _s;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region node function
|
||||
function nodeLoad(_data, scale = false, _group = noone) {
|
||||
INLINE
|
||||
if(!is_struct(_data)) return;
|
||||
|
||||
var _x = _data.x;
|
||||
var _y = _data.y;
|
||||
var _type = _data.type;
|
||||
|
||||
if(ds_map_exists(APPEND_MAP, _data.id)) {
|
||||
var _node = APPEND_MAP[? _data.id];
|
||||
_node.x = _x;
|
||||
_node.y = _y;
|
||||
_node.deserialize(_data, scale);
|
||||
return _node;
|
||||
}
|
||||
|
||||
var _node = nodeBuild(_type, _x, _y, _group);
|
||||
if(_node) _node.deserialize(_data, scale);
|
||||
|
||||
return _node;
|
||||
}
|
||||
|
||||
function nodeCleanUp() {
|
||||
var key = ds_map_find_first(PROJECT.nodeMap);
|
||||
repeat(ds_map_size(PROJECT.nodeMap)) {
|
||||
if(PROJECT.nodeMap[? key]) {
|
||||
PROJECT.nodeMap[? key].active = false;
|
||||
PROJECT.nodeMap[? key].cleanUp();
|
||||
delete PROJECT.nodeMap[? key];
|
||||
}
|
||||
key = ds_map_find_next(PROJECT.nodeMap, key);
|
||||
}
|
||||
|
||||
ds_map_clear(APPEND_MAP);
|
||||
}
|
||||
|
||||
function graphFocusNode(node) {
|
||||
PANEL_INSPECTOR.setInspecting(node);
|
||||
PANEL_GRAPH.nodes_selecting = [ node ];
|
||||
PANEL_GRAPH.fullView();
|
||||
}
|
||||
|
||||
function refreshNodeMap() {
|
||||
ds_map_clear(PROJECT.nodeNameMap);
|
||||
var key = ds_map_find_first(PROJECT.nodeMap);
|
||||
var amo = ds_map_size(PROJECT.nodeMap);
|
||||
|
||||
repeat(amo) {
|
||||
var node = PROJECT.nodeMap[? key];
|
||||
|
||||
if(node.internalName != "")
|
||||
PROJECT.nodeNameMap[? node.internalName] = node;
|
||||
|
||||
key = ds_map_find_next(PROJECT.nodeMap, key);
|
||||
}
|
||||
}
|
||||
|
||||
function nodeGetData(str) {
|
||||
str = string_trim(str);
|
||||
var strs = string_splice(str, ".");
|
||||
|
||||
if(array_length(strs) == 0) return 0;
|
||||
|
||||
if(array_length(strs) == 1) {
|
||||
var splt = string_splice(strs[0], "[");
|
||||
var inp = PROJECT.globalNode.getInput(strs[0]);
|
||||
if(inp == 0) return 0;
|
||||
|
||||
var _arr = [ 0, 0 ];
|
||||
inp.getValueRecursive(_arr);
|
||||
|
||||
return _arr[0];
|
||||
|
||||
} else if(struct_has(PROJECT_VARIABLES, strs[0])) {
|
||||
var _str_var = PROJECT_VARIABLES[$ strs[0]];
|
||||
if(!struct_has(_str_var, strs[1])) return 0;
|
||||
|
||||
var val = _str_var[$ strs[1]][0];
|
||||
if(is_callable(val))
|
||||
return val();
|
||||
return val;
|
||||
} else if(array_length(strs) > 2) {
|
||||
var key = strs[0];
|
||||
if(!ds_map_exists(PROJECT.nodeNameMap, key)) return 0;
|
||||
|
||||
var node = PROJECT.nodeNameMap[? key];
|
||||
var map = noone;
|
||||
switch(string_lower(strs[1])) {
|
||||
case "inputs" :
|
||||
case "input" :
|
||||
map = node.inputMap;
|
||||
break;
|
||||
case "outputs" :
|
||||
case "output" :
|
||||
map = node.outputMap;
|
||||
break;
|
||||
default : return 0;
|
||||
}
|
||||
|
||||
var _junc_key = string_lower(strs[2]);
|
||||
var _junc = ds_map_try_get(map, _junc_key, noone);
|
||||
|
||||
if(_junc == noone) return 0;
|
||||
|
||||
return _junc.getValue();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function nodeGetDataAnim(str) {
|
||||
str = string_trim(str);
|
||||
var strs = string_splice(str, ".");
|
||||
|
||||
if(array_length(strs) == 0) return 0;
|
||||
|
||||
if(array_length(strs) == 1) {
|
||||
return EXPRESS_TREE_ANIM.none;
|
||||
} else if(struct_has(PROJECT_VARIABLES, strs[0])) {
|
||||
var _str_var = PROJECT_VARIABLES[$ strs[0]];
|
||||
if(!struct_has(_str_var, strs[1])) return EXPRESS_TREE_ANIM.none;
|
||||
|
||||
var val = _str_var[$ strs[1]][1];
|
||||
return val;
|
||||
} else if(array_length(strs) > 2) {
|
||||
var key = strs[0];
|
||||
if(!ds_map_exists(PROJECT.nodeNameMap, key)) return EXPRESS_TREE_ANIM.none;
|
||||
|
||||
var node = PROJECT.nodeNameMap[? key];
|
||||
var map = noone;
|
||||
switch(string_lower(strs[1])) {
|
||||
case "inputs" :
|
||||
case "input" :
|
||||
map = node.inputMap;
|
||||
break;
|
||||
case "outputs" :
|
||||
case "output" :
|
||||
map = node.outputMap;
|
||||
break;
|
||||
default : return EXPRESS_TREE_ANIM.none;
|
||||
}
|
||||
|
||||
var _junc_key = string_lower(strs[2]);
|
||||
var _junc = ds_map_try_get(map, _junc_key, noone);
|
||||
|
||||
if(_junc == noone) return EXPRESS_TREE_ANIM.none;
|
||||
|
||||
return _junc.is_anim * 2;
|
||||
}
|
||||
|
||||
return EXPRESS_TREE_ANIM.none;
|
||||
}
|
||||
|
||||
function create_preview_window(node) {
|
||||
if(node == noone) return;
|
||||
var win = new Panel_Preview_Window();
|
||||
win.node_target = node;
|
||||
win.preview_channel = node.preview_channel;
|
||||
var dia = dialogPanelCall(win, mouse_mx, mouse_my);
|
||||
dia.destroy_on_click_out = false;
|
||||
}
|
||||
#endregion
|
305
#backups/scripts/node_functions/node_functions.gml.backup1
Normal file
305
#backups/scripts/node_functions/node_functions.gml.backup1
Normal file
|
@ -0,0 +1,305 @@
|
|||
// 2024-04-20 08:21:22
|
||||
#macro DEF_SURF_W PROJECT.attributes.surface_dimension[0]
|
||||
#macro DEF_SURF_H PROJECT.attributes.surface_dimension[1]
|
||||
#macro DEF_SURF PROJECT.attributes.surface_dimension
|
||||
|
||||
#macro DEF_PALETTE PROJECT.attributes.palette
|
||||
|
||||
#region
|
||||
function node_draw_transform_init() {
|
||||
drag_type = -1;
|
||||
dragging_sx = 0;
|
||||
dragging_sy = 0;
|
||||
dragging_mx = 0;
|
||||
dragging_my = 0;
|
||||
rot_anc_x = 0;
|
||||
rot_anc_y = 0;
|
||||
}
|
||||
|
||||
function node_draw_transform_box(active, _x, _y, _s, _mx, _my, _snx, _sny, _posInd, _rotInd, _scaInd, _scaUnit = false) {
|
||||
var _pos = getInputData(_posInd);
|
||||
var _rot = getInputData(_rotInd);
|
||||
var _sca = getInputData(_scaInd);
|
||||
|
||||
if(drag_type > -1) {
|
||||
if(drag_type == 0) {
|
||||
var _dx = (_mx - dragging_mx) / _s;
|
||||
var _dy = (_my - dragging_my) / _s;
|
||||
|
||||
if(key_mod_press(SHIFT)) {
|
||||
if(abs(_dx) > abs(_dy) + ui(16))
|
||||
_dy = 0;
|
||||
else if(abs(_dy) > abs(_dx) + ui(16))
|
||||
_dx = 0;
|
||||
else {
|
||||
_dx = max(_dx, _dy);
|
||||
_dy = _dx;
|
||||
}
|
||||
}
|
||||
|
||||
_pos[0] = value_snap(dragging_sx + _dx, _snx);
|
||||
_pos[1] = value_snap(dragging_sy + _dy, _sny);
|
||||
|
||||
if(inputs[| _posInd].setValue(_pos))
|
||||
UNDO_HOLDING = true;
|
||||
|
||||
if(inputs[| _posInd].unit.mode == VALUE_UNIT.reference) {
|
||||
var p = [ _pos[0], _pos[1] ];
|
||||
_pos = inputs[| _posInd].unit.apply(p);
|
||||
}
|
||||
} else if(drag_type == 1) {
|
||||
var aa = point_direction(rot_anc_x, rot_anc_y, _mx, _my);
|
||||
var da = angle_difference(dragging_mx, aa);
|
||||
|
||||
if(key_mod_press(CTRL))
|
||||
_rot = round((dragging_sx - da) / 15) * 15;
|
||||
else
|
||||
_rot = dragging_sx - da;
|
||||
|
||||
if(inputs[| _rotInd].setValue(_rot))
|
||||
UNDO_HOLDING = true;
|
||||
} else if(drag_type == 2) {
|
||||
var _p = point_rotate(_mx - dragging_mx, _my - dragging_my, 0, 0, -_rot);
|
||||
_sca[0] = _p[0] / _s;
|
||||
_sca[1] = _p[1] / _s;
|
||||
|
||||
if(key_mod_press(SHIFT)) {
|
||||
_sca[0] = min(_sca[0], _sca[1]);
|
||||
_sca[1] = min(_sca[0], _sca[1]);
|
||||
}
|
||||
|
||||
if(inputs[| _scaInd].setValue(_sca))
|
||||
UNDO_HOLDING = true;
|
||||
|
||||
if(_scaUnit && inputs[| _scaInd].unit.mode == VALUE_UNIT.reference) {
|
||||
var s = [ _sca[0], _sca[1] ];
|
||||
_sca = inputs[| _scaInd].unit.apply(s);
|
||||
}
|
||||
}
|
||||
|
||||
if(mouse_release(mb_left)) {
|
||||
drag_type = -1;
|
||||
UNDO_HOLDING = false;
|
||||
}
|
||||
}
|
||||
|
||||
var p0 = point_rotate(-_sca[0], -_sca[1], 0, 0, _rot);
|
||||
var p1 = point_rotate( _sca[0], -_sca[1], 0, 0, _rot);
|
||||
var p2 = point_rotate(-_sca[0], _sca[1], 0, 0, _rot);
|
||||
var p3 = point_rotate( _sca[0], _sca[1], 0, 0, _rot);
|
||||
var pr = point_rotate( 0, -_sca[1] - 1, 0, 0, _rot);
|
||||
|
||||
var pd0x = _x + (p0[0] + _pos[0]) * _s; var pd0y = _y + (p0[1] + _pos[1]) * _s;
|
||||
var pd1x = _x + (p1[0] + _pos[0]) * _s; var pd1y = _y + (p1[1] + _pos[1]) * _s;
|
||||
var pd2x = _x + (p2[0] + _pos[0]) * _s; var pd2y = _y + (p2[1] + _pos[1]) * _s;
|
||||
var pd3x = _x + (p3[0] + _pos[0]) * _s; var pd3y = _y + (p3[1] + _pos[1]) * _s;
|
||||
var prx = _x + (pr[0] + _pos[0]) * _s; var pry = _y + (pr[1] + _pos[1]) * _s;
|
||||
|
||||
var hovering = -1;
|
||||
|
||||
if(drag_type == -1) {
|
||||
if(point_in_rectangle_points(_mx, _my, pd0x, pd0y, pd1x, pd1y, pd2x, pd2y, pd3x, pd3y))
|
||||
hovering = 0;
|
||||
if(point_in_circle(_mx, _my, prx, pry, 12))
|
||||
hovering = 1;
|
||||
if(point_in_circle(_mx, _my, pd3x, pd3y, 12))
|
||||
hovering = 2;
|
||||
}
|
||||
|
||||
draw_set_color(COLORS._main_accent);
|
||||
draw_line_width(pd0x, pd0y, pd1x, pd1y, hovering == 0? 2 : 1);
|
||||
draw_line_width(pd0x, pd0y, pd2x, pd2y, hovering == 0? 2 : 1);
|
||||
draw_line_width(pd3x, pd3y, pd1x, pd1y, hovering == 0? 2 : 1);
|
||||
draw_line_width(pd3x, pd3y, pd2x, pd2y, hovering == 0? 2 : 1);
|
||||
|
||||
draw_sprite_colored(THEME.anchor_rotate, hovering == 1, prx, pry,, _rot);
|
||||
draw_sprite_colored(THEME.anchor_scale, hovering == 2, pd3x, pd3y,, _rot);
|
||||
|
||||
if(hovering == -1) return;
|
||||
if(drag_type > -1) return;
|
||||
|
||||
if(mouse_press(mb_left, active)) {
|
||||
drag_type = hovering;
|
||||
if(hovering == 0) {
|
||||
dragging_sx = _pos[0];
|
||||
dragging_sy = _pos[1];
|
||||
dragging_mx = _mx;
|
||||
dragging_my = _my;
|
||||
} else if(hovering == 1) { //rot
|
||||
dragging_sx = _rot;
|
||||
rot_anc_x = _x + _pos[0] * _s;
|
||||
rot_anc_y = _y + _pos[1] * _s;
|
||||
dragging_mx = point_direction(rot_anc_x, rot_anc_y, _mx, _my);
|
||||
} else if(hovering == 2) { //sca
|
||||
dragging_sx = _sca[0];
|
||||
dragging_sy = _sca[1];
|
||||
dragging_mx = _x + _pos[0] * _s;
|
||||
dragging_my = _y + _pos[1] * _s;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region node function
|
||||
function nodeLoad(_data, scale = false, _group = noone) {
|
||||
INLINE
|
||||
if(!is_struct(_data)) return;
|
||||
|
||||
var _x = _data.x;
|
||||
var _y = _data.y;
|
||||
var _type = _data.type;
|
||||
|
||||
if(ds_map_exists(APPEND_MAP, _data.id)) {
|
||||
var _node = APPEND_MAP[? _data.id];
|
||||
_node.x = _x;
|
||||
_node.y = _y;
|
||||
_node.deserialize(_data, scale);
|
||||
return _node;
|
||||
}
|
||||
|
||||
var _node = nodeBuild(_type, _x, _y, _group);
|
||||
if(_node) _node.deserialize(_data, scale);
|
||||
|
||||
return _node;
|
||||
}
|
||||
|
||||
function nodeCleanUp() {
|
||||
var key = ds_map_find_first(PROJECT.nodeMap);
|
||||
repeat(ds_map_size(PROJECT.nodeMap)) {
|
||||
if(PROJECT.nodeMap[? key]) {
|
||||
PROJECT.nodeMap[? key].active = false;
|
||||
PROJECT.nodeMap[? key].cleanUp();
|
||||
delete PROJECT.nodeMap[? key];
|
||||
}
|
||||
key = ds_map_find_next(PROJECT.nodeMap, key);
|
||||
}
|
||||
|
||||
ds_map_clear(APPEND_MAP);
|
||||
}
|
||||
|
||||
function graphFocusNode(node) {
|
||||
PANEL_INSPECTOR.setInspecting(node);
|
||||
PANEL_GRAPH.nodes_selecting = [ node ];
|
||||
PANEL_GRAPH.fullView();
|
||||
}
|
||||
|
||||
function refreshNodeMap() {
|
||||
ds_map_clear(PROJECT.nodeNameMap);
|
||||
var key = ds_map_find_first(PROJECT.nodeMap);
|
||||
var amo = ds_map_size(PROJECT.nodeMap);
|
||||
|
||||
repeat(amo) {
|
||||
var node = PROJECT.nodeMap[? key];
|
||||
|
||||
if(node.internalName != "")
|
||||
PROJECT.nodeNameMap[? node.internalName] = node;
|
||||
|
||||
key = ds_map_find_next(PROJECT.nodeMap, key);
|
||||
}
|
||||
}
|
||||
|
||||
function nodeGetData(str) {
|
||||
str = string_trim(str);
|
||||
var strs = string_splice(str, ".");
|
||||
|
||||
if(array_length(strs) == 0) return 0;
|
||||
|
||||
if(array_length(strs) == 1) {
|
||||
var splt = string_splice(strs[0], "[");
|
||||
var inp = PROJECT.globalNode.getInput(strs[0]);
|
||||
if(inp == 0) return 0;
|
||||
|
||||
var _arr = [ 0, 0 ];
|
||||
inp.getValueRecursive(_arr);
|
||||
|
||||
return _arr[0];
|
||||
|
||||
} else if(struct_has(PROJECT_VARIABLES, strs[0])) {
|
||||
var _str_var = PROJECT_VARIABLES[$ strs[0]];
|
||||
if(!struct_has(_str_var, strs[1])) return 0;
|
||||
|
||||
var val = _str_var[$ strs[1]][0];
|
||||
if(is_callable(val))
|
||||
return val();
|
||||
return val;
|
||||
} else if(array_length(strs) > 2) {
|
||||
var key = strs[0];
|
||||
if(!ds_map_exists(PROJECT.nodeNameMap, key)) return 0;
|
||||
|
||||
var node = PROJECT.nodeNameMap[? key];
|
||||
var map = noone;
|
||||
switch(string_lower(strs[1])) {
|
||||
case "inputs" :
|
||||
case "input" :
|
||||
map = node.inputMap;
|
||||
break;
|
||||
case "outputs" :
|
||||
case "output" :
|
||||
map = node.outputMap;
|
||||
break;
|
||||
default : return 0;
|
||||
}
|
||||
|
||||
var _junc_key = string_lower(strs[2]);
|
||||
var _junc = ds_map_try_get(map, _junc_key, noone);
|
||||
|
||||
if(_junc == noone) return 0;
|
||||
|
||||
return _junc.getValue();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function nodeGetDataAnim(str) {
|
||||
str = string_trim(str);
|
||||
var strs = string_splice(str, ".");
|
||||
|
||||
if(array_length(strs) == 0) return 0;
|
||||
|
||||
if(array_length(strs) == 1) {
|
||||
return EXPRESS_TREE_ANIM.none;
|
||||
} else if(struct_has(PROJECT_VARIABLES, strs[0])) {
|
||||
var _str_var = PROJECT_VARIABLES[$ strs[0]];
|
||||
if(!struct_has(_str_var, strs[1])) return EXPRESS_TREE_ANIM.none;
|
||||
|
||||
var val = _str_var[$ strs[1]][1];
|
||||
return val;
|
||||
} else if(array_length(strs) > 2) {
|
||||
var key = strs[0];
|
||||
if(!ds_map_exists(PROJECT.nodeNameMap, key)) return EXPRESS_TREE_ANIM.none;
|
||||
|
||||
var node = PROJECT.nodeNameMap[? key];
|
||||
var map = noone;
|
||||
switch(string_lower(strs[1])) {
|
||||
case "inputs" :
|
||||
case "input" :
|
||||
map = node.inputMap;
|
||||
break;
|
||||
case "outputs" :
|
||||
case "output" :
|
||||
map = node.outputMap;
|
||||
break;
|
||||
default : return EXPRESS_TREE_ANIM.none;
|
||||
}
|
||||
|
||||
var _junc_key = string_lower(strs[2]);
|
||||
var _junc = ds_map_try_get(map, _junc_key, noone);
|
||||
|
||||
if(_junc == noone) return EXPRESS_TREE_ANIM.none;
|
||||
|
||||
return _junc.is_anim * 2;
|
||||
}
|
||||
|
||||
return EXPRESS_TREE_ANIM.none;
|
||||
}
|
||||
|
||||
function create_preview_window(node) {
|
||||
if(node == noone) return;
|
||||
var win = new Panel_Preview_Window();
|
||||
win.node_target = node;
|
||||
win.preview_channel = node.preview_channel;
|
||||
var dia = dialogPanelCall(win, mouse_mx, mouse_my);
|
||||
dia.destroy_on_click_out = false;
|
||||
}
|
||||
#endregion
|
740
#backups/scripts/node_keyframe/node_keyframe.gml.backup0
Normal file
740
#backups/scripts/node_keyframe/node_keyframe.gml.backup0
Normal file
|
@ -0,0 +1,740 @@
|
|||
// 2024-04-20 09:03:18
|
||||
enum KEY_TYPE { normal, adder }
|
||||
enum CURVE_TYPE { linear, bezier, cut }
|
||||
enum DRIVER_TYPE { none, linear, wiggle, sine }
|
||||
|
||||
function valueKey(_time, _value, _anim = noone, _in = 0, _ot = 0) constructor {
|
||||
#region ---- main ----
|
||||
time = _time;
|
||||
ratio = time / (TOTAL_FRAMES - 1);
|
||||
value = _value;
|
||||
anim = _anim;
|
||||
|
||||
ease_y_lock = true;
|
||||
ease_in = is_array(_in)? _in : [_in, 1];
|
||||
ease_out = is_array(_ot)? _ot : [_ot, 0];
|
||||
|
||||
var _int = anim? anim.prop.key_inter : CURVE_TYPE.linear;
|
||||
ease_in_type = _int;
|
||||
ease_out_type = _int;
|
||||
|
||||
dopesheet_x = 0;
|
||||
|
||||
drivers = {
|
||||
seed : irandom_range(100000, 999999),
|
||||
type : DRIVER_TYPE.none,
|
||||
speed : 1,
|
||||
octave : 2,
|
||||
frequency : 4,
|
||||
amplitude : 1,
|
||||
axis_sync : false,
|
||||
phase : 0,
|
||||
};
|
||||
#endregion
|
||||
|
||||
static setTime = function(time) { #region
|
||||
self.time = time;
|
||||
ratio = time / (TOTAL_FRAMES - 1);
|
||||
} #endregion
|
||||
|
||||
static clone = function(target = noone) { #region
|
||||
var key = new valueKey(time, value, target);
|
||||
key.ease_in = ease_in;
|
||||
key.ease_out = ease_out;
|
||||
key.ease_in_type = ease_in_type;
|
||||
key.ease_out_type = ease_out_type;
|
||||
|
||||
return key;
|
||||
} #endregion
|
||||
|
||||
static cloneAnimator = function(shift = 0, anim = noone, removeDup = true) { #region
|
||||
if(anim != noone) { //check value compat between animator
|
||||
if(value_bit(self.anim.prop.type) & value_bit(anim.prop.type) == 0) {
|
||||
noti_warning("Type incompatible");
|
||||
return noone;
|
||||
}
|
||||
|
||||
if(typeArray(self.anim.prop.display_type) != typeArray(anim.prop.display_type)) {
|
||||
noti_warning("Type incompatible");
|
||||
return noone;
|
||||
}
|
||||
}
|
||||
|
||||
if(anim == noone) anim = self.anim;
|
||||
|
||||
var key = new valueKey(time + shift, value, anim);
|
||||
key.ease_in = ease_in;
|
||||
key.ease_out = ease_out;
|
||||
key.ease_in_type = ease_in_type;
|
||||
key.ease_out_type = ease_out_type;
|
||||
ds_list_add(anim.values, key);
|
||||
anim.setKeyTime(key, time + shift, removeDup);
|
||||
|
||||
return key;
|
||||
} #endregion
|
||||
|
||||
static getDrawIndex = function() { #region
|
||||
if(anim.prop.type == VALUE_TYPE.trigger)
|
||||
return 1;
|
||||
|
||||
if(drivers.type)
|
||||
return 2;
|
||||
|
||||
if(ease_in_type == CURVE_TYPE.cut)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
} #endregion
|
||||
|
||||
static toString = function() { return $"[Keyframe] {time}: {value}"; }
|
||||
}
|
||||
|
||||
function valueAnimator(_val, _prop, _sep_axis = false) constructor {
|
||||
#region ---- main ----
|
||||
suffix = "";
|
||||
values = ds_list_create();
|
||||
//staticValue = 0;
|
||||
|
||||
length = 1;
|
||||
sep_axis = _sep_axis;
|
||||
|
||||
index = 0;
|
||||
prop = _prop;
|
||||
y = 0;
|
||||
key_map = array_create(TOTAL_FRAMES);
|
||||
key_map_mode = KEYFRAME_END.hold;
|
||||
|
||||
animate_frames = [];
|
||||
|
||||
if(_prop.type != VALUE_TYPE.trigger)
|
||||
ds_list_add(values, new valueKey(0, _val, self));
|
||||
#endregion
|
||||
|
||||
static refreshAnimation = function() { #region
|
||||
animate_frames = array_verify(animate_frames, TOTAL_FRAMES);
|
||||
|
||||
var _anim = false;
|
||||
var _fr = noone;
|
||||
|
||||
for( var i = 0, n = ds_list_size(values); i < n; i++ ) {
|
||||
var _key = values[| i];
|
||||
|
||||
if(_fr == noone) {
|
||||
array_fill(animate_frames, 0, _key.time, 0);
|
||||
} else {
|
||||
if(array_equals(_fr.ease_out, [0, 0]) && array_equals(_fr.ease_in, [0, 1]) && isEqual(_fr.value, _key.value))
|
||||
array_fill(animate_frames, _fr.time, _key.time, 0);
|
||||
else
|
||||
array_fill(animate_frames, _fr.time, _key.time, 1);
|
||||
}
|
||||
|
||||
_fr = _key;
|
||||
}
|
||||
|
||||
if(_fr) array_fill(animate_frames, _fr.time, TOTAL_FRAMES, 0);
|
||||
} #endregion
|
||||
|
||||
static updateKeyMap = function() { #region
|
||||
length = ds_list_size(values);
|
||||
|
||||
if(!prop.is_anim && !LOADING && !APPENDING) return;
|
||||
|
||||
if(ds_list_empty(values)) {
|
||||
array_resize(key_map, TOTAL_FRAMES);
|
||||
return;
|
||||
}
|
||||
|
||||
var _len = max(TOTAL_FRAMES, values[| ds_list_size(values) - 1].time);
|
||||
key_map_mode = prop.on_end;
|
||||
|
||||
if(array_length(key_map) != _len)
|
||||
array_resize(key_map, _len);
|
||||
|
||||
if(prop.type == VALUE_TYPE.trigger) {
|
||||
array_fill(key_map, 0, _len, 0);
|
||||
for( var i = 0, n = ds_list_size(values); i < n; i++ )
|
||||
key_map[values[| i].time] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ds_list_size(values) < 2) {
|
||||
array_fill(key_map, 0, _len, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
var _firstKey = values[| 0].time;
|
||||
array_fill(key_map, 0, _firstKey, -1);
|
||||
var _keyIndex = _firstKey;
|
||||
|
||||
for( var i = 1, n = ds_list_size(values); i < n; i++ ) {
|
||||
var _k1 = values[| i].time;
|
||||
array_fill(key_map, _keyIndex, _k1, i - 1);
|
||||
_keyIndex = _k1;
|
||||
}
|
||||
|
||||
array_fill(key_map, _keyIndex, _len, 999_999);
|
||||
} #endregion
|
||||
|
||||
static interpolate = function(from, to, rat) { #region
|
||||
if(prop.type == VALUE_TYPE.boolean)
|
||||
return 0;
|
||||
|
||||
if(to.ease_in_type == CURVE_TYPE.linear && from.ease_out_type == CURVE_TYPE.linear)
|
||||
return rat;
|
||||
if(to.ease_in_type == CURVE_TYPE.cut)
|
||||
return 0;
|
||||
if(from.ease_out_type == CURVE_TYPE.cut)
|
||||
return 1;
|
||||
if(rat == 0 || rat == 1)
|
||||
return rat;
|
||||
|
||||
var eox = clamp(from.ease_out[0], 0, 0.9);
|
||||
var eix = clamp(to.ease_in[0], 0, 0.9);
|
||||
var eoy = from.ease_out[1];
|
||||
var eiy = to.ease_in[1];
|
||||
|
||||
var bz = [0, eox, eoy, 1. - eix, eiy, 1];
|
||||
return eval_curve_segment_x(bz, rat);
|
||||
} #endregion
|
||||
|
||||
static lerpValue = function(from, to, _lrp) { #region
|
||||
var _f = from.value;
|
||||
var _t = to.value;
|
||||
|
||||
if(is_struct(_f)) {
|
||||
if(!struct_has(_f, "lerpTo")) return _f;
|
||||
return _f.lerpTo(_t, _lrp);
|
||||
}
|
||||
|
||||
if(prop.display_type == VALUE_DISPLAY.d3quarternion) {
|
||||
if(prop.display_data.angle_display == 0) {
|
||||
var _qf = new BBMOD_Quaternion(_f[0], _f[1], _f[2], _f[3]);
|
||||
var _qt = new BBMOD_Quaternion(_t[0], _t[1], _t[2], _t[3]);
|
||||
var _ql = _qf.Slerp(_qt, _lrp);
|
||||
|
||||
return _ql.ToArray();
|
||||
} else {
|
||||
return [
|
||||
lerp(_f[0], _t[0], _lrp),
|
||||
lerp(_f[1], _t[1], _lrp),
|
||||
lerp(_f[2], _t[2], _lrp),
|
||||
0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if(prop.type == VALUE_TYPE.color) {
|
||||
if(is_array(_f) && is_array(_t)) {
|
||||
var _len = ceil(lerp(array_length(_f), array_length(_t), _lrp));
|
||||
var res = array_create(_len);
|
||||
|
||||
for( var i = 0; i < _len; i++ ) {
|
||||
var rat = i / (_len - 1);
|
||||
|
||||
var rf = rat * (array_length(_f) - 1);
|
||||
var rt = rat * (array_length(_t) - 1);
|
||||
|
||||
var cf = array_get_decimal(_f, rf, true);
|
||||
var ct = array_get_decimal(_t, rt, true);
|
||||
|
||||
res[i] = merge_color(cf, ct, _lrp);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return processType(merge_color(_f, _t, _lrp));
|
||||
}
|
||||
|
||||
if(is_array(_f) || is_array(_t)) {
|
||||
var _len = max(array_safe_length(_f), array_safe_length(_t));
|
||||
var _vec = array_create(_len);
|
||||
|
||||
for(var i = 0; i < _len; i++)
|
||||
_vec[i] = processType(
|
||||
lerp(
|
||||
is_array(_f)? array_safe_get_fast(_f, i, 0) : _f,
|
||||
is_array(_t)? array_safe_get_fast(_t, i, 0) : _t,
|
||||
_lrp)
|
||||
);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
if(prop.type == VALUE_TYPE.text)
|
||||
return processType(_f);
|
||||
|
||||
return processType(lerp(_f, _t, _lrp));
|
||||
} #endregion
|
||||
|
||||
static getName = function() { return prop.name + suffix; }
|
||||
|
||||
static getValue = function(_time = CURRENT_FRAME) { #region
|
||||
//if(!prop.is_anim) return staticValue;
|
||||
length = ds_list_size(values);
|
||||
|
||||
///////////////////////////////////////////////////////////// TRIGGER TYPE /////////////////////////////////////////////////////////////
|
||||
|
||||
if(prop.type == VALUE_TYPE.trigger) {
|
||||
if(length == 0 || !prop.is_anim) return false;
|
||||
|
||||
if(array_length(key_map) != TOTAL_FRAMES) updateKeyMap();
|
||||
|
||||
return key_map[_time];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////// OPTIMIZATION /////////////////////////////////////////////////////////////
|
||||
|
||||
if(length == 0) return processTypeDefault();
|
||||
if(length == 1) {
|
||||
var _key = values[| 0];
|
||||
|
||||
if(_key.drivers.type && _time >= _key.time)
|
||||
return processType(processDriver(_time, _key));
|
||||
|
||||
return processType(_key.value);
|
||||
}
|
||||
|
||||
if(prop.type == VALUE_TYPE.path) return processType(values[| 0].value);
|
||||
if(!prop.is_anim) return processType(values[| 0].value);
|
||||
var _len = max(TOTAL_FRAMES, values[| length - 1].time);
|
||||
if(array_length(key_map) != _len) updateKeyMap();
|
||||
|
||||
var _time_first = prop.loop_range == -1? values[| 0].time : values[| length - 1 - prop.loop_range].time;
|
||||
var _time_last = values[| length - 1].time;
|
||||
var _time_dura = _time_last - _time_first;
|
||||
|
||||
////////////////////////////////////////////////////////////// LOOP TIME ///////////////////////////////////////////////////////////////
|
||||
|
||||
if(_time > _time_last) {
|
||||
switch(prop.on_end) {
|
||||
case KEYFRAME_END.loop :
|
||||
_time = _time_first + safe_mod(_time - _time_last, _time_dura + 1);
|
||||
break;
|
||||
case KEYFRAME_END.ping :
|
||||
var time_in_loop = safe_mod(_time - _time_first, _time_dura * 2);
|
||||
if(time_in_loop < _time_dura)
|
||||
_time = _time_first + time_in_loop;
|
||||
else
|
||||
_time = _time_first + _time_dura * 2 - time_in_loop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var _keyIndex;
|
||||
if(_time >= _len) _keyIndex = 999_999;
|
||||
else if(_time <= 0) _keyIndex = -1;
|
||||
else _keyIndex = array_safe_get_fast(key_map, _time);
|
||||
|
||||
//////////////////////////////////////////////////////////// BEFORE FIRST //////////////////////////////////////////////////////////////
|
||||
|
||||
if(_keyIndex == -1) {
|
||||
if(prop.on_end == KEYFRAME_END.wrap) {
|
||||
var from = values[| length - 1];
|
||||
var to = values[| 0];
|
||||
|
||||
var fTime = from.time;
|
||||
var tTime = to.time;
|
||||
|
||||
var prog = TOTAL_FRAMES - fTime + _time;
|
||||
var totl = TOTAL_FRAMES - fTime + tTime;
|
||||
|
||||
var rat = prog / totl;
|
||||
var _lrp = interpolate(from, to, rat);
|
||||
|
||||
return lerpValue(from, to, _lrp);
|
||||
}
|
||||
|
||||
return processType(values[| 0].value); //First frame
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////// AFTER LAST ///////////////////////////////////////////////////////////////
|
||||
|
||||
if(_keyIndex == 999_999) {
|
||||
var _lstKey = values[| length - 1];
|
||||
|
||||
if(_lstKey.drivers.type)
|
||||
return processType(processDriver(_time, _lstKey));
|
||||
|
||||
if(prop.on_end == KEYFRAME_END.wrap) {
|
||||
var from = _lstKey;
|
||||
var to = values[| 0];
|
||||
var prog = _time - from.time;
|
||||
var totl = TOTAL_FRAMES - from.time + to.time;
|
||||
|
||||
var rat = prog / totl;
|
||||
var _lrp = interpolate(from, to, rat);
|
||||
|
||||
return lerpValue(from, to, _lrp);
|
||||
}
|
||||
|
||||
return processType(_lstKey.value); //Last frame
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////// INBETWEEN ////////////////////////////////////////////////////////////////
|
||||
|
||||
var from = values[| _keyIndex];
|
||||
var to = values[| _keyIndex + 1];
|
||||
|
||||
var rat = (_time - from.time) / (to.time - from.time);
|
||||
var _lrp = interpolate(from, to, rat);
|
||||
|
||||
if(from.drivers.type)
|
||||
return processDriver(_time, from, lerpValue(from, to, _lrp), rat);
|
||||
|
||||
return lerpValue(from, to, _lrp);
|
||||
|
||||
} #endregion
|
||||
|
||||
static processTypeDefault = function() { #region
|
||||
if(!sep_axis && typeArray(prop.display_type)) return [];
|
||||
return 0;
|
||||
} #endregion
|
||||
|
||||
static processDriver = function(_time, _key, _val = undefined, _intp = 0) { #region
|
||||
|
||||
static _processDriver = function(val, drivers, _t, _index = 0, _intp = 0) {
|
||||
switch(drivers.type) {
|
||||
case DRIVER_TYPE.linear :
|
||||
return val + _t * drivers.speed;
|
||||
|
||||
case DRIVER_TYPE.wiggle :
|
||||
var w = perlin1D(_t, drivers.seed + _index, drivers.frequency / 10, drivers.octave, -1, 1) * drivers.amplitude;
|
||||
return val + w;
|
||||
|
||||
case DRIVER_TYPE.sine :
|
||||
var w = sin((drivers.phase * (_index + 1) + _t * drivers.frequency / TOTAL_FRAMES) * pi * 2) * drivers.amplitude;
|
||||
return val + w;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var _dt = _time - _key.time;
|
||||
_val = _val == undefined? _key.value : _val;
|
||||
var _res = _val;
|
||||
|
||||
if(prop.type == VALUE_TYPE.integer || prop.type == VALUE_TYPE.float) {
|
||||
if(is_array(_val)) {
|
||||
_res = array_create(array_length(_val));
|
||||
for( var i = 0, n = array_length(_val); i < n; i++ )
|
||||
_res[i] = is_numeric(_val[i])? _processDriver(_val[i], _key.drivers, _dt, _key.drivers.axis_sync? 0 : i, _intp) : _val[i];
|
||||
} else
|
||||
_res = _processDriver(_val, _key.drivers, _dt, 0, _intp);
|
||||
}
|
||||
|
||||
return _res;
|
||||
} #endregion
|
||||
|
||||
static processType = function(_val) { #region
|
||||
INLINE
|
||||
|
||||
var _res = _val;
|
||||
|
||||
if(!sep_axis && typeArray(prop.display_type) && is_array(_val)) {
|
||||
for(var i = 0; i < array_length(_val); i++)
|
||||
_res[i] = processValue(_val[i]);
|
||||
} else
|
||||
_res = processValue(_val);
|
||||
|
||||
return _res;
|
||||
} #endregion
|
||||
|
||||
static processValue = function(_val) { #region
|
||||
INLINE
|
||||
|
||||
if(is_array(_val)) return _val;
|
||||
if(is_struct(_val)) return _val;
|
||||
//if(is_undefined(_val)) return 0;
|
||||
|
||||
switch(prop.type) {
|
||||
case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val;
|
||||
case VALUE_TYPE.float : return _val;
|
||||
case VALUE_TYPE.text : return is_string(_val)? _val : string_real(_val);
|
||||
case VALUE_TYPE.color : return is_real(_val)? cola(_val) : _val;
|
||||
case VALUE_TYPE.surface : return is_string(_val)? get_asset(_val) : _val;
|
||||
}
|
||||
|
||||
return _val;
|
||||
} #endregion
|
||||
|
||||
static insertKey = function(_key, _index) { ds_list_insert(values, _index, _key); }
|
||||
|
||||
static setKeyTime = function(_key, _time, _replace = true, record = false) { #region
|
||||
if(!ds_list_exist(values, _key)) return 0;
|
||||
if(_key.time == _time && !_replace) return 0;
|
||||
|
||||
if(!LOADING) PROJECT.modified = true;
|
||||
|
||||
var _prevTime = _key.time;
|
||||
_time = max(_time, 0);
|
||||
_key.setTime(_time);
|
||||
ds_list_remove(values, _key);
|
||||
|
||||
if(_replace)
|
||||
for( var i = 0; i < ds_list_size(values); i++ ) {
|
||||
if(values[| i].time != _time) continue;
|
||||
|
||||
if(record) {
|
||||
var act = new Action(ACTION_TYPE.custom, function(data) {
|
||||
if(data.undo) insertKey(data.overKey, data.index);
|
||||
updateKeyMap();
|
||||
|
||||
data.undo = !data.undo;
|
||||
}, { overKey : values[| i], index : i, undo : true });
|
||||
mergeAction(act);
|
||||
}
|
||||
|
||||
values[| i] = _key;
|
||||
updateKeyMap();
|
||||
return 2;
|
||||
}
|
||||
|
||||
for( var i = 0; i < ds_list_size(values); i++ ) { //insert key before the last key
|
||||
if(values[| i].time < _time) continue;
|
||||
|
||||
if(record) recordAction(ACTION_TYPE.custom, function(data) {
|
||||
var _prevTime = data.key.time;
|
||||
setKeyTime(data.key, data.time, false);
|
||||
|
||||
data.time = _prevTime;
|
||||
}, { key : _key, time : _prevTime });
|
||||
|
||||
ds_list_insert(values, i, _key);
|
||||
if(_replace) updateKeyMap();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(record) recordAction(ACTION_TYPE.custom, function(data) { // insert key after the last key
|
||||
var _prevTime = data.key.time;
|
||||
setKeyTime(data.key, data.time, false);
|
||||
|
||||
data.time = _prevTime;
|
||||
}, { key : _key, time : _prevTime });
|
||||
|
||||
ds_list_add(values, _key);
|
||||
if(_replace) updateKeyMap();
|
||||
return 1;
|
||||
} #endregion
|
||||
|
||||
static setValue = function(_val = 0, _record = true, _time = CURRENT_FRAME, ease_in = 0, ease_out = 0) { #region
|
||||
//staticValue = _val;
|
||||
|
||||
if(prop.type == VALUE_TYPE.trigger) {
|
||||
if(!prop.is_anim) {
|
||||
values[| 0] = new valueKey(0, _val, self);
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
|
||||
for(var i = 0; i < ds_list_size(values); i++) { //Find trigger
|
||||
var _key = values[| i];
|
||||
if(_key.time == _time) {
|
||||
if(!global.FLAG.keyframe_override) return false;
|
||||
|
||||
_key.value = _val;
|
||||
return false;
|
||||
|
||||
} else if(_key.time > _time) {
|
||||
ds_list_insert(values, i, new valueKey(_time, _val, self));
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//print($"{_time}: {_val} | Insert last");
|
||||
ds_list_add(values, new valueKey(_time, _val, self));
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!prop.is_anim) {
|
||||
if(isEqual(values[| 0].value, _val))
|
||||
return false;
|
||||
|
||||
if(_record) recordAction(ACTION_TYPE.var_modify, values[| 0], [ values[| 0].value, "value", prop.name ]);
|
||||
|
||||
values[| 0].value = _val;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ds_list_size(values) == 0) { // Should not be called normally
|
||||
var k = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
ds_list_add(values, k);
|
||||
if(_record) recordAction(ACTION_TYPE.list_insert, values, [ k, ds_list_size(values) - 1, $"add {prop.name} keyframe" ], function() { updateKeyMap(); });
|
||||
return true;
|
||||
}
|
||||
|
||||
for(var i = 0; i < ds_list_size(values); i++) {
|
||||
var _key = values[| i];
|
||||
if(_key.time == _time) {
|
||||
if(!global.FLAG.keyframe_override) return false;
|
||||
|
||||
if(_key.value != _val) {
|
||||
if(_record) recordAction(ACTION_TYPE.var_modify, _key, [ _key.value, "value", prop.name ]);
|
||||
_key.value = _val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if(_key.time > _time) {
|
||||
var k = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
ds_list_insert(values, i, k);
|
||||
if(_record) recordAction(ACTION_TYPE.list_insert, values, [k, i, $"add {prop.name} keyframe" ], function() { updateKeyMap(); });
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var k = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
if(_record) recordAction(ACTION_TYPE.list_insert, values, [ k, ds_list_size(values), $"add {prop.name} keyframe" ], function() { updateKeyMap(); });
|
||||
ds_list_add(values, k);
|
||||
updateKeyMap();
|
||||
return true;
|
||||
} #endregion
|
||||
|
||||
static removeKey = function(key) { #region
|
||||
if(ds_list_size(values) > 1)
|
||||
ds_list_remove(values, key);
|
||||
else
|
||||
prop.is_anim = false;
|
||||
updateKeyMap();
|
||||
} #endregion
|
||||
|
||||
static serialize = function(scale = false) { #region
|
||||
var _data = [];
|
||||
|
||||
for(var i = 0; i < ds_list_size(values); i++) {
|
||||
var _value_list = [];
|
||||
if(scale)
|
||||
_value_list[0] = values[| i].time / (TOTAL_FRAMES - 1);
|
||||
else
|
||||
_value_list[0] = values[| i].time;
|
||||
|
||||
var val = values[| i].value;
|
||||
|
||||
if(prop.type == VALUE_TYPE.struct) {
|
||||
val = json_stringify(val);
|
||||
|
||||
} else if(is_struct(val)) {
|
||||
val = val.serialize();
|
||||
|
||||
} else if(!sep_axis && typeArray(prop.display_type) && is_array(val)) {
|
||||
var __v = [];
|
||||
for(var j = 0; j < array_length(val); j++) {
|
||||
if(is_struct(val[j]) && struct_has(val[j], "serialize"))
|
||||
array_push(__v, val[j].serialize());
|
||||
else
|
||||
array_push(__v, val[j]);
|
||||
}
|
||||
val = __v;
|
||||
|
||||
}
|
||||
|
||||
_value_list[1] = val;
|
||||
_value_list[2] = values[| i].ease_in;
|
||||
_value_list[3] = values[| i].ease_out;
|
||||
_value_list[4] = values[| i].ease_in_type;
|
||||
_value_list[5] = values[| i].ease_out_type;
|
||||
_value_list[6] = values[| i].ease_y_lock;
|
||||
_value_list[7] = values[| i].drivers;
|
||||
|
||||
array_push(_data, _value_list);
|
||||
}
|
||||
|
||||
return _data;
|
||||
} #endregion
|
||||
|
||||
static deserialize = function(_data, scale = false) { #region
|
||||
ds_list_clear(values);
|
||||
|
||||
if(prop.type == VALUE_TYPE.gradient && LOADING_VERSION < 1340 && !CLONING) { #region //backward compat: Gradient
|
||||
var _val = [];
|
||||
var value = _data[0][1];
|
||||
|
||||
if(is_array(value))
|
||||
for(var i = 0; i < array_length(value); i++) {
|
||||
var _keyframe = value[i];
|
||||
var _t = struct_try_get(_keyframe, "time");
|
||||
var _v = struct_try_get(_keyframe, "value");
|
||||
|
||||
array_push(_val, new gradientKey(_t, _v));
|
||||
}
|
||||
|
||||
var grad = new gradientObject();
|
||||
grad.keys = _val;
|
||||
ds_list_add(values, new valueKey(0, grad, self));
|
||||
|
||||
updateKeyMap();
|
||||
return;
|
||||
} #endregion
|
||||
|
||||
var base = prop.def_val;
|
||||
|
||||
for(var i = 0; i < array_length(_data); i++) {
|
||||
var _keyframe = _data[i];
|
||||
var _time = array_safe_get_fast(_keyframe, 0);
|
||||
|
||||
if(scale && _time <= 1)
|
||||
_time = round(_time * (TOTAL_FRAMES - 1));
|
||||
|
||||
var value = array_safe_get_fast(_keyframe, 1);
|
||||
var ease_in = array_safe_get_fast(_keyframe, 2);
|
||||
var ease_out = array_safe_get_fast(_keyframe, 3);
|
||||
var ease_in_type = array_safe_get_fast(_keyframe, 4);
|
||||
var ease_out_type = array_safe_get_fast(_keyframe, 5);
|
||||
var ease_y_lock = array_safe_get_fast(_keyframe, 6, true);
|
||||
var driver = array_safe_get_fast(_keyframe, 7, {});
|
||||
|
||||
var _val = value;
|
||||
|
||||
if(prop.type == VALUE_TYPE.struct)
|
||||
_val = json_try_parse(value);
|
||||
|
||||
else if(prop.type == VALUE_TYPE.path && prop.display_type == VALUE_DISPLAY.path_array) {
|
||||
for(var j = 0; j < array_length(value); j++)
|
||||
_val[j] = value[j];
|
||||
|
||||
} else if(prop.type == VALUE_TYPE.gradient) {
|
||||
var grad = new gradientObject();
|
||||
_val = grad.deserialize(value);
|
||||
|
||||
} else if(prop.type == VALUE_TYPE.d3Material) {
|
||||
var mat = new __d3dMaterial();
|
||||
_val = mat.deserialize(value);
|
||||
|
||||
} else if(prop.type == VALUE_TYPE.color) {
|
||||
if(is_array(_val)) {
|
||||
for( var i = 0, n = array_length(_val); i < n; i++ )
|
||||
_val[i] = LOADING_VERSION < 11640 && !is_int64(_val[i])? cola(_val[i]) : int64(_val[i]);
|
||||
} else
|
||||
_val = LOADING_VERSION < 11640 && !is_int64(_val)? cola(_val) : int64(_val);
|
||||
|
||||
} else if(!sep_axis && typeArray(prop.display_type)) {
|
||||
_val = [];
|
||||
|
||||
if(is_array(value)) {
|
||||
for(var j = 0; j < array_length(value); j++)
|
||||
_val[j] = processValue(value[j]);
|
||||
} else if(is_array(base)) {
|
||||
for(var j = 0; j < array_length(base); j++)
|
||||
_val[j] = processValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
//print($"Deserialize {prop.node.name}:{prop.name} = {_val} ");
|
||||
var vk = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
vk.ease_in_type = ease_in_type;
|
||||
vk.ease_out_type = ease_out_type;
|
||||
vk.ease_y_lock = ease_y_lock;
|
||||
struct_override(vk.drivers, driver);
|
||||
|
||||
ds_list_add(values, vk);
|
||||
}
|
||||
|
||||
//staticValue = ds_list_empty(values)? 0 : values[| 0].value;
|
||||
updateKeyMap();
|
||||
} #endregion
|
||||
|
||||
static cleanUp = function() { #region
|
||||
ds_list_destroy(values);
|
||||
} #endregion
|
||||
}
|
740
#backups/scripts/node_keyframe/node_keyframe.gml.backup1
Normal file
740
#backups/scripts/node_keyframe/node_keyframe.gml.backup1
Normal file
|
@ -0,0 +1,740 @@
|
|||
// 2024-04-20 09:02:54
|
||||
enum KEY_TYPE { normal, adder }
|
||||
enum CURVE_TYPE { linear, bezier, cut }
|
||||
enum DRIVER_TYPE { none, linear, wiggle, sine }
|
||||
|
||||
function valueKey(_time, _value, _anim = noone, _in = 0, _ot = 0) constructor {
|
||||
#region ---- main ----
|
||||
time = _time;
|
||||
ratio = time / (TOTAL_FRAMES - 1);
|
||||
value = _value;
|
||||
anim = _anim;
|
||||
|
||||
ease_y_lock = true;
|
||||
ease_in = is_array(_in)? _in : [_in, 1];
|
||||
ease_out = is_array(_ot)? _ot : [_ot, 0];
|
||||
|
||||
var _int = anim? anim.prop.key_inter : CURVE_TYPE.linear;
|
||||
ease_in_type = _int;
|
||||
ease_out_type = _int;
|
||||
|
||||
dopesheet_x = 0;
|
||||
|
||||
drivers = {
|
||||
seed : irandom_range(100000, 999999),
|
||||
type : DRIVER_TYPE.none,
|
||||
speed : 1,
|
||||
octave : 2,
|
||||
frequency : 4,
|
||||
amplitude : 1,
|
||||
axis_sync : false,
|
||||
phase : 0,
|
||||
};
|
||||
#endregion
|
||||
|
||||
static setTime = function(time) { #region
|
||||
self.time = time;
|
||||
ratio = time / (TOTAL_FRAMES - 1);
|
||||
} #endregion
|
||||
|
||||
static clone = function(target = noone) { #region
|
||||
var key = new valueKey(time, value, target);
|
||||
key.ease_in = ease_in;
|
||||
key.ease_out = ease_out;
|
||||
key.ease_in_type = ease_in_type;
|
||||
key.ease_out_type = ease_out_type;
|
||||
|
||||
return key;
|
||||
} #endregion
|
||||
|
||||
static cloneAnimator = function(shift = 0, anim = noone, removeDup = true) { #region
|
||||
if(anim != noone) { //check value compat between animator
|
||||
if(value_bit(self.anim.prop.type) & value_bit(anim.prop.type) == 0) {
|
||||
noti_warning("Type incompatible");
|
||||
return noone;
|
||||
}
|
||||
|
||||
if(typeArray(self.anim.prop.display_type) != typeArray(anim.prop.display_type)) {
|
||||
noti_warning("Type incompatible");
|
||||
return noone;
|
||||
}
|
||||
}
|
||||
|
||||
if(anim == noone) anim = self.anim;
|
||||
|
||||
var key = new valueKey(time + shift, value, anim);
|
||||
key.ease_in = ease_in;
|
||||
key.ease_out = ease_out;
|
||||
key.ease_in_type = ease_in_type;
|
||||
key.ease_out_type = ease_out_type;
|
||||
ds_list_add(anim.values, key);
|
||||
anim.setKeyTime(key, time + shift, removeDup);
|
||||
|
||||
return key;
|
||||
} #endregion
|
||||
|
||||
static getDrawIndex = function() { #region
|
||||
if(anim.prop.type == VALUE_TYPE.trigger)
|
||||
return 1;
|
||||
|
||||
if(drivers.type)
|
||||
return 2;
|
||||
|
||||
if(ease_in_type == CURVE_TYPE.cut)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
} #endregion
|
||||
|
||||
static toString = function() { return $"[Keyframe] {time}: {value}"; }
|
||||
}
|
||||
|
||||
function valueAnimator(_val, _prop, _sep_axis = false) constructor {
|
||||
#region ---- main ----
|
||||
suffix = "";
|
||||
values = ds_list_create();
|
||||
//staticValue = 0;
|
||||
|
||||
length = 1;
|
||||
sep_axis = _sep_axis;
|
||||
|
||||
index = 0;
|
||||
prop = _prop;
|
||||
y = 0;
|
||||
key_map = array_create(TOTAL_FRAMES);
|
||||
key_map_mode = KEYFRAME_END.hold;
|
||||
|
||||
animate_frames = [];
|
||||
|
||||
if(_prop.type != VALUE_TYPE.trigger)
|
||||
ds_list_add(values, new valueKey(0, _val, self));
|
||||
#endregion
|
||||
|
||||
static refreshAnimation = function() { #region
|
||||
animate_frames = array_verify(animate_frames, TOTAL_FRAMES);
|
||||
|
||||
var _anim = false;
|
||||
var _fr = noone;
|
||||
|
||||
for( var i = 0, n = ds_list_size(values); i < n; i++ ) {
|
||||
var _key = values[| i];
|
||||
|
||||
if(_fr == noone) {
|
||||
array_fill(animate_frames, 0, _key.time, 0);
|
||||
} else {
|
||||
if(array_equals(_fr.ease_out, [0, 0]) && array_equals(_fr.ease_in, [0, 1]) && isEqual(_fr.value, _key.value))
|
||||
array_fill(animate_frames, _fr.time, _key.time, 0);
|
||||
else
|
||||
array_fill(animate_frames, _fr.time, _key.time, 1);
|
||||
}
|
||||
|
||||
_fr = _key;
|
||||
}
|
||||
|
||||
if(_fr) array_fill(animate_frames, _fr.time, TOTAL_FRAMES, 0);
|
||||
} #endregion
|
||||
|
||||
static updateKeyMap = function() { #region
|
||||
length = ds_list_size(values);
|
||||
|
||||
if(!prop.is_anim && !LOADING && !APPENDING) return;
|
||||
|
||||
if(ds_list_empty(values)) {
|
||||
array_resize(key_map, TOTAL_FRAMES);
|
||||
return;
|
||||
}
|
||||
|
||||
var _len = max(TOTAL_FRAMES, values[| ds_list_size(values) - 1].time);
|
||||
key_map_mode = prop.on_end;
|
||||
|
||||
if(array_length(key_map) != _len)
|
||||
array_resize(key_map, _len);
|
||||
|
||||
if(prop.type == VALUE_TYPE.trigger) {
|
||||
array_fill(key_map, 0, _len, 0);
|
||||
for( var i = 0, n = ds_list_size(values); i < n; i++ )
|
||||
key_map[values[| i].time] = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ds_list_size(values) < 2) {
|
||||
array_fill(key_map, 0, _len, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
var _firstKey = values[| 0].time;
|
||||
array_fill(key_map, 0, _firstKey, -1);
|
||||
var _keyIndex = _firstKey;
|
||||
|
||||
for( var i = 1, n = ds_list_size(values); i < n; i++ ) {
|
||||
var _k1 = values[| i].time;
|
||||
array_fill(key_map, _keyIndex, _k1, i - 1);
|
||||
_keyIndex = _k1;
|
||||
}
|
||||
|
||||
array_fill(key_map, _keyIndex, _len, 999_999);
|
||||
} #endregion
|
||||
|
||||
static interpolate = function(from, to, rat) { #region
|
||||
if(prop.type == VALUE_TYPE.boolean)
|
||||
return 0;
|
||||
|
||||
if(to.ease_in_type == CURVE_TYPE.linear && from.ease_out_type == CURVE_TYPE.linear)
|
||||
return rat;
|
||||
if(to.ease_in_type == CURVE_TYPE.cut)
|
||||
return 0;
|
||||
if(from.ease_out_type == CURVE_TYPE.cut)
|
||||
return 1;
|
||||
if(rat == 0 || rat == 1)
|
||||
return rat;
|
||||
|
||||
var eox = clamp(from.ease_out[0], 0, 0.9);
|
||||
var eix = clamp(to.ease_in[0], 0, 0.9);
|
||||
var eoy = from.ease_out[1];
|
||||
var eiy = to.ease_in[1];
|
||||
|
||||
var bz = [0, eox, eoy, 1. - eix, eiy, 1];
|
||||
return eval_curve_segment_x(bz, rat);
|
||||
} #endregion
|
||||
|
||||
static lerpValue = function(from, to, _lrp) { #region
|
||||
var _f = from.value;
|
||||
var _t = to.value;
|
||||
|
||||
if(is_struct(_f)) {
|
||||
if(!struct_has(_f, "lerpTo")) return _f;
|
||||
return _f.lerpTo(_t, _lrp);
|
||||
}
|
||||
|
||||
if(prop.display_type == VALUE_DISPLAY.d3quarternion) {
|
||||
if(prop.display_data.angle_display == 0) {
|
||||
var _qf = new BBMOD_Quaternion(_f[0], _f[1], _f[2], _f[3]);
|
||||
var _qt = new BBMOD_Quaternion(_t[0], _t[1], _t[2], _t[3]);
|
||||
var _ql = _qf.Slerp(_qt, _lrp);
|
||||
|
||||
return _ql.ToArray();
|
||||
} else {
|
||||
return [
|
||||
lerp(_f[0], _t[0], _lrp),
|
||||
lerp(_f[1], _t[1], _lrp),
|
||||
lerp(_f[2], _t[2], _lrp),
|
||||
0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if(prop.type == VALUE_TYPE.color) {
|
||||
if(is_array(_f) && is_array(_t)) {
|
||||
var _len = ceil(lerp(array_length(_f), array_length(_t), _lrp));
|
||||
var res = array_create(_len);
|
||||
|
||||
for( var i = 0; i < _len; i++ ) {
|
||||
var rat = i / (_len - 1);
|
||||
|
||||
var rf = rat * (array_length(_f) - 1);
|
||||
var rt = rat * (array_length(_t) - 1);
|
||||
|
||||
var cf = array_get_decimal(_f, rf, true);
|
||||
var ct = array_get_decimal(_t, rt, true);
|
||||
|
||||
res[i] = merge_color(cf, ct, _lrp);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
return processType(merge_color(_f, _t, _lrp));
|
||||
}
|
||||
|
||||
if(is_array(_f) || is_array(_t)) {
|
||||
var _len = max(array_safe_length(_f), array_safe_length(_t));
|
||||
var _vec = array_create(_len);
|
||||
|
||||
for(var i = 0; i < _len; i++)
|
||||
_vec[i] = processType(
|
||||
lerp(
|
||||
is_array(_f)? array_safe_get_fast(_f, i, 0) : _f,
|
||||
is_array(_t)? array_safe_get_fast(_t, i, 0) : _t,
|
||||
_lrp)
|
||||
);
|
||||
return _vec;
|
||||
}
|
||||
|
||||
if(prop.type == VALUE_TYPE.text)
|
||||
return processType(_f);
|
||||
|
||||
return processType(lerp(_f, _t, _lrp));
|
||||
} #endregion
|
||||
|
||||
static getName = function() { return prop.name + suffix; }
|
||||
|
||||
static getValue = function(_time = CURRENT_FRAME) { #region
|
||||
//if(!prop.is_anim) return staticValue;
|
||||
length = ds_list_size(values);
|
||||
|
||||
///////////////////////////////////////////////////////////// TRIGGER TYPE /////////////////////////////////////////////////////////////
|
||||
|
||||
if(prop.type == VALUE_TYPE.trigger) {
|
||||
if(length == 0 || !prop.is_anim) return false;
|
||||
|
||||
if(array_length(key_map) != TOTAL_FRAMES) updateKeyMap();
|
||||
|
||||
return key_map[_time];
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////// OPTIMIZATION /////////////////////////////////////////////////////////////
|
||||
|
||||
if(length == 0) return processTypeDefault();
|
||||
if(length == 1) {
|
||||
var _key = values[| 0];
|
||||
|
||||
if(_key.drivers.type && _time >= _key.time)
|
||||
return processType(processDriver(_time, _key));
|
||||
|
||||
return processType(_key.value);
|
||||
}
|
||||
|
||||
if(prop.type == VALUE_TYPE.path) return processType(values[| 0].value);
|
||||
if(!prop.is_anim) return processType(values[| 0].value);
|
||||
var _len = max(TOTAL_FRAMES, values[| length - 1].time);
|
||||
if(array_length(key_map) != _len) updateKeyMap();
|
||||
|
||||
var _time_first = prop.loop_range == -1? values[| 0].time : values[| length - 1 - prop.loop_range].time;
|
||||
var _time_last = values[| length - 1].time;
|
||||
var _time_dura = _time_last - _time_first;
|
||||
|
||||
////////////////////////////////////////////////////////////// LOOP TIME ///////////////////////////////////////////////////////////////
|
||||
|
||||
if(_time > _time_last) {
|
||||
switch(prop.on_end) {
|
||||
case KEYFRAME_END.loop :
|
||||
_time = _time_first + safe_mod(_time - _time_last, _time_dura + 1);
|
||||
break;
|
||||
case KEYFRAME_END.ping :
|
||||
var time_in_loop = safe_mod(_time - _time_first, _time_dura * 2);
|
||||
if(time_in_loop < _time_dura)
|
||||
_time = _time_first + time_in_loop;
|
||||
else
|
||||
_time = _time_first + _time_dura * 2 - time_in_loop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var _keyIndex;
|
||||
if(_time >= _len) _keyIndex = 999_999;
|
||||
else if(_time <= 0) _keyIndex = -1;
|
||||
else _keyIndex = array_safe_get_fast(key_map, _time);
|
||||
|
||||
//////////////////////////////////////////////////////////// BEFORE FIRST //////////////////////////////////////////////////////////////
|
||||
|
||||
if(_keyIndex == -1) {
|
||||
if(prop.on_end == KEYFRAME_END.wrap) {
|
||||
var from = values[| length - 1];
|
||||
var to = values[| 0];
|
||||
|
||||
var fTime = from.time;
|
||||
var tTime = to.time;
|
||||
|
||||
var prog = TOTAL_FRAMES - fTime + _time;
|
||||
var totl = TOTAL_FRAMES - fTime + tTime;
|
||||
|
||||
var rat = prog / totl;
|
||||
var _lrp = interpolate(from, to, rat);
|
||||
|
||||
return lerpValue(from, to, _lrp);
|
||||
}
|
||||
|
||||
return processType(values[| 0].value); //First frame
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////// AFTER LAST ///////////////////////////////////////////////////////////////
|
||||
|
||||
if(_keyIndex == 999_999) {
|
||||
var _lstKey = values[| length - 1];
|
||||
|
||||
if(_lstKey.drivers.type)
|
||||
return processType(processDriver(_time, _lstKey));
|
||||
|
||||
if(prop.on_end == KEYFRAME_END.wrap) {
|
||||
var from = _lstKey;
|
||||
var to = values[| 0];
|
||||
var prog = _time - from.time;
|
||||
var totl = TOTAL_FRAMES - from.time + to.time;
|
||||
|
||||
var rat = prog / totl;
|
||||
var _lrp = interpolate(from, to, rat);
|
||||
|
||||
return lerpValue(from, to, _lrp);
|
||||
}
|
||||
|
||||
return processType(_lstKey.value); //Last frame
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////// INBETWEEN ////////////////////////////////////////////////////////////////
|
||||
|
||||
var from = values[| _keyIndex];
|
||||
var to = values[| _keyIndex + 1];
|
||||
|
||||
var rat = (_time - from.time) / (to.time - from.time);
|
||||
var _lrp = interpolate(from, to, rat);
|
||||
|
||||
if(from.drivers.type)
|
||||
return processDriver(_time, from, lerpValue(from, to, _lrp), rat);
|
||||
|
||||
return lerpValue(from, to, _lrp);
|
||||
|
||||
} #endregion
|
||||
|
||||
static processTypeDefault = function() { #region
|
||||
if(!sep_axis && typeArray(prop.display_type)) return [];
|
||||
return 0;
|
||||
} #endregion
|
||||
|
||||
static processDriver = function(_time, _key, _val = undefined, _intp = 0) { #region
|
||||
|
||||
static _processDriver = function(val, drivers, _t, _index = 0, _intp = 0) {
|
||||
switch(drivers.type) {
|
||||
case DRIVER_TYPE.linear :
|
||||
return val + _t * drivers.speed;
|
||||
|
||||
case DRIVER_TYPE.wiggle :
|
||||
var w = perlin1D(_t, drivers.seed + _index, drivers.frequency / 10, drivers.octave, -1, 1) * drivers.amplitude;
|
||||
return val + w;
|
||||
|
||||
case DRIVER_TYPE.sine :
|
||||
var w = sin((drivers.phase * (_index + 1) + _t * drivers.frequency / TOTAL_FRAMES) * pi * 2) * drivers.amplitude;
|
||||
return val + w;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var _dt = _time - _key.time;
|
||||
_val = _val == undefined? _key.value : _val;
|
||||
var _res = _val;
|
||||
|
||||
if(prop.type == VALUE_TYPE.integer || prop.type == VALUE_TYPE.float) {
|
||||
if(is_array(_val)) {
|
||||
_res = array_create(array_length(_val));
|
||||
for( var i = 0, n = array_length(_val); i < n; i++ )
|
||||
_res[i] = is_numeric(_val[i])? _processDriver(_val[i], _key.drivers, _dt, _key.drivers.axis_sync? 0 : i, _intp) : _val[i];
|
||||
} else
|
||||
_res = _processDriver(_val, _key.drivers, _dt, 0, _intp);
|
||||
}
|
||||
|
||||
return _res;
|
||||
} #endregion
|
||||
|
||||
static processType = function(_val) { #region
|
||||
INLINE
|
||||
|
||||
var _res = _val;
|
||||
|
||||
if(!sep_axis && typeArray(prop.display_type) && is_array(_val)) {
|
||||
for(var i = 0; i < array_length(_val); i++)
|
||||
_res[i] = processValue(_val[i]);
|
||||
} else
|
||||
_res = processValue(_val);
|
||||
|
||||
return _res;
|
||||
} #endregion
|
||||
|
||||
static processValue = function(_val) { #region
|
||||
INLINE
|
||||
|
||||
if(is_array(_val)) return _val;
|
||||
if(is_struct(_val)) return _val;
|
||||
//if(is_undefined(_val)) return 0;
|
||||
|
||||
switch(prop.type) {
|
||||
case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val;
|
||||
case VALUE_TYPE.float : return _val;
|
||||
case VALUE_TYPE.text : return is_string(_val)? _val : string_real(_val);
|
||||
case VALUE_TYPE.color : return _val;
|
||||
case VALUE_TYPE.surface : return is_string(_val)? get_asset(_val) : _val;
|
||||
}
|
||||
|
||||
return _val;
|
||||
} #endregion
|
||||
|
||||
static insertKey = function(_key, _index) { ds_list_insert(values, _index, _key); }
|
||||
|
||||
static setKeyTime = function(_key, _time, _replace = true, record = false) { #region
|
||||
if(!ds_list_exist(values, _key)) return 0;
|
||||
if(_key.time == _time && !_replace) return 0;
|
||||
|
||||
if(!LOADING) PROJECT.modified = true;
|
||||
|
||||
var _prevTime = _key.time;
|
||||
_time = max(_time, 0);
|
||||
_key.setTime(_time);
|
||||
ds_list_remove(values, _key);
|
||||
|
||||
if(_replace)
|
||||
for( var i = 0; i < ds_list_size(values); i++ ) {
|
||||
if(values[| i].time != _time) continue;
|
||||
|
||||
if(record) {
|
||||
var act = new Action(ACTION_TYPE.custom, function(data) {
|
||||
if(data.undo) insertKey(data.overKey, data.index);
|
||||
updateKeyMap();
|
||||
|
||||
data.undo = !data.undo;
|
||||
}, { overKey : values[| i], index : i, undo : true });
|
||||
mergeAction(act);
|
||||
}
|
||||
|
||||
values[| i] = _key;
|
||||
updateKeyMap();
|
||||
return 2;
|
||||
}
|
||||
|
||||
for( var i = 0; i < ds_list_size(values); i++ ) { //insert key before the last key
|
||||
if(values[| i].time < _time) continue;
|
||||
|
||||
if(record) recordAction(ACTION_TYPE.custom, function(data) {
|
||||
var _prevTime = data.key.time;
|
||||
setKeyTime(data.key, data.time, false);
|
||||
|
||||
data.time = _prevTime;
|
||||
}, { key : _key, time : _prevTime });
|
||||
|
||||
ds_list_insert(values, i, _key);
|
||||
if(_replace) updateKeyMap();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(record) recordAction(ACTION_TYPE.custom, function(data) { // insert key after the last key
|
||||
var _prevTime = data.key.time;
|
||||
setKeyTime(data.key, data.time, false);
|
||||
|
||||
data.time = _prevTime;
|
||||
}, { key : _key, time : _prevTime });
|
||||
|
||||
ds_list_add(values, _key);
|
||||
if(_replace) updateKeyMap();
|
||||
return 1;
|
||||
} #endregion
|
||||
|
||||
static setValue = function(_val = 0, _record = true, _time = CURRENT_FRAME, ease_in = 0, ease_out = 0) { #region
|
||||
//staticValue = _val;
|
||||
|
||||
if(prop.type == VALUE_TYPE.trigger) {
|
||||
if(!prop.is_anim) {
|
||||
values[| 0] = new valueKey(0, _val, self);
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
|
||||
for(var i = 0; i < ds_list_size(values); i++) { //Find trigger
|
||||
var _key = values[| i];
|
||||
if(_key.time == _time) {
|
||||
if(!global.FLAG.keyframe_override) return false;
|
||||
|
||||
_key.value = _val;
|
||||
return false;
|
||||
|
||||
} else if(_key.time > _time) {
|
||||
ds_list_insert(values, i, new valueKey(_time, _val, self));
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//print($"{_time}: {_val} | Insert last");
|
||||
ds_list_add(values, new valueKey(_time, _val, self));
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!prop.is_anim) {
|
||||
if(isEqual(values[| 0].value, _val))
|
||||
return false;
|
||||
|
||||
if(_record) recordAction(ACTION_TYPE.var_modify, values[| 0], [ values[| 0].value, "value", prop.name ]);
|
||||
|
||||
values[| 0].value = _val;
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ds_list_size(values) == 0) { // Should not be called normally
|
||||
var k = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
ds_list_add(values, k);
|
||||
if(_record) recordAction(ACTION_TYPE.list_insert, values, [ k, ds_list_size(values) - 1, $"add {prop.name} keyframe" ], function() { updateKeyMap(); });
|
||||
return true;
|
||||
}
|
||||
|
||||
for(var i = 0; i < ds_list_size(values); i++) {
|
||||
var _key = values[| i];
|
||||
if(_key.time == _time) {
|
||||
if(!global.FLAG.keyframe_override) return false;
|
||||
|
||||
if(_key.value != _val) {
|
||||
if(_record) recordAction(ACTION_TYPE.var_modify, _key, [ _key.value, "value", prop.name ]);
|
||||
_key.value = _val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if(_key.time > _time) {
|
||||
var k = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
ds_list_insert(values, i, k);
|
||||
if(_record) recordAction(ACTION_TYPE.list_insert, values, [k, i, $"add {prop.name} keyframe" ], function() { updateKeyMap(); });
|
||||
updateKeyMap();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var k = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
if(_record) recordAction(ACTION_TYPE.list_insert, values, [ k, ds_list_size(values), $"add {prop.name} keyframe" ], function() { updateKeyMap(); });
|
||||
ds_list_add(values, k);
|
||||
updateKeyMap();
|
||||
return true;
|
||||
} #endregion
|
||||
|
||||
static removeKey = function(key) { #region
|
||||
if(ds_list_size(values) > 1)
|
||||
ds_list_remove(values, key);
|
||||
else
|
||||
prop.is_anim = false;
|
||||
updateKeyMap();
|
||||
} #endregion
|
||||
|
||||
static serialize = function(scale = false) { #region
|
||||
var _data = [];
|
||||
|
||||
for(var i = 0; i < ds_list_size(values); i++) {
|
||||
var _value_list = [];
|
||||
if(scale)
|
||||
_value_list[0] = values[| i].time / (TOTAL_FRAMES - 1);
|
||||
else
|
||||
_value_list[0] = values[| i].time;
|
||||
|
||||
var val = values[| i].value;
|
||||
|
||||
if(prop.type == VALUE_TYPE.struct) {
|
||||
val = json_stringify(val);
|
||||
|
||||
} else if(is_struct(val)) {
|
||||
val = val.serialize();
|
||||
|
||||
} else if(!sep_axis && typeArray(prop.display_type) && is_array(val)) {
|
||||
var __v = [];
|
||||
for(var j = 0; j < array_length(val); j++) {
|
||||
if(is_struct(val[j]) && struct_has(val[j], "serialize"))
|
||||
array_push(__v, val[j].serialize());
|
||||
else
|
||||
array_push(__v, val[j]);
|
||||
}
|
||||
val = __v;
|
||||
|
||||
}
|
||||
|
||||
_value_list[1] = val;
|
||||
_value_list[2] = values[| i].ease_in;
|
||||
_value_list[3] = values[| i].ease_out;
|
||||
_value_list[4] = values[| i].ease_in_type;
|
||||
_value_list[5] = values[| i].ease_out_type;
|
||||
_value_list[6] = values[| i].ease_y_lock;
|
||||
_value_list[7] = values[| i].drivers;
|
||||
|
||||
array_push(_data, _value_list);
|
||||
}
|
||||
|
||||
return _data;
|
||||
} #endregion
|
||||
|
||||
static deserialize = function(_data, scale = false) { #region
|
||||
ds_list_clear(values);
|
||||
|
||||
if(prop.type == VALUE_TYPE.gradient && LOADING_VERSION < 1340 && !CLONING) { #region //backward compat: Gradient
|
||||
var _val = [];
|
||||
var value = _data[0][1];
|
||||
|
||||
if(is_array(value))
|
||||
for(var i = 0; i < array_length(value); i++) {
|
||||
var _keyframe = value[i];
|
||||
var _t = struct_try_get(_keyframe, "time");
|
||||
var _v = struct_try_get(_keyframe, "value");
|
||||
|
||||
array_push(_val, new gradientKey(_t, _v));
|
||||
}
|
||||
|
||||
var grad = new gradientObject();
|
||||
grad.keys = _val;
|
||||
ds_list_add(values, new valueKey(0, grad, self));
|
||||
|
||||
updateKeyMap();
|
||||
return;
|
||||
} #endregion
|
||||
|
||||
var base = prop.def_val;
|
||||
|
||||
for(var i = 0; i < array_length(_data); i++) {
|
||||
var _keyframe = _data[i];
|
||||
var _time = array_safe_get_fast(_keyframe, 0);
|
||||
|
||||
if(scale && _time <= 1)
|
||||
_time = round(_time * (TOTAL_FRAMES - 1));
|
||||
|
||||
var value = array_safe_get_fast(_keyframe, 1);
|
||||
var ease_in = array_safe_get_fast(_keyframe, 2);
|
||||
var ease_out = array_safe_get_fast(_keyframe, 3);
|
||||
var ease_in_type = array_safe_get_fast(_keyframe, 4);
|
||||
var ease_out_type = array_safe_get_fast(_keyframe, 5);
|
||||
var ease_y_lock = array_safe_get_fast(_keyframe, 6, true);
|
||||
var driver = array_safe_get_fast(_keyframe, 7, {});
|
||||
|
||||
var _val = value;
|
||||
|
||||
if(prop.type == VALUE_TYPE.struct)
|
||||
_val = json_try_parse(value);
|
||||
|
||||
else if(prop.type == VALUE_TYPE.path && prop.display_type == VALUE_DISPLAY.path_array) {
|
||||
for(var j = 0; j < array_length(value); j++)
|
||||
_val[j] = value[j];
|
||||
|
||||
} else if(prop.type == VALUE_TYPE.gradient) {
|
||||
var grad = new gradientObject();
|
||||
_val = grad.deserialize(value);
|
||||
|
||||
} else if(prop.type == VALUE_TYPE.d3Material) {
|
||||
var mat = new __d3dMaterial();
|
||||
_val = mat.deserialize(value);
|
||||
|
||||
} else if(prop.type == VALUE_TYPE.color) {
|
||||
if(is_array(_val)) {
|
||||
for( var i = 0, n = array_length(_val); i < n; i++ )
|
||||
_val[i] = LOADING_VERSION < 11640 && !is_int64(_val[i])? cola(_val[i]) : int64(_val[i]);
|
||||
} else
|
||||
_val = LOADING_VERSION < 11640 && !is_int64(_val)? cola(_val) : int64(_val);
|
||||
|
||||
} else if(!sep_axis && typeArray(prop.display_type)) {
|
||||
_val = [];
|
||||
|
||||
if(is_array(value)) {
|
||||
for(var j = 0; j < array_length(value); j++)
|
||||
_val[j] = processValue(value[j]);
|
||||
} else if(is_array(base)) {
|
||||
for(var j = 0; j < array_length(base); j++)
|
||||
_val[j] = processValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
//print($"Deserialize {prop.node.name}:{prop.name} = {_val} ");
|
||||
var vk = new valueKey(_time, _val, self, ease_in, ease_out);
|
||||
vk.ease_in_type = ease_in_type;
|
||||
vk.ease_out_type = ease_out_type;
|
||||
vk.ease_y_lock = ease_y_lock;
|
||||
struct_override(vk.drivers, driver);
|
||||
|
||||
ds_list_add(values, vk);
|
||||
}
|
||||
|
||||
//staticValue = ds_list_empty(values)? 0 : values[| 0].value;
|
||||
updateKeyMap();
|
||||
} #endregion
|
||||
|
||||
static cleanUp = function() { #region
|
||||
ds_list_destroy(values);
|
||||
} #endregion
|
||||
}
|
53
#backups/scripts/node_palette/node_palette.gml.backup0
Normal file
53
#backups/scripts/node_palette/node_palette.gml.backup0
Normal file
|
@ -0,0 +1,53 @@
|
|||
// 2024-04-20 09:44:05
|
||||
function Node_Palette(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
|
||||
name = "Palette";
|
||||
setDimension(96);
|
||||
|
||||
inputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 1] = nodeValue("Trim range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 1 ])
|
||||
.setDisplay(VALUE_DISPLAY.slider_range);
|
||||
|
||||
outputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.output, VALUE_TYPE.color, [])
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
input_display_list = [0,
|
||||
["Trim", true], 1
|
||||
];
|
||||
|
||||
static processData = function(_outSurf, _data, _output_index, _array_index) { #region
|
||||
var pal = _data[0];
|
||||
var ran = _data[1];
|
||||
|
||||
var st = floor(clamp(min(ran[0], ran[1]), 0, 1) * array_length(pal));
|
||||
var en = floor(clamp(max(ran[0], ran[1]), 0, 1) * array_length(pal));
|
||||
var ar = [];
|
||||
|
||||
for( var i = st; i < en; i++ )
|
||||
ar[i - st] = array_safe_get_fast(pal, i);
|
||||
|
||||
return ar;
|
||||
} #endregion
|
||||
|
||||
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region
|
||||
var bbox = drawGetBbox(xx, yy, _s);
|
||||
if(bbox.h < 1) return;
|
||||
|
||||
var pal = outputs[| 0].getValue();
|
||||
if(array_empty(pal)) return;
|
||||
if(!is_array(pal[0])) pal = [ pal ];
|
||||
|
||||
var _h = array_length(pal) * 32;
|
||||
var _y = bbox.y0;
|
||||
var gh = bbox.h / array_length(pal);
|
||||
|
||||
for( var i = 0, n = array_length(pal); i < n; i++ ) {
|
||||
drawPalette(pal[i], bbox.x0, _y, bbox.w, gh);
|
||||
_y += gh;
|
||||
}
|
||||
|
||||
if(_h != min_h) will_setHeight = true;
|
||||
min_h = _h;
|
||||
} #endregion
|
||||
}
|
63
#backups/scripts/node_palette/node_palette.gml.backup1
Normal file
63
#backups/scripts/node_palette/node_palette.gml.backup1
Normal file
|
@ -0,0 +1,63 @@
|
|||
// 2024-04-20 09:23:40
|
||||
function Node_Palette(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
|
||||
name = "Palette";
|
||||
setDimension(96);
|
||||
|
||||
inputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
var p = "";
|
||||
var pl = inputs[| 0].animator.values[| 0].value;
|
||||
for (var i = 0, n = array_length(pl); i < n; i++) p += number_to_hex(pl[i]) + ", ";
|
||||
print(p);
|
||||
|
||||
var p = "";
|
||||
var pl = DEF_PALETTE;
|
||||
for (var i = 0, n = array_length(pl); i < n; i++) p += number_to_hex(pl[i]) + ", ";
|
||||
print(p);
|
||||
|
||||
inputs[| 1] = nodeValue("Trim range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 1 ])
|
||||
.setDisplay(VALUE_DISPLAY.slider_range);
|
||||
|
||||
outputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.output, VALUE_TYPE.color, [])
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
input_display_list = [0,
|
||||
["Trim", true], 1
|
||||
];
|
||||
|
||||
static processData = function(_outSurf, _data, _output_index, _array_index) { #region
|
||||
var pal = _data[0];
|
||||
var ran = _data[1];
|
||||
|
||||
var st = floor(clamp(min(ran[0], ran[1]), 0, 1) * array_length(pal));
|
||||
var en = floor(clamp(max(ran[0], ran[1]), 0, 1) * array_length(pal));
|
||||
var ar = [];
|
||||
|
||||
for( var i = st; i < en; i++ )
|
||||
ar[i - st] = array_safe_get_fast(pal, i);
|
||||
|
||||
return ar;
|
||||
} #endregion
|
||||
|
||||
static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region
|
||||
var bbox = drawGetBbox(xx, yy, _s);
|
||||
if(bbox.h < 1) return;
|
||||
|
||||
var pal = outputs[| 0].getValue();
|
||||
if(array_empty(pal)) return;
|
||||
if(!is_array(pal[0])) pal = [ pal ];
|
||||
|
||||
var _h = array_length(pal) * 32;
|
||||
var _y = bbox.y0;
|
||||
var gh = bbox.h / array_length(pal);
|
||||
|
||||
for( var i = 0, n = array_length(pal); i < n; i++ ) {
|
||||
drawPalette(pal[i], bbox.x0, _y, bbox.w, gh);
|
||||
_y += gh;
|
||||
}
|
||||
|
||||
if(_h != min_h) will_setHeight = true;
|
||||
min_h = _h;
|
||||
} #endregion
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
61
#backups/scripts/string_decimal/string_decimal.gml.backup0
Normal file
61
#backups/scripts/string_decimal/string_decimal.gml.backup0
Normal file
|
@ -0,0 +1,61 @@
|
|||
// 2024-04-20 09:11:58
|
||||
function string_variable_valid(str) {
|
||||
static valid_char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789";
|
||||
|
||||
for( var i = 1; i <= string_length(str); i++ ) {
|
||||
var cch = string_char_at(str, i);
|
||||
if(string_pos(cch, valid_char) == 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function string_decimal(str) {
|
||||
var neg = string_char_at(str, 1) == "-";
|
||||
if(neg) str = string_copy(str, 2, string_length(str) - 1);
|
||||
|
||||
var dec = string_pos(".", str);
|
||||
if(dec == 0) return (neg? "-" : "") + string_digits(str);
|
||||
|
||||
var pre = string_copy(str, 1, dec - 1);
|
||||
var pos = string_copy(str, dec + 1, string_length(str) - dec);
|
||||
|
||||
return (neg? "-" : "") + string_digits(pre) + "." + string_digits(pos);
|
||||
}
|
||||
|
||||
function toNumber(str) {
|
||||
INLINE
|
||||
|
||||
if(is_numeric(str)) return str;
|
||||
|
||||
try { return real(str); }
|
||||
catch(e) {}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//function toNumber(str) {
|
||||
// INLINE
|
||||
|
||||
// if(is_real(str)) return str;
|
||||
// if(!isNumber(str)) return 0;
|
||||
|
||||
// var expo = 0;
|
||||
// if(string_pos("e", str)) {
|
||||
// var pos = string_pos("e", str);
|
||||
// expo = real(string_copy(str, pos + 1, string_length(str) - pos));
|
||||
// }
|
||||
|
||||
// str = string_replace_all(str, ",", ".");
|
||||
// str = string_decimal(str);
|
||||
// if(str == "") return 0;
|
||||
// if(str == ".") return 0;
|
||||
// if(str == "-") return 0;
|
||||
// return real(str) * power(10, expo);
|
||||
//}
|
||||
|
||||
function isNumber(str) {
|
||||
if(is_real(str)) return true;
|
||||
str = string_trim(str);
|
||||
return str == string_decimal(str);
|
||||
}
|
61
#backups/scripts/string_decimal/string_decimal.gml.backup1
Normal file
61
#backups/scripts/string_decimal/string_decimal.gml.backup1
Normal file
|
@ -0,0 +1,61 @@
|
|||
// 2024-04-20 09:11:25
|
||||
function string_variable_valid(str) {
|
||||
static valid_char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789";
|
||||
|
||||
for( var i = 1; i <= string_length(str); i++ ) {
|
||||
var cch = string_char_at(str, i);
|
||||
if(string_pos(cch, valid_char) == 0) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function string_decimal(str) {
|
||||
var neg = string_char_at(str, 1) == "-";
|
||||
if(neg) str = string_copy(str, 2, string_length(str) - 1);
|
||||
|
||||
var dec = string_pos(".", str);
|
||||
if(dec == 0) return (neg? "-" : "") + string_digits(str);
|
||||
|
||||
var pre = string_copy(str, 1, dec - 1);
|
||||
var pos = string_copy(str, dec + 1, string_length(str) - dec);
|
||||
|
||||
return (neg? "-" : "") + string_digits(pre) + "." + string_digits(pos);
|
||||
}
|
||||
|
||||
function toNumber(str) {
|
||||
INLINE
|
||||
|
||||
if(is_numeric(str)) return str;
|
||||
|
||||
try { return real(str); }
|
||||
catch(e) {}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//function toNumber(str) {
|
||||
// INLINE
|
||||
|
||||
// if(is_real(str)) return str;
|
||||
// if(!isNumber(str)) return 0;
|
||||
|
||||
// var expo = 0;
|
||||
// if(string_pos("e", str)) {
|
||||
// var pos = string_pos("e", str);
|
||||
// expo = real(string_copy(str, pos + 1, string_length(str) - pos));
|
||||
// }
|
||||
|
||||
// str = string_replace_all(str, ",", ".");
|
||||
// str = string_decimal(str);
|
||||
// if(str == "") return 0;
|
||||
// if(str == ".") return 0;
|
||||
// if(str == "-") return 0;
|
||||
// return real(str) * power(10, expo);
|
||||
//}
|
||||
|
||||
function isNumber(str) {
|
||||
if(is_real(str)) return true;
|
||||
str = string_trim(str);
|
||||
return str == string_decimal(str);
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
// 2024-04-20 08:32:56
|
||||
function string_hexadecimal(str) {
|
||||
static HEX = "0123456789ABCDEF";
|
||||
|
||||
var i = string_length(str);
|
||||
var d = 1;
|
||||
var v = 0;
|
||||
|
||||
while(i > 0) {
|
||||
var ch = string_char_at(str, i);
|
||||
var val = string_pos(string_upper(ch), HEX) - 1;
|
||||
v += val * d;
|
||||
|
||||
d *= 16;
|
||||
i--;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
function number_to_hex(val) {
|
||||
static HEX = "0123456789ABCDEF";
|
||||
var ss = "";
|
||||
while(val > 0) {
|
||||
var i = val % 16;
|
||||
ss = string_char_at(HEX, i + 1) + ss;
|
||||
val = floor(val / 16);
|
||||
}
|
||||
while(string_length(ss) < 2) {
|
||||
ss = "0" + ss;
|
||||
}
|
||||
|
||||
return ss;
|
||||
}
|
||||
|
||||
function color_get_hex(color) {
|
||||
var arr = is_array(color) && array_length(color) == 4;
|
||||
var r = arr? round(color[0] * 256) : color_get_red(color);
|
||||
var g = arr? round(color[1] * 256) : color_get_green(color);
|
||||
var b = arr? round(color[2] * 256) : color_get_blue(color);
|
||||
var a = arr? round(color[3] * 256) : color_get_alpha(color);
|
||||
|
||||
return number_to_hex(r) + number_to_hex(g) + number_to_hex(b) + (is_int64(color)? number_to_hex(a) : "");
|
||||
}
|
||||
|
||||
function color_from_rgb(str) {
|
||||
var _r = string_hexadecimal(string_copy(str, 1, 2));
|
||||
var _g = string_hexadecimal(string_copy(str, 3, 2));
|
||||
var _b = string_hexadecimal(string_copy(str, 5, 2));
|
||||
|
||||
return make_color_rgb(_r, _g, _b);
|
||||
}
|
||||
|
||||
function colorFromHex(hex) {
|
||||
if(string_length(hex) != 6) return 0;
|
||||
|
||||
var rr = string_hexadecimal(string_copy(hex, 1, 2));
|
||||
var gg = string_hexadecimal(string_copy(hex, 3, 2));
|
||||
var bb = string_hexadecimal(string_copy(hex, 5, 2));
|
||||
|
||||
return make_color_rgb(rr, gg, bb);
|
||||
}
|
|
@ -86,9 +86,7 @@ event_inherited();
|
|||
|
||||
if(isHover) {
|
||||
if(mouse_press(mb_left, interactable && sFOCUS)) {
|
||||
palette = array_create(array_length(pal.palette));
|
||||
for( var j = 0; j < array_length(pal.palette); j++ )
|
||||
palette[j] = cola(pal.palette[j]);
|
||||
palette = array_clone(pal.palette);
|
||||
onApply(palette);
|
||||
|
||||
index_selecting = 0;
|
||||
|
|
|
@ -45,7 +45,7 @@ function Node_Color_adjust(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
|
|||
inputs[| 12] = nodeValue("Input Type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
|
||||
.setDisplay(VALUE_DISPLAY.enum_button, [ "Surface", "Color" ]);
|
||||
|
||||
inputs[| 13] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 13] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette)
|
||||
.setVisible(true, true);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ function Node_Color_Remove(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
|
|||
|
||||
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
|
||||
|
||||
inputs[| 1] = nodeValue("Colors", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 1] = nodeValue("Colors", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.1)
|
||||
|
|
|
@ -2,10 +2,10 @@ function Node_Color_replace(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
|
|||
name = "Replace Palette";
|
||||
|
||||
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
|
||||
inputs[| 1] = nodeValue("Palette from", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE, "Color to be replaced.")
|
||||
inputs[| 1] = nodeValue("Palette from", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE), "Color to be replaced.")
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Palette to", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE, "Palette to be replaced to.")
|
||||
inputs[| 2] = nodeValue("Palette to", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE), "Palette to be replaced to.")
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 3] = nodeValue("Threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.1)
|
||||
|
|
|
@ -18,7 +18,7 @@ function Node_Dither(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
|
|||
|
||||
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
|
||||
|
||||
inputs[| 1] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 1] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Pattern", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
|
||||
|
|
|
@ -2,7 +2,7 @@ function Node_Gradient_Palette(_x, _y, _group = noone) : Node_Processor(_x, _y,
|
|||
name = "Palette to Gradient";
|
||||
w = 96;
|
||||
|
||||
inputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette)
|
||||
.setVisible(true, true);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ function Node_Gradient_Points(_x, _y, _group = noone) : Node_Processor(_x, _y, _
|
|||
|
||||
inputs[| 9] = nodeValue("Use palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false );
|
||||
|
||||
inputs[| 10] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 10] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 11] = nodeValue("Falloff 1", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 6 )
|
||||
|
|
|
@ -5,10 +5,10 @@ function Node_Gradient_Replace_Color(_x, _y, _group = noone) : Node_Processor(_x
|
|||
inputs[| 0] = nodeValue("Gradient", self, JUNCTION_CONNECT.input, VALUE_TYPE.gradient, new gradientObject(c_white) )
|
||||
.setVisible(true, true);
|
||||
|
||||
inputs[| 1] = nodeValue("Color from", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 1] = nodeValue("Color from", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Color to", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 2] = nodeValue("Color to", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 3] = nodeValue("Threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.1)
|
||||
|
|
|
@ -448,9 +448,9 @@ function valueAnimator(_val, _prop, _sep_axis = false) constructor {
|
|||
switch(prop.type) {
|
||||
case VALUE_TYPE.integer : return prop.unit.mode == VALUE_UNIT.constant? round(_val) : _val;
|
||||
case VALUE_TYPE.float : return _val;
|
||||
case VALUE_TYPE.text : return is_string(_val)? _val : string_real(_val);
|
||||
case VALUE_TYPE.color : return is_real(_val)? cola(_val) : _val;
|
||||
case VALUE_TYPE.surface : return is_string(_val)? get_asset(_val) : _val;
|
||||
case VALUE_TYPE.text : return is_string(_val)? _val : string_real(_val);
|
||||
case VALUE_TYPE.color : return is_real(_val)? cola(_val) : _val;
|
||||
case VALUE_TYPE.surface : return is_string(_val)? get_asset(_val) : _val;
|
||||
}
|
||||
|
||||
return _val;
|
||||
|
|
|
@ -2,7 +2,7 @@ function Node_Palette(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
|
|||
name = "Palette";
|
||||
setDimension(96);
|
||||
|
||||
inputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE)
|
||||
inputs[| 0] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 1] = nodeValue("Trim range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 1 ])
|
||||
|
|
|
@ -2,14 +2,14 @@ function Node_Palette_Replace(_x, _y, _group = noone) : Node_Processor(_x, _y, _
|
|||
name = "Palette Replace";
|
||||
setDimension(96);
|
||||
|
||||
inputs[| 0] = nodeValue("Palette in", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 0] = nodeValue("Palette in", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette)
|
||||
.setVisible(true, true);
|
||||
|
||||
inputs[| 1] = nodeValue("Palette from", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 1] = nodeValue("Palette from", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Palette to", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 2] = nodeValue("Palette to", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 3] = nodeValue("Threshold", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.1)
|
||||
|
|
|
@ -3,7 +3,7 @@ function Node_Palette_Shift(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr
|
|||
|
||||
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
|
||||
|
||||
inputs[| 1] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE)
|
||||
inputs[| 1] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Shift", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
|
||||
|
|
|
@ -2,7 +2,7 @@ function Node_Palette_Sort(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro
|
|||
name = "Sort Palette";
|
||||
setDimension(96);
|
||||
|
||||
inputs[| 0] = nodeValue("Palette in", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 0] = nodeValue("Palette in", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette)
|
||||
.setVisible(true, true);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ function Node_Posterize(_x, _y, _group = noone) : Node_Processor(_x, _y, _group)
|
|||
|
||||
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
|
||||
|
||||
inputs[| 1] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 1] = nodeValue("Palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 2] = nodeValue("Use palette", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true);
|
||||
|
|
|
@ -5,7 +5,7 @@ function Node_Region_Fill(_x, _y, _group = noone) : Node_Processor(_x, _y, _grou
|
|||
|
||||
inputs[| 1] = nodeValue("Mask", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
|
||||
|
||||
inputs[| 2] = nodeValue("Fill Colors", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 2] = nodeValue("Fill Colors", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
inputs[| 3] = nodeValue("Fill", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
function Node_Surface_From_Color(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
|
||||
name = "Surface from Color";
|
||||
|
||||
inputs[| 0] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE )
|
||||
inputs[| 0] = nodeValue("Color", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE))
|
||||
.setDisplay(VALUE_DISPLAY.palette);
|
||||
|
||||
outputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
|
||||
|
|
|
@ -587,9 +587,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
|
|||
if(_type == VALUE_TYPE.color) {
|
||||
if(is_array(_value)) {
|
||||
for( var i = 0, n = array_length(_value); i < n; i++ )
|
||||
_value[i] = int64(cola(_value[i]));
|
||||
_value[i] = cola(_value[i], _color_get_alpha(_value[i]));
|
||||
} else
|
||||
_value = int64(cola(_value));
|
||||
_value = cola(_value, _color_get_alpha(_value));
|
||||
}
|
||||
|
||||
key_inter = CURVE_TYPE.linear;
|
||||
|
|
|
@ -26,7 +26,7 @@ function Node_Widget_Test(_x, _y, _group = noone) : Node(_x, _y, _group) constru
|
|||
inputs[| 19] = nodeValue("checkBox", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false) .setDisplay(VALUE_DISPLAY._default)
|
||||
|
||||
inputs[| 20] = nodeValue("buttonColor", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, 0) .setDisplay(VALUE_DISPLAY._default)
|
||||
inputs[| 21] = nodeValue("buttonPalette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, DEF_PALETTE) .setDisplay(VALUE_DISPLAY.palette)
|
||||
inputs[| 21] = nodeValue("buttonPalette", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, array_clone(DEF_PALETTE)) .setDisplay(VALUE_DISPLAY.palette)
|
||||
inputs[| 22] = nodeValue("buttonGradient", self, JUNCTION_CONNECT.input, VALUE_TYPE.gradient, new gradientObject(c_white)) .setDisplay(VALUE_DISPLAY._default)
|
||||
|
||||
inputs[| 23] = nodeValue("pathArrayBox", self, JUNCTION_CONNECT.input, VALUE_TYPE.path, []) .setDisplay(VALUE_DISPLAY.path_array, { filter: [ "image|*.png;*.jpg", "" ] })
|
||||
|
|
|
@ -25,6 +25,8 @@ function string_decimal(str) {
|
|||
function toNumber(str) {
|
||||
INLINE
|
||||
|
||||
if(is_numeric(str)) return str;
|
||||
|
||||
try { return real(str); }
|
||||
catch(e) {}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ function string_hexadecimal(str) {
|
|||
var v = 0;
|
||||
|
||||
while(i > 0) {
|
||||
var ch = string_char_at(str, i);
|
||||
var ch = string_char_at(str, i);
|
||||
var val = string_pos(string_upper(ch), HEX) - 1;
|
||||
v += val * d;
|
||||
|
||||
|
|
Loading…
Reference in a new issue