Expression

This commit is contained in:
Tanasart 2023-07-12 16:28:32 +02:00
parent d46795a40b
commit 26b230431a
23 changed files with 680 additions and 87 deletions

View file

@ -223,6 +223,7 @@
{"name":"s_node_particle_effector","order":13,"path":"sprites/s_node_particle_effector/s_node_particle_effector.yy",},
{"name":"sh_blur_bokeh","order":8,"path":"shaders/sh_blur_bokeh/sh_blur_bokeh.yy",},
{"name":"s_node_translate_point","order":14,"path":"sprites/s_node_translate_point/s_node_translate_point.yy",},
{"name":"o_dialog_textbox_autocomplete","order":6,"path":"objects/o_dialog_textbox_autocomplete/o_dialog_textbox_autocomplete.yy",},
{"name":"s_node_loop_input","order":14,"path":"sprites/s_node_loop_input/s_node_loop_input.yy",},
{"name":"node_strand_length_adjust","order":11,"path":"scripts/node_strand_length_adjust/node_strand_length_adjust.yy",},
{"name":"fd_rectangle_add_material_surface","order":25,"path":"scripts/fd_rectangle_add_material_surface/fd_rectangle_add_material_surface.yy",},
@ -582,6 +583,8 @@
{"name":"sh_draw_single_channel","order":3,"path":"shaders/sh_draw_single_channel/sh_draw_single_channel.yy",},
{"name":"draw_sprite_ext_override","order":9,"path":"scripts/draw_sprite_ext_override/draw_sprite_ext_override.yy",},
{"name":"node_array_add","order":9,"path":"scripts/node_array_add/node_array_add.yy",},
{"name":"o_dialog_textbox_function_guide","order":7,"path":"objects/o_dialog_textbox_function_guide/o_dialog_textbox_function_guide.yy",},
{"name":"pxl_server","order":2,"path":"scripts/pxl_server/pxl_server.yy",},
{"name":"s_node_array_set","order":9,"path":"sprites/s_node_array_set/s_node_array_set.yy",},
{"name":"node_noise_cell","order":2,"path":"scripts/node_noise_cell/node_noise_cell.yy",},
{"name":"__background_get_internal","order":2,"path":"scripts/__background_get_internal/__background_get_internal.yy",},

View file

@ -236,6 +236,9 @@
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"graphics.json","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"1.png.tmp$$","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"graphics x2.ai","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ac_constant.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ac_function.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_ac_node.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_action_history.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_add_24.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_add_32.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
@ -713,6 +716,7 @@
{"id":{"name":"s_node_particle_effector","path":"sprites/s_node_particle_effector/s_node_particle_effector.yy",},},
{"id":{"name":"sh_blur_bokeh","path":"shaders/sh_blur_bokeh/sh_blur_bokeh.yy",},},
{"id":{"name":"s_node_translate_point","path":"sprites/s_node_translate_point/s_node_translate_point.yy",},},
{"id":{"name":"o_dialog_textbox_autocomplete","path":"objects/o_dialog_textbox_autocomplete/o_dialog_textbox_autocomplete.yy",},},
{"id":{"name":"s_node_loop_input","path":"sprites/s_node_loop_input/s_node_loop_input.yy",},},
{"id":{"name":"node_strand_length_adjust","path":"scripts/node_strand_length_adjust/node_strand_length_adjust.yy",},},
{"id":{"name":"fd_rectangle_add_material_surface","path":"scripts/fd_rectangle_add_material_surface/fd_rectangle_add_material_surface.yy",},},
@ -1128,6 +1132,8 @@
{"id":{"name":"sh_draw_single_channel","path":"shaders/sh_draw_single_channel/sh_draw_single_channel.yy",},},
{"id":{"name":"draw_sprite_ext_override","path":"scripts/draw_sprite_ext_override/draw_sprite_ext_override.yy",},},
{"id":{"name":"node_array_add","path":"scripts/node_array_add/node_array_add.yy",},},
{"id":{"name":"o_dialog_textbox_function_guide","path":"objects/o_dialog_textbox_function_guide/o_dialog_textbox_function_guide.yy",},},
{"id":{"name":"pxl_server","path":"scripts/pxl_server/pxl_server.yy",},},
{"id":{"name":"s_node_array_set","path":"sprites/s_node_array_set/s_node_array_set.yy",},},
{"id":{"name":"node_noise_cell","path":"scripts/node_noise_cell/node_noise_cell.yy",},},
{"id":{"name":"__background_get_internal","path":"scripts/__background_get_internal/__background_get_internal.yy",},},

Binary file not shown.

View file

@ -0,0 +1,98 @@
/// @description
#region data
depth = -9999;
active = false;
dialog_x = 0;
dialog_y = 0;
dialog_w = 300;
dialog_h = 160;
selecting = 0;
textbox = noone;
prompt = "";
data = [];
sc_content = new scrollPane(dialog_w, dialog_h, function(_y, _m) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var hght = line_get_height(f_p0, 8);
var _dw = sc_content.surface_w;
var _h = 0;
var _ly = _y;
for(var i = 0; i < array_length(data); i++) {
var _dat = data[i];
//if(point_in_rectangle(_m[0], _m[1], 0, _ly + 1, _dw, _ly + hght - 1)) {
// selecting = i;
// if(mouse_press(mb_left))
// applyAutoComplete(_dat[3]);
//}
if(selecting == i) {
draw_sprite_stretched_ext(THEME.textbox, 3, 0, _ly, _dw, hght, COLORS.dialog_menubox_highlight, 1);
if(keyboard_check_pressed(vk_tab))
applyAutoComplete(_dat[3]);
}
var icn = _dat[0][0];
var ss = 16 / sprite_get_width(icn);
draw_sprite_ext(icn, _dat[0][1], ui(4 + 12), _ly + hght / 2, ss, ss, 0, c_white, 1);
draw_set_text(f_p2, fa_right, fa_center, COLORS._main_text_sub);
draw_text_cut(_dw - ui(8), _ly + hght / 2 - ui(2), _dat[2], _dw);
draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text);
draw_text_cut(ui(4 + 24 + 4), _ly + hght / 2 - ui(2), _dat[1], _dw);
_ly += hght;
_h += hght;
}
if(keyboard_check_pressed(vk_up)) {
selecting--;
if(selecting < 0) selecting = array_length(data) - 1;
sc_content.scroll_y_to = -(selecting - 2) * hght;
}
if(keyboard_check_pressed(vk_down)) {
selecting = safe_mod(selecting + 1, array_length(data));
sc_content.scroll_y_to = -(selecting - 2) * hght;
}
return _h;
});
function applyAutoComplete(rep) {
var line = array_safe_get(textbox._input_text_line, textbox.cursor_line, "");
var crop = string_copy(line, 1, textbox.cursor - textbox.char_run);
var slp = string_splice(crop, [" ", "(", ","], true);
print(slp)
slp[array_length(slp) - 1] = rep;
var txt = "";
for( var i = 0; i < array_length(textbox._input_text_line); i++ ) {
if(i == textbox.cursor_line) {
for( var j = 0; j < array_length(slp); j++ )
txt += slp[j];
continue;
}
txt += textbox._input_text_line[i];
}
var shf = string_length(rep) - string_length(prompt);
textbox.cursor += shf;
textbox._input_text = txt;
textbox.cut_line();
textbox.apply();
active = false;
}
#endregion

View file

@ -0,0 +1,41 @@
/// @description
if(!active) exit;
if(textbox == noone) exit;
#region
dialog_x = clamp(dialog_x, 0, WIN_W - dialog_w - 1);
dialog_y = clamp(dialog_y, 0, WIN_H - dialog_h - 1);
var _w = 300;
var _h = array_length(data) * line_get_height(f_p0, 8);
for( var i = 0; i < array_length(data); i++ ) {
var _dat = data[i];
var __w = ui(40 + 32);
draw_set_font(f_p2);
__w += string_width(_dat[2]);
draw_set_font(f_p0);
__w += string_width(_dat[1]);
_w = max(_w, __w);
}
dialog_w = _w;
dialog_h = min(_h, 160);
sc_content.resize(dialog_w, dialog_h);
#endregion
#region draw
draw_sprite_stretched(THEME.textbox, 3, dialog_x, dialog_y, dialog_w, dialog_h);
sc_content.draw(dialog_x, dialog_y);
draw_sprite_stretched(THEME.textbox, 1, dialog_x, dialog_y, dialog_w, dialog_h);
#endregion
if(keyboard_check_pressed(vk_escape))
active = false;

View file

@ -0,0 +1,34 @@
{
"resourceType": "GMObject",
"resourceVersion": "1.0",
"name": "o_dialog_textbox_autocomplete",
"eventList": [
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,},
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,},
],
"managed": true,
"overriddenProperties": [],
"parent": {
"name": "widget",
"path": "folders/dialog/widget.yy",
},
"parentObjectId": null,
"persistent": false,
"physicsAngularDamping": 0.1,
"physicsDensity": 0.5,
"physicsFriction": 0.2,
"physicsGroup": 1,
"physicsKinematic": false,
"physicsLinearDamping": 0.1,
"physicsObject": false,
"physicsRestitution": 0.1,
"physicsSensor": false,
"physicsShape": 1,
"physicsShapePoints": [],
"physicsStartAwake": true,
"properties": [],
"solid": false,
"spriteId": null,
"spriteMaskId": null,
"visible": true,
}

View file

@ -0,0 +1,15 @@
/// @description
#region data
depth = -9999;
active = false;
dialog_x = 0;
dialog_y = 0;
dialog_w = 280;
dialog_h = 32;
textbox = noone;
prompt = "";
index = 0;
#endregion

View file

@ -0,0 +1,50 @@
/// @description
if(!active) exit;
if(textbox == noone) exit;
#region
draw_set_text(f_code, fa_left, fa_top, COLORS._main_text);
dialog_w = string_width(prompt) + ui(16);
dialog_h = string_height(prompt) + ui(16);
dialog_x = clamp(dialog_x, 0, WIN_W - dialog_w - 1);
var dy = clamp(dialog_y - dialog_h, 0, WIN_H - dialog_h - 1);
#endregion
#region draw
draw_sprite_stretched(THEME.textbox, 3, dialog_x, dy, dialog_w, dialog_h);
var cx = dialog_x + ui(8);
var cy = dy + ui(8);
var ind = 1;
var amo = string_length(prompt);
var cch = "";
var fname = true;
var var_ind = 0;
repeat(amo) {
cch = string_char_at(prompt, ind);
ind++;
if(cch == "(") fname = false;
if(cch == ",") var_ind++;
if(cch == "(" || cch == ")" || cch == "[" || cch == "]" || cch == "{" || cch == "}")
draw_set_color(COLORS.lua_highlight_bracklet);
else if(cch == ",")
draw_set_color(COLORS._main_text);
else if(fname)
draw_set_color(COLORS.lua_highlight_function);
else
draw_set_color(var_ind == index? COLORS._main_text : COLORS._main_text_sub);
draw_text(cx, cy, cch);
cx += string_width(cch);
}
draw_sprite_stretched(THEME.textbox, 1, dialog_x, dy, dialog_w, dialog_h);
#endregion
if(keyboard_check_pressed(vk_escape))
active = false;

View file

@ -0,0 +1,34 @@
{
"resourceType": "GMObject",
"resourceVersion": "1.0",
"name": "o_dialog_textbox_function_guide",
"eventList": [
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,},
{"resourceType":"GMEvent","resourceVersion":"1.0","name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,},
],
"managed": true,
"overriddenProperties": [],
"parent": {
"name": "widget",
"path": "folders/dialog/widget.yy",
},
"parentObjectId": null,
"persistent": false,
"physicsAngularDamping": 0.1,
"physicsDensity": 0.5,
"physicsFriction": 0.2,
"physicsGroup": 1,
"physicsKinematic": false,
"physicsLinearDamping": 0.1,
"physicsObject": false,
"physicsRestitution": 0.1,
"physicsSensor": false,
"physicsShape": 1,
"physicsShapePoints": [],
"physicsStartAwake": true,
"properties": [],
"solid": false,
"spriteId": null,
"spriteMaskId": null,
"visible": true,
}

View file

@ -237,8 +237,9 @@
#endregion
#region dialog
globalvar DIALOGS;
globalvar DIALOGS, WIDGET_TAB_BLOCK;
DIALOGS = ds_list_create();
WIDGET_TAB_BLOCK = false;
#endregion
#region async

View file

@ -9,16 +9,20 @@ if(OS == os_windows && gameframe_is_minimized()) {
}
#region widget scroll
if(keyboard_check_pressed(vk_tab) && key_mod_press(SHIFT))
widget_previous();
else if(keyboard_check_pressed(vk_tab))
widget_next();
if(!WIDGET_TAB_BLOCK) {
if(keyboard_check_pressed(vk_tab) && key_mod_press(SHIFT))
widget_previous();
else if(keyboard_check_pressed(vk_tab))
widget_next();
if(keyboard_check_pressed(vk_enter))
widget_trigger();
if(keyboard_check_pressed(vk_enter))
widget_trigger();
if(keyboard_check_pressed(vk_escape))
widget_clear();
if(keyboard_check_pressed(vk_escape))
widget_clear();
}
WIDGET_TAB_BLOCK = false;
#endregion
#region register UI element

View file

@ -53,7 +53,7 @@ function array_safe_get(arr, index, def = 0, overflow = ARRAY_OVERFLOW._default)
if(index < 0) return def;
if(index >= array_length(arr)) return def;
return arr[index];
return arr[index] == undefined? def : arr[index];
}
function array_push_create(arr, val) {

View file

@ -55,6 +55,12 @@
PROJECTS = [];
PROJECT = new Project();
}
globalvar PROJECT_VARIABLES;
PROJECT_VARIABLES = ds_map_create();
PROJECT_VARIABLES[? "frame"] = [ function() { return PROJECT.animator.current_frame; }];
PROJECT_VARIABLES[? "frameTotal"] = [ function() { return PROJECT.animator.frames_total; }];
PROJECT_VARIABLES[? "fps"] = [ function() { return PROJECT.animator.framerate; }];
#endregion
#region main
@ -70,7 +76,7 @@
VERSION = 1147;
SAVE_VERSION = 1447;
VERSION_STRING = "1.14.6n3";
VERSION_STRING = "1.14.6n4";
BUILD_NUMBER = 114600;
globalvar APPEND_MAP;

View file

@ -193,6 +193,8 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc
if(jun.expUse) {
var expValid = jun.expTree != noone && jun.expTree.validate();
jun.express_edit.boxColor = expValid? COLORS._main_value_positive : COLORS._main_value_negative;
jun.express_edit.rx = rx;
jun.express_edit.ry = ry;
jun.express_edit.setFocusHover(_focus, _hover);
if(_focus) jun.express_edit.register(_scrollPane);
@ -221,6 +223,9 @@ function drawWidget(xx, yy, ww, _m, jun, global_var = true, _hover = false, _foc
mouse: _m,
}
jun.editWidget.rx = rx;
jun.editWidget.ry = ry;
switch(jun.display_type) {
case VALUE_DISPLAY.button :
jun.editWidget.draw(editBoxX, editBoxY, editBoxW, editBoxH, _m);

View file

@ -729,12 +729,8 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor {
var inp = PROJECT.globalNode.getInput(strs[0]);
return inp == noone? 0 : inp.getValueRecursive()[0];
} else if(string_lower(strs[0]) == "project") {
switch(string_lower(strs[1])) {
case "frame" : return PROJECT.animator.current_frame;
case "frameTotal" : return PROJECT.animator.frames_total;
case "fps" : return PROJECT.animator.framerate;
}
return 0;
if(!ds_map_exists(PROJECT_VARIABLES, strs[1])) return 0;
return PROJECT_VARIABLES[? strs[1]]();
} else if(array_length(strs) > 2) {
var key = strs[0];
if(!ds_map_exists(PROJECT.nodeNameMap, key)) return 0;

View file

@ -439,6 +439,10 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
expression = str;
expressionUpdate();
});
express_edit.autocomplete_server = pxl_autocomplete_server;
express_edit.function_guide_server = pxl_function_guide_server;
express_edit.format = TEXT_AREA_FORMAT.code;
express_edit.font = f_code;
express_edit.boxColor = COLORS._main_value_positive;
express_edit.align = fa_left;
@ -1464,6 +1468,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
return -1;
}
junction_drawing = [ THEME.node_junctions_single, type ];
static drawJunction = function(_s, _mx, _my, sca = 1) {
if(!isVisible()) return false;
@ -1479,16 +1484,18 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru
is_hover = true;
if(type == VALUE_TYPE.action)
draw_sprite_ext(THEME.node_junction_inspector, 1, x, y, ss, ss, 0, c_white, 1);
else
draw_sprite_ext(isArray()? THEME.node_junctions_array_hover : THEME.node_junctions_single_hover, type, x, y, ss, ss, 0, c_white, 1);
junction_drawing = [THEME.node_junction_inspector, 1];
else
junction_drawing = [isArray()? THEME.node_junctions_array_hover : THEME.node_junctions_single_hover, type];
} else {
if(type == VALUE_TYPE.action)
draw_sprite_ext(THEME.node_junction_inspector, 0, x, y, ss, ss, 0, c_white, 1);
else
draw_sprite_ext(isArray()? THEME.node_junctions_array : THEME.node_junctions_single, type, x, y, ss, ss, 0, c_white, 1);
junction_drawing = [THEME.node_junction_inspector, 0];
else
junction_drawing = [isArray()? THEME.node_junctions_array : THEME.node_junctions_single, type];
}
draw_sprite_ext(junction_drawing[0], junction_drawing[1], x, y, ss, ss, 0, c_white, 1);
return is_hover;
}

View file

@ -0,0 +1,148 @@
global.GLOBAL_VAR = [ "project" ];
global.NODE_SUB_CATAG = [ "input", "output" ];
function pxl_autocomplete_server(prompt) {
var res = [];
var pr_list = ds_priority_create();
//////////////////////////////////
ds_priority_clear(pr_list);
for( var i = 0; i < array_length(global.GLOBAL_VAR); i++ ) {
var gl = global.GLOBAL_VAR[i];
var match = string_partial_match(string_lower(gl), string_lower(prompt));
if(match == -9999) continue;
ds_priority_add(pr_list, [[THEME.ac_constant, 0], gl, "global", gl], match);
}
repeat(ds_priority_size(pr_list))
array_push(res, ds_priority_delete_max(pr_list));
//////////////////////////////////
ds_priority_clear(pr_list);
var sp = string_splice(prompt, ".");
if(array_length(sp) > 1) {
if(sp[0] == "project") {
var F = PROJECT_VARIABLES;
var k = ds_map_find_first(F);
var a = ds_map_size(F);
repeat(a) {
var match = string_partial_match(string_lower(k), string_lower(sp[1]));
if(match == -9999 && sp[1] != "") {
k = ds_map_find_next(F, k);
continue;
}
var fn = F[? prompt];
ds_priority_add(pr_list, [[THEME.ac_constant, 0], k, sp[0], $"{sp[0]}.{k}"], match);
k = ds_map_find_next(F, k);
}
} else if(ds_map_exists(PROJECT.nodeNameMap, sp[0])) {
if(array_length(sp) == 2) {
for( var i = 0; i < array_length(global.NODE_SUB_CATAG); i++ ) {
var gl = global.NODE_SUB_CATAG[i];
var match = string_partial_match(string_lower(gl), string_lower(sp[1]));
if(match == -9999 && sp[1] != "") continue;
ds_priority_add(pr_list, [[THEME.ac_node, i], gl, sp[0], $"{sp[0]}.{gl}"], match);
}
} else if(array_length(sp) == 3) {
var node = PROJECT.nodeNameMap[? sp[0]];
var F = noone;
var tag = "";
switch(string_lower(sp[1])) {
case "inputs" :
case "input" :
F = node.inputMap;
tag = "input";
break;
case "outputs" :
case "output" :
F = node.outputMap;
tag = "output";
break;
default : return 0;
}
var k = ds_map_find_first(F);
var a = ds_map_size(F);
repeat(a) {
var match = string_partial_match(string_lower(k), string_lower(sp[2]));
if(match == -9999 && sp[2] != "") {
k = ds_map_find_next(F, k);
continue;
}
var fn = F[? k];
ds_priority_add(pr_list, [fn.junction_drawing, k, sp[0] + "." + tag, $"{sp[0]}.{sp[1]}.{k}"], match);
k = ds_map_find_next(F, k);
}
}
}
}
repeat(ds_priority_size(pr_list))
array_push(res, ds_priority_delete_max(pr_list));
//////////////////////////////////
ds_priority_clear(pr_list);
var F = PROJECT.nodeNameMap;
var k = ds_map_find_first(F);
var a = ds_map_size(F);
repeat(a) {
var match = string_partial_match(string_lower(k), string_lower(prompt));
if(match == -9999) {
k = ds_map_find_next(F, k);
continue;
}
var fn = F[? prompt];
ds_priority_add(pr_list, [[THEME.ac_constant, 0], k, "node", k], match);
k = ds_map_find_next(F, k);
}
repeat(ds_priority_size(pr_list))
array_push(res, ds_priority_delete_max(pr_list));
//////////////////////////////////
ds_priority_clear(pr_list);
var F = global.FUNCTIONS;
var k = ds_map_find_first(F);
var a = ds_map_size(F);
repeat(a) {
var match = string_partial_match(string_lower(k), string_lower(prompt));
if(match == -9999) {
k = ds_map_find_next(F, k);
continue;
}
var fn = F[? prompt];
ds_priority_add(pr_list, [[THEME.ac_function, 0], k, "function", k], match);
k = ds_map_find_next(F, k);
}
repeat(ds_priority_size(pr_list))
array_push(res, ds_priority_delete_max(pr_list));
ds_priority_destroy(pr_list);
return res;
}
function pxl_function_guide_server(prompt) {
if(!ds_map_exists(global.FUNCTIONS, prompt)) return "";
var fn = global.FUNCTIONS[? prompt];
var guide = prompt + "(";
for( var i = 0; i < array_length(fn[0]); i++ )
guide += (i? ", " : "") + string(fn[0][i]);
guide += ")";
return guide;
}

View file

@ -0,0 +1,11 @@
{
"resourceType": "GMScript",
"resourceVersion": "1.0",
"name": "pxl_server",
"isCompatibility": false,
"isDnD": false,
"parent": {
"name": "eval",
"path": "folders/functions/eval.yy",
},
}

View file

@ -1,3 +1,14 @@
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);

View file

@ -25,19 +25,41 @@
global.EQUATION_PRES[? "@"] = 5; //array accerssor symbol
global.FUNCTIONS = ds_map_create();
global.FUNCTIONS[? "sin"] = [ 1, function(val) { return sin(val[0]); } ];
global.FUNCTIONS[? "cos"] = [ 1, function(val) { return cos(val[0]); } ];
global.FUNCTIONS[? "tan"] = [ 1, function(val) { return tan(val[0]); } ];
global.FUNCTIONS[? "abs"] = [ 1, function(val) { return abs(val[0]); } ];
global.FUNCTIONS[? "round"] = [ 1, function(val) { return round(val[0]); } ];
global.FUNCTIONS[? "ceil"] = [ 1, function(val) { return ceil(val[0]); } ];
global.FUNCTIONS[? "floor"] = [ 1, function(val) { return floor(val[0]); } ];
global.FUNCTIONS[? "sin"] = [ ["radian"], function(val) { return sin(val[0]); } ];
global.FUNCTIONS[? "cos"] = [ ["radian"], function(val) { return cos(val[0]); } ];
global.FUNCTIONS[? "tan"] = [ ["radian"], function(val) { return tan(val[0]); } ];
global.FUNCTIONS[? "abs"] = [ ["number"], function(val) { return abs(val[0]); } ];
global.FUNCTIONS[? "round"] = [ ["number"], function(val) { return round(val[0]); } ];
global.FUNCTIONS[? "ceil"] = [ ["number"], function(val) { return ceil(val[0]); } ];
global.FUNCTIONS[? "floor"] = [ ["number"], function(val) { return floor(val[0]); } ];
global.FUNCTIONS[? "wiggle"] = [ 2, function(val) { return wiggle(0, 1, val[1], val[0]); } ];
global.FUNCTIONS[? "wiggle"] = [ ["time", "frequency", "octave", "seed"], function(val) {
return wiggle(0, 1, array_safe_get(val, 1),
array_safe_get(val, 0),
array_safe_get(val, 3, 0),
array_safe_get(val, 2, 1));
} ];
#endregion
function functionStringClean(fx) {
//fx = string_replace_all(fx, " ", "");
var ch = "", ind = 0, len = string_length(fx);
var _fx = "", str = false;
while(ind++ <= len) {
ch = string_char_at(fx, ind);
if(ch == " ") {
if(str)
_fx += ch;
} else
_fx += ch;
if(ch == "\"")
str = !str;
}
fx = _fx;
fx = string_replace_all(fx, "\n", "");
fx = string_replace_all(fx, "**", "$");
fx = string_replace_all(fx, "<<", "«");
@ -65,6 +87,7 @@ function functionStringClean(fx) {
self.symbol = symbol;
self.l = l;
self.r = r;
dependency = [];
static _string = function(str) {
return string_char_at(str, 1) == "\"" &&
@ -102,21 +125,19 @@ function functionStringClean(fx) {
var strs = string_splice(val, ".");
if(array_length(strs) < 2) return false;
if(strs[0] == "Project") {
switch(strs[1]) {
case "frame" :
case "frameTotal" :
case "fps" :
return true;
}
return false;
}
if(strs[0] == "Project")
return ds_map_exists(PROJECT_VARIABLES, strs[1]);
var key = strs[0];
return ds_map_exists(PROJECT.nodeNameMap, key);
if(!ds_map_exists(PROJECT.nodeNameMap, strs[0]))
return false;
array_push_unique(dependency, strs[0])
return true;
}
static validate = function() {
dependency = [];
if(ds_map_exists(global.FUNCTIONS, symbol)) {
if(!is_array(l)) return false;
for( var i = 0; i < array_length(l); i++ )
@ -268,12 +289,10 @@ function functionStringClean(fx) {
var _ch = "";
var in_str = false;
//print($"===== Function: {fx} =====");
while(l <= len) {
ch = string_char_at(fx, l);
if(ch == " ") {
l++;
continue;
}
if(ds_map_exists(pres, ch)) { //symbol is operator
if(ds_stack_empty(op)) ds_stack_push(op, ch);
@ -299,9 +318,6 @@ function functionStringClean(fx) {
last_push = "op";
l++;
} else if (ch == ")") {
while(ds_stack_top(op) != "(" && !ds_stack_empty(op))
ds_stack_push(vl, buildFuncTree(ds_stack_pop(op), vl));
while(!ds_stack_empty(op)) {
var _top = ds_stack_pop(op);
if(_top == "(") break;
@ -347,7 +363,6 @@ function functionStringClean(fx) {
if(_top == "[" || _top == "(" || (is_array(_top) && _top[0] == "{")) break;
ds_stack_push(vl, buildFuncTree(_top, vl));
ds_stack_pop(op);
}
last_push = "vl";
@ -357,7 +372,11 @@ function functionStringClean(fx) {
while(l <= len) {
cch = string_char_at(fx, l);
if(ds_map_exists(pres, cch) || array_exists(__BRACKETS, cch) || cch == ",") break;
if(ds_map_exists(pres, cch) || array_exists(__BRACKETS, cch)) break;
if(cch == ",") {
l++;
break;
}
vsl += cch;
l++;
@ -393,10 +412,8 @@ function functionStringClean(fx) {
if(!is_struct(tree))
tree = new __funcTree("", tree);
print("=====");
print(fx);
print(tree);
print("");
//print(tree);
//print("");
return tree;
}
@ -404,6 +421,14 @@ function functionStringClean(fx) {
function buildFuncTree(operator, vl) {
if(ds_stack_empty(vl)) return noone;
if(ds_map_exists(global.FUNCTIONS, operator)) {
if(ds_stack_empty(vl))
return noone;
var _v1 = ds_stack_pop(vl);
return new __funcTree(operator, _v1);
}
switch(operator) {
case "-": //deal with preceeding negative number -5
if(ds_stack_size(vl) >= 2) {

View file

@ -1,21 +1,30 @@
function string_splice(str, delim) {
function string_splice(str, delim = " ", keep = false) {
var st = [];
var ss = str;
var sp;
var wd = string_length(delim);
if(!is_array(delim)) delim = [ delim ];
do {
sp = string_pos(delim, ss);
while(1) {
sp = 99999;
var found = false;
for( var i = 0; i < array_length(delim); i++ ) {
var pos = string_pos(delim[i], ss);
if(pos) {
sp = min(sp, pos);
found = true;
}
}
if(sp == 0) { //no delim left
if(!found) { //no delim left
array_push(st, ss);
break;
} else {
var _ss = string_copy(ss, 1, sp - 1);
var _ss = string_copy(ss, 1, keep? sp : sp - 1);
array_push(st, _ss);
}
ss = string_copy(ss, sp + 1, string_length(ss) - sp);
} until(sp == 0);
}
return st;
}

View file

@ -30,6 +30,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
cursor_pos_y_to = 0;
cursor_line = 0;
char_run = 0
cursor_select = -1;
click_block = 0;
@ -37,6 +39,14 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
code_line_width = 48;
autocomplete_box = instance_create(0, 0, o_dialog_textbox_autocomplete);
autocomplete_box.textbox = self;
autocomplete_server = noone;
function_guide_box = instance_create(0, 0, o_dialog_textbox_function_guide);
function_guide_box.textbox = self;
function_guide_server = noone;
_cl = -1;
static activate = function() {
@ -96,7 +106,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
}
}
}
if(format != TEXT_AREA_FORMAT.code || !autocomplete_box.active)
if(key == vk_up) {
var _target;
@ -130,7 +141,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
cursor = _target;
}
if(format != TEXT_AREA_FORMAT.code || !autocomplete_box.active)
if(key == vk_down) {
var _target;
@ -151,7 +163,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
if(_run > cursor_pos_x_to) break;
_char++;
}
_target = _char;
}
@ -226,6 +238,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
}
static editText = function() {
var modified = false;
#region text editor
if(key_mod_press(CTRL) && keyboard_check_pressed(ord("A"))) {
cursor_select = 0;
@ -241,28 +255,28 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
KEYBOARD_STRING = clipboard_get_text();
if(keyboard_check_pressed(vk_escape)) {
} else if(keyboard_check_pressed(vk_enter)) {
if(key_mod_press(SHIFT)) {
var ch = "\n";
if(cursor_select == -1) {
var str_before = string_copy(_input_text, 1, cursor);
var str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor);
} else if(keyboard_check_pressed(vk_tab)) {
} else if(keyboard_check_pressed(vk_enter) && !key_mod_press(SHIFT)) {
var ch = "\n";
if(cursor_select == -1) {
var str_before = string_copy(_input_text, 1, cursor);
var str_after = string_copy(_input_text, cursor + 1, string_length(_input_text) - cursor);
_input_text = str_before + ch + str_after;
cut_line();
move_cursor(string_length(ch));
} else {
var minc = min(cursor, cursor_select);
var maxc = max(cursor, cursor_select);
_input_text = str_before + ch + str_after;
cut_line();
move_cursor(string_length(ch));
} else {
var minc = min(cursor, cursor_select);
var maxc = max(cursor, cursor_select);
var str_before = string_copy(_input_text, 1, minc);
var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc);
var str_before = string_copy(_input_text, 1, minc);
var str_after = string_copy(_input_text, maxc + 1, string_length(_input_text) - maxc);
_input_text = str_before + ch + str_after;
cut_line();
cursor = minc + string_length(ch);
}
_input_text = str_before + ch + str_after;
cut_line();
cursor = minc + string_length(ch);
}
modified = true;
} else if(KEYBOARD_PRESSED == vk_backspace) {
if(cursor_select == -1) {
var str_before = string_copy(_input_text, 1, cursor - 1);
@ -284,6 +298,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
cursor_select = -1;
move_cursor(-1);
modified = true;
} else if(KEYBOARD_PRESSED == vk_delete || (keyboard_check_pressed(ord("X")) && key_mod_press(CTRL) && cursor_select != -1)) {
if(cursor_select == -1) {
var str_before = string_copy(_input_text, 1, cursor);
@ -303,6 +318,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
cut_line();
}
cursor_select = -1;
modified = true;
} else if(KEYBOARD_STRING != "") {
var ch = KEYBOARD_STRING;
@ -326,6 +342,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
}
cursor_select = -1;
modified = true;
}
}
@ -333,6 +350,65 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
keyboard_lastkey = -1;
#endregion
if(modified) {
#region autocomplete
if(format == TEXT_AREA_FORMAT.code && autocomplete_server != noone) {
var crop = string_copy(_input_text, 1, cursor);
var slp = string_splice(crop, [" ", "(", ","]);
var pmt = array_safe_get(slp, -1,, ARRAY_OVERFLOW.loop);
var data = autocomplete_server(pmt);
if(array_length(data)) {
autocomplete_box.data = data;
autocomplete_box.active = true;
autocomplete_box.dialog_x = rx + cursor_pos_x + 1;
autocomplete_box.dialog_y = ry + cursor_pos_y + line_get_height() + 1;
autocomplete_box.prompt = pmt;
autocomplete_box.selecting= 0;
} else
autocomplete_box.active = false;
var _c = cursor;
var _v = false;
var _fn = "";
var _el = 0;
var amo = 0;
while(_c > 1) {
var cch0 = string_char_at(_input_text, _c - 1);
var cch1 = string_char_at(_input_text, _c);
if(_el == 0 && cch1 == ",") amo++;
if(_el == 0 && cch1 == "(" && string_variable_valid(cch0))
_v = true;
else if(cch1 == ")") _el++;
else if(cch1 == "(") _el--;
if(_v) {
if(!string_variable_valid(cch0))
break;
_fn = cch0 + _fn;
}
_c--;
}
var guide = function_guide_server(_fn);
if(guide != "") {
function_guide_box.active = true;
function_guide_box.dialog_x = rx + cursor_pos_x + 1;
function_guide_box.dialog_y = ry + cursor_pos_y - 12;
function_guide_box.prompt = guide;
function_guide_box.index = amo;
} else
function_guide_box.active = false;
}
#endregion
}
if(auto_update && keyboard_check_pressed(vk_anykey))
apply();
@ -368,7 +444,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
_input_text = _last_value;
cut_line();
deactivate();
} else if(keyboard_check_pressed(vk_enter) && !key_mod_press(SHIFT)) {
} else if(keyboard_check_pressed(vk_enter) && key_mod_press(SHIFT)) {
deactivate();
}
}
@ -464,6 +540,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
y = _y;
w = _w;
h = _h;
_text = string_real(_text);
_current_text = _text;
@ -513,6 +590,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + hh);
if(self == WIDGET_CURRENT) {
WIDGET_TAB_BLOCK = true;
draw_set_text(font, fa_left, fa_top, COLORS._main_text);
draw_sprite_stretched_ext(THEME.textbox, 2, _x, _y, _w, hh, COLORS._main_accent, 1);
editText();
@ -521,12 +600,14 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
draw_set_text(font, fa_left, fa_top, COLORS._main_text);
#region draw cursor highlight
var char_run = 0, _l, _str;
var _l, _str;
var ch_x = tx;
var ch_y = _y + ui(7);
var ch_sel_min = -1;
var ch_sel_max = -1;
char_run = 0;
if(cursor_select != -1) {
ch_sel_min = min(cursor_select, cursor);
ch_sel_max = max(cursor_select, cursor);
@ -555,7 +636,7 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
}
}
if(char_run <= cursor && cursor <= char_run + _l) {
if(char_run <= cursor && cursor < char_run + _l) {
if(format == TEXT_AREA_FORMAT.delimiter) {
var str_cur = string_copy(_str, 1, cursor - char_run);
str_cur = string_replace_all(str_cur, " ", "<space>");
@ -564,7 +645,10 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
cursor_pos_x_to = ch_x + string_width(string_copy(_str, 1, cursor - char_run));
cursor_pos_y_to = ch_y;
cursor_line = i;
break;
}
char_run += _l;
ch_y += line_get_height();
}
@ -603,6 +687,8 @@ function textArea(_input, _onModify, _extras = noone) : textInput(_input, _onMod
draw_sprite_stretched_ext(THEME.textbox, 0, _x, _y, _w, hh, boxColor, 0.5 + 0.5 * interactable);
display_text(tx, _y + ui(7), _text, _w - ui(4));
autocomplete_box.active = 0;
}
if(DRAGGING && (DRAGGING.type == "Text" || DRAGGING.type == "Number") && hover && hoverRect) {

View file

@ -14,6 +14,9 @@ function widget() constructor {
w = 0;
h = 0;
rx = 0;
ry = 0;
static setLua = function(_lua_thread, _lua_key, _lua_func) {
lua_thread = _lua_thread;
lua_thread_key = _lua_key;