This commit is contained in:
Tanasart 2024-04-16 15:34:05 +07:00
parent 85c0ba395c
commit 79f6f5fb36
81 changed files with 10407 additions and 1296 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:48:07
// 2024-04-16 10:48:46
function canvas_tool() constructor {
node = noone;
@ -17,6 +17,12 @@ function canvas_tool() constructor {
subtool = 0;
function disable() {
PANEL_PREVIEW.tool_current = noone;
}
function getTool() { return self; }
function init() {}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {}

View file

@ -1,4 +1,4 @@
// 2024-04-14 10:20:09
// 2024-04-16 10:48:44
function canvas_tool() constructor {
node = noone;
@ -17,6 +17,12 @@ function canvas_tool() constructor {
subtool = 0;
function disable() {
PANEL_PREVIEW.tool_current = noone;
}
function getTool() { return self; }
function init() {}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {}

View file

@ -0,0 +1,162 @@
// 2024-04-16 09:39:26
function buttonPalette(_onApply, dialog = noone) : widget() constructor {
onApply = _onApply;
parentDialog = dialog;
current_palette = [];
side_button = noone;
function apply(value) { #region
if(!interactable) return;
onApply(value);
} #endregion
static trigger = function() { #region
var dialog = dialogCall(o_dialog_palette, WIN_W / 2, WIN_H / 2);
dialog.setDefault(current_palette);
dialog.onApply = apply;
dialog.interactable = interactable;
if(parentDialog)
parentDialog.addChildren(dialog);
} #endregion
static drawParam = function(params) { return draw(params.x, params.y, params.w, params.h, params.data, params.m); }
static draw = function(_x, _y, _w, _h, _color, _m) { #region
x = _x;
y = _y;
w = _w;
h = _h;
var _bs = min(_h, ui(32));
hovering = hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h);
if(_w - _bs > ui(100) && side_button && instanceof(side_button) == "buttonClass") {
side_button.setFocusHover(active, hover);
side_button.draw(_x + _w -_bs, _y + _h / 2 - _bs / 2, _bs, _bs, _m, THEME.button_hide);
_w -= _bs + ui(8);
}
var _pw = _w - ui(8);
var _ph = _h - ui(8);
current_palette = _color;
if(array_length(_color) > 0 && is_array(_color[0])) {
if(array_length(_color[0]) == 0) return 0;
h = ui(12) + array_length(_color) * _ph;
current_palette = _color[0];
} else {
h = _h;
}
if(!is_array(current_palette) || array_empty(current_palette) || is_array(current_palette[0]))
return 0;
var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + h);
if(ihover && hoverRect) {
draw_sprite_stretched(THEME.button_def, 1, _x, _y, _w, h);
if(mouse_press(mb_left, iactive))
trigger();
if(mouse_click(mb_left, iactive)) {
draw_sprite_stretched(THEME.button_def, 2, _x, _y, _w, h);
draw_sprite_stretched_ext(THEME.button_def, 3, _x, _y, _w, h, COLORS._main_accent, 1);
}
} else {
draw_sprite_stretched(THEME.button_def, 0, _x, _y, _w, h);
if(mouse_press(mb_left)) deactivate();
}
if(!is_array(_color[0])) _color = [ _color ];
for( var i = 0, n = array_length(_color); i < n; i++ ) {
var _pal = _color[i];
var _px = _x + ui(4);
var _py = _y + ui(4) + i * _ph;
if(is_array(_pal))
drawPalette(_pal, _px, _py, _pw, _ph);
}
if(WIDGET_CURRENT == self)
draw_sprite_stretched_ext(THEME.widget_selecting, 0, _x - ui(3), _y - ui(3), _w + ui(6), h + ui(6), COLORS._main_accent, 1);
if(DRAGGING && DRAGGING.type == "Palette" && hover && hoverRect) {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, _y, _w, h, COLORS._main_value_positive, 1);
if(mouse_release(mb_left))
onApply(DRAGGING.data);
}
resetFocus();
return h;
} #endregion
static clone = function() { #region
var cln = new buttonPalette(onApply, parentDialog);
return cln;
} #endregion
}
function drawPalette(_pal, _x, _y, _w, _h, _a = 1) { #region
var aa = array_length(_pal);
if(aa == 1) {
draw_sprite_stretched_ext(THEME.palette_mask, 1, _x, _y, _w, _h, _pal[0], _a);
return;
}
var ww = _w / aa;
var _x0 = _x;
var _in;
for(var i = 0; i < aa; i++) {
if(!is_numeric(_pal[i])) continue;
if(i == 0) _in = 2;
else if(i == aa - 1) _in = 3;
else _in = 0;
var _ca = _color_get_alpha(_pal[i]);
if(_ca == 1) {
draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h, _pal[i], _a);
} else {
draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h - ui(8), _pal[i], _a);
draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww), ui(6), c_black, _a);
draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww) * _ca, ui(6), c_white, _a);
}
_x0 += ww;
}
} #endregion
function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { #region
var amo = array_length(_pal);
var col = floor(_w / _gs);
var row = ceil(amo / col);
var cx = -1, cy = -1;
var _pd = ui(5);
for(var i = 0; i < array_length(_pal); i++) {
draw_set_color(_pal[i]);
var _x0 = _x + safe_mod(i, col) * _gs;
var _y0 = _y + floor(i / col) * _gs;
draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false);
if(c_color == _pal[i]) {
cx = _x0;
cy = _y0;
}
}
if(cx == -1) return;
draw_sprite_stretched_ext(THEME.palette_selecting, 0, cx - _pd, cy + 1 - _pd, _gs + _pd * 2, _gs + _pd * 2);
} #endregion

View file

@ -0,0 +1,162 @@
// 2024-04-16 09:39:25
function buttonPalette(_onApply, dialog = noone) : widget() constructor {
onApply = _onApply;
parentDialog = dialog;
current_palette = [];
side_button = noone;
function apply(value) { #region
if(!interactable) return;
onApply(value);
} #endregion
static trigger = function() { #region
var dialog = dialogCall(o_dialog_palette, WIN_W / 2, WIN_H / 2);
dialog.setDefault(current_palette);
dialog.onApply = apply;
dialog.interactable = interactable;
if(parentDialog)
parentDialog.addChildren(dialog);
} #endregion
static drawParam = function(params) { return draw(params.x, params.y, params.w, params.h, params.data, params.m); }
static draw = function(_x, _y, _w, _h, _color, _m) { #region
x = _x;
y = _y;
w = _w;
h = _h;
var _bs = min(_h, ui(32));
hovering = hover && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h);
if(_w - _bs > ui(100) && side_button && instanceof(side_button) == "buttonClass") {
side_button.setFocusHover(active, hover);
side_button.draw(_x + _w -_bs, _y + _h / 2 - _bs / 2, _bs, _bs, _m, THEME.button_hide);
_w -= _bs + ui(8);
}
var _pw = _w - ui(8);
var _ph = _h - ui(8);
current_palette = _color;
if(array_length(_color) > 0 && is_array(_color[0])) {
if(array_length(_color[0]) == 0) return 0;
h = ui(12) + array_length(_color) * _ph;
current_palette = _color[0];
} else {
h = _h;
}
if(!is_array(current_palette) || array_empty(current_palette) || is_array(current_palette[0]))
return 0;
var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + h);
if(ihover && hoverRect) {
draw_sprite_stretched(THEME.button_def, 1, _x, _y, _w, h);
if(mouse_press(mb_left, iactive))
trigger();
if(mouse_click(mb_left, iactive)) {
draw_sprite_stretched(THEME.button_def, 2, _x, _y, _w, h);
draw_sprite_stretched_ext(THEME.button_def, 3, _x, _y, _w, h, COLORS._main_accent, 1);
}
} else {
draw_sprite_stretched(THEME.button_def, 0, _x, _y, _w, h);
if(mouse_press(mb_left)) deactivate();
}
if(!is_array(_color[0])) _color = [ _color ];
for( var i = 0, n = array_length(_color); i < n; i++ ) {
var _pal = _color[i];
var _px = _x + ui(4);
var _py = _y + ui(4) + i * _ph;
if(is_array(_pal))
drawPalette(_pal, _px, _py, _pw, _ph);
}
if(WIDGET_CURRENT == self)
draw_sprite_stretched_ext(THEME.widget_selecting, 0, _x - ui(3), _y - ui(3), _w + ui(6), h + ui(6), COLORS._main_accent, 1);
if(DRAGGING && DRAGGING.type == "Palette" && hover && hoverRect) {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, _x, _y, _w, h, COLORS._main_value_positive, 1);
if(mouse_release(mb_left))
onApply(DRAGGING.data);
}
resetFocus();
return h;
} #endregion
static clone = function() { #region
var cln = new buttonPalette(onApply, parentDialog);
return cln;
} #endregion
}
function drawPalette(_pal, _x, _y, _w, _h, _a = 1) { #region
var aa = array_length(_pal);
if(aa == 1) {
draw_sprite_stretched_ext(THEME.palette_mask, 1, _x, _y, _w, _h, _pal[0], _a);
return;
}
var ww = _w / aa;
var _x0 = _x;
var _in;
for(var i = 0; i < aa; i++) {
if(!is_numeric(_pal[i])) continue;
if(i == 0) _in = 2;
else if(i == aa - 1) _in = 3;
else _in = 0;
var _ca = _color_get_alpha(_pal[i]);
if(_ca == 1) {
draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h, _pal[i], _a);
} else {
draw_sprite_stretched_ext(THEME.palette_mask, _in, floor(_x0), _y, ceil(ww), _h - ui(8), _pal[i], _a);
draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww), ui(6), c_black, _a);
draw_sprite_stretched_ext(THEME.palette_mask, 1, floor(_x0), _y + _h - ui(6), ceil(ww) * _ca, ui(6), c_white, _a);
}
_x0 += ww;
}
} #endregion
function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { #region
var amo = array_length(_pal);
var col = floor(_w / _gs);
var row = ceil(amo / col);
var cx = -1, cy = -1;
var _pd = ui(5);
for(var i = 0; i < array_length(_pal); i++) {
draw_set_color(_pal[i]);
var _x0 = _x + safe_mod(i, col) * _gs;
var _y0 = _y + floor(i / col) * _gs;
draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false);
if(c_color == _pal[i]) {
cx = _x0;
cy = _y0;
}
}
if(cx == -1) return;
draw_sprite_stretched_ext(THEME.palette_selecting, 0, cx - _pd, cy + 1 - _pd, _gs + _pd * 2, _gs + _pd * 2);
} #endregion

View file

@ -0,0 +1,191 @@
// 2024-04-15 17:50:18
function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region
if(brush.brush_surface == noone) {
if(brush.brush_size <= 1)
draw_point(_x, _y);
else if(brush.brush_size < global.FIX_POINTS_AMOUNT) {
var fx = global.FIX_POINTS[brush.brush_size];
for( var i = 0, n = array_length(fx); i < n; i++ )
draw_point(_x + fx[i][0], _y + fx[i][1]);
} else
draw_circle_prec(_x, _y, brush.brush_size / 2, 0);
} else {
var _sw = surface_get_width_safe(brush.brush_surface);
var _sh = surface_get_height_safe(brush.brush_surface);
var _r = brush.brush_direction + angle_random_eval(brush.brush_rand_dir, brush.brush_seed);
var _p = point_rotate(-_sw / 2, -_sh / 2, 0, 0, _r);
draw_surface_ext_safe(brush.brush_surface, _x + _p[0], _y + _p[1], 1, 1, _r, draw_get_color(), draw_get_alpha());
if(_draw) brush.brush_seed = irandom_range(100000, 999999);
}
} #endregion
function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false, _cap = false) { #region
if(brush.brush_surface == noone) {
if(brush.brush_size < global.FIX_POINTS_AMOUNT) {
if(_x1 > _x0) _x0--;
if(_y1 > _y0) _y0--;
if(_y1 < _y0) _y1--;
if(_x1 < _x0) _x1--;
}
if(brush.brush_size == 1) {
draw_line(_x0, _y0, _x1, _y1);
} else if(brush.brush_size < global.FIX_POINTS_AMOUNT) {
var fx = global.FIX_POINTS[brush.brush_size];
for( var i = 0, n = array_length(fx); i < n; i++ )
draw_line(_x0 + fx[i][0], _y0 + fx[i][1], _x1 + fx[i][0], _y1 + fx[i][1]);
} else {
draw_line_width(_x0, _y0, _x1, _y1, brush.brush_size);
if(_cap) {
canvas_draw_point_size(brush, _x0, _y0, true);
canvas_draw_point_size(brush, _x1, _y1, true);
}
}
} else {
var diss = point_distance(_x0, _y0, _x1, _y1);
var dirr = point_direction(_x0, _y0, _x1, _y1);
var st_x = lengthdir_x(1, dirr);
var st_y = lengthdir_y(1, dirr);
var _i = _draw? brush.brush_next_dist : 0;
var _dst = diss;
if(_i < diss) {
while(_i < diss) {
var _px = _x0 + st_x * _i;
var _py = _y0 + st_y * _i;
canvas_draw_point_size(brush, _px, _py, _draw);
brush.brush_next_dist = random_range(brush.brush_dist_min, brush.brush_dist_max);
_i += brush.brush_next_dist;
_dst -= brush.brush_next_dist;
}
brush.brush_next_dist -= _dst;
} else
brush.brush_next_dist -= diss;
if(brush.brush_dist_min == brush.brush_dist_max && brush.brush_dist_min == 1)
canvas_draw_point_size(brush, _x1, _y1, _draw);
}
} #endregion
function canvas_draw_rect_size(brush, _x0, _y0, _x1, _y1, _fill) { #region
if(_x0 == _x1 && _y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
return;
} else if(_x0 == _x1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x0, _y1);
return;
} else if(_y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x1, _y0);
return;
}
var _min_x = min(_x0, _x1);
var _max_x = max(_x0, _x1);
var _min_y = min(_y0, _y1);
var _may_y = max(_y0, _y1);
if(_fill) draw_rectangle(_min_x, _min_y, _max_x, _may_y, 0);
if(brush.brush_size == 1 && brush.brush_surface == noone)
draw_rectangle(_min_x + 1, _min_y + 1, _max_x - 1, _may_y - 1, 1);
else {
canvas_draw_line_size(brush, _min_x, _min_y, _max_x, _min_y);
canvas_draw_line_size(brush, _min_x, _min_y, _min_x, _may_y);
canvas_draw_line_size(brush, _max_x, _may_y, _max_x, _min_y);
canvas_draw_line_size(brush, _max_x, _may_y, _min_x, _may_y);
}
} #endregion
function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region
if(_x0 == _x1 && _y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
return;
} else if(_x0 == _x1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x0, _y1);
return;
} else if(_y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x1, _y0);
return;
}
var _min_x = min(_x0, _x1) - 1;
var _max_x = max(_x0, _x1);
var _min_y = min(_y0, _y1) - 1;
var _max_y = max(_y0, _y1);
if(_fill) {
draw_set_circle_precision(64);
draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0);
}
var samp = 64;
var cx = (_min_x + _max_x) / 2;
var cy = (_min_y + _max_y) / 2;
var rx = abs(_x0 - _x1) / 2;
var ry = abs(_y0 - _y1) / 2;
var ox, oy, nx, ny;
for( var i = 0; i <= samp; i++ ) {
nx = round(cx + lengthdir_x(rx, 360 / samp * i));
ny = round(cy + lengthdir_y(ry, 360 / samp * i));
if(i) canvas_draw_line_size(brush, ox, oy, nx, ny);
ox = nx;
oy = ny;
}
} #endregion
function canvas_draw_curve_brush(brush, x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region
var ox, oy, nx, ny;
var _st = 1 / prec;
for (var i = 0; i <= prec; i++) {
var _t = _st * i;
var _t1 = 1 - _t;
nx = _t1 * _t1 * _t1 * x0 +
3 * (_t1 * _t1 * _t) * cx0 +
3 * (_t1 * _t * _t) * cx1 +
_t * _t * _t * x1;
ny = _t1 * _t1 * _t1 * y0 +
3 * (_t1 * _t1 * _t) * cy0 +
3 * (_t1 * _t * _t) * cy1 +
_t * _t * _t * y1;
if(i) canvas_draw_line_size(brush, ox, oy, nx, ny, true, true);
ox = nx;
oy = ny;
}
} #endregion

View file

@ -0,0 +1,191 @@
// 2024-04-15 17:50:17
function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region
if(brush.brush_surface == noone) {
if(brush.brush_size <= 1)
draw_point(_x, _y);
else if(brush.brush_size < global.FIX_POINTS_AMOUNT) {
var fx = global.FIX_POINTS[brush.brush_size];
for( var i = 0, n = array_length(fx); i < n; i++ )
draw_point(_x + fx[i][0], _y + fx[i][1]);
} else
draw_circle_prec(_x, _y, brush.brush_size / 2, 0);
} else {
var _sw = surface_get_width_safe(brush.brush_surface);
var _sh = surface_get_height_safe(brush.brush_surface);
var _r = brush.brush_direction + angle_random_eval(brush.brush_rand_dir, brush.brush_seed);
var _p = point_rotate(-_sw / 2, -_sh / 2, 0, 0, _r);
draw_surface_ext_safe(brush.brush_surface, _x + _p[0], _y + _p[1], 1, 1, _r, draw_get_color(), draw_get_alpha());
if(_draw) brush.brush_seed = irandom_range(100000, 999999);
}
} #endregion
function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false, _cap = false) { #region
if(brush.brush_surface == noone) {
if(brush.brush_size < global.FIX_POINTS_AMOUNT) {
if(_x1 > _x0) _x0--;
if(_y1 > _y0) _y0--;
if(_y1 < _y0) _y1--;
if(_x1 < _x0) _x1--;
}
if(brush.brush_size == 1) {
draw_line(_x0, _y0, _x1, _y1);
} else if(brush.brush_size < global.FIX_POINTS_AMOUNT) {
var fx = global.FIX_POINTS[brush.brush_size];
for( var i = 0, n = array_length(fx); i < n; i++ )
draw_line(_x0 + fx[i][0], _y0 + fx[i][1], _x1 + fx[i][0], _y1 + fx[i][1]);
} else {
draw_line_width(_x0, _y0, _x1, _y1, brush.brush_size);
if(_cap) {
canvas_draw_point_size(brush, _x0, _y0, true);
canvas_draw_point_size(brush, _x1, _y1, true);
}
}
} else {
var diss = point_distance(_x0, _y0, _x1, _y1);
var dirr = point_direction(_x0, _y0, _x1, _y1);
var st_x = lengthdir_x(1, dirr);
var st_y = lengthdir_y(1, dirr);
var _i = _draw? brush.brush_next_dist : 0;
var _dst = diss;
if(_i < diss) {
while(_i < diss) {
var _px = _x0 + st_x * _i;
var _py = _y0 + st_y * _i;
canvas_draw_point_size(brush, _px, _py, _draw);
brush.brush_next_dist = random_range(brush.brush_dist_min, brush.brush_dist_max);
_i += brush.brush_next_dist;
_dst -= brush.brush_next_dist;
}
brush.brush_next_dist -= _dst;
} else
brush.brush_next_dist -= diss;
if(brush.brush_dist_min == brush.brush_dist_max && brush.brush_dist_min == 1)
canvas_draw_point_size(brush, _x1, _y1, _draw);
}
} #endregion
function canvas_draw_rect_size(brush, _x0, _y0, _x1, _y1, _fill) { #region
if(_x0 == _x1 && _y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
return;
} else if(_x0 == _x1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x0, _y1);
return;
} else if(_y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x1, _y0);
return;
}
var _min_x = min(_x0, _x1);
var _max_x = max(_x0, _x1);
var _min_y = min(_y0, _y1);
var _may_y = max(_y0, _y1);
if(_fill) draw_rectangle(_min_x, _min_y, _max_x, _may_y, 0);
if(brush.brush_size == 1 && brush.brush_surface == noone)
draw_rectangle(_min_x + 1, _min_y + 1, _max_x - 1, _may_y - 1, 1);
else {
canvas_draw_line_size(brush, _min_x, _min_y, _max_x, _min_y);
canvas_draw_line_size(brush, _min_x, _min_y, _min_x, _may_y);
canvas_draw_line_size(brush, _max_x, _may_y, _max_x, _min_y);
canvas_draw_line_size(brush, _max_x, _may_y, _min_x, _may_y);
}
} #endregion
function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region
if(_x0 == _x1 && _y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
return;
} else if(_x0 == _x1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x0, _y1);
return;
} else if(_y0 == _y1) {
canvas_draw_point_size(brush, _x0, _y0);
canvas_draw_point_size(brush, _x1, _y1);
canvas_draw_line_size(brush, _x0, _y0, _x1, _y0);
return;
}
var _min_x = min(_x0, _x1) - 1;
var _max_x = max(_x0, _x1);
var _min_y = min(_y0, _y1) - 1;
var _max_y = max(_y0, _y1);
if(_fill) {
draw_set_circle_precision(64);
draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0);
}
var samp = 64;
var cx = (_min_x + _max_x) / 2;
var cy = (_min_y + _max_y) / 2;
var rx = abs(_x0 - _x1) / 2;
var ry = abs(_y0 - _y1) / 2;
var ox, oy, nx, ny;
for( var i = 0; i <= samp; i++ ) {
nx = round(cx + lengthdir_x(rx, 360 / samp * i));
ny = round(cy + lengthdir_y(ry, 360 / samp * i));
if(i) canvas_draw_line_size(brush, ox, oy, nx, ny);
ox = nx;
oy = ny;
}
} #endregion
function canvas_draw_curve_brush(brush, x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region
var ox, oy, nx, ny;
var _st = 1 / prec;
for (var i = 0; i <= prec; i++) {
var _t = _st * i;
var _t1 = 1 - _t;
nx = _t1 * _t1 * _t1 * x0 +
3 * (_t1 * _t1 * _t) * cx0 +
3 * (_t1 * _t * _t) * cx1 +
_t * _t * _t * x1;
ny = _t1 * _t1 * _t1 * y0 +
3 * (_t1 * _t1 * _t) * cy0 +
3 * (_t1 * _t * _t) * cy1 +
_t * _t * _t * y1;
if(i) canvas_draw_line_size(brush, ox, oy, nx, ny, true, true);
ox = nx;
oy = ny;
}
} #endregion

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:50:50
// 2024-04-14 18:56:07
function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
self.brush = brush;
isEraser = eraser;
@ -28,7 +28,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
}
if(mouse_press(mb_left, active)) {
brush_next_dist = 0;
surface_set_shader(drawing_surface, noone);
canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y, true);
@ -37,7 +36,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
mouse_holding = true;
if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT)) { ///////////////// shift line
surface_set_shader(drawing_surface, noone, true, BLEND.alpha);
brush_next_dist = 0;
canvas_draw_line_size(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, true);
surface_reset_shader();
mouse_holding = false;

View file

@ -1,4 +1,4 @@
// 2024-04-14 10:04:07
// 2024-04-14 14:45:30
function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
self.brush = brush;
isEraser = eraser;

View file

@ -0,0 +1,75 @@
// 2024-04-16 10:15:33
enum CANVAS_TOOL_SHAPE {
rectangle,
ellipse
}
function canvas_tool_shape(brush, shape) : canvas_tool() constructor {
self.brush = brush;
self.shape = shape;
brush_resizable = true;
mouse_holding = false;
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
mouse_cur_x = round((_mx - _x) / _s - 0.5);
mouse_cur_y = round((_my - _y) / _s - 0.5);
if(mouse_holding && key_mod_press(SHIFT)) {
var ww = mouse_cur_x - mouse_pre_x;
var hh = mouse_cur_y - mouse_pre_y;
var ss = max(abs(ww), abs(hh));
mouse_cur_x = mouse_pre_x + ss * sign(ww);
mouse_cur_y = mouse_pre_y + ss * sign(hh);
}
if(mouse_holding) {
surface_set_shader(drawing_surface, noone);
if(shape == CANVAS_TOOL_SHAPE.rectangle)
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
else if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
surface_reset_shader();
if(mouse_release(mb_left)) {
apply_draw_surface();
mouse_holding = false;
}
} else if(mouse_press(mb_left, active)) {
mouse_pre_x = mouse_cur_x;
mouse_pre_y = mouse_cur_y;
mouse_holding = true;
node.tool_pick_color(mouse_cur_x, mouse_cur_y);
}
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(!mouse_holding) {
canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y);
return;
}
if(shape == CANVAS_TOOL_SHAPE.rectangle)
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
}
}

View file

@ -0,0 +1,75 @@
// 2024-04-16 10:15:33
enum CANVAS_TOOL_SHAPE {
rectangle,
ellipse
}
function canvas_tool_shape(brush, shape) : canvas_tool() constructor {
self.brush = brush;
self.shape = shape;
brush_resizable = true;
mouse_holding = false;
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
mouse_cur_x = round((_mx - _x) / _s - 0.5);
mouse_cur_y = round((_my - _y) / _s - 0.5);
if(mouse_holding && key_mod_press(SHIFT)) {
var ww = mouse_cur_x - mouse_pre_x;
var hh = mouse_cur_y - mouse_pre_y;
var ss = max(abs(ww), abs(hh));
mouse_cur_x = mouse_pre_x + ss * sign(ww);
mouse_cur_y = mouse_pre_y + ss * sign(hh);
}
if(mouse_holding) {
surface_set_shader(drawing_surface, noone);
if(shape == CANVAS_TOOL_SHAPE.rectangle)
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
else if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
surface_reset_shader();
if(mouse_release(mb_left)) {
apply_draw_surface();
mouse_holding = false;
}
} else if(mouse_press(mb_left, active)) {
mouse_pre_x = mouse_cur_x;
mouse_pre_y = mouse_cur_y;
mouse_holding = true;
node.tool_pick_color(mouse_cur_x, mouse_cur_y);
}
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(!mouse_holding) {
canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y);
return;
}
if(shape == CANVAS_TOOL_SHAPE.rectangle)
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
}
}

View file

@ -1,4 +1,185 @@
// 2024-04-14 12:31:27
function canvas_tool_curve() : canvas_tool() constructor {
// 2024-04-16 11:00:41
function canvas_tool_curve_bezier(brush) : canvas_tool() constructor {
self.brush = brush;
brush_resizable = true;
anchors = [];
mouse_cur_x = 0;
mouse_cur_y = 0;
editing = [ noone, 0 ];
mouse_edit_mx = 0;
mouse_edit_my = 0;
mouse_edit_sx = 0;
mouse_edit_sy = 0;
mouse_hovering = [ noone, 0 ];
draw_hovering = [];
function init() {
anchors = [];
editing = [ noone, 0 ];
}
function apply() {
apply_draw_surface();
disable();
}
function cancel() {
surface_clear(drawing_surface);
disable();
}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
mouse_cur_x = (_mx - _x) / _s;
mouse_cur_y = (_my - _y) / _s;
if(editing[0] != noone) {
var _a = anchors[editing[0]];
var _dx = mouse_cur_x - mouse_edit_mx;
var _dy = mouse_cur_y - mouse_edit_my;
if(editing[1] == 0) {
_a[2] += _dx;
_a[3] += _dy;
} else if(editing[1] == -1) {
_a[0] += _dx;
_a[1] += _dy;
_a[4] -= _dx;
_a[5] -= _dy;
} else if(editing[1] == 1) {
_a[0] -= _dx;
_a[1] -= _dy;
_a[4] += _dx;
_a[5] += _dy;
}
mouse_edit_mx = mouse_cur_x;
mouse_edit_my = mouse_cur_y;
if(mouse_release(mb_left))
editing[0] = noone;
}
if(mouse_press(mb_left, active)) {
if(mouse_hovering[0] == noone) {
array_push(anchors, [ 0, 0, mouse_cur_x, mouse_cur_y, 0, 0 ]);
editing[0] = array_length(anchors) - 1;
editing[1] = 1;
} else {
if(key_mod_press(SHIFT))
array_delete(anchors, mouse_hovering[0], 1);
else {
editing[0] = mouse_hovering[0];
editing[1] = mouse_hovering[1];
}
}
mouse_edit_mx = mouse_cur_x;
mouse_edit_my = mouse_cur_y;
mouse_edit_sx = mouse_cur_x;
mouse_edit_sy = mouse_cur_y;
}
surface_set_shader(drawing_surface, noone);
var ox, oy, nx, ny;
var oax1, oay1, nax0, nay0;
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = anchors[i][2];
ny = anchors[i][3];
nax0 = nx + anchors[i][0];
nay0 = ny + anchors[i][1];
if(i) canvas_draw_curve_brush(brush, ox, oy, oax1, oay1, nax0, nay0, nx, ny);
oax1 = nx + anchors[i][4];
oay1 = ny + anchors[i][5];
ox = nx;
oy = ny;
}
surface_reset_shader();
node.tool_curve_apply.setInteract(!array_empty(anchors));
node.tool_curve_cancel.setInteract(!array_empty(anchors));
if(key_press(vk_enter)) apply();
if(key_press(vk_escape)) disable();
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
draw_surface_ext_safe(drawing_surface, _x, _y, _s, _s);
}
function drawMask(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var ox, oy, nx, ny, ax0, ay0, ax1, ay1;
var oax1, oay1, nax0, nay0;
draw_set_color(c_white);
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = _x + anchors[i][2] * _s;
ny = _y + anchors[i][3] * _s;
nax0 = nx + anchors[i][0] * _s;
nay0 = ny + anchors[i][1] * _s;
if(i) draw_curve_bezier(ox, oy, oax1, oay1, nax0, nay0, nx, ny);
oax1 = nx + anchors[i][4] * _s;
oay1 = ny + anchors[i][5] * _s;
draw_line(nx, ny, nax0, nay0);
draw_line(nx, ny, oax1, oay1);
ox = nx;
oy = ny;
}
mouse_hovering = [ noone, 0 ];
draw_hovering = array_verify(draw_hovering, array_length(anchors) * 3);
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = _x + anchors[i][2] * _s;
ny = _y + anchors[i][3] * _s;
ax0 = nx + anchors[i][0] * _s;
ay0 = ny + anchors[i][1] * _s;
ax1 = nx + anchors[i][4] * _s;
ay1 = ny + anchors[i][5] * _s;
draw_anchor(0, nx, ny, lerp(10, 13, draw_hovering[i * 3 + 1]));
draw_anchor(0, ax0, ay0, lerp( 7, 10, draw_hovering[i * 3 + 0]));
draw_anchor(0, ax1, ay1, lerp( 7, 10, draw_hovering[i * 3 + 2]));
if(point_in_circle(_mx, _my, nx, ny, 10)) mouse_hovering = [ i, 0 ];
else if(point_in_circle(_mx, _my, ax0, ay0, 10)) mouse_hovering = [ i, -1 ];
else if(point_in_circle(_mx, _my, ax1, ay1, 10)) mouse_hovering = [ i, 1 ];
}
if(mouse_hovering[0] != noone) {
var index = mouse_hovering[0] * 3 + mouse_hovering[1] + 1;
for (var i = 0, n = array_length(draw_hovering); i < n; i++)
draw_hovering[i] = lerp_float(draw_hovering[i], i == index, 4);
}
}
}

View file

@ -1,4 +1,185 @@
// 2024-04-14 12:31:12
function canvas_tool_curve() : canvas_tool() constructor {
// 2024-04-16 11:00:38
function canvas_tool_curve_bezier(brush) : canvas_tool() constructor {
self.brush = brush;
brush_resizable = true;
anchors = [];
mouse_cur_x = 0;
mouse_cur_y = 0;
editing = [ noone, 0 ];
mouse_edit_mx = 0;
mouse_edit_my = 0;
mouse_edit_sx = 0;
mouse_edit_sy = 0;
mouse_hovering = [ noone, 0 ];
draw_hovering = [];
function init() {
anchors = [];
editing = [ noone, 0 ];
}
function apply() {
apply_draw_surface();
disable();
}
function cancel() {
surface_clear(drawing_surface);
disable();
}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
mouse_cur_x = (_mx - _x) / _s;
mouse_cur_y = (_my - _y) / _s;
if(editing[0] != noone) {
var _a = anchors[editing[0]];
var _dx = mouse_cur_x - mouse_edit_mx;
var _dy = mouse_cur_y - mouse_edit_my;
if(editing[1] == 0) {
_a[2] += _dx;
_a[3] += _dy;
} else if(editing[1] == -1) {
_a[0] += _dx;
_a[1] += _dy;
_a[4] -= _dx;
_a[5] -= _dy;
} else if(editing[1] == 1) {
_a[0] -= _dx;
_a[1] -= _dy;
_a[4] += _dx;
_a[5] += _dy;
}
mouse_edit_mx = mouse_cur_x;
mouse_edit_my = mouse_cur_y;
if(mouse_release(mb_left))
editing[0] = noone;
}
if(mouse_press(mb_left, active)) {
if(mouse_hovering[0] == noone) {
array_push(anchors, [ 0, 0, mouse_cur_x, mouse_cur_y, 0, 0 ]);
editing[0] = array_length(anchors) - 1;
editing[1] = 1;
} else {
if(key_mod_press(SHIFT))
array_delete(anchors, mouse_hovering[0], 1);
else {
editing[0] = mouse_hovering[0];
editing[1] = mouse_hovering[1];
}
}
mouse_edit_mx = mouse_cur_x;
mouse_edit_my = mouse_cur_y;
mouse_edit_sx = mouse_cur_x;
mouse_edit_sy = mouse_cur_y;
}
surface_set_shader(drawing_surface, noone);
var ox, oy, nx, ny;
var oax1, oay1, nax0, nay0;
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = anchors[i][2];
ny = anchors[i][3];
nax0 = nx + anchors[i][0];
nay0 = ny + anchors[i][1];
if(i) canvas_draw_curve_brush(brush, ox, oy, oax1, oay1, nax0, nay0, nx, ny);
oax1 = nx + anchors[i][4];
oay1 = ny + anchors[i][5];
ox = nx;
oy = ny;
}
surface_reset_shader();
node.tool_curve_apply.setInteract(!array_empty(anchors));
node.tool_curve_cancel.setInteract(!array_empty(anchors));
if(key_press(vk_enter)) apply();
if(key_press(vk_escape)) disable();
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
draw_surface_ext_safe(drawing_surface, _x, _y, _s, _s);
}
function drawMask(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var ox, oy, nx, ny, ax0, ay0, ax1, ay1;
var oax1, oay1, nax0, nay0;
draw_set_color(c_white);
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = _x + anchors[i][2] * _s;
ny = _y + anchors[i][3] * _s;
nax0 = nx + anchors[i][0] * _s;
nay0 = ny + anchors[i][1] * _s;
if(i) draw_curve_bezier(ox, oy, oax1, oay1, nax0, nay0, nx, ny);
oax1 = nx + anchors[i][4] * _s;
oay1 = ny + anchors[i][5] * _s;
draw_line(nx, ny, nax0, nay0);
draw_line(nx, ny, oax1, oay1);
ox = nx;
oy = ny;
}
mouse_hovering = [ noone, 0 ];
draw_hovering = array_verify(draw_hovering, array_length(anchors) * 3);
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = _x + anchors[i][2] * _s;
ny = _y + anchors[i][3] * _s;
ax0 = nx + anchors[i][0] * _s;
ay0 = ny + anchors[i][1] * _s;
ax1 = nx + anchors[i][4] * _s;
ay1 = ny + anchors[i][5] * _s;
draw_anchor(0, nx, ny, lerp(10, 13, draw_hovering[i * 3 + 1]));
draw_anchor(0, ax0, ay0, lerp( 7, 10, draw_hovering[i * 3 + 0]));
draw_anchor(0, ax1, ay1, lerp( 7, 10, draw_hovering[i * 3 + 2]));
if(point_in_circle(_mx, _my, nx, ny, 10)) mouse_hovering = [ i, 0 ];
else if(point_in_circle(_mx, _my, ax0, ay0, 10)) mouse_hovering = [ i, -1 ];
else if(point_in_circle(_mx, _my, ax1, ay1, 10)) mouse_hovering = [ i, 1 ];
}
if(mouse_hovering[0] != noone) {
var index = mouse_hovering[0] * 3 + mouse_hovering[1] + 1;
for (var i = 0, n = array_length(draw_hovering); i < n; i++)
draw_hovering[i] = lerp_float(draw_hovering[i], i == index, 4);
}
}
}

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:48:46
// 2024-04-16 15:02:26
function canvas_tool_node(canvas, node) : canvas_tool() constructor {
self.canvas = canvas;
@ -28,8 +28,15 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
if(applySelection) canvas.tool_selection.apply();
canvas.nodeTool = noone;
surface_free(targetSurface);
surface_free(maskedSurface);
surface_free_safe(maskedSurface);
cleanUp();
}
static cleanUp = function() {
surface_free_safe(targetSurface);
surface_free_safe(maskedSurface);
nodeObject.destroy();
}
nodeObject = node.build(0, 0);
@ -66,21 +73,41 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
////////////////////////////////////////////////////////////////////////////////////////////////////////
function apply() {
var _surf = surface_create(sw, sh);
if(applySelection) {
surface_set_shader(_surf, sh_blend_normal);
shader_set_surface("fore", maskedSurface);
shader_set_f("dimension", 1, 1);
shader_set_f("opacity", 1);
draw_surface(canvas.tool_selection.selection_surface, 0, 0);
surface_reset_shader();
surface_free(canvas.tool_selection.selection_surface);
canvas.tool_selection.selection_surface = maskedSurface;
canvas.tool_selection.selection_surface = _surf;
canvas.tool_selection.apply();
} else {
canvas.storeAction();
canvas.setCanvasSurface(maskedSurface);
surface_set_shader(_surf, sh_blend_normal);
shader_set_surface("fore", maskedSurface);
shader_set_f("dimension", 1, 1);
shader_set_f("opacity", 1);
draw_surface(canvas.getCanvasSurface(), 0, 0);
surface_reset_shader();
canvas.setCanvasSurface(_surf);
canvas.surface_store_buffer();
}
PANEL_PREVIEW.tool_current = noone;
canvas.nodeTool = noone;
surface_free_safe(targetSurface);
cleanUp();
}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
@ -110,7 +137,10 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
else if(inputJunction.name == "Dimension")
inputJunction.setValue([ sw, sh ]);
}
nodeObject.update();
if(is_instanceof(nodeObject, Node_Collection))
RenderList(nodeObject.nodes);
else
nodeObject.update();
var _surf = outputJunction.getValue();
@ -126,6 +156,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
} else
maskedSurface = _surf;
draw_surface_ext_safe(destiSurface, _dx, _dy, _s, _s);
draw_surface_ext_safe(maskedSurface, _dx, _dy, _s, _s);
if(mouse_press(mb_left, active)) { apply(); MOUSE_BLOCK = true; }

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:22:33
// 2024-04-16 15:02:19
function canvas_tool_node(canvas, node) : canvas_tool() constructor {
self.canvas = canvas;
@ -28,8 +28,15 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
if(applySelection) canvas.tool_selection.apply();
canvas.nodeTool = noone;
surface_free(targetSurface);
surface_free(maskedSurface);
surface_free_safe(maskedSurface);
cleanUp();
}
static cleanUp = function() {
surface_free_safe(targetSurface);
surface_free_safe(maskedSurface);
nodeObject.destroy();
}
nodeObject = node.build(0, 0);
@ -66,21 +73,41 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
////////////////////////////////////////////////////////////////////////////////////////////////////////
function apply() {
var _surf = surface_create(sw, sh);
if(applySelection) {
surface_set_shader(_surf, sh_blend_normal);
shader_set_surface("fore", maskedSurface);
shader_set_f("dimension", 1, 1);
shader_set_f("opacity", 1);
draw_surface(canvas.tool_selection.selection_surface, 0, 0);
surface_reset_shader();
surface_free(canvas.tool_selection.selection_surface);
canvas.tool_selection.selection_surface = maskedSurface;
canvas.tool_selection.selection_surface = _surf;
canvas.tool_selection.apply();
} else {
canvas.storeAction();
canvas.setCanvasSurface(maskedSurface);
surface_set_shader(_surf, sh_blend_normal);
shader_set_surface("fore", maskedSurface);
shader_set_f("dimension", 1, 1);
shader_set_f("opacity", 1);
draw_surface(canvas.getCanvasSurface(), 0, 0);
surface_reset_shader();
canvas.setCanvasSurface(_surf);
canvas.surface_store_buffer();
}
PANEL_PREVIEW.tool_current = noone;
canvas.nodeTool = noone;
surface_free_safe(targetSurface);
cleanUp();
}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
@ -110,7 +137,10 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
else if(inputJunction.name == "Dimension")
inputJunction.setValue([ sw, sh ]);
}
nodeObject.update();
if(is_instanceof(nodeObject, Node_Collection))
RenderList(nodeObject.nodes);
else
nodeObject.update();
var _surf = outputJunction.getValue();
@ -126,6 +156,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
} else
maskedSurface = _surf;
draw_surface_ext_safe(destiSurface, _dx, _dy, _s, _s);
draw_surface_ext_safe(maskedSurface, _dx, _dy, _s, _s);
if(mouse_press(mb_left, active)) { apply(); MOUSE_BLOCK = true; }

View file

@ -0,0 +1,9 @@
// 2024-04-16 09:50:49
function canvas_tool_outline_select() : canvas_tool() constructor {
override = true;
function init(node) {
PANEL_PREVIEW.tool_current = node.tools[1];
node.selection_tool_after = new canvas_tool_outline();
}
}

View file

@ -0,0 +1,9 @@
// 2024-04-16 09:50:30
function canvas_tool_outline_select() : canvas_tool() constructor {
override = true;
function init(node) {
PANEL_PREVIEW.tool_current = node.tools[1];
node.selection_tool_after = new canvas_tool_outline();
}
}

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:48:56
// 2024-04-14 17:59:42
function canvas_tool_resize() : canvas_tool() constructor {
override = true;

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:31:10
// 2024-04-14 12:48:56
function canvas_tool_resize() : canvas_tool() constructor {
override = true;

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:51:12
// 2024-04-15 19:18:42
function canvas_tool_selection(selector = noone) : canvas_tool() constructor {
self.selector = selector;
@ -23,8 +23,13 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor {
mouse_pre_y = 0;
function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region
if(is_selected)
apply();
else {
createNewSelection(_mask, sel_x0, sel_y0, sel_w, sel_h);
return;
}
if(key_mod_press(SHIFT))
modifySelection(_mask, sel_x0, sel_y0, sel_w, sel_h, true);

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:51:08
// 2024-04-15 19:18:37
function canvas_tool_selection(selector = noone) : canvas_tool() constructor {
self.selector = selector;
@ -23,8 +23,13 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor {
mouse_pre_y = 0;
function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region
if(is_selected)
apply();
else {
createNewSelection(_mask, sel_x0, sel_y0, sel_w, sel_h);
return;
}
if(key_mod_press(SHIFT))
modifySelection(_mask, sel_x0, sel_y0, sel_w, sel_h, true);

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:49:02
// 2024-04-16 09:27:06
function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(selector) constructor {
self.brush = brush;
@ -63,10 +63,10 @@ function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(se
sel_x1 = max(sel_x1, mouse_cur_x + brush.brush_size);
sel_y1 = max(sel_y1, mouse_cur_y + brush.brush_size);
if(mouse_release(mb_left)) {
var _sel_w = sel_x1 - sel_x0;
var _sel_h = sel_y1 - sel_y0;
var _sel_w = sel_x1 - sel_x0;
var _sel_h = sel_y1 - sel_y0;
if(mouse_release(mb_left)) {
var _sel = surface_create(_sel_w, _sel_h);
surface_set_shader(_sel);
draw_surface(selection_mask, -sel_x0, -sel_y0);

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:16:19
// 2024-04-16 07:47:35
function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(selector) constructor {
self.brush = brush;
@ -63,10 +63,12 @@ function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(se
sel_x1 = max(sel_x1, mouse_cur_x + brush.brush_size);
sel_y1 = max(sel_y1, mouse_cur_y + brush.brush_size);
if(mouse_release(mb_left)) {
var _sel_w = sel_x1 - sel_x0;
var _sel_h = sel_y1 - sel_y0;
var _sel_w = sel_x1 - sel_x0;
var _sel_h = sel_y1 - sel_y0;
PANEL_PREVIEW.mouse_pos_string = $"[{_sel_w}, {_sel_h}]";
if(mouse_release(mb_left)) {
var _sel = surface_create(_sel_w, _sel_h);
surface_set_shader(_sel);
draw_surface(selection_mask, -sel_x0, -sel_y0);

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:49:17
// 2024-04-16 10:03:25
function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor {
self.tool_attribute = toolAttr;
@ -54,6 +54,10 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
surface_free_safe(selection_mask);
if(node.selection_tool_after != noone)
node.selection_tool_after.toggle();
node.selection_tool_after = noone;
}
}
}

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:16:16
// 2024-04-16 10:03:18
function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor {
self.tool_attribute = toolAttr;
@ -54,6 +54,10 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
surface_free_safe(selection_mask);
if(node.selection_tool_after != noone)
node.selection_tool_after.toggle();
node.selection_tool_after = noone;
}
}
}

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:49:25
// 2024-04-16 09:29:46
function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(selector) constructor {
self.shape = shape;
@ -37,6 +37,8 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se
surface_reset_target();
PANEL_PREVIEW.mouse_pos_string = $"[{sel_w}, {sel_h}]";
if(mouse_release(mb_left)) {
is_selecting = false;
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:45:07
// 2024-04-16 09:29:45
function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(selector) constructor {
self.shape = shape;
@ -37,6 +37,8 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se
surface_reset_target();
PANEL_PREVIEW.mouse_pos_string = $"[{sel_w}, {sel_h}]";
if(mouse_release(mb_left)) {
is_selecting = false;
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
@ -52,4 +54,7 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se
}
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y);
}
}

View file

@ -0,0 +1,10 @@
// 2024-04-16 10:54:27
function canvas_tool_with_selector(tool) : canvas_tool() constructor {
self.tool = tool;
function init(node) {
node.selection_tool_after = tool;
}
function getTool() { return node.tool_sel_magic; }
}

View file

@ -0,0 +1,10 @@
// 2024-04-16 10:54:26
function canvas_tool_with_selector(tool) : canvas_tool() constructor {
self.tool = tool;
function init(node) {
node.selection_tool_after = tool;
}
function getTool() { return node.tool_sel_magic; }
}

View file

@ -0,0 +1,223 @@
// 2024-04-15 17:50:18
//curve format [-cx0, -cy0, x0, y0, +cx0, +cy0, -cx1, -cy1, x1, y1, +cx1, +cy1]
//segment format [y0, +cx0, +cy0, -cx1, -cy1, y1]
#macro CURVE_DEF_00 [0, 0, 0, 0, 1/3, 0, /**/ -1/3, 0, 1, 0, 0, 0]
#macro CURVE_DEF_01 [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0]
#macro CURVE_DEF_10 [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0]
#macro CURVE_DEF_11 [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0]
function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { #region
var segments = array_length(_bz) / 6 - 1;
for( var i = 0; i < segments; i++ ) {
var ind = i * 6;
var _x0 = _bz[ind + 2];
var _y0 = _bz[ind + 3];
//var bx0 = _x0 + _bz[ind + 0];
//var by0 = _y0 + _bz[ind + 1];
var ax0 = _x0 + _bz[ind + 4];
var ay0 = _y0 + _bz[ind + 5];
var _x1 = _bz[ind + 6 + 2];
var _y1 = _bz[ind + 6 + 3];
var bx1 = _x1 + _bz[ind + 6 + 0];
var by1 = _y1 + _bz[ind + 6 + 1];
//var ax1 = _x1 + _bz[ind + 6 + 4];
//var ay1 = _y1 + _bz[ind + 6 + 5];
var dx0 = x0 + _w * _x0;
var dx1 = x0 + _w * _x1;
var dw = dx1 - dx0;
var smp = ceil((_x1 - _x0) * 32);
draw_curve_segment(dx0, y0, dw, _h, [_y0, ax0, ay0, bx1, by1, _y1], smp, miny, maxy);
}
} #endregion
function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1) { #region
var _ox, _oy;
for(var i = 0; i <= SAMPLE; i++) {
var t = i / SAMPLE;
var _r = eval_curve_segment_t_position(t, _bz);
var _rx = _r[0], _ry = _r[1];
_ry = (_ry - miny) / (maxy - miny);
var _nx = _rx * _w + x0;
var _ny = (_h? _ry : 1 - _ry) * abs(_h) + y0;
if(i)
draw_line(_ox, _oy, _nx, _ny);
_ox = _nx;
_oy = _ny;
}
} #endregion
function eval_curve_segment_t_position(t, _bz) { #region
return [
power(1 - t, 3) * 0
+ 3 * power(1 - t, 2) * t * _bz[1]
+ 3 * (1 - t) * power(t, 2) * _bz[3]
+ power(t, 3) * 1,
power(1 - t, 3) * _bz[0]
+ 3 * power(1 - t, 2) * t * _bz[2]
+ 3 * (1 - t) * power(t, 2) * _bz[4]
+ power(t, 3) * _bz[5]
];
} #endregion
function eval_curve_segment_t(_bz, t) { #region
return power(1 - t, 3) * _bz[0]
+ 3 * power(1 - t, 2) * t * _bz[2]
+ 3 * (1 - t) * power(t, 2) * _bz[4]
+ power(t, 3) * _bz[5];
} #endregion
function eval_curve_x(_bz, _x, _tolr = 0.00001) { #region
static _CURVE_DEF_01 = [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0];
static _CURVE_DEF_10 = [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0];
static _CURVE_DEF_11 = [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0];
if(array_equals(_bz, _CURVE_DEF_11)) return 1;
if(array_equals(_bz, _CURVE_DEF_01)) return _x;
if(array_equals(_bz, _CURVE_DEF_10)) return 1 - _x;
var segments = array_length(_bz) / 6 - 1;
_x = clamp(_x, 0, 1);
for( var i = 0; i < segments; i++ ) {
var ind = i * 6;
var _x0 = _bz[ind + 2];
var _y0 = _bz[ind + 3];
//var bx0 = _x0 + _bz[ind + 0];
//var by0 = _y0 + _bz[ind + 1];
var ax0 = _x0 + _bz[ind + 4];
var ay0 = _y0 + _bz[ind + 5];
var _x1 = _bz[ind + 6 + 2];
var _y1 = _bz[ind + 6 + 3];
var bx1 = _x1 + _bz[ind + 6 + 0];
var by1 = _y1 + _bz[ind + 6 + 1];
//var ax1 = _x1 + _bz[ind + 6 + 4];
//var ay1 = _y1 + _bz[ind + 6 + 5];
if(_x < _x0) continue;
if(_x > _x1) continue;
return eval_curve_segment_x([_y0, ax0, ay0, bx1, by1, _y1], (_x - _x0) / (_x1 - _x0), _tolr);
}
return array_safe_get_fast(_bz, array_length(_bz) - 3);
} #endregion
function eval_curve_segment_x(_bz, _x, _tolr = 0.00001) { #region
var st = 0;
var ed = 1;
var _xt = _x;
var _binRep = 8;
if(_x <= 0) return _bz[0];
if(_x >= 1) return _bz[5];
if(_bz[0] == _bz[2] && _bz[0] == _bz[4] && _bz[0] == _bz[5]) return _bz[0];
repeat(_binRep) {
var _1xt = 1 - _xt;
var _ftx = 3 * _1xt * _1xt * _xt * _bz[1]
+ 3 * _1xt * _xt * _xt * _bz[3]
+ _xt * _xt * _xt;
if(abs(_ftx - _x) < _tolr)
return eval_curve_segment_t(_bz, _xt);
if(_xt < _x) st = _xt;
else ed = _xt;
_xt = (st + ed) / 2;
}
var _newRep = 8;
repeat(_newRep) {
var _bz1 = _bz[1];
var _bz3 = _bz[3];
var slope = ( 9 * _bz1 - 9 * _bz3 + 3) * _xt * _xt
+ (-12 * _bz1 + 6 * _bz3) * _xt
+ 3 * _bz1;
var _1xt = 1 - _xt;
var _ftx = 3 * _1xt * _1xt * _xt * _bz1
+ 3 * _1xt * _xt * _xt * _bz3
+ _xt * _xt * _xt
- _x;
_xt -= _ftx / slope;
if(abs(_ftx) < _tolr)
break;
}
_xt = clamp(_xt, 0, 1);
return eval_curve_segment_t(_bz, _xt);
} #endregion
function bezier_range(bz) { return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ]; }
function ease_cubic_in(rat) { return power(rat, 3); }
function ease_cubic_out(rat) { return 1 - power(1 - rat, 3); }
function ease_cubic_inout(rat) { return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2; }
function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor {
bz = _bz;
prec = _prec;
size = 1 / _prec;
tolr = _tolr;
map = array_create(_prec);
for( var i = 0; i < _prec; i++ )
map[i] = eval_curve_x(bz, i * size, tolr);
static get = function(i) { #region
INLINE
var _ind = clamp(i, 0, 1) * (prec - 1);
var _indL = floor(_ind);
var _indH = ceil(_ind);
var _indF = frac(_ind);
if(_indL == _indH) return map[_ind];
return lerp(map[_indL], map[_indH], _indF);
} #endregion
}
function draw_curve_bezier(x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region
var ox, oy, nx, ny;
var _st = 1 / prec;
for (var i = 0; i <= prec; i++) {
var _t = _st * i;
var _t1 = 1 - _t;
nx = _t1 * _t1 * _t1 * x0 +
3 * (_t1 * _t1 * _t) * cx0 +
3 * (_t1 * _t * _t) * cx1 +
_t * _t * _t * x1;
ny = _t1 * _t1 * _t1 * y0 +
3 * (_t1 * _t1 * _t) * cy0 +
3 * (_t1 * _t * _t) * cy1 +
_t * _t * _t * y1;
if(i) draw_line(ox, oy, nx, ny);
ox = nx;
oy = ny;
}
} #endregion

View file

@ -0,0 +1,223 @@
// 2024-04-15 17:50:17
//curve format [-cx0, -cy0, x0, y0, +cx0, +cy0, -cx1, -cy1, x1, y1, +cx1, +cy1]
//segment format [y0, +cx0, +cy0, -cx1, -cy1, y1]
#macro CURVE_DEF_00 [0, 0, 0, 0, 1/3, 0, /**/ -1/3, 0, 1, 0, 0, 0]
#macro CURVE_DEF_01 [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0]
#macro CURVE_DEF_10 [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0]
#macro CURVE_DEF_11 [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0]
function draw_curve(x0, y0, _w, _h, _bz, miny = 0, maxy = 1) { #region
var segments = array_length(_bz) / 6 - 1;
for( var i = 0; i < segments; i++ ) {
var ind = i * 6;
var _x0 = _bz[ind + 2];
var _y0 = _bz[ind + 3];
//var bx0 = _x0 + _bz[ind + 0];
//var by0 = _y0 + _bz[ind + 1];
var ax0 = _x0 + _bz[ind + 4];
var ay0 = _y0 + _bz[ind + 5];
var _x1 = _bz[ind + 6 + 2];
var _y1 = _bz[ind + 6 + 3];
var bx1 = _x1 + _bz[ind + 6 + 0];
var by1 = _y1 + _bz[ind + 6 + 1];
//var ax1 = _x1 + _bz[ind + 6 + 4];
//var ay1 = _y1 + _bz[ind + 6 + 5];
var dx0 = x0 + _w * _x0;
var dx1 = x0 + _w * _x1;
var dw = dx1 - dx0;
var smp = ceil((_x1 - _x0) * 32);
draw_curve_segment(dx0, y0, dw, _h, [_y0, ax0, ay0, bx1, by1, _y1], smp, miny, maxy);
}
} #endregion
function draw_curve_segment(x0, y0, _w, _h, _bz, SAMPLE = 32, miny = 0, maxy = 1) { #region
var _ox, _oy;
for(var i = 0; i <= SAMPLE; i++) {
var t = i / SAMPLE;
var _r = eval_curve_segment_t_position(t, _bz);
var _rx = _r[0], _ry = _r[1];
_ry = (_ry - miny) / (maxy - miny);
var _nx = _rx * _w + x0;
var _ny = (_h? _ry : 1 - _ry) * abs(_h) + y0;
if(i)
draw_line(_ox, _oy, _nx, _ny);
_ox = _nx;
_oy = _ny;
}
} #endregion
function eval_curve_segment_t_position(t, _bz) { #region
return [
power(1 - t, 3) * 0
+ 3 * power(1 - t, 2) * t * _bz[1]
+ 3 * (1 - t) * power(t, 2) * _bz[3]
+ power(t, 3) * 1,
power(1 - t, 3) * _bz[0]
+ 3 * power(1 - t, 2) * t * _bz[2]
+ 3 * (1 - t) * power(t, 2) * _bz[4]
+ power(t, 3) * _bz[5]
];
} #endregion
function eval_curve_segment_t(_bz, t) { #region
return power(1 - t, 3) * _bz[0]
+ 3 * power(1 - t, 2) * t * _bz[2]
+ 3 * (1 - t) * power(t, 2) * _bz[4]
+ power(t, 3) * _bz[5];
} #endregion
function eval_curve_x(_bz, _x, _tolr = 0.00001) { #region
static _CURVE_DEF_01 = [0, 0, 0, 0, 1/3, 1/3, /**/ -1/3, -1/3, 1, 1, 0, 0];
static _CURVE_DEF_10 = [0, 0, 0, 1, 1/3, -1/3, /**/ -1/3, 1/3, 1, 0, 0, 0];
static _CURVE_DEF_11 = [0, 0, 0, 1, 1/3, 0, /**/ -1/3, 0, 1, 1, 0, 0];
if(array_equals(_bz, _CURVE_DEF_11)) return 1;
if(array_equals(_bz, _CURVE_DEF_01)) return _x;
if(array_equals(_bz, _CURVE_DEF_10)) return 1 - _x;
var segments = array_length(_bz) / 6 - 1;
_x = clamp(_x, 0, 1);
for( var i = 0; i < segments; i++ ) {
var ind = i * 6;
var _x0 = _bz[ind + 2];
var _y0 = _bz[ind + 3];
//var bx0 = _x0 + _bz[ind + 0];
//var by0 = _y0 + _bz[ind + 1];
var ax0 = _x0 + _bz[ind + 4];
var ay0 = _y0 + _bz[ind + 5];
var _x1 = _bz[ind + 6 + 2];
var _y1 = _bz[ind + 6 + 3];
var bx1 = _x1 + _bz[ind + 6 + 0];
var by1 = _y1 + _bz[ind + 6 + 1];
//var ax1 = _x1 + _bz[ind + 6 + 4];
//var ay1 = _y1 + _bz[ind + 6 + 5];
if(_x < _x0) continue;
if(_x > _x1) continue;
return eval_curve_segment_x([_y0, ax0, ay0, bx1, by1, _y1], (_x - _x0) / (_x1 - _x0), _tolr);
}
return array_safe_get_fast(_bz, array_length(_bz) - 3);
} #endregion
function eval_curve_segment_x(_bz, _x, _tolr = 0.00001) { #region
var st = 0;
var ed = 1;
var _xt = _x;
var _binRep = 8;
if(_x <= 0) return _bz[0];
if(_x >= 1) return _bz[5];
if(_bz[0] == _bz[2] && _bz[0] == _bz[4] && _bz[0] == _bz[5]) return _bz[0];
repeat(_binRep) {
var _1xt = 1 - _xt;
var _ftx = 3 * _1xt * _1xt * _xt * _bz[1]
+ 3 * _1xt * _xt * _xt * _bz[3]
+ _xt * _xt * _xt;
if(abs(_ftx - _x) < _tolr)
return eval_curve_segment_t(_bz, _xt);
if(_xt < _x) st = _xt;
else ed = _xt;
_xt = (st + ed) / 2;
}
var _newRep = 8;
repeat(_newRep) {
var _bz1 = _bz[1];
var _bz3 = _bz[3];
var slope = ( 9 * _bz1 - 9 * _bz3 + 3) * _xt * _xt
+ (-12 * _bz1 + 6 * _bz3) * _xt
+ 3 * _bz1;
var _1xt = 1 - _xt;
var _ftx = 3 * _1xt * _1xt * _xt * _bz1
+ 3 * _1xt * _xt * _xt * _bz3
+ _xt * _xt * _xt
- _x;
_xt -= _ftx / slope;
if(abs(_ftx) < _tolr)
break;
}
_xt = clamp(_xt, 0, 1);
return eval_curve_segment_t(_bz, _xt);
} #endregion
function bezier_range(bz) { return [ min(bz[0], bz[2], bz[4], bz[5]), max(bz[0], bz[2], bz[4], bz[5]) ]; }
function ease_cubic_in(rat) { return power(rat, 3); }
function ease_cubic_out(rat) { return 1 - power(1 - rat, 3); }
function ease_cubic_inout(rat) { return rat < 0.5 ? 4 * power(rat, 3) : 1 - power(-2 * rat + 2, 3) / 2; }
function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor {
bz = _bz;
prec = _prec;
size = 1 / _prec;
tolr = _tolr;
map = array_create(_prec);
for( var i = 0; i < _prec; i++ )
map[i] = eval_curve_x(bz, i * size, tolr);
static get = function(i) { #region
INLINE
var _ind = clamp(i, 0, 1) * (prec - 1);
var _indL = floor(_ind);
var _indH = ceil(_ind);
var _indF = frac(_ind);
if(_indL == _indH) return map[_ind];
return lerp(map[_indL], map[_indH], _indF);
} #endregion
}
function draw_curve_bezier(x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region
var ox, oy, nx, ny;
var _st = 1 / prec;
for (var i = 0; i <= prec; i++) {
var _t = _st * i;
var _t1 = 1 - _t;
nx = _t1 * _t1 * _t1 * x0 +
3 * (_t1 * _t1 * _t) * cx0 +
3 * (_t1 * _t * _t) * cx1 +
_t * _t * _t * x1;
ny = _t1 * _t1 * _t1 * y0 +
3 * (_t1 * _t1 * _t) * cy0 +
3 * (_t1 * _t * _t) * cy1 +
_t * _t * _t * y1;
if(i) draw_line(ox, oy, nx, ny);
ox = nx;
oy = ny;
}
} #endregion

View file

@ -0,0 +1,60 @@
// 2024-04-16 14:58:31
globalvar BLEND_TYPES;
BLEND_TYPES = [
"Normal", "Add", "Subtract", "Multiply", "Screen",
"Overlay", "Hue", "Saturation", "Luminosity", "Maximum",
"Minimum", "Replace", "Difference"
];
function draw_surface_blend(background, foreground, blend = 0, alpha = 1, _pre_alp = true, _mask = 0, tile = 0) {
if(!is_surface(background)) return;
var sh = sh_blend_normal
switch(array_safe_get_fast(BLEND_TYPES, blend)) {
case "Normal" : sh = sh_blend_normal break;
case "Add" : sh = sh_blend_add; break;
case "Subtract" : sh = sh_blend_subtract; break;
case "Multiply" : sh = sh_blend_multiply; break;
case "Screen" : sh = sh_blend_screen; break;
case "Overlay" : sh = sh_blend_overlay; break;
case "Hue" : sh = sh_blend_hue; break;
case "Saturation" : sh = sh_blend_sat; break;
case "Luminosity" : sh = sh_blend_luma; break;
case "Maximum" : sh = sh_blend_max; break;
case "Minimum" : sh = sh_blend_min; break;
case "Replace" : sh = sh_blend_replace; break;
case "Difference" : sh = sh_blend_difference; break;
default: return;
}
var surf = surface_get_target();
var surf_w = surface_get_width_safe(surf);
var surf_h = surface_get_height_safe(surf);
if(is_surface(foreground)) {
shader_set(sh);
shader_set_surface("fore", foreground);
shader_set_surface("mask", _mask);
shader_set_i("useMask", is_surface(_mask));
shader_set_f("dimension", surface_get_width_safe(background) / surface_get_width_safe(foreground), surface_get_height_safe(background) / surface_get_height_safe(foreground));
shader_set_f("opacity", alpha);
shader_set_i("preserveAlpha", _pre_alp);
shader_set_i("tile_type", tile);
}
BLEND_OVERRIDE
draw_surface_stretched_safe(background, 0, 0, surf_w, surf_h);
BLEND_NORMAL
shader_reset();
}
function draw_surface_blend_ext(bg, fg, _x, _y, _sx = 1, _sy = 1, _rot = 0, _col = c_white, _alpha = 1, _blend = 0, _pre_alp = false) {
surface_set_shader(blend_temp_surface);
shader_set_interpolation(fg);
draw_surface_ext_safe(fg, _x, _y, _sx, _sy, _rot, _col, 1);
surface_reset_shader();
draw_surface_blend(bg, blend_temp_surface, _blend, _alpha, _pre_alp);
}

View file

@ -1,122 +1,56 @@
// 2023-08-07 09:56:48
// 2024-04-16 08:32:52
#region save
globalvar LOADING, APPENDING, CLONING, SAFE_MODE;
globalvar CONNECTION_CONFLICT, ALWAYS_FULL;
globalvar LOADING, CLONING, CLONING_GROUP;
globalvar CONNECTION_CONFLICT, LOADING_VERSION;
globalvar MESSAGE;
LOADING = false;
CLONING = false;
APPENDING = false;
SAFE_MODE = false;
globalvar APPENDING, APPEND_MAP, APPEND_LIST;
APPEND_MAP = ds_map_create();
APPEND_LIST = ds_list_create();
LOADING = false;
LOADING_VERSION = 0;
CLONING_GROUP = noone;
CLONING = false;
APPENDING = false;
MESSAGE = noone;
CONNECTION_CONFLICT = ds_queue_create();
randomize();
ALWAYS_FULL = false;
#endregion
#region project
function Project() constructor {
active = true; /// @is {bool}
path = ""; /// @is {string}
version = SAVE_VERSION; /// @is {number}
seed = irandom_range(100000, 999999); /// @is {number}
modified = false; /// @is {bool}
readonly = false; /// @is {bool}
nodes = ds_list_create();
nodeMap = ds_map_create();
nodeNameMap = ds_map_create();
animator = new AnimationManager();
globalNode = new Node_Global();
previewGrid = {
show : false,
snap : false,
width : 16,
height : 16,
opacity : 0.5,
color : COLORS.panel_preview_grid,
}
graphGrid = {
show : true,
snap : true,
size : 32,
opacity : 0.05,
color : c_white,
}
addons = {};
onion_skin = {
enabled: false,
range: [ -1, 1 ],
step: 1,
color: [ c_red, c_blue ],
alpha: 0.5,
on_top: true,
};
attributes = {
surface_dimension: [ 32, 32 ],
palette: [ c_black, c_white ]
}
attributeEditor = [
[ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; }) ],
[ "Palette", "palette", new buttonPalette(function(pal) { attributes.palette = pal; }) ],
]
static cleanup = function() {
if(!ds_map_empty(nodeMap))
array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { nodeMap[? _key].active = false; });
ds_list_destroy(nodes);
ds_map_destroy(nodeMap);
ds_map_destroy(nodeNameMap);
}
}
globalvar PROJECTS; /// @is {Project[]}
globalvar PROJECT; /// @is {Project}
gml_pragma("global", "__init()");
function __init() {
PROJECT = new Project();
PROJECTS = [ PROJECT ];
}
#endregion
#region main
#region ======================================================================= MAIN =======================================================================
globalvar OS, DEBUG, THEME, COLOR_KEYS;
OS = os_type;
//OS = os_macosx;
globalvar CMD, CMDIN;
globalvar FPS_REAL;
OS = os_type;
CMD = [];
CMDIN = [];
FPS_REAL = 0;
DEBUG = false;
THEME = new Theme();
COLOR_KEYS = [];
globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER;
globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION;
VERSION = 11484;
SAVE_VERSION = 11482;
VERSION_STRING = "1.15rc4";
BUILD_NUMBER = 11484;
globalvar APPEND_MAP;
APPEND_MAP = ds_map_create();
LATEST_VERSION = 11600;
VERSION = 11700;
SAVE_VERSION = 11690;
VERSION_STRING = "1.17.rc1";
BUILD_NUMBER = 11700;
globalvar HOTKEYS, HOTKEY_CONTEXT;
HOTKEYS = ds_map_create();
HOTKEY_CONTEXT = ds_list_create();
HOTKEY_CONTEXT[| 0] = "";
globalvar CURSOR, TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER;
globalvar UPDATE, RENDER_QUEUE;
globalvar TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER;
global.KEYS = {
download_links: "",
};
#endregion
#region inputs
@ -126,37 +60,48 @@
DOUBLE_CLICK_POS = [ 0, 0 ];
DOUBLE_CLICK = false;
FOCUS = noone;
FOCUS = noone;
FOCUS_STR = "";
HOVER = noone;
HOVER = noone;
HOVERING_ELEMENT = noone;
_HOVERING_ELEMENT = noone;
DIALOG_CLICK = true;
globalvar ADD_NODE_PAGE;
ADD_NODE_PAGE = 0;
globalvar ADD_NODE_PAGE, ADD_NODE_SCROLL;
ADD_NODE_PAGE = 0;
ADD_NODE_SCROLL = 0;
#endregion
#region macro
#macro TEMPDIR filepath_resolve(PREFERENCES.temp_path)
#macro NOT_LOAD !LOADING && !APPENDING
#macro WIN_W window_get_width()
#macro WIN_H window_get_height()
#macro WIN_SW window_get_width()
#macro WIN_SH window_get_height()
#macro UI_SCALE PREF_MAP[? "display_scaling"]
#macro UI_SCALE PREFERENCES.display_scaling
#macro mouse_mx device_mouse_x_to_gui(0)
#macro mouse_my device_mouse_y_to_gui(0)
#macro mouse_mx (PEN_USE? PEN_X : device_mouse_x_to_gui(0))
#macro mouse_my (PEN_USE? PEN_Y : device_mouse_y_to_gui(0))
#macro mouse_raw_x (device_mouse_raw_x(0) + window_get_x())
#macro mouse_raw_y (device_mouse_raw_y(0) + window_get_y())
#macro mouse_ui [device_mouse_x_to_gui(0), device_mouse_y_to_gui(0)]
#macro sFOCUS FOCUS == self.id
#macro sHOVER HOVER == self.id
#macro sFOCUS (FOCUS == self.id)
#macro sHOVER (!CURSOR_IS_LOCK && HOVER == self.id)
#macro DELTA_TIME delta_time / 1_000_000
#macro INLINE gml_pragma("forceinline");
#macro CONF_TESTING false
globalvar TESTING, TEST_ERROR;
TESTING = CONF_TESTING;
@ -165,10 +110,6 @@
#macro DEMO false
#macro ItchDemo:DEMO true
#macro SteamDemo:DEMO true
#macro MacAlpha:DEMO true
#macro ALPHA false
#macro MacAlpha:ALPHA true
#region color
#macro c_ui_blue_dkblack $251919
@ -202,22 +143,20 @@
#macro PANEL_PAD THEME_VALUE.panel_padding
function print(str) {
//show_debug_message(string(str));
INLINE
noti_status(string(str));
}
function printIf(cond, log) {
if(!cond) return;
show_debug_message(log);
INLINE
if(cond) print(log);
}
#endregion
#region presets
function INIT_FOLDERS() {
if(!directory_exists(DIRECTORY + "Palettes"))
directory_create(DIRECTORY + "Palettes");
if(!directory_exists(DIRECTORY + "Gradients"))
directory_create(DIRECTORY + "Gradients");
directory_verify(DIRECTORY + "Palettes");
directory_verify(DIRECTORY + "Gradients");
}
#endregion
@ -237,10 +176,33 @@
DEF_SURFACE_RESET();
#endregion
#region PATCH
#macro PATCH_STATIC static _doUpdate = function() { doUpdate() };
#region functions
function __fnInit_Global() {
__registerFunction("fullscreen", global_fullscreen);
__registerFunction("render_all", global_render_all);
__registerFunction("project_close", global_project_close);
__registerFunction("theme_reload", global_theme_reload);
}
function global_fullscreen() { CALL("fullscreen"); winMan_setFullscreen(!window_is_fullscreen); }
function global_render_all() { CALL("render_all"); RENDER_ALL_REORDER }
function global_project_close() { CALL("project_close"); PANEL_GRAPH.close(); }
function global_theme_reload() { CALL("theme_reload"); loadGraphic(PREFERENCES.theme); resetPanel(); }
function reset_global_getset() {
COLORS_GLOBAL_GET = noone;
COLORS_GLOBAL_SET = noone;
}
#endregion
#region debug
global.FLAG = {};
global.FLAG.render = 0;
global.FLAG.renderTime = false;
global.FLAG.keyframe_override = true;
global.FLAG.wav_import = true;
global.FLAG.ase_import = false;
#endregion

View file

@ -1,122 +1,56 @@
// 2023-08-07 09:55:37
// 2024-04-15 17:50:18
#region save
globalvar LOADING, APPENDING, CLONING, SAFE_MODE;
globalvar CONNECTION_CONFLICT, ALWAYS_FULL;
globalvar LOADING, CLONING, CLONING_GROUP;
globalvar CONNECTION_CONFLICT, LOADING_VERSION;
globalvar MESSAGE;
LOADING = false;
CLONING = false;
APPENDING = false;
SAFE_MODE = false;
globalvar APPENDING, APPEND_MAP, APPEND_LIST;
APPEND_MAP = ds_map_create();
APPEND_LIST = ds_list_create();
LOADING = false;
LOADING_VERSION = 0;
CLONING_GROUP = noone;
CLONING = false;
APPENDING = false;
MESSAGE = noone;
CONNECTION_CONFLICT = ds_queue_create();
randomize();
ALWAYS_FULL = false;
#endregion
#region project
function Project() constructor {
active = true; /// @is {bool}
path = ""; /// @is {string}
version = SAVE_VERSION; /// @is {number}
seed = irandom_range(100000, 999999); /// @is {number}
modified = false; /// @is {bool}
readonly = false; /// @is {bool}
nodes = ds_list_create();
nodeMap = ds_map_create();
nodeNameMap = ds_map_create();
animator = new AnimationManager();
globalNode = new Node_Global();
previewGrid = {
show : false,
snap : false,
width : 16,
height : 16,
opacity : 0.5,
color : COLORS.panel_preview_grid,
}
graphGrid = {
show : true,
snap : true,
size : 32,
opacity : 0.05,
color : c_white,
}
addons = {};
onion_skin = {
enabled: false,
range: [ -1, 1 ],
step: 1,
color: [ c_red, c_blue ],
alpha: 0.5,
on_top: true,
};
attributes = {
surface_dimension: [ 32, 32 ],
palette: [ c_black, c_white ]
}
attributeEditor = [
[ "Default Surface", "surface_dimension", new vectorBox(2, function(ind, val) { attributes.surface_dimension[ind] = val; }) ],
[ "Palette", "palette", new buttonPalette(function(pal) { attributes.palette = pal; }) ],
]
static cleanup = function() {
if(!ds_map_empty(nodeMap))
array_map(ds_map_keys_to_array(nodeMap), function(_key, _ind) { nodeMap[? _key].active = false; });
ds_list_destroy(nodes);
ds_map_destroy(nodeMap);
ds_map_destroy(nodeNameMap);
}
}
globalvar PROJECTS; /// @is {Project[]}
globalvar PROJECT; /// @is {Project}
gml_pragma("global", "__init()");
function __init() {
PROJECT = new Project();
PROJECTS = [ PROJECT ];
}
#endregion
#region main
#region ======================================================================= MAIN =======================================================================
globalvar OS, DEBUG, THEME, COLOR_KEYS;
OS = os_type;
//OS = os_macosx;
globalvar CMD, CMDIN;
globalvar FPS_REAL;
OS = os_type;
CMD = [];
CMDIN = [];
FPS_REAL = 0;
DEBUG = false;
THEME = new Theme();
COLOR_KEYS = [];
globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER;
globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION;
VERSION = 11484;
SAVE_VERSION = 11482;
VERSION_STRING = "1.15rc4";
BUILD_NUMBER = 11484;
globalvar APPEND_MAP;
APPEND_MAP = ds_map_create();
LATEST_VERSION = 11600;
VERSION = 11700;
SAVE_VERSION = 11690;
VERSION_STRING = "1.17.rc1";
BUILD_NUMBER = 11700;
globalvar HOTKEYS, HOTKEY_CONTEXT;
HOTKEYS = ds_map_create();
HOTKEY_CONTEXT = ds_list_create();
HOTKEY_CONTEXT[| 0] = "";
globalvar CURSOR, TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER;
globalvar UPDATE, RENDER_QUEUE;
globalvar TOOLTIP, DRAGGING, DIALOG_DEPTH_HOVER;
global.KEYS = {
download_links: "",
};
#endregion
#region inputs
@ -126,37 +60,48 @@
DOUBLE_CLICK_POS = [ 0, 0 ];
DOUBLE_CLICK = false;
FOCUS = noone;
FOCUS = noone;
FOCUS_STR = "";
HOVER = noone;
HOVER = noone;
HOVERING_ELEMENT = noone;
_HOVERING_ELEMENT = noone;
DIALOG_CLICK = true;
globalvar ADD_NODE_PAGE;
ADD_NODE_PAGE = 0;
globalvar ADD_NODE_PAGE, ADD_NODE_SCROLL;
ADD_NODE_PAGE = 0;
ADD_NODE_SCROLL = 0;
#endregion
#region macro
#macro TEMPDIR filepath_resolve(PREFERENCES.temp_path)
#macro NOT_LOAD !LOADING && !APPENDING
#macro WIN_W window_get_width()
#macro WIN_H window_get_height()
#macro WIN_SW window_get_width()
#macro WIN_SH window_get_height()
#macro UI_SCALE PREF_MAP[? "display_scaling"]
#macro UI_SCALE PREFERENCES.display_scaling
#macro mouse_mx device_mouse_x_to_gui(0)
#macro mouse_my device_mouse_y_to_gui(0)
#macro mouse_mx (PEN_USE? PEN_X : device_mouse_x_to_gui(0))
#macro mouse_my (PEN_USE? PEN_Y : device_mouse_y_to_gui(0))
#macro mouse_raw_x (device_mouse_raw_x(0) + window_get_x())
#macro mouse_raw_y (device_mouse_raw_y(0) + window_get_y())
#macro mouse_ui [device_mouse_x_to_gui(0), device_mouse_y_to_gui(0)]
#macro sFOCUS FOCUS == self.id
#macro sHOVER HOVER == self.id
#macro sFOCUS (FOCUS == self.id)
#macro sHOVER (!CURSOR_IS_LOCK && HOVER == self.id)
#macro DELTA_TIME delta_time / 1_000_000
#macro INLINE gml_pragma("forceinline");
#macro CONF_TESTING false
globalvar TESTING, TEST_ERROR;
TESTING = CONF_TESTING;
@ -165,10 +110,6 @@
#macro DEMO false
#macro ItchDemo:DEMO true
#macro SteamDemo:DEMO true
#macro MacAlpha:DEMO true
#macro ALPHA false
#macro MacAlpha:ALPHA true
#region color
#macro c_ui_blue_dkblack $251919
@ -202,22 +143,20 @@
#macro PANEL_PAD THEME_VALUE.panel_padding
function print(str) {
//show_debug_message(string(str));
INLINE
noti_status(string(str));
}
function printIf(cond, log) {
if(!cond) return;
show_debug_message(log);
INLINE
if(cond) print(log);
}
#endregion
#region presets
function INIT_FOLDERS() {
if(!directory_exists(DIRECTORY + "Palettes"))
directory_create(DIRECTORY + "Palettes");
if(!directory_exists(DIRECTORY + "Gradients"))
directory_create(DIRECTORY + "Gradients");
directory_verify(DIRECTORY + "Palettes");
directory_verify(DIRECTORY + "Gradients");
}
#endregion
@ -237,10 +176,33 @@
DEF_SURFACE_RESET();
#endregion
#region PATCH
#macro PATCH_STATIC static _doUpdate = function() { doUpdate() };
#region functions
function __fnInit_Global() {
__registerFunction("fullscreen", global_fullscreen);
__registerFunction("render_all", global_render_all);
__registerFunction("project_close", global_project_close);
__registerFunction("theme_reload", global_theme_reload);
}
function global_fullscreen() { CALL("fullscreen"); winMan_setFullscreen(!window_is_fullscreen); }
function global_render_all() { CALL("render_all"); RENDER_ALL_REORDER }
function global_project_close() { CALL("project_close"); PANEL_GRAPH.close(); }
function global_theme_reload() { CALL("theme_reload"); loadGraphic(PREFERENCES.theme); resetPanel(); }
function reset_global_getset() {
COLORS_GLOBAL_GET = noone;
COLORS_GLOBAL_SET = noone;
}
#endregion
#region debug
global.FLAG = {};
global.FLAG.render = 0;
global.FLAG.renderTime = false;
global.FLAG.keyframe_override = true;
global.FLAG.wav_import = true;
global.FLAG.ase_import = false;
#endregion

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:59:25
// 2024-04-16 14:17:00
function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "Canvas";
color = COLORS.node_blend_canvas;
@ -54,7 +54,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
frame_renderer_x_max = 0;
frame_renderer_content = surface_create(1, 1);
frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region
frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region frame_renderer
var _h = 64;
_y += 8;
@ -183,7 +183,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
preview_draw_mask = surface_create_empty(1, 1);
draw_stack = ds_list_create();
brush = new canvas_brush();
#endregion
#region ++++ tool object ++++
brush = new canvas_brush();
tool_selection = new canvas_tool_selection();
tool_brush = new canvas_tool_brush(brush, false);
tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush);
tool_curve_bez = new canvas_tool_curve_bezier(brush);
tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle);
tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse);
tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush);
tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute);
tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush);
#endregion
@ -197,7 +217,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_attribute.pickColor = c_white;
tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; });
tool_attribute.mirror = [ false, false ];
tool_attribute.mirror = [ false, false, false ];
tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; });
tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ],
@ -223,48 +243,52 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_fil8_edit = new checkBox(function() { tool_attribute.fill8 = !tool_attribute.fill8; });
tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ];
tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]),
tool_attribute.button_apply = [ false, false ];
tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0);
tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1);
new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
.setSetting(tool_thrs)
.setSetting(tool_fil8),
.setSetting(tool_fil8)
.setToolObject(tool_sel_magic)
tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ])
.setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]),
toolObject_selection_magic,
new NodeTool( "Pencil", THEME.canvas_tools_pencil)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_brush),
new NodeTool( "Eraser", THEME.canvas_tools_eraser)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_eraser),
new NodeTool( "Rectangle", [ THEME.canvas_tools_rect, THEME.canvas_tools_rect_fill ])
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_rectangle),
new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ])
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_ellipse),
new NodeTool( "Curve", THEME.canvas_tool_curve_icon)
.setSetting(tool_size)
.setSetting([ "", tool_curve_apply, 0, tool_attribute ])
.setSetting([ "", tool_curve_cancel, 0, tool_attribute ])
.setToolObject(tool_curve_bez),
new NodeTool( "Freeform", THEME.canvas_tools_freeform)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_freeform),
new NodeTool( "Fill", THEME.canvas_tools_bucket)
.setSetting(tool_thrs)
.setSetting(tool_fil8),
.setSetting(tool_fil8)
.setToolObject(tool_fill),
];
tool_selection = new canvas_tool_selection();
tool_brush = new canvas_tool_brush(brush, false);
tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush);
tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle);
tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse);
tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush);
tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute);
tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush);
#endregion
#region ++++ right tools ++++
@ -314,9 +338,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
new NodeTool( "Make/Reset Brush", THEME.canvas_tools_pencil ).setToolFn( __action_make_brush ),
-1,
new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ),
new NodeTool( [ "Extrude", "Inset" ],
[ THEME.canvas_tools_extrude, THEME.canvas_tools_inset ] )
.setToolObject( [ new canvas_tool_extrude(), new canvas_tool_inset() ] ),
new NodeTool( "Extrude", THEME.canvas_tools_extrude ).setToolObject( new canvas_tool_extrude() ),
new NodeTool( "Inset", THEME.canvas_tools_inset ).setToolObject( new canvas_tool_inset() ),
];
rightTools_not_selection = [
-1,
new NodeTool( "Outline", THEME.canvas_tools_outline, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[3]) ),
new NodeTool( "Extrude", THEME.canvas_tools_extrude, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[4]) ),
new NodeTool( "Inset", THEME.canvas_tools_inset, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[5]) ),
];
rightTools_brush = [
@ -330,6 +360,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_eraser.rightTools = rightTools_brush;
tool_rectangle.rightTools = rightTools_brush;
tool_ellipse.rightTools = rightTools_brush;
selection_tool_after = noone;
#endregion
function setToolColor(color) { tool_attribute.color = color; }
@ -391,7 +423,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
return hh + ui(4);
} #endregion
function removeFrame(index = 0) { #region
static removeFrame = function(index = 0) { #region
if(attributes.frames <= 1) return;
if(preview_index == attributes.frames)
@ -403,7 +435,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
update();
} #endregion
function refreshFrames() { #region
static refreshFrames = function() { #region
var fr = attributes.frames;
var _dim = attributes.dimension;
@ -429,7 +461,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
function setCanvasSurface(surface, index = preview_index) { INLINE canvas_surface[index] = surface; }
function storeAction() { #region
static storeAction = function() { #region
var action = recordAction(ACTION_TYPE.custom, function(data) {
is_selected = false;
@ -447,7 +479,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
action.clear_action = function(data) { surface_free_safe(data.surface); };
} #endregion
function apply_surfaces() { #region
static apply_surfaces = function() { #region
for( var i = 0; i < attributes.frames; i++ )
apply_surface(i);
} #endregion
@ -502,7 +534,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
apply_surface(index);
} #endregion
function tool_pick_color(_x, _y) { #region
static tool_pick_color = function(_x, _y) { #region
if(tool_selection.is_selected)
tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]);
else
@ -532,9 +564,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
BLEND_ALPHA
if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1);
BLEND_NORMAL
@ -554,11 +586,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_surface(drawing_surface, 0, 0);
BLEND_ALPHA
if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1);
if(tool_attribute.mirror[0] == false) {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1);
} else {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, 1, -90);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, 0, -1, 1, 90);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], 1, 1, 180);
}
BLEND_NORMAL
surface_reset_target();
@ -642,6 +678,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
array_append(rightTools, rightTools_general);
if(tool_selection.is_selected) array_append(rightTools, rightTools_selection);
else array_append(rightTools, rightTools_not_selection);
if(nodeTool != noone)
_tool = nodeTool;
@ -649,37 +686,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
else if(_currTool != noone) {
_tool = _currTool.getToolObject();
switch(_currTool.getName()) {
case "Pencil" : _tool = tool_brush; break;
case "Eraser" : _tool = tool_eraser; break;
case "Fill" : _tool = tool_fill; break;
case "Freeform" : _tool = tool_freeform; break;
case "Rectangle" :
_tool = tool_rectangle;
_tool.fill = _currTool.selecting == 1;
break;
case "Ellipse" :
_tool = tool_ellipse;
_tool.fill = _currTool.selecting == 1;
break;
case "Selection" :
switch(_currTool.selecting) {
case 0 : _tool = tool_sel_rectangle; break;
case 1 : _tool = tool_sel_ellipse; break;
case 2 : _tool = tool_sel_freeform; break;
case 3 : _tool = tool_sel_brush; break;
}
break;
case "Magic Selection" : _tool = tool_sel_magic; break;
}
if(_tool) {
_tool.node = self;
_tool = _tool.getTool();
_tool.subtool = _currTool.selecting;
array_append(rightTools, _tool.rightTools);
}
@ -690,6 +699,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_selection.apply_draw_surface = apply_draw_surface;
if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
tool_mirror_edit.sprs = (!tool_selection.is_selected && tool_attribute.mirror[0])? THEME.canvas_mirror_diag : THEME.canvas_mirror;
}
if(_tool && _tool.override) {
@ -771,14 +782,20 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
var _spw = tool_selection.selection_size[0];
var _sph = tool_selection.selection_size[1];
if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1);
} else {
if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1);
if(tool_attribute.mirror[0] == false) {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1);
} else {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, 1, -90);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, 0, -1, 1, 90);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], 1, 1, 180);
}
}
draw_set_color(tool_attribute.color);
@ -786,7 +803,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
canvas_draw_point_size(brush, brush.brush_sizing_dx, brush.brush_sizing_dy);
else if(_tool)
_tool.drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
surface_reset_shader();
draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp);

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:58:03
// 2024-04-16 14:16:53
function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "Canvas";
color = COLORS.node_blend_canvas;
@ -54,7 +54,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
frame_renderer_x_max = 0;
frame_renderer_content = surface_create(1, 1);
frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region
frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region frame_renderer
var _h = 64;
_y += 8;
@ -183,7 +183,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
preview_draw_mask = surface_create_empty(1, 1);
draw_stack = ds_list_create();
brush = new canvas_brush();
#endregion
#region ++++ tool object ++++
brush = new canvas_brush();
tool_selection = new canvas_tool_selection();
tool_brush = new canvas_tool_brush(brush, false);
tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush);
tool_curve_bez = new canvas_tool_curve_bezier(brush);
tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle);
tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse);
tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush);
tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute);
tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush);
#endregion
@ -197,7 +217,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_attribute.pickColor = c_white;
tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; });
tool_attribute.mirror = [ false, false ];
tool_attribute.mirror = [ false, false, false ];
tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; });
tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ],
@ -223,48 +243,52 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_fil8_edit = new checkBox(function() { tool_attribute.fill8 = !tool_attribute.fill8; });
tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ];
tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]),
tool_attribute.button_apply = [ false, false ];
tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0);
tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1);
new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
.setSetting(tool_thrs)
.setSetting(tool_fil8),
.setSetting(tool_fil8)
.setToolObject(tool_sel_magic)
tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ])
.setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]),
toolObject_selection_magic,
new NodeTool( "Pencil", THEME.canvas_tools_pencil)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_brush),
new NodeTool( "Eraser", THEME.canvas_tools_eraser)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_eraser),
new NodeTool( "Rectangle", [ THEME.canvas_tools_rect, THEME.canvas_tools_rect_fill ])
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_rectangle),
new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ])
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_ellipse),
new NodeTool( "Curve", THEME.canvas_tool_curve_icon)
.setSetting(tool_size)
.setSetting([ "", tool_curve_apply, 0, tool_attribute ])
.setSetting([ "", tool_curve_cancel, 0, tool_attribute ])
.setToolObject(tool_curve_bez),
new NodeTool( "Freeform", THEME.canvas_tools_freeform)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_freeform),
new NodeTool( "Fill", THEME.canvas_tools_bucket)
.setSetting(tool_thrs)
.setSetting(tool_fil8),
.setSetting(tool_fil8)
.setToolObject(tool_fill),
];
tool_selection = new canvas_tool_selection();
tool_brush = new canvas_tool_brush(brush, false);
tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush);
tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle);
tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse);
tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush);
tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute);
tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush);
#endregion
#region ++++ right tools ++++
@ -314,9 +338,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
new NodeTool( "Make/Reset Brush", THEME.canvas_tools_pencil ).setToolFn( __action_make_brush ),
-1,
new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ),
new NodeTool( [ "Extrude", "Inset" ],
[ THEME.canvas_tools_extrude, THEME.canvas_tools_inset ] )
.setToolObject( [ new canvas_tool_extrude(), new canvas_tool_inset() ] ),
new NodeTool( "Extrude", THEME.canvas_tools_extrude ).setToolObject( new canvas_tool_extrude() ),
new NodeTool( "Inset", THEME.canvas_tools_inset ).setToolObject( new canvas_tool_inset() ),
];
rightTools_not_selection = [
-1,
new NodeTool( "Outline", THEME.canvas_tools_outline, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[3]) ),
new NodeTool( "Extrude", THEME.canvas_tools_extrude, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[4]) ),
new NodeTool( "Inset", THEME.canvas_tools_inset, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[5]) ),
];
rightTools_brush = [
@ -330,6 +360,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_eraser.rightTools = rightTools_brush;
tool_rectangle.rightTools = rightTools_brush;
tool_ellipse.rightTools = rightTools_brush;
selection_tool_after = noone;
#endregion
function setToolColor(color) { tool_attribute.color = color; }
@ -391,7 +423,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
return hh + ui(4);
} #endregion
function removeFrame(index = 0) { #region
static removeFrame = function(index = 0) { #region
if(attributes.frames <= 1) return;
if(preview_index == attributes.frames)
@ -403,7 +435,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
update();
} #endregion
function refreshFrames() { #region
static refreshFrames = function() { #region
var fr = attributes.frames;
var _dim = attributes.dimension;
@ -429,7 +461,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
function setCanvasSurface(surface, index = preview_index) { INLINE canvas_surface[index] = surface; }
function storeAction() { #region
static storeAction = function() { #region
var action = recordAction(ACTION_TYPE.custom, function(data) {
is_selected = false;
@ -447,7 +479,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
action.clear_action = function(data) { surface_free_safe(data.surface); };
} #endregion
function apply_surfaces() { #region
static apply_surfaces = function() { #region
for( var i = 0; i < attributes.frames; i++ )
apply_surface(i);
} #endregion
@ -502,7 +534,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
apply_surface(index);
} #endregion
function tool_pick_color(_x, _y) { #region
static tool_pick_color = function(_x, _y) { #region
if(tool_selection.is_selected)
tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]);
else
@ -532,9 +564,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
BLEND_ALPHA
if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1);
BLEND_NORMAL
@ -554,11 +586,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_surface(drawing_surface, 0, 0);
BLEND_ALPHA
if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1);
if(tool_attribute.mirror[0] == false) {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1);
} else {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, 1, -90);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, 0, -1, 1, 90);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], 1, 1, 180);
}
BLEND_NORMAL
surface_reset_target();
@ -642,6 +678,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
array_append(rightTools, rightTools_general);
if(tool_selection.is_selected) array_append(rightTools, rightTools_selection);
else array_append(rightTools, rightTools_not_selection);
if(nodeTool != noone)
_tool = nodeTool;
@ -649,37 +686,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
else if(_currTool != noone) {
_tool = _currTool.getToolObject();
switch(_currTool.getName()) {
case "Pencil" : _tool = tool_brush; break;
case "Eraser" : _tool = tool_eraser; break;
case "Fill" : _tool = tool_fill; break;
case "Freeform" : _tool = tool_freeform; break;
case "Rectangle" :
_tool = tool_rectangle;
_tool.fill = _currTool.selecting == 1;
break;
case "Ellipse" :
_tool = tool_ellipse;
_tool.fill = _currTool.selecting == 1;
break;
case "Selection" :
switch(_currTool.selecting) {
case 0 : _tool = tool_sel_rectangle; break;
case 1 : _tool = tool_sel_ellipse; break;
case 2 : _tool = tool_sel_freeform; break;
case 3 : _tool = tool_sel_brush; break;
}
break;
case "Magic Selection" : _tool = tool_sel_magic; break;
}
if(_tool) {
_tool.node = self;
_tool = _tool.getTool();
_tool.subtool = _currTool.selecting;
array_append(rightTools, _tool.rightTools);
}
@ -690,6 +699,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_selection.apply_draw_surface = apply_draw_surface;
if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
tool_mirror_edit.sprs = (!tool_selection.is_selected && tool_attribute.mirror[0])? THEME.canvas_mirror_diag : THEME.canvas_mirror;
}
if(_tool && _tool.override) {
@ -771,14 +782,20 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
var _spw = tool_selection.selection_size[0];
var _sph = tool_selection.selection_size[1];
if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1);
} else {
if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1);
if(tool_attribute.mirror[0] == false) {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1);
} else {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, 1, -90);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, 0, -1, 1, 90);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], 1, 1, 180);
}
}
draw_set_color(tool_attribute.color);
@ -786,7 +803,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
canvas_draw_point_size(brush, brush.brush_sizing_dx, brush.brush_sizing_dy);
else if(_tool)
_tool.drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
surface_reset_shader();
draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp);

View file

@ -0,0 +1,717 @@
// 2024-04-16 08:42:15
enum COLLECTION_TAG {
group = 1,
loop = 2
}
function groupNodes(nodeArray, _group = noone, record = true, check_connect = true) { #region
#region check inline
var _ctx_nodes = [];
for(var i = 0; i < array_length(nodeArray); i++) {
var node = nodeArray[i];
var ctx = node.inline_context;
if(ctx == noone) continue;
array_push_unique(_ctx_nodes, ctx);
for( var k = 0, n = array_length(ctx.members); k < n; k++ ) {
if(array_exists(nodeArray, ctx.members[k])) continue;
noti_warning("Grouping incomplete inline group is not allowed.");
return;
}
}
#endregion
UNDO_HOLDING = true;
if(_group == noone) {
var cx = 0;
var cy = 0;
for(var i = 0; i < array_length(nodeArray); i++) {
var _node = nodeArray[i];
cx += _node.x;
cy += _node.y;
}
cx = value_snap(cx / array_length(nodeArray), 32);
cy = value_snap(cy / array_length(nodeArray), 32);
_group = new Node_Group(cx, cy, PANEL_GRAPH.getCurrentContext());
}
var _content = [];
for(var i = 0; i < array_length(nodeArray); i++) {
_group.add(nodeArray[i]);
_content[i] = nodeArray[i];
}
for( var i = 0, n = array_length(_ctx_nodes); i < n; i++ ) {
_group.add(_ctx_nodes[i]);
_content[i] = _ctx_nodes[i];
}
var _io = { inputs: {}, outputs: {}, map: {} };
if(check_connect) { #region IO creation
for(var i = 0; i < array_length(nodeArray); i++)
nodeArray[i].checkConnectGroup(_io);
var _in = _io.inputs;
var _inKey = struct_get_names(_in);
var _x, _y, m;
for( var i = 0, n = array_length(_inKey); i < n; i++ ) {
var _frm = _io.map[$ _inKey[i]];
var _tos = _in[$ _inKey[i]];
_x = 0
_y = 0;
m = array_length(_tos);
for( var j = 0; j < m; j++ ) {
var _to = _tos[j];
_x = min(_x, _to.node.x);
_y += _to.node.y;
}
_x = value_snap(_x - 64 - 128, 32);
_y = value_snap(_y / m, 32);
var _n = new Node_Group_Input(_x, _y, _group);
_n.inputs[| 2].setValue(_frm.type);
_n.onValueUpdate(0);
_n.inParent.setFrom(_frm);
for( var j = 0; j < m; j++ ) {
var _to = _tos[j];
_to.setFrom(_n.outputs[| 0]);
}
}
var _ot = _io.outputs;
var _otKey = struct_get_names(_ot);
for( var i = 0, n = array_length(_otKey); i < n; i++ ) {
var _frm = _io.map[$ _otKey[i]];
var _tos = _ot[$ _otKey[i]];
_x = value_snap(_frm.node.x + _frm.node.w + 64, 32);
_y = value_snap(_frm.node.y, 32);
m = array_length(_tos);
var _n = new Node_Group_Output(_x, _y, _group);
_n.inputs[| 0].setFrom(_frm);
for( var j = 0; j < m; j++ ) {
var _to = _tos[j];
_to.setFrom(_n.outParent);
}
}
} #endregion
UNDO_HOLDING = false;
if(record) recordAction(ACTION_TYPE.group, _group, { content: _content });
return _group;
} #endregion
function upgroupNode(collection, record = true) { #region
UNDO_HOLDING = true;
var _content = [];
var node_list = collection.getNodeList();
while(!ds_list_empty(node_list)) {
var remNode = node_list[| 0];
if(!remNode.destroy_when_upgroup)
array_push(_content, remNode);
collection.remove(remNode);
}
collection.destroy();
UNDO_HOLDING = false;
if(record) recordAction(ACTION_TYPE.ungroup, collection, { content: _content });
} #endregion
function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
nodes = ds_list_create();
node_length = ds_list_size(nodes);
ungroupable = true;
auto_render_time = false;
combine_render_time = true;
previewable = true;
reset_all_child = false;
isInstancer = false;
instanceBase = noone;
input_display_list_def = [];
custom_input_index = 0;
custom_output_index = 0;
metadata = new MetaDataManager();
attributes.input_display_list = [];
attributes.output_display_list = [];
managedRenderOrder = false;
input_dummy = nodeValue("Add to group", self, JUNCTION_CONNECT.input, VALUE_TYPE.any, 0);
draw_dummy = false;
input_dummy.onSetFrom = function(juncFrom) { #region
array_remove(juncFrom.value_to, input_dummy);
input_dummy.value_from = noone;
var input = nodeBuild("Node_Group_Input", 0, 0, self);
var _type = juncFrom.type;
var _tind = array_find(input.data_type_map, juncFrom.type);
input.attributes.inherit_type = false;
if(_tind != -1)
input.inputs[| 2].setValue(_tind);
input.inParent.setFrom(juncFrom);
if(onNewInputFromGraph != noone) onNewInputFromGraph(juncFrom);
} #endregion
onNewInputFromGraph = noone;
tool_node = noone;
draw_input_overlay = true;
array_push(attributeEditors, ["Edit Input Display", function() { return 0; },
button(function() { dialogCall(o_dialog_group_input_order).setNode(self, JUNCTION_CONNECT.input); }) ]);
array_push(attributeEditors, ["Edit Output Display", function() { return 0; },
button(function() { dialogCall(o_dialog_group_input_order).setNode(self, JUNCTION_CONNECT.output); }) ]);
hasInsp1 = false;
insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node contents");
insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ];
hasInsp2 = false;
insp2UpdateTooltip = "Clear cache";
insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ];
static inspector1Update = function() { onInspector1Update(); }
static onInspector1Update = function() { RenderList(nodes); }
static hasInspector1Update = function() { INLINE return hasInsp1; }
static inspector2Update = function() { onInspector2Update(); }
static onInspector2Update = function() { #region
var i = 0;
repeat(ds_list_size(nodes)) {
if(nodes[| i].hasInspector2Update())
nodes[| i].inspector2Update();
i++;
}
} #endregion
static hasInspector2Update = function() { INLINE return hasInsp2; }
will_refresh = false;
static refreshNodes = function() { #region
will_refresh = false;
hasInsp1 = false;
hasInsp2 = false;
node_length = ds_list_size(nodes);
var i = 0;
repeat(node_length) {
hasInsp1 |= nodes[| i].hasInspector1Update();
hasInsp2 |= nodes[| i].hasInspector2Update();
i++;
}
} #endregion
static getNodeBase = function() { #region
if(instanceBase == noone) return self;
return instanceBase.getNodeBase();
} #endregion
static getNodeList = function() { #region
INLINE
if(instanceBase == noone) return nodes;
return instanceBase.getNodeList();
} #endregion
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
if(!draw_input_overlay) return;
for(var i = custom_input_index; i < ds_list_size(inputs); i++) {
var _in = inputs[| i];
var _show = _in.from.getInputData(6);
if(!_show) continue;
var _hov = _in.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
if(_hov != undefined) active &= !_hov;
}
} #endregion
static getOutputNodes = function() { #region
var _nodes = [];
for( var i = custom_output_index; i < ds_list_size(outputs); i++ ) {
var _junc = outputs[| i];
for( var j = 0; j < array_length(_junc.value_to); j++ ) {
var _to = _junc.value_to[j];
if(_to.value_from != _junc) continue;
array_push_unique(_nodes, _to.node);
}
}
return _nodes;
} #endregion
static getInput = function(junc = noone) { #region
return input_dummy;
} #endregion
static getNextNodes = function() { return getNextNodesInternal(); }
static getNextNodesInternal = function() { #region //get node inside the group
LOG_BLOCK_START();
LOG_IF(global.FLAG.render == 1, $"→→→→→ Call get next node from group: {INAME}");
var _nodes = [];
if(isRenderActive()) {
var allReady = true;
for(var i = custom_input_index; i < ds_list_size(inputs); i++) {
var _in = inputs[| i].from;
if(!_in.isRenderActive()) continue;
if(!_in.isRenderable()) {
LOG_IF(global.FLAG.render == 1, $"Node {_in.internalName} not ready, loop skip.");
LOG_BLOCK_END();
return [];
}
}
_nodes = __nodeLeafList(getNodeList());
}
LOG_BLOCK_END();
return _nodes;
} #endregion
static getNextNodesExternal = function() { #region //get node connected to the parent object
LOG_IF(global.FLAG.render == 1, $"Checking next node external for {INAME}");
LOG_BLOCK_START();
var nextNodes = [];
for( var i = 0; i < ds_list_size(outputs); i++ ) {
var _ot = outputs[| i];
if(!_ot.forward) continue;
if(_ot.type == VALUE_TYPE.node) continue;
var _tos = _ot.getJunctionTo();
for( var j = 0, n = array_length(_tos); j < n; j++ ) {
var _to = _tos[j];
var _node = _to.node;
LOG_IF(global.FLAG.render == 1, $"Checking node {_node.internalName} : {_node.isRenderable()}");
if(!_node.isRenderable()) continue;
array_push(nextNodes, _to.node);
}
}
LOG_BLOCK_END();
return nextNodes;
} #endregion
static clearTopoSorted = function() { INLINE topoSorted = false; for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { nodes[| i].clearTopoSorted(); } }
static setRenderStatus = function(result) { #region
LOG_BLOCK_START();
LOG_IF(global.FLAG.render == 1, $"Set render status for {INAME} : {result}");
rendered = result;
if(rendered == result) return;
if(result)
for( var i = custom_output_index, n = ds_list_size(outputs); i < n; i++ ) {
var _o = outputs[| i];
if(_o.from.rendered) continue;
LOG_IF(global.FLAG.render == 1, $"Set fail because {_o.from.internalName} is not rendered.");
rendered = false;
break;
}
if(rendered) exitGroup();
if(!result && group != noone)
group.setRenderStatus(result);
LOG_BLOCK_END();
} #endregion
static isActiveDynamic = function(frame = CURRENT_FRAME) { #region
if(update_on_frame) return true;
if(!rendered) return true;
for( var i = custom_input_index, n = ds_list_size(inputs); i < n; i++ )
if(inputs[| i].isActiveDynamic(frame) || !inputs[| i].from.rendered) return true;
return false;
} #endregion
static exitGroup = function() {}
static add = function(_node) { #region
ds_list_add(getNodeList(), _node);
var list = _node.group == noone? PANEL_GRAPH.nodes_list : _node.group.getNodeList();
ds_list_remove(list, _node);
recordAction(ACTION_TYPE.group_added, self, _node);
_node.group = self;
will_refresh = true;
node_length = ds_list_size(nodes);
} #endregion
static remove = function(_node) { #region
var node_list = getNodeList();
var _pos = ds_list_find_index(node_list, _node);
ds_list_delete(node_list, _pos);
var list = group == noone? PANEL_GRAPH.nodes_list : group.getNodeList();
ds_list_add(list, _node);
recordAction(ACTION_TYPE.group_removed, self, _node);
if(struct_has(_node, "ungroup"))
_node.ungroup();
if(_node.destroy_when_upgroup)
_node.destroy();
else
_node.group = group;
will_refresh = true;
node_length = ds_list_size(nodes);
} #endregion
static clearCache = function() { #region
var node_list = getNodeList();
for(var i = 0; i < ds_list_size(node_list); i++) {
node_list[| i].clearCache();
}
} #endregion
static stepBegin = function() { #region
if(will_refresh) refreshNodes();
doStepBegin();
} #endregion
static step = function() { #region
if(combine_render_time) {
render_time = 0;
var node_list = getNodeList();
for(var i = 0; i < ds_list_size(node_list); i++)
render_time += node_list[| i].render_time;
}
onStep();
} #endregion
static onStep = function() {}
static onPreDraw = function(_x, _y, _s, _iny, _outy) { #region
var xx = x * _s + _x;
var yy = y * _s + _y;
input_dummy.x = xx;
input_dummy.y = _iny;
} #endregion
static preConnect = function() { #region
sortIO();
deserialize(load_map, load_scale);
} #endregion
static onDrawJunctions = function(_x, _y, _mx, _my, _s) { #region
input_dummy.visible = false;
if(draw_dummy) {
input_dummy.visible = true;
input_dummy.drawJunction(_s, _mx, _my);
}
draw_dummy = false;
} #endregion
static sortIO = function() { #region
var _ilen = ds_list_size(inputs);
var _iarr = attributes.input_display_list;
for( var i = 0; i < _ilen; i++ )
array_push_unique(_iarr, i);
for( var i = array_length(_iarr) - 1; i >= 0; i-- ) {
if(is_array(_iarr[i])) continue;
if(_iarr[i] >= _ilen) array_delete(_iarr, i, 1);
}
input_display_list = attributes.input_display_list;
///////////////////////////////////////////////////////////////////
var _olen = ds_list_size(outputs);
var _oarr = attributes.output_display_list;
for( var i = 0; i < _olen; i++ )
array_push_unique(_oarr, i);
for( var i = array_length(_oarr) - 1; i >= 0; i-- ) {
if(is_array(_oarr[i])) continue;
if(_oarr[i] >= _olen) array_delete(_oarr, i, 1);
}
output_display_list = attributes.output_display_list;
///////////////////////////////////////////////////////////////////
refreshNodeDisplay();
} #endregion
static getTool = function() { #region
for(var i = 0, n = ds_list_size(nodes); i < n; i++) {
var _node = nodes[| i];
if(!_node.active) continue;
if(_node.isTool) return _node.getTool();
}
return self;
} #endregion
static onClone = function(_newNode, target = PANEL_GRAPH.getCurrentContext()) { #region
if(instanceBase != noone) {
_newNode.instanceBase = instanceBase;
return;
}
var dups = ds_list_create();
for(var i = 0, n = ds_list_size(nodes); i < n; i++) {
var _node = nodes[| i];
var _cnode = _node.clone(target);
ds_list_add(dups, _cnode);
APPEND_MAP[? _node.node_id] = _cnode.node_id;
}
APPENDING = true;
for(var i = 0; i < ds_list_size(dups); i++) {
var _node = dups[| i];
_node.connect();
}
APPENDING = false;
ds_list_destroy(dups);
} #endregion
static enable = function() { #region
active = true;
var node_list = getNodeList();
for( var i = 0; i < ds_list_size(node_list); i++ )
node_list[| i].enable();
} #endregion
static disable = function() { #region
active = false;
var node_list = getNodeList();
for( var i = 0; i < ds_list_size(node_list); i++ )
node_list[| i].disable();
} #endregion
static resetRender = function(_clearCache = false) { #region
LOG_LINE_IF(global.FLAG.render == 1, $"Reset Render for group {INAME}");
setRenderStatus(false);
if(_clearCache) clearInputCache();
if(reset_all_child)
for(var i = 0, n = ds_list_size(nodes); i < n; i++)
nodes[| i].resetRender(_clearCache);
} #endregion
static setInstance = function(node) { #region
instanceBase = node;
} #endregion
static resetInstance = function() { #region
instanceBase = noone;
} #endregion
static onDoubleClick = function(panel) { #region
if(PREFERENCES.panel_graph_group_require_shift && !key_mod_press(SHIFT)) return false;
__temp_panel = panel;
if(PREFERENCES.graph_open_group_in_tab)
run_in(1, function() { __temp_panel.openGroupTab(self) });
else
panel.addContext(self);
if(ononDoubleClick != noone)
ononDoubleClick(panel);
return true;
} #endregion
static ononDoubleClick = noone;
static getGraphPreviewSurface = function() { #region
var _output_junc = outputs[| preview_channel];
for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) {
if(!nodes[| i].active) continue;
if(is_instanceof(nodes[| i], Node_Group_Thumbnail))
_output_junc = nodes[| i].inputs[| 0];
}
if(!is_instanceof(_output_junc, NodeValue)) return noone;
switch(_output_junc.type) {
case VALUE_TYPE.surface :
case VALUE_TYPE.dynaSurface :
return _output_junc.getValue();
}
return noone;
} #endregion
static enable = function() { #region
active = true; timeline_item.active = true;
for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) nodes[| i].enable();
} #endregion
static disable = function() { #region
active = false; timeline_item.active = false;
for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) nodes[| i].disable();
} #endregion
static attributeSerialize = function() { #region
sortIO();
var _attr = variable_clone(attributes);
_attr.custom_input_list = [];
for( var i = custom_input_index, n = ds_list_size(inputs); i < n; i++ ) {
if(struct_has(inputs[| i], "from"))
array_push(_attr.custom_input_list, inputs[| i].from.node_id);
}
_attr.custom_output_list = [];
for( var i = custom_output_index, n = ds_list_size(outputs); i < n; i++ ) {
if(struct_has(outputs[| i], "from"))
array_push(_attr.custom_output_list , outputs[| i].from.node_id);
}
return _attr;
} #endregion
static preApplyDeserialize = function() { #region
var attr = attributes;
if(LOADING_VERSION < 11690) { #region
var pr = ds_priority_create();
for( var i = ds_list_size(inputs) - 1; i >= custom_input_index; i-- ) {
if(!struct_has(inputs[| i].attributes, "input_priority")) continue;
var _pri = inputs[| i].attributes.input_priority;
ds_priority_add(pr, inputs[| i], _pri);
ds_list_delete(inputs, i);
}
repeat(ds_priority_size(pr)) ds_list_add(inputs, ds_priority_delete_min(pr));
for( var i = ds_list_size(outputs) - 1; i >= custom_output_index; i-- ) {
if(!struct_has(outputs[| i].attributes, "output_priority")) continue;
var _pri = outputs[| i].attributes.output_priority;
ds_priority_add(pr, outputs[| i], _pri);
ds_list_delete(outputs, i);
}
repeat(ds_priority_size(pr)) ds_list_add(outputs, ds_priority_delete_min(pr));
ds_priority_destroy(pr);
return;
} #endregion
if(struct_has(attr, "custom_input_list")) {
var _ilist = attr.custom_input_list;
var _inarr = {};
var _dilst = [];
if(APPENDING)
for( var i = 0, n = array_length(_ilist); i < n; i++ )
_ilist[i] = ds_map_try_get(APPEND_MAP, _ilist[i], _ilist[i]);
for( var i = ds_list_size(inputs) - 1; i >= custom_input_index; i-- ) {
if(!struct_has(inputs[| i], "from")) continue;
var _frNode = inputs[| i].from.node_id;
if(array_exists(_ilist, _frNode)) {
_inarr[$ _frNode] = inputs[| i];
ds_list_delete(inputs, i);
}
}
for( var i = 0, n = array_length(_ilist); i < n; i++ ) {
if(!struct_has(_inarr, _ilist[i])) continue;
ds_list_add(inputs, _inarr[$ _ilist[i]]);
}
}
if(struct_has(attr, "custom_output_list")) {
var _ilist = attr.custom_output_list;
var _inarr = {};
if(APPENDING)
for( var i = 0, n = array_length(_ilist); i < n; i++ )
_ilist[i] = ds_map_try_get(APPEND_MAP, _ilist[i], _ilist[i]);
for( var i = ds_list_size(outputs) - 1; i >= custom_output_index; i-- ) {
if(!struct_has(outputs[| i], "from")) continue;
var _frNode = outputs[| i].from.node_id;
if(array_exists(_ilist, _frNode)) {
_inarr[$ _frNode] = outputs[| i];
ds_list_delete(outputs, i);
}
}
for( var i = 0, n = array_length(_ilist); i < n; i++ ) {
if(!struct_has(_inarr, _ilist[i])) continue;
ds_list_add(outputs, _inarr[$ _ilist[i]]);
}
}
} #endregion
static processSerialize = function(_map) { #region
_map.instance_base = instanceBase? instanceBase.node_id : noone;
} #endregion
static preConnect = function() { #region
instanceBase = GetAppendID(struct_try_get(load_map, "instance_base", noone));
sortIO();
applyDeserialize();
} #endregion
}

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
// 2023-08-08 14:41:40
// 2023-08-08 14:42:15
global.loop_nodes = [ "Node_Iterate", "Node_Iterate_Each" ];
function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x, _y) constructor {
@ -1445,7 +1445,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x
for(var i = 0; i < amo; i++) {
if(inputs[| i] == noone || _inputs[i] == noone) continue;
print($"Apply deserialize {_inputs[| i].name} to {inputs[| i].name}");
print($"Apply deserialize {_inputs[i].name} to {inputs[| i].name}");
inputs[| i].applyDeserialize(_inputs[i], load_scale, preset);
}

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:51:01
// 2024-04-16 10:52:40
function NodeTool(name, spr, context = instanceof(other)) constructor {
ctx = context;
self.name = name;
@ -79,7 +79,7 @@ function NodeTool(name, spr, context = instanceof(other)) constructor {
onToggle();
var _obj = getToolObject();
if(_obj) _obj.init();
if(_obj) _obj.init(ctx);
}
static toggleKeyboard = function() {

View file

@ -0,0 +1,102 @@
// 2024-04-14 12:51:01
function NodeTool(name, spr, context = instanceof(other)) constructor {
ctx = context;
self.name = name;
self.spr = spr;
subtools = is_array(spr)? array_length(spr) : 0;
selecting = 0;
settings = [];
attribute = {};
toolObject = noone;
toolFn = noone;
toolFnParam = {};
static checkHotkey = function() {
INLINE
return getToolHotkey(ctx, name);
}
static setToolObject = function(toolObject) { self.toolObject = toolObject; return self; }
static setToolFn = function(toolFn) { self.toolFn = toolFn; return self; }
static getName = function(index = 0) { return is_array(name)? array_safe_get_fast(name, index, "") : name; }
static getToolObject = function() { return is_array(toolObject)? toolObject[selecting] : toolObject; }
static getDisplayName = function(index = 0) {
var _key = checkHotkey();
var _nme = getName(index);
if(_key != "") _nme += $" ({_key})";
return _nme;
}
static setSetting = function(sets) { array_push(settings, sets); return self; }
static addSetting = function(name, type, onEdit, keyAttr, val) {
var w;
switch(type) {
case VALUE_TYPE.float :
w = new textBox(TEXTBOX_INPUT.number, onEdit);
w.font = f_p3;
break;
case VALUE_TYPE.boolean :
w = new checkBox(onEdit);
break;
}
array_push(settings, [ name, w, keyAttr, attribute ]);
attribute[$ keyAttr] = val;
return self;
}
static toggle = function(index = 0) {
if(toolFn != noone) {
if(subtools == 0) toolFn(ctx);
else toolFn[index](ctx);
return;
}
if(subtools == 0) {
PANEL_PREVIEW.tool_current = PANEL_PREVIEW.tool_current == self? noone : self;
} else {
if(PANEL_PREVIEW.tool_current == self && index == selecting) {
PANEL_PREVIEW.tool_current = noone;
selecting = 0;
} else {
PANEL_PREVIEW.tool_current = self;
selecting = index;
}
}
if(PANEL_PREVIEW.tool_current == self)
onToggle();
var _obj = getToolObject();
if(_obj) _obj.init();
}
static toggleKeyboard = function() {
if(subtools == 0) {
PANEL_PREVIEW.tool_current = PANEL_PREVIEW.tool_current == self? noone : self;
} else if(PANEL_PREVIEW.tool_current != self) {
PANEL_PREVIEW.tool_current = self;
selecting = 0;
} else if(selecting == subtools - 1) {
PANEL_PREVIEW.tool_current = noone;
selecting = 0;
} else
selecting++;
if(PANEL_PREVIEW.tool_current == self)
onToggle();
}
static onToggle = function() {}
}

View file

@ -0,0 +1,183 @@
// 2024-04-16 09:31:58
enum COLOR_SELECTOR_MODE {
hue,
value
}
function Panel_Color() : PanelContent() constructor {
title = __txt("Color");
padding = 8;
w = ui(320);
h = ui(320);
mode = COLOR_SELECTOR_MODE.hue;
hue = 1;
sat = 1;
val = 1;
color = c_black;
drag_con = false;
drag_sel = false;
colors = [];
static setColor = function(color) {
self.color = color;
hue = color_get_hue(color) / 255;
sat = color_get_saturation(color) / 255;
val = color_get_value(color) / 255;
if(COLORS_GLOBAL_SET != noone)
COLORS_GLOBAL_SET(color);
}
static setHSV = function(h = hue, s = sat, v = val) {
hue = h;
sat = s;
val = v;
color = make_color_hsv(h * 255, s * 255, v * 255);
if(COLORS_GLOBAL_SET != noone)
COLORS_GLOBAL_SET(color);
}
setHSV();
function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var px = ui(padding);
var py = ui(padding);
var pw = w - ui(padding + padding);
var ph = h - ui(padding + padding);
draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16));
if(COLORS_GLOBAL_GET != noone) {
var c = COLORS_GLOBAL_GET();
if(c != color) setColor(c);
}
var cont_x = ui(padding);
var cont_y = ui(padding);
var cont_w = w - ui(padding + padding + ui(16 + 8));
var cont_h = h - ui(padding + padding + ui(24 + 8));
shader_set(sh_color_select_content);
shader_set_i("mode", mode);
shader_set_f("hue", hue);
shader_set_f("val", val);
draw_sprite_stretched(s_fx_pixel, 0, cont_x, cont_y, cont_w, cont_h);
var sel_x = cont_x + cont_w + ui(8);
var sel_y = ui(padding);
var sel_w = ui(16);
var sel_h = cont_h;
shader_set(sh_color_select_side);
shader_set_i("mode", mode);
shader_set_f("hue", hue);
draw_sprite_stretched(s_fx_pixel, 0, sel_x, sel_y, sel_w, sel_h);
shader_reset();
if(drag_con) {
if(mode == 0) {
sat = clamp((mx - cont_x) / cont_w, 0, 1);
val = 1 - clamp((my - cont_y) / cont_h, 0, 1);
} else if(mode == 1) {
hue = clamp((mx - cont_x) / cont_w, 0, 1);
sat = 1 - clamp((my - cont_y) / cont_h, 0, 1);
}
setHSV();
if(mouse_release(mb_left))
drag_con = false;
}
if(drag_sel) {
if(mode == 0)
hue = clamp((my - sel_y) / sel_h, 0, 1);
else if(mode == 1)
val = 1 - clamp((my - sel_y) / sel_h, 0, 1);
setHSV();
if(mouse_release(mb_left))
drag_sel = false;
}
if(mouse_press(mb_left, pFOCUS)) {
if(point_in_rectangle(mx, my, cont_x, cont_y, cont_x + cont_w, cont_y + cont_h))
drag_con = true;
if(point_in_rectangle(mx, my, sel_x, sel_y, sel_x + sel_w, sel_y + sel_h))
drag_sel = true;
}
if(mode == 0) {
var hy = sel_y + hue * sel_h;
var cx = cont_x + sat * cont_w - ui(6);
var cy = cont_y + (1 - val) * cont_h - ui(6);
draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), hy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, 255), 1);
draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1);
} else if(mode == 1) {
var vy = sel_y + (1 - val) * sel_h;
var cx = cont_x + hue * cont_w - ui(6);
var cy = cont_y + (1 - sat) * cont_h - ui(6);
draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), vy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, val * 255), 1);
draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1);
}
var amo = min(array_length(colors) + 1, floor((w - ui(padding * 2)) / ui(24 + 4)));
for( var i = 0; i < amo; i++ ) {
var cx = ui(padding) + ui(24 + 4) * i;
var cy = cont_y + cont_h + ui(8);
if(i == 0) {
draw_sprite_stretched_ext(s_ui_base_white, 0, cx + ui(4), cy + ui(4), ui(16), ui(16), color, 1);
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 0.5);
if(pHOVER && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 1);
if(mouse_press(mb_left, pFOCUS)) {
array_insert(colors, 0, color);
if(COLORS_GLOBAL_SET != noone) {
COLORS_GLOBAL_SET(color);
} else {
DRAGGING = {
type: "Color",
data: color
}
MESSAGE = DRAGGING;
}
}
}
continue;
}
var c = colors[i - 1];
draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(24), ui(24), c, 1);
if(mouse_press(mb_left, pFOCUS) && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) {
DRAGGING = {
type: "Color",
data: c
}
MESSAGE = DRAGGING;
}
}
if(DRAGGING && DRAGGING.type == "Color" && pHOVER) {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, 2, 2, w - 4, h - 4, COLORS._main_value_positive, 1);
if(mouse_release(mb_left))
setColor(DRAGGING.data);
}
}
}

View file

@ -0,0 +1,183 @@
// 2024-04-16 09:31:56
enum COLOR_SELECTOR_MODE {
hue,
value
}
function Panel_Color() : PanelContent() constructor {
title = __txt("Color");
padding = 8;
w = ui(320);
h = ui(320);
mode = COLOR_SELECTOR_MODE.hue;
hue = 1;
sat = 1;
val = 1;
color = c_black;
drag_con = false;
drag_sel = false;
colors = [];
static setColor = function(color) {
self.color = color;
hue = color_get_hue(color) / 255;
sat = color_get_saturation(color) / 255;
val = color_get_value(color) / 255;
if(COLORS_GLOBAL_SET != noone)
COLORS_GLOBAL_SET(color);
}
static setHSV = function(h = hue, s = sat, v = val) {
hue = h;
sat = s;
val = v;
color = make_color_hsv(h * 255, s * 255, v * 255);
if(COLORS_GLOBAL_SET != noone)
COLORS_GLOBAL_SET(color);
}
setHSV();
function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var px = ui(padding);
var py = ui(padding);
var pw = w - ui(padding + padding);
var ph = h - ui(padding + padding);
draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16));
if(COLORS_GLOBAL_GET != noone) {
var c = COLORS_GLOBAL_GET();
if(c != color) setColor(c);
}
var cont_x = ui(padding);
var cont_y = ui(padding);
var cont_w = w - ui(padding + padding + ui(16 + 8));
var cont_h = h - ui(padding + padding + ui(24 + 8));
shader_set(sh_color_select_content);
shader_set_i("mode", mode);
shader_set_f("hue", hue);
shader_set_f("val", val);
draw_sprite_stretched(s_fx_pixel, 0, cont_x, cont_y, cont_w, cont_h);
var sel_x = cont_x + cont_w + ui(8);
var sel_y = ui(padding);
var sel_w = ui(16);
var sel_h = cont_h;
shader_set(sh_color_select_side);
shader_set_i("mode", mode);
shader_set_f("hue", hue);
draw_sprite_stretched(s_fx_pixel, 0, sel_x, sel_y, sel_w, sel_h);
shader_reset();
if(drag_con) {
if(mode == 0) {
sat = clamp((mx - cont_x) / cont_w, 0, 1);
val = 1 - clamp((my - cont_y) / cont_h, 0, 1);
} else if(mode == 1) {
hue = clamp((mx - cont_x) / cont_w, 0, 1);
sat = 1 - clamp((my - cont_y) / cont_h, 0, 1);
}
setHSV();
if(mouse_release(mb_left))
drag_con = false;
}
if(drag_sel) {
if(mode == 0)
hue = clamp((my - sel_y) / sel_h, 0, 1);
else if(mode == 1)
val = 1 - clamp((my - sel_y) / sel_h, 0, 1);
setHSV();
if(mouse_release(mb_left))
drag_sel = false;
}
if(mouse_press(mb_left, pFOCUS)) {
if(point_in_rectangle(mx, my, cont_x, cont_y, cont_x + cont_w, cont_y + cont_h))
drag_con = true;
if(point_in_rectangle(mx, my, sel_x, sel_y, sel_x + sel_w, sel_y + sel_h))
drag_sel = true;
}
if(mode == 0) {
var hy = sel_y + hue * sel_h;
var cx = cont_x + sat * cont_w - ui(6);
var cy = cont_y + (1 - val) * cont_h - ui(6);
draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), hy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, 255), 1);
draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1);
} else if(mode == 1) {
var vy = sel_y + (1 - val) * sel_h;
var cx = cont_x + hue * cont_w - ui(6);
var cy = cont_y + (1 - sat) * cont_h - ui(6);
draw_sprite_stretched_ext(s_ui_base_white, 0, sel_x - ui(3), vy - ui(6), ui(16 + 6), ui(10), make_color_hsv(hue * 255, 255, val * 255), 1);
draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1);
}
var amo = min(array_length(colors) + 1, floor((w - ui(padding * 2)) / ui(24 + 4)));
for( var i = 0; i < amo; i++ ) {
var cx = ui(padding) + ui(24 + 4) * i;
var cy = cont_y + cont_h + ui(8);
if(i == 0) {
draw_sprite_stretched_ext(s_ui_base_white, 0, cx + ui(4), cy + ui(4), ui(16), ui(16), color, 1);
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 0.5);
if(pHOVER && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 1);
if(mouse_press(mb_left, pFOCUS)) {
array_insert(colors, 0, color);
if(COLORS_GLOBAL_SET != noone) {
COLORS_GLOBAL_SET(color);
} else {
DRAGGING = {
type: "Color",
data: color
}
MESSAGE = DRAGGING;
}
}
}
continue;
}
var c = colors[i - 1];
draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(24), ui(24), c, 1);
if(mouse_press(mb_left, pFOCUS) && point_in_rectangle(mx, my, cx, cy, cx + ui(24), cy + ui(24))) {
DRAGGING = {
type: "Color",
data: c
}
MESSAGE = DRAGGING;
}
}
if(DRAGGING && DRAGGING.type == "Color" && pHOVER) {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, 2, 2, w - 4, h - 4, COLORS._main_value_positive, 1);
if(mouse_release(mb_left))
setColor(DRAGGING.data);
}
}
}

View file

@ -0,0 +1,123 @@
// 2024-04-16 09:33:06
function Panel_Palette() : PanelContent() constructor {
title = __txt("Palettes");
padding = 8;
w = ui(320);
h = ui(480);
view_mode = 0;
color_dragging = noone;
function onResize() {
sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding));
}
sp_palettes = new scrollPane(w - ui(padding + padding), h - ui(padding + padding), function(_y, _m) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var ww = sp_palettes.surface_w;
var hh = ui(28);
var _gs = ui(24);
switch(view_mode) {
case 0 : _gs = ui(24); break;
case 1 : _gs = ui(32); break;
case 2 : _gs = ui(16); break;
}
var _height;
var yy = _y;
var cur = COLORS_GLOBAL_GET != noone? COLORS_GLOBAL_GET() : noone;
for(var i = 0; i < array_length(PALETTES); i++) {
var preset = PALETTES[i];
var pre_amo = array_length(preset.palette);
var col = floor((ww - ui(20)) / _gs);
var row = ceil(pre_amo / col);
_height = ui(34) + row * _gs;
var isHover = pHOVER && point_in_rectangle(_m[0], _m[1], 0, max(0, yy), ww, min(sp_palettes.h, yy + _height));
draw_sprite_stretched(THEME.ui_panel_bg, 3, 0, yy, ww, _height);
if(isHover)
draw_sprite_stretched_ext(THEME.node_active, 1, 0, yy, ww, _height, COLORS._main_accent, 1);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text(ui(10), yy + ui(2), preset.name);
drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs, cur);
if(isHover) {
if(mouse_press(mb_left, pFOCUS)) {
if(point_in_rectangle(_m[0], _m[1], ui(10), yy + ui(24), ww - ui(10), yy + ui(24) + _height)) {
var m_ax = _m[0] - ui(10);
var m_ay = _m[1] - (yy + ui(24));
var m_gx = floor(m_ax / _gs);
var m_gy = floor(m_ay / _gs);
var _index = m_gy * col + m_gx;
if(_index < pre_amo && _index >= 0) {
if(COLORS_GLOBAL_SET != noone) {
COLORS_GLOBAL_SET(array_safe_get_fast(preset.palette, _index));
} else {
DRAGGING = {
type: "Color",
data: array_safe_get_fast(preset.palette, _index)
}
MESSAGE = DRAGGING;
}
}
} else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) {
DRAGGING = {
type: "Palette",
data: preset.palette
}
MESSAGE = DRAGGING;
}
}
if(mouse_press(mb_right, pFOCUS)) {
hovering = preset;
menuCall("palette_window_preset_menu",,, [
menuItem(__txt("Refresh"), function() {
__initPalette();
}),
menuItem(__txtx("palette_change_preview_size", "Change preview size"), function() {
view_mode = (view_mode + 1) % 3;
}),
-1,
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 += _height + ui(8);
hh += _height + ui(8);
}
return hh;
});
function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var px = ui(padding);
var py = ui(padding);
var pw = w - ui(padding + padding);
var ph = h - ui(padding + padding);
draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16));
sp_palettes.setFocusHover(pFOCUS, pHOVER);
sp_palettes.draw(px, py, mx - px, my - py);
}
}

View file

@ -0,0 +1,123 @@
// 2024-04-16 09:33:05
function Panel_Palette() : PanelContent() constructor {
title = __txt("Palettes");
padding = 8;
w = ui(320);
h = ui(480);
view_mode = 0;
color_dragging = noone;
function onResize() {
sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding));
}
sp_palettes = new scrollPane(w - ui(padding + padding), h - ui(padding + padding), function(_y, _m) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var ww = sp_palettes.surface_w;
var hh = ui(28);
var _gs = ui(24);
switch(view_mode) {
case 0 : _gs = ui(24); break;
case 1 : _gs = ui(32); break;
case 2 : _gs = ui(16); break;
}
var _height;
var yy = _y;
var cur = COLORS_GLOBAL_GET != noone? COLORS_GLOBAL_GET() : noone;
for(var i = 0; i < array_length(PALETTES); i++) {
var preset = PALETTES[i];
var pre_amo = array_length(preset.palette);
var col = floor((ww - ui(20)) / _gs);
var row = ceil(pre_amo / col);
_height = ui(34) + row * _gs;
var isHover = pHOVER && point_in_rectangle(_m[0], _m[1], 0, max(0, yy), ww, min(sp_palettes.h, yy + _height));
draw_sprite_stretched(THEME.ui_panel_bg, 3, 0, yy, ww, _height);
if(isHover)
draw_sprite_stretched_ext(THEME.node_active, 1, 0, yy, ww, _height, COLORS._main_accent, 1);
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text(ui(10), yy + ui(2), preset.name);
drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs, cur);
if(isHover) {
if(mouse_press(mb_left, pFOCUS)) {
if(point_in_rectangle(_m[0], _m[1], ui(10), yy + ui(24), ww - ui(10), yy + ui(24) + _height)) {
var m_ax = _m[0] - ui(10);
var m_ay = _m[1] - (yy + ui(24));
var m_gx = floor(m_ax / _gs);
var m_gy = floor(m_ay / _gs);
var _index = m_gy * col + m_gx;
if(_index < pre_amo && _index >= 0) {
if(COLORS_GLOBAL_SET != noone) {
COLORS_GLOBAL_SET(array_safe_get_fast(preset.palette, _index));
} else {
DRAGGING = {
type: "Color",
data: array_safe_get_fast(preset.palette, _index)
}
MESSAGE = DRAGGING;
}
}
} else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) {
DRAGGING = {
type: "Palette",
data: preset.palette
}
MESSAGE = DRAGGING;
}
}
if(mouse_press(mb_right, pFOCUS)) {
hovering = preset;
menuCall("palette_window_preset_menu",,, [
menuItem(__txt("Refresh"), function() {
__initPalette();
}),
menuItem(__txtx("palette_change_preview_size", "Change preview size"), function() {
view_mode = (view_mode + 1) % 3;
}),
-1,
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 += _height + ui(8);
hh += _height + ui(8);
}
return hh;
});
function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0);
var px = ui(padding);
var py = ui(padding);
var pw = w - ui(padding + padding);
var ph = h - ui(padding + padding);
draw_sprite_stretched(THEME.ui_panel_bg, 1, px - ui(8), py - ui(8), pw + ui(16), ph + ui(16));
sp_palettes.setFocusHover(pFOCUS, pHOVER);
sp_palettes.draw(px, py, mx - px, my - py);
}
}

View file

@ -1,4 +1,4 @@
// 2024-04-14 12:50:29
// 2024-04-16 09:29:34
#region funtion calls
function __fnInit_Preview() {
__registerFunction("preview_focus_content", panel_preview_focus_content);
@ -100,6 +100,8 @@ function Panel_Preview() : PanelContent() constructor {
tileMode = 0;
bg_color = COLORS.panel_bg_clear;
mouse_pos_string = "";
#endregion
#region ---- tool ----
@ -1072,8 +1074,15 @@ function Panel_Preview() : PanelContent() constructor {
var mpx = floor((mx - canvas_x) / canvas_s);
var mpy = floor((my - canvas_y) / canvas_s);
draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]");
if(mouse_pos_string != "") {
right_menu_y += string_height("l");
draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}");
}
}
mouse_pos_string = "";
if(_node == noone) return;
right_menu_y += string_height("l");
@ -1478,9 +1487,9 @@ function Panel_Preview() : PanelContent() constructor {
var key = sett[2];
var atr = sett[3];
if(i == 0 && nme != "") {
tolx += ui(8);
tol_max_w += ui(8);
if(nme != "") {
tolx += ui(8) + bool(i == 0) * ui(8);
tol_max_w += ui(8) + bool(i == 0) * ui(8);
}
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub);
@ -1501,6 +1510,7 @@ function Panel_Preview() : PanelContent() constructor {
case "checkBoxGroup" : tolw = tolh * wdg.size; break;
case "checkBox" : tolw = tolh; break;
case "scrollBox" : tolw = ui(96); break;
case "buttonClass" : tolw = wdg.text == ""? tolh : tolw; break;
}
var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ])
@ -1509,11 +1519,6 @@ function Panel_Preview() : PanelContent() constructor {
wdg.drawParam(params);
if(nme != "") {
tolx += ui(8);
tol_max_w += ui(8);
}
tolx += tolw + ui(8) + (nme != "") * ui(8);
tol_max_w += tolw + ui(8) + (nme != "") * ui(8);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,298 @@
// 2024-04-15 17:50:18
#region preference
globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA;
PREFERENCES = {};
HOTKEYS_DATA = {};
#region ////////////////////////////////////////////////////////////////////// GENERAL UI //////////////////////////////////////////////////////////////////////
PREFERENCES.display_scaling = 1;
PREFERENCES.window_width = 1600;
PREFERENCES.window_height = 800;
PREFERENCES.window_maximize = false;
PREFERENCES.theme = "default";
PREFERENCES.local = "en";
PREFERENCES.font_overwrite = "";
PREFERENCES.ui_framerate = 120;
PREFERENCES.path_resolution = 32;
PREFERENCES.move_directory = false;
PREFERENCES.notification_time = 180;
PREFERENCES.notify_load_version = true;
PREFERENCES.show_crash_dialog = false;
PREFERENCES.test_mode = false;
PREFERENCES.auto_save_time = 300;
PREFERENCES.use_legacy_exception = false;
PREFERENCES.caret_blink = 0.75;
PREFERENCES.textbox_shake = 0;
PREFERENCES.textbox_particle = 0;
#endregion
#region ////////////////////////////////////////////////////////////////////////// IO //////////////////////////////////////////////////////////////////////////
PREFERENCES.double_click_delay = 0.25;
PREFERENCES.mouse_wheel_speed = 1.00;
PREFERENCES.keyboard_repeat_start = 0.50;
PREFERENCES.keyboard_repeat_speed = 0.10;
#endregion
#region ///////////////////////////////////////////////////////////////////////// DIALOG ////////////////////////////////////////////////////////////////////////
PREFERENCES.node_recents_amount = 20;
PREFERENCES.show_splash = true;
PREFERENCES.splash_expand_recent = false;
PREFERENCES.dialog_add_node_grouping = true;
PREFERENCES.dialog_add_node_view = 0;
PREFERENCES.dialog_add_node_w = 532;
PREFERENCES.dialog_add_node_h = 400;
PREFERENCES.add_node_remember = true;
#endregion
#region //////////////////////////////////////////////////////////////////////// PANEL /////////////////////////////////////////////////////////////////////////
PREFERENCES.panel_layout_file = "Vertical";
PREFERENCES.panel_graph_dragging = MOD_KEY.alt;
PREFERENCES.panel_graph_group_require_shift = true;
PREFERENCES.panel_preview_dragging = MOD_KEY.alt;
PREFERENCES.panel_preview_show_real_fps = false;
PREFERENCES.panel_menu_resource_monitor = false;
PREFERENCES.panel_menu_right_control = os_type == os_windows;
PREFERENCES.inspector_focus_on_double_click = true;
PREFERENCES.inspector_view_default = 1;
PREFERENCES.node_show_render_status = false;
PREFERENCES.node_show_time = true;
PREFERENCES.expand_hover = false;
PREFERENCES.graph_zoom_smoooth = 4;
PREFERENCES.graph_open_group_in_tab = false;
PREFERENCES.connection_line_width = 2;
PREFERENCES.connection_line_sample = 1;
PREFERENCES.connection_line_corner = 8;
PREFERENCES.connection_line_aa = 2;
PREFERENCES.connection_line_transition = true;
PREFERENCES.connection_line_highlight = 0;
PREFERENCES.connection_line_highlight_fade = 0.75;
PREFERENCES.connection_line_highlight_all = false;
PREFERENCES.curve_connection_line = 1;
PREFERENCES.collection_animated = true;
PREFERENCES.collection_preview_speed = 60;
PREFERENCES.collection_scale = 1;
PREFERENCES.pan_mouse_key = mb_middle;
#endregion
#region //////////////////////////////////////////////////////////////////////// WIDGET ////////////////////////////////////////////////////////////////////////
PREFERENCES.widget_autocomplete_delay = 500;
PREFERENCES.alt_picker = true;
#endregion
#region //////////////////////////////////////////////////////////////////////// NODES /////////////////////////////////////////////////////////////////////////
PREFERENCES.node_param_show = false;
PREFERENCES.node_param_width = 192;
#endregion
#region //////////////////////////////////////////////////////////////////////// MISC //////////////////////////////////////////////////////////////////////////
PREFERENCES.save_file_minify = true;
PREFERENCES.render_all_export = true;
PREFERENCES.clear_temp_on_close = true;
PREFERENCES.show_supporter_icon = true;
#endregion
#region //////////////////////////////////////////////////////////////////////// PATHS /////////////////////////////////////////////////////////////////////////
PREFERENCES.temp_path = "%DIR%/temp/";
PREFERENCES.ImageMagick_path = "%APP%/imagemagick/";
PREFERENCES.webp_path = "%APP%/webp/";
PREFERENCES.gifski_path = "%APP%/gifski/";
PREFERENCES.ffmpeg_path = "%APP%/ffmpeg/";
PREFERENCES.versions = {};
#endregion
PREFERENCES_DEF = variable_clone(PREFERENCES);
#endregion
#region recent files
globalvar RECENT_FILES, RECENT_FILE_DATA;
RECENT_FILES = ds_list_create();
RECENT_FILE_DATA = ds_list_create();
function RECENT_SAVE() {
var map = ds_map_create();
var l = ds_list_create();
ds_list_copy(l, RECENT_FILES);
ds_map_add_list(map, "Recents", l);
var path = DIRECTORY + "recent.json";
var file = file_text_open_write(path);
file_text_write_string(file, json_encode_minify(map));
file_text_close(file);
ds_map_destroy(map);
}
function RECENT_LOAD() {
var path = DIRECTORY + "recent.json";
if(!file_exists_empty(path)) return;
var file = file_text_open_read(path);
var load_str = "";
while(!file_text_eof(file)) {
load_str += file_text_readln(file);
}
file_text_close(file);
var map = json_decode(load_str);
if(ds_map_exists(map, "Recents")) {
var l = map[? "Recents"];
ds_list_clear(RECENT_FILES);
for(var i = 0; i < ds_list_size(l); i++) {
if(!file_exists_empty(l[| i])) continue;
ds_list_add(RECENT_FILES, l[| i]);
}
}
RECENT_REFRESH();
}
function RECENT_REFRESH() {
for( var i = 0; i < ds_list_size(RECENT_FILE_DATA); i++ ) {
var d = RECENT_FILE_DATA[| i];
if(sprite_exists(d.spr)) sprite_delete(d.spr);
if(surface_exists(d.thumbnail)) surface_free(d.thumbnail);
}
ds_list_clear(RECENT_FILE_DATA);
for( var i = 0; i < ds_list_size(RECENT_FILES); i++ ) {
var p = RECENT_FILES[| i];
RECENT_FILE_DATA[| i] = new FileObject(filename_name_only(p), p);
}
}
#endregion
#region save load
function PREF_SAVE() { #region
if(IS_CMD) return;
var map = {};
var save_l = [];
for(var j = 0; j < ds_list_size(HOTKEY_CONTEXT); j++) {
var ll = HOTKEYS[? HOTKEY_CONTEXT[| j]];
for(var i = 0; i < ds_list_size(ll); i++)
array_push(save_l, ll[| i].serialize());
}
map.key = save_l;
PREFERENCES.window_maximize = window_is_maximized;
PREFERENCES.window_width = max(960, window_minimize_size[0]);
PREFERENCES.window_height = max(600, window_minimize_size[1]);
map.preferences = PREFERENCES;
json_save_struct(DIRECTORY + "keys.json", map);
json_save_struct(DIRECTORY + "Nodes/fav.json", global.FAV_NODES);
json_save_struct(DIRECTORY + "Nodes/recent.json", global.RECENT_NODES);
json_save_struct(DIRECTORY + "key_nodes.json", HOTKEYS_CUSTOM);
} #endregion
function PREF_LOAD() { #region
var path = DIRECTORY + "keys.json";
if(!file_exists_empty(path)) return;
var map = json_load_struct(path);
if(array_empty(variable_struct_get_names(map))) return;
HOTKEYS_DATA = {};
for(var i = 0; i < array_length(map.key); i++) {
var key_list = map.key[i];
var _context = is_struct(key_list)? key_list.context : key_list[0];
var name = is_struct(key_list)? key_list.name : key_list[1];
HOTKEYS_DATA[$ $"{_context}_{name}"] = key_list;
}
struct_override(PREFERENCES, map.preferences);
if(!directory_exists($"{DIRECTORY}Themes/{PREFERENCES.theme}"))
PREFERENCES.theme = "default";
var f = json_load_struct(DIRECTORY + "key_nodes.json");
struct_override_nested(HOTKEYS_CUSTOM, f);
LOCALE_DEF = PREFERENCES.local == "en";
THEME_DEF = PREFERENCES.theme == "default";
FONT_DEF = PREFERENCES.theme == "default" && PREFERENCES.local == "en" && PREFERENCES.display_scaling == 1;
directory_verify(filepath_resolve(PREFERENCES.temp_path));
if(PREFERENCES.move_directory) directory_set_current_working(DIRECTORY);
} #endregion
function PREF_APPLY() { #region
if(PREFERENCES.double_click_delay > 1)
PREFERENCES.double_click_delay /= 60;
TESTING = struct_try_get(PREFERENCES, "test_mode", false);
if(TESTING) {
log_message("PREFERENCE", "Test mode enabled");
instance_create_depth(0, 0, 0, addon_key_displayer);
}
if(PREFERENCES.use_legacy_exception) resetException();
else setException();
if(OS != os_macosx && !LOADING) {
if(PREFERENCES.window_maximize) {
winMan_Maximize();
} else {
var ww = PREFERENCES.window_width;
var hh = PREFERENCES.window_height;
window_minimize_size = [ ww, hh ];
window_set_position(display_get_width() / 2 - ww / 2, display_get_height() / 2 - hh / 2);
window_set_size(ww, hh);
gameframe_set_shadow(true);
}
}
window_refresh();
game_set_speed(PREFERENCES.ui_framerate, gamespeed_fps);
var grav = struct_try_get(PREFERENCES, "physics_gravity", [ 0, 10 ]);
physics_world_gravity(array_safe_get_fast(grav, 0, 0), array_safe_get_fast(grav, 1, 10));
} #endregion
#endregion

View file

@ -0,0 +1,298 @@
// 2024-04-15 17:50:17
#region preference
globalvar PREFERENCES, PREFERENCES_DEF, HOTKEYS_DATA;
PREFERENCES = {};
HOTKEYS_DATA = {};
#region ////////////////////////////////////////////////////////////////////// GENERAL UI //////////////////////////////////////////////////////////////////////
PREFERENCES.display_scaling = 1;
PREFERENCES.window_width = 1600;
PREFERENCES.window_height = 800;
PREFERENCES.window_maximize = false;
PREFERENCES.theme = "default";
PREFERENCES.local = "en";
PREFERENCES.font_overwrite = "";
PREFERENCES.ui_framerate = 120;
PREFERENCES.path_resolution = 32;
PREFERENCES.move_directory = false;
PREFERENCES.notification_time = 180;
PREFERENCES.notify_load_version = true;
PREFERENCES.show_crash_dialog = false;
PREFERENCES.test_mode = false;
PREFERENCES.auto_save_time = 300;
PREFERENCES.use_legacy_exception = false;
PREFERENCES.caret_blink = 0.75;
PREFERENCES.textbox_shake = 0;
PREFERENCES.textbox_particle = 0;
#endregion
#region ////////////////////////////////////////////////////////////////////////// IO //////////////////////////////////////////////////////////////////////////
PREFERENCES.double_click_delay = 0.25;
PREFERENCES.mouse_wheel_speed = 1.00;
PREFERENCES.keyboard_repeat_start = 0.50;
PREFERENCES.keyboard_repeat_speed = 0.10;
#endregion
#region ///////////////////////////////////////////////////////////////////////// DIALOG ////////////////////////////////////////////////////////////////////////
PREFERENCES.node_recents_amount = 20;
PREFERENCES.show_splash = true;
PREFERENCES.splash_expand_recent = false;
PREFERENCES.dialog_add_node_grouping = true;
PREFERENCES.dialog_add_node_view = 0;
PREFERENCES.dialog_add_node_w = 532;
PREFERENCES.dialog_add_node_h = 400;
PREFERENCES.add_node_remember = true;
#endregion
#region //////////////////////////////////////////////////////////////////////// PANEL /////////////////////////////////////////////////////////////////////////
PREFERENCES.panel_layout_file = "Vertical";
PREFERENCES.panel_graph_dragging = MOD_KEY.alt;
PREFERENCES.panel_graph_group_require_shift = true;
PREFERENCES.panel_preview_dragging = MOD_KEY.alt;
PREFERENCES.panel_preview_show_real_fps = false;
PREFERENCES.panel_menu_resource_monitor = false;
PREFERENCES.panel_menu_right_control = os_type == os_windows;
PREFERENCES.inspector_focus_on_double_click = true;
PREFERENCES.inspector_view_default = 1;
PREFERENCES.node_show_render_status = false;
PREFERENCES.node_show_time = true;
PREFERENCES.expand_hover = false;
PREFERENCES.graph_zoom_smoooth = 4;
PREFERENCES.graph_open_group_in_tab = false;
PREFERENCES.connection_line_width = 2;
PREFERENCES.connection_line_sample = 1;
PREFERENCES.connection_line_corner = 8;
PREFERENCES.connection_line_aa = 2;
PREFERENCES.connection_line_transition = true;
PREFERENCES.connection_line_highlight = 0;
PREFERENCES.connection_line_highlight_fade = 0.75;
PREFERENCES.connection_line_highlight_all = false;
PREFERENCES.curve_connection_line = 1;
PREFERENCES.collection_animated = true;
PREFERENCES.collection_preview_speed = 60;
PREFERENCES.collection_scale = 1;
PREFERENCES.pan_mouse_key = mb_middle;
#endregion
#region //////////////////////////////////////////////////////////////////////// WIDGET ////////////////////////////////////////////////////////////////////////
PREFERENCES.widget_autocomplete_delay = 500;
PREFERENCES.alt_picker = true;
#endregion
#region //////////////////////////////////////////////////////////////////////// NODES /////////////////////////////////////////////////////////////////////////
PREFERENCES.node_param_show = false;
PREFERENCES.node_param_width = 192;
#endregion
#region //////////////////////////////////////////////////////////////////////// MISC //////////////////////////////////////////////////////////////////////////
PREFERENCES.save_file_minify = true;
PREFERENCES.render_all_export = true;
PREFERENCES.clear_temp_on_close = true;
PREFERENCES.show_supporter_icon = true;
#endregion
#region //////////////////////////////////////////////////////////////////////// PATHS /////////////////////////////////////////////////////////////////////////
PREFERENCES.temp_path = "%DIR%/temp/";
PREFERENCES.ImageMagick_path = "%APP%/imagemagick/";
PREFERENCES.webp_path = "%APP%/webp/";
PREFERENCES.gifski_path = "%APP%/gifski/";
PREFERENCES.ffmpeg_path = "%APP%/ffmpeg/";
PREFERENCES.versions = {};
#endregion
PREFERENCES_DEF = variable_clone(PREFERENCES);
#endregion
#region recent files
globalvar RECENT_FILES, RECENT_FILE_DATA;
RECENT_FILES = ds_list_create();
RECENT_FILE_DATA = ds_list_create();
function RECENT_SAVE() {
var map = ds_map_create();
var l = ds_list_create();
ds_list_copy(l, RECENT_FILES);
ds_map_add_list(map, "Recents", l);
var path = DIRECTORY + "recent.json";
var file = file_text_open_write(path);
file_text_write_string(file, json_encode_minify(map));
file_text_close(file);
ds_map_destroy(map);
}
function RECENT_LOAD() {
var path = DIRECTORY + "recent.json";
if(!file_exists_empty(path)) return;
var file = file_text_open_read(path);
var load_str = "";
while(!file_text_eof(file)) {
load_str += file_text_readln(file);
}
file_text_close(file);
var map = json_decode(load_str);
if(ds_map_exists(map, "Recents")) {
var l = map[? "Recents"];
ds_list_clear(RECENT_FILES);
for(var i = 0; i < ds_list_size(l); i++) {
if(!file_exists_empty(l[| i])) continue;
ds_list_add(RECENT_FILES, l[| i]);
}
}
RECENT_REFRESH();
}
function RECENT_REFRESH() {
for( var i = 0; i < ds_list_size(RECENT_FILE_DATA); i++ ) {
var d = RECENT_FILE_DATA[| i];
if(sprite_exists(d.spr)) sprite_delete(d.spr);
if(surface_exists(d.thumbnail)) surface_free(d.thumbnail);
}
ds_list_clear(RECENT_FILE_DATA);
for( var i = 0; i < ds_list_size(RECENT_FILES); i++ ) {
var p = RECENT_FILES[| i];
RECENT_FILE_DATA[| i] = new FileObject(filename_name_only(p), p);
}
}
#endregion
#region save load
function PREF_SAVE() { #region
if(IS_CMD) return;
var map = {};
var save_l = [];
for(var j = 0; j < ds_list_size(HOTKEY_CONTEXT); j++) {
var ll = HOTKEYS[? HOTKEY_CONTEXT[| j]];
for(var i = 0; i < ds_list_size(ll); i++)
array_push(save_l, ll[| i].serialize());
}
map.key = save_l;
PREFERENCES.window_maximize = window_is_maximized;
PREFERENCES.window_width = max(960, window_minimize_size[0]);
PREFERENCES.window_height = max(600, window_minimize_size[1]);
map.preferences = PREFERENCES;
json_save_struct(DIRECTORY + "keys.json", map);
json_save_struct(DIRECTORY + "Nodes/fav.json", global.FAV_NODES);
json_save_struct(DIRECTORY + "Nodes/recent.json", global.RECENT_NODES);
json_save_struct(DIRECTORY + "key_nodes.json", HOTKEYS_CUSTOM);
} #endregion
function PREF_LOAD() { #region
var path = DIRECTORY + "keys.json";
if(!file_exists_empty(path)) return;
var map = json_load_struct(path);
if(array_empty(variable_struct_get_names(map))) return;
HOTKEYS_DATA = {};
for(var i = 0; i < array_length(map.key); i++) {
var key_list = map.key[i];
var _context = is_struct(key_list)? key_list.context : key_list[0];
var name = is_struct(key_list)? key_list.name : key_list[1];
HOTKEYS_DATA[$ $"{_context}_{name}"] = key_list;
}
struct_override(PREFERENCES, map.preferences);
if(!directory_exists($"{DIRECTORY}Themes/{PREFERENCES.theme}"))
PREFERENCES.theme = "default";
var f = json_load_struct(DIRECTORY + "key_nodes.json");
struct_override_nested(HOTKEYS_CUSTOM, f);
LOCALE_DEF = PREFERENCES.local == "en";
THEME_DEF = PREFERENCES.theme == "default";
FONT_DEF = PREFERENCES.theme == "default" && PREFERENCES.local == "en" && PREFERENCES.display_scaling == 1;
directory_verify(filepath_resolve(PREFERENCES.temp_path));
if(PREFERENCES.move_directory) directory_set_current_working(DIRECTORY);
} #endregion
function PREF_APPLY() { #region
if(PREFERENCES.double_click_delay > 1)
PREFERENCES.double_click_delay /= 60;
TESTING = struct_try_get(PREFERENCES, "test_mode", false);
if(TESTING) {
log_message("PREFERENCE", "Test mode enabled");
instance_create_depth(0, 0, 0, addon_key_displayer);
}
if(PREFERENCES.use_legacy_exception) resetException();
else setException();
if(OS != os_macosx && !LOADING) {
if(PREFERENCES.window_maximize) {
winMan_Maximize();
} else {
var ww = PREFERENCES.window_width;
var hh = PREFERENCES.window_height;
window_minimize_size = [ ww, hh ];
window_set_position(display_get_width() / 2 - ww / 2, display_get_height() / 2 - hh / 2);
window_set_size(ww, hh);
gameframe_set_shadow(true);
}
}
window_refresh();
game_set_speed(PREFERENCES.ui_framerate, gamespeed_fps);
var grav = struct_try_get(PREFERENCES, "physics_gravity", [ 0, 10 ]);
physics_world_gravity(array_safe_get_fast(grav, 0, 0), array_safe_get_fast(grav, 1, 10));
} #endregion
#endregion

View file

@ -0,0 +1,77 @@
// 2024-04-16 08:41:19
function string_to_array(str) { #region
var amo = string_length(str);
var arr = array_create(amo);
for( var i = 0; i < amo; i++ )
arr[i] = string_char_at(str, i + 1);
return arr;
} #endregion
function string_partial_match(str, key) { #region
var amo = string_length(str);
var run = 1;
var consec = 0;
var conMax = 0;
var misMatch = 0;
var kchr = string_char_at(key, run);
for( var i = 1; i <= amo; i++ ) {
var ch = string_char_at(str, i);
if(ch == kchr) {
consec++;
conMax = max(conMax, consec);
run++;
if(run > string_length(key)) return conMax - (misMatch + (amo - i));
kchr = string_char_at(key, run);
} else {
consec = 0;
misMatch += amo - i;
}
}
return -9999;
} #endregion
function string_real(val, digMax = 999, decMin = 5) { #region
if(is_string(val)) return val;
if(is_struct(val)) return string(val);
if(is_array(val)) {
var s = "[";
var i = 0, n = array_length(val);
repeat( n ) { s += (i? ", " : "") + string_real(val[i]); i++; }
return s + "]";
}
if(val == 0 || !is_numeric(val)) return "0";
var pres, p = 1;
var presMax = min(decMin, digMax - ceil(log10(ceil(abs(val)))));
for( pres = 0; pres < presMax; pres++ ) {
if(frac(val * p) == 0)
break;
p *= 10;
}
return string_format(val, -1, pres);
} #endregion
function string_char_last(str, shift = 0) { #region
INLINE
return string_char_at(str, string_length(str) - shift);
} #endregion
function filename_name_only(name) { #region
name = filename_name(name);
return string_replace(name, filename_ext(name), "")
} #endregion
function string_to_var(str) { #region
INLINE
return string_replace_all(string_lower(str), " ", "_");
} #endregion
function string_quote(str) { #region
INLINE
return $"\"{str}\"";
} #endregion

View file

@ -0,0 +1,77 @@
// 2024-04-16 08:29:49
function string_to_array(str) { #region
var amo = string_length(str);
var arr = array_create(amo);
for( var i = 0; i < amo; i++ )
arr[i] = string_char_at(str, i + 1);
return arr;
} #endregion
function string_partial_match(str, key) { #region
var amo = string_length(str);
var run = 1;
var consec = 0;
var conMax = 0;
var misMatch = 0;
var kchr = string_char_at(key, run);
for( var i = 1; i <= amo; i++ ) {
var ch = string_char_at(str, i);
if(ch == kchr) {
consec++;
conMax = max(conMax, consec);
run++;
if(run > string_length(key)) return conMax - (misMatch + (amo - i));
kchr = string_char_at(key, run);
} else {
consec = 0;
misMatch += amo - i;
}
}
return -9999;
} #endregion
function string_real(val, digMax = 999, decMin = 5) { #region
if(is_string(val)) return val;
if(is_struct(val)) return string(val);
if(is_array(val)) {
var s = "[";
var i = 0, n = array_length(val);
repeat( n ) { s += (i? ", " : "") + string_real(val[i]); i++; }
return s + "]";
}
if(val == 0 || !is_numeric(val)) return "0";
var pres, p = 1;
var presMax = min(decMin, digMax - ceil(log10(ceil(abs(val)))));
for( pres = 0; pres < presMax; pres++ ) {
if(frac(val * p) == 0)
break;
p *= 10;
}
return string_format(val, -1, pres);
} #endregion
function string_char_last(str, shift = 0) { #region
INLINE
return string_char_at(str, string_length(str) - shift);
} #endregion
function filename_name_only(name) { #region
name = filename_name(name);
return string_replace(name, filename_ext(name), "")
} #endregion
function string_to_var(str) { #region
INLINE
return string_replace_all(string_lower(str), " ", "_");
} #endregion
function string_quote(str) { #region
INLINE
return $"\"{str}\"";
} #endregion

View file

@ -1,4 +1,4 @@
// 2023-08-07 09:34:22
// 2024-04-16 14:58:44
//
// Simple passthrough fragment shader
//
@ -21,20 +21,19 @@ float sampleMask() {
}
void main() {
vec4 _col1 = texture2D( gm_BaseTexture, v_vTexcoord );
vec4 _cBg = texture2D( gm_BaseTexture, v_vTexcoord );
vec2 fore_tex = v_vTexcoord;
if(tile_type == 0) {
if(tile_type == 0)
fore_tex = v_vTexcoord;
} else if(tile_type == 1) {
else if(tile_type == 1)
fore_tex = fract(v_vTexcoord * dimension);
}
vec4 _col0 = texture2D( fore, fore_tex );
_col0.a *= opacity * sampleMask();
vec4 _cFg = texture2D( fore, fore_tex );
_cFg.a *= opacity * sampleMask();
float al = _col0.a + _col1.a * (1. - _col0.a);
vec4 res = ((_col0 * _col0.a) + (_col1 * _col1.a * (1. - _col0.a))) / al;
float al = _cFg.a + _cBg.a * (1. - _cFg.a);
vec4 res = ((_cFg * _cFg.a) + (_cBg * _cBg.a * (1. - _cFg.a))) / al;
res.a = al;
gl_FragColor = res;

View file

@ -0,0 +1,41 @@
// 2023-08-07 09:34:22
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform vec2 dimension;
uniform int tile_type;
uniform int useMask;
uniform int preserveAlpha;
uniform sampler2D mask;
uniform sampler2D fore;
uniform float opacity;
float sampleMask() {
if(useMask == 0) return 1.;
vec4 m = texture2D( mask, v_vTexcoord );
return (m.r + m.g + m.b) / 3. * m.a;
}
void main() {
vec4 _col1 = texture2D( gm_BaseTexture, v_vTexcoord );
vec2 fore_tex = v_vTexcoord;
if(tile_type == 0) {
fore_tex = v_vTexcoord;
} else if(tile_type == 1) {
fore_tex = fract(v_vTexcoord * dimension);
}
vec4 _col0 = texture2D( fore, fore_tex );
_col0.a *= opacity * sampleMask();
float al = _col0.a + _col1.a * (1. - _col0.a);
vec4 res = ((_col0 * _col0.a) + (_col1 * _col1.a * (1. - _col0.a))) / al;
res.a = al;
gl_FragColor = res;
}

8
#config/properties.json Normal file
View file

@ -0,0 +1,8 @@
{
"builderSettings": {
"runtimeVersion": "runtime-2024.2.0.163"
},
"linterPrefs": {
}
}

View file

@ -353,6 +353,7 @@
{"name":"canvas_freeform","order":3,"path":"scripts/canvas_freeform/canvas_freeform.yy",},
{"name":"canvas_magic_selection_functions","order":4,"path":"scripts/canvas_magic_selection_functions/canvas_magic_selection_functions.yy",},
{"name":"canvas_tool_brush_shape","order":3,"path":"scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.yy",},
{"name":"canvas_tool_curve","order":14,"path":"scripts/canvas_tool_curve/canvas_tool_curve.yy",},
{"name":"canvas_tool_draw_freeform","order":5,"path":"scripts/canvas_tool_draw_freeform/canvas_tool_draw_freeform.yy",},
{"name":"canvas_tool_extrude","order":1,"path":"scripts/canvas_tool_extrude/canvas_tool_extrude.yy",},
{"name":"canvas_tool_fill","order":4,"path":"scripts/canvas_tool_fill/canvas_tool_fill.yy",},
@ -360,6 +361,7 @@
{"name":"canvas_tool_node","order":12,"path":"scripts/canvas_tool_node/canvas_tool_node.yy",},
{"name":"canvas_tool_outline","order":3,"path":"scripts/canvas_tool_outline/canvas_tool_outline.yy",},
{"name":"canvas_tool_resize","order":11,"path":"scripts/canvas_tool_resize/canvas_tool_resize.yy",},
{"name":"canvas_tool_selection_brush","order":13,"path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",},
{"name":"canvas_tool_selection_freeform","order":8,"path":"scripts/canvas_tool_selection_freeform/canvas_tool_selection_freeform.yy",},
{"name":"canvas_tool_selection_magic","order":9,"path":"scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.yy",},
{"name":"canvas_tool_selection_shape","order":6,"path":"scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.yy",},
@ -1127,7 +1129,7 @@
{"name":"safe_operation","order":6,"path":"scripts/safe_operation/safe_operation.yy",},
{"name":"sample_projects","order":6,"path":"scripts/sample_projects/sample_projects.yy",},
{"name":"save_function","order":1,"path":"scripts/save_function/save_function.yy",},
{"name":"canvas_tool_selection_brush","order":13,"path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",},
{"name":"canvas_tool_with_selector","order":5,"path":"scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy",},
{"name":"scrollBox","order":2,"path":"scripts/scrollBox/scrollBox.yy",},
{"name":"scrollPane","order":3,"path":"scripts/scrollPane/scrollPane.yy",},
{"name":"shell_functions","order":20,"path":"scripts/shell_functions/shell_functions.yy",},

View file

@ -714,6 +714,7 @@
{"id":{"name":"canvas_magic_selection_functions","path":"scripts/canvas_magic_selection_functions/canvas_magic_selection_functions.yy",},},
{"id":{"name":"canvas_tool_brush_shape","path":"scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.yy",},},
{"id":{"name":"canvas_tool_brush","path":"scripts/canvas_tool_brush/canvas_tool_brush.yy",},},
{"id":{"name":"canvas_tool_curve","path":"scripts/canvas_tool_curve/canvas_tool_curve.yy",},},
{"id":{"name":"canvas_tool_draw_freeform","path":"scripts/canvas_tool_draw_freeform/canvas_tool_draw_freeform.yy",},},
{"id":{"name":"canvas_tool_extrude","path":"scripts/canvas_tool_extrude/canvas_tool_extrude.yy",},},
{"id":{"name":"canvas_tool_fill","path":"scripts/canvas_tool_fill/canvas_tool_fill.yy",},},
@ -721,6 +722,7 @@
{"id":{"name":"canvas_tool_node","path":"scripts/canvas_tool_node/canvas_tool_node.yy",},},
{"id":{"name":"canvas_tool_outline","path":"scripts/canvas_tool_outline/canvas_tool_outline.yy",},},
{"id":{"name":"canvas_tool_resize","path":"scripts/canvas_tool_resize/canvas_tool_resize.yy",},},
{"id":{"name":"canvas_tool_selection_brush","path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",},},
{"id":{"name":"canvas_tool_selection_freeform","path":"scripts/canvas_tool_selection_freeform/canvas_tool_selection_freeform.yy",},},
{"id":{"name":"canvas_tool_selection_magic","path":"scripts/canvas_tool_selection_magic/canvas_tool_selection_magic.yy",},},
{"id":{"name":"canvas_tool_selection_shape","path":"scripts/canvas_tool_selection_shape/canvas_tool_selection_shape.yy",},},
@ -1608,7 +1610,7 @@
{"id":{"name":"safe_operation","path":"scripts/safe_operation/safe_operation.yy",},},
{"id":{"name":"sample_projects","path":"scripts/sample_projects/sample_projects.yy",},},
{"id":{"name":"save_function","path":"scripts/save_function/save_function.yy",},},
{"id":{"name":"canvas_tool_selection_brush","path":"scripts/canvas_tool_selection_brush/canvas_tool_selection_brush.yy",},},
{"id":{"name":"canvas_tool_with_selector","path":"scripts/canvas_tool_with_selector/canvas_tool_with_selector.yy",},},
{"id":{"name":"scrollBox","path":"scripts/scrollBox/scrollBox.yy",},},
{"id":{"name":"scrollPane","path":"scripts/scrollPane/scrollPane.yy",},},
{"id":{"name":"shader_functions","path":"scripts/shader_functions/shader_functions.yy",},},

0
PixelComposer.yyp.css Normal file
View file

Binary file not shown.

View file

@ -248,7 +248,7 @@ event_inherited();
}
} #endregion
catagory_pane = new scrollPane(category_width, dialog_h - ui(66), function(_y, _m) { #region
catagory_pane = new scrollPane(category_width, dialog_h - ui(66), function(_y, _m) { #region catagory_pane
draw_clear_alpha(COLORS._main_text, 0);
var ww = category_width - ui(32);
@ -339,7 +339,7 @@ event_inherited();
return hh;
}); #endregion
content_pane = new scrollPane(dialog_w - category_width - ui(8), dialog_h - ui(66), function(_y, _m) { #region
content_pane = new scrollPane(dialog_w - category_width - ui(8), dialog_h - ui(66), function(_y, _m) { #region content_pane
draw_clear_alpha(c_white, 0);
var _hover = sHOVER && content_pane.hover;
var _list = node_list;

View file

@ -16,6 +16,12 @@ function canvas_tool() constructor {
subtool = 0;
function disable() {
PANEL_PREVIEW.tool_current = noone;
}
function getTool() { return self; }
function init() {}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {}

View file

@ -139,23 +139,23 @@ function drawPaletteGrid(_pal, _x, _y, _w, _gs = 24, c_color = -1) { #region
var amo = array_length(_pal);
var col = floor(_w / _gs);
var row = ceil(amo / col);
var cx = -1, cy = -1;
var _pd = ui(5);
for(var i = 0; i < array_length(_pal); i++) {
draw_set_color(_pal[i]);
var _x0 = _x + safe_mod(i, col) * _gs;
var _y0 = _y + floor(i / col) * _gs;
draw_rectangle(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, false);
if(c_color == _pal[i]) {
cx = _x0;
cy = _y0;
}
}
if(c_color == -1) return;
if(cx == -1) return;
for(var i = 0; i < array_length(_pal); i++) {
if(c_color != _pal[i]) continue;
var _x0 = _x + safe_mod(i, col) * _gs;
var _y0 = _y + floor(i / col) * _gs;
draw_set_color(c_white);
draw_rectangle_border(_x0, _y0 + 1, _x0 + _gs, _y0 + _gs, 2);
}
draw_sprite_stretched_ext(THEME.palette_selecting, 0, cx - _pd, cy + 1 - _pd, _gs + _pd * 2, _gs + _pd * 2);
} #endregion

View file

@ -24,7 +24,7 @@ function canvas_draw_point_size(brush, _x, _y, _draw = false) { #region
}
} #endregion
function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false) { #region
function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false, _cap = false) { #region
if(brush.brush_surface == noone) {
@ -44,8 +44,13 @@ function canvas_draw_line_size(brush, _x0, _y0, _x1, _y1, _draw = false) { #regi
for( var i = 0, n = array_length(fx); i < n; i++ )
draw_line(_x0 + fx[i][0], _y0 + fx[i][1], _x1 + fx[i][0], _y1 + fx[i][1]);
} else
} else {
draw_line_width(_x0, _y0, _x1, _y1, brush.brush_size);
if(_cap) {
canvas_draw_point_size(brush, _x0, _y0, true);
canvas_draw_point_size(brush, _x1, _y1, true);
}
}
} else {
var diss = point_distance(_x0, _y0, _x1, _y1);
@ -157,3 +162,29 @@ function canvas_draw_ellp_size(brush, _x0, _y0, _x1, _y1, _fill) { #region
oy = ny;
}
} #endregion
function canvas_draw_curve_brush(brush, x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region
var ox, oy, nx, ny;
var _st = 1 / prec;
for (var i = 0; i <= prec; i++) {
var _t = _st * i;
var _t1 = 1 - _t;
nx = _t1 * _t1 * _t1 * x0 +
3 * (_t1 * _t1 * _t) * cx0 +
3 * (_t1 * _t * _t) * cx1 +
_t * _t * _t * x1;
ny = _t1 * _t1 * _t1 * y0 +
3 * (_t1 * _t1 * _t) * cy0 +
3 * (_t1 * _t * _t) * cy1 +
_t * _t * _t * y1;
if(i) canvas_draw_line_size(brush, ox, oy, nx, ny, true, true);
ox = nx;
oy = ny;
}
} #endregion

View file

@ -27,7 +27,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
}
if(mouse_press(mb_left, active)) {
brush_next_dist = 0;
surface_set_shader(drawing_surface, noone);
canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y, true);
@ -36,7 +35,6 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
mouse_holding = true;
if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT)) { ///////////////// shift line
surface_set_shader(drawing_surface, noone, true, BLEND.alpha);
brush_next_dist = 0;
canvas_draw_line_size(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, true);
surface_reset_shader();
mouse_holding = false;

View file

@ -6,7 +6,6 @@ enum CANVAS_TOOL_SHAPE {
function canvas_tool_shape(brush, shape) : canvas_tool() constructor {
self.brush = brush;
self.shape = shape;
self.fill = false;
brush_resizable = true;
mouse_holding = false;
@ -35,10 +34,10 @@ function canvas_tool_shape(brush, shape) : canvas_tool() constructor {
surface_set_shader(drawing_surface, noone);
if(shape == CANVAS_TOOL_SHAPE.rectangle)
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill);
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
else if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill);
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
surface_reset_shader();
@ -66,10 +65,10 @@ function canvas_tool_shape(brush, shape) : canvas_tool() constructor {
}
if(shape == CANVAS_TOOL_SHAPE.rectangle)
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill);
canvas_draw_rect_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill);
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, subtool);
}
}

View file

@ -0,0 +1,184 @@
function canvas_tool_curve_bezier(brush) : canvas_tool() constructor {
self.brush = brush;
brush_resizable = true;
anchors = [];
mouse_cur_x = 0;
mouse_cur_y = 0;
editing = [ noone, 0 ];
mouse_edit_mx = 0;
mouse_edit_my = 0;
mouse_edit_sx = 0;
mouse_edit_sy = 0;
mouse_hovering = [ noone, 0 ];
draw_hovering = [];
function init() {
anchors = [];
editing = [ noone, 0 ];
}
function apply() {
apply_draw_surface();
disable();
}
function cancel() {
surface_clear(drawing_surface);
disable();
}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
mouse_cur_x = (_mx - _x) / _s;
mouse_cur_y = (_my - _y) / _s;
if(editing[0] != noone) {
var _a = anchors[editing[0]];
var _dx = mouse_cur_x - mouse_edit_mx;
var _dy = mouse_cur_y - mouse_edit_my;
if(editing[1] == 0) {
_a[2] += _dx;
_a[3] += _dy;
} else if(editing[1] == -1) {
_a[0] += _dx;
_a[1] += _dy;
_a[4] -= _dx;
_a[5] -= _dy;
} else if(editing[1] == 1) {
_a[0] -= _dx;
_a[1] -= _dy;
_a[4] += _dx;
_a[5] += _dy;
}
mouse_edit_mx = mouse_cur_x;
mouse_edit_my = mouse_cur_y;
if(mouse_release(mb_left))
editing[0] = noone;
}
if(mouse_press(mb_left, active)) {
if(mouse_hovering[0] == noone) {
array_push(anchors, [ 0, 0, mouse_cur_x, mouse_cur_y, 0, 0 ]);
editing[0] = array_length(anchors) - 1;
editing[1] = 1;
} else {
if(key_mod_press(SHIFT))
array_delete(anchors, mouse_hovering[0], 1);
else {
editing[0] = mouse_hovering[0];
editing[1] = mouse_hovering[1];
}
}
mouse_edit_mx = mouse_cur_x;
mouse_edit_my = mouse_cur_y;
mouse_edit_sx = mouse_cur_x;
mouse_edit_sy = mouse_cur_y;
}
surface_set_shader(drawing_surface, noone);
var ox, oy, nx, ny;
var oax1, oay1, nax0, nay0;
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = anchors[i][2];
ny = anchors[i][3];
nax0 = nx + anchors[i][0];
nay0 = ny + anchors[i][1];
if(i) canvas_draw_curve_brush(brush, ox, oy, oax1, oay1, nax0, nay0, nx, ny);
oax1 = nx + anchors[i][4];
oay1 = ny + anchors[i][5];
ox = nx;
oy = ny;
}
surface_reset_shader();
node.tool_curve_apply.setInteract(!array_empty(anchors));
node.tool_curve_cancel.setInteract(!array_empty(anchors));
if(key_press(vk_enter)) apply();
if(key_press(vk_escape)) disable();
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
draw_surface_ext_safe(drawing_surface, _x, _y, _s, _s);
}
function drawMask(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var ox, oy, nx, ny, ax0, ay0, ax1, ay1;
var oax1, oay1, nax0, nay0;
draw_set_color(c_white);
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = _x + anchors[i][2] * _s;
ny = _y + anchors[i][3] * _s;
nax0 = nx + anchors[i][0] * _s;
nay0 = ny + anchors[i][1] * _s;
if(i) draw_curve_bezier(ox, oy, oax1, oay1, nax0, nay0, nx, ny);
oax1 = nx + anchors[i][4] * _s;
oay1 = ny + anchors[i][5] * _s;
draw_line(nx, ny, nax0, nay0);
draw_line(nx, ny, oax1, oay1);
ox = nx;
oy = ny;
}
mouse_hovering = [ noone, 0 ];
draw_hovering = array_verify(draw_hovering, array_length(anchors) * 3);
for (var i = 0, n = array_length(anchors); i < n; i++) {
nx = _x + anchors[i][2] * _s;
ny = _y + anchors[i][3] * _s;
ax0 = nx + anchors[i][0] * _s;
ay0 = ny + anchors[i][1] * _s;
ax1 = nx + anchors[i][4] * _s;
ay1 = ny + anchors[i][5] * _s;
draw_anchor(0, nx, ny, lerp(10, 13, draw_hovering[i * 3 + 1]));
draw_anchor(0, ax0, ay0, lerp( 7, 10, draw_hovering[i * 3 + 0]));
draw_anchor(0, ax1, ay1, lerp( 7, 10, draw_hovering[i * 3 + 2]));
if(point_in_circle(_mx, _my, nx, ny, 10)) mouse_hovering = [ i, 0 ];
else if(point_in_circle(_mx, _my, ax0, ay0, 10)) mouse_hovering = [ i, -1 ];
else if(point_in_circle(_mx, _my, ax1, ay1, 10)) mouse_hovering = [ i, 1 ];
}
if(mouse_hovering[0] != noone) {
var index = mouse_hovering[0] * 3 + mouse_hovering[1] + 1;
for (var i = 0, n = array_length(draw_hovering); i < n; i++)
draw_hovering[i] = lerp_float(draw_hovering[i], i == index, 4);
}
}
}

View file

@ -0,0 +1,13 @@
{
"$GMScript":"",
"%Name":"canvas_tool_curve",
"isCompatibility":false,
"isDnD":false,
"name":"canvas_tool_curve",
"parent":{
"name":"tools",
"path":"folders/nodes/data/canvas/tools.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",
}

View file

@ -27,8 +27,15 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
if(applySelection) canvas.tool_selection.apply();
canvas.nodeTool = noone;
surface_free(targetSurface);
surface_free(maskedSurface);
surface_free_safe(maskedSurface);
cleanUp();
}
static cleanUp = function() {
surface_free_safe(targetSurface);
surface_free_safe(maskedSurface);
nodeObject.destroy();
}
nodeObject = node.build(0, 0);
@ -65,21 +72,41 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
////////////////////////////////////////////////////////////////////////////////////////////////////////
function apply() {
var _surf = surface_create(sw, sh);
if(applySelection) {
surface_set_shader(_surf, sh_blend_normal);
shader_set_surface("fore", maskedSurface);
shader_set_f("dimension", 1, 1);
shader_set_f("opacity", 1);
draw_surface(canvas.tool_selection.selection_surface, 0, 0);
surface_reset_shader();
surface_free(canvas.tool_selection.selection_surface);
canvas.tool_selection.selection_surface = maskedSurface;
canvas.tool_selection.selection_surface = _surf;
canvas.tool_selection.apply();
} else {
canvas.storeAction();
canvas.setCanvasSurface(maskedSurface);
surface_set_shader(_surf, sh_blend_normal);
shader_set_surface("fore", maskedSurface);
shader_set_f("dimension", 1, 1);
shader_set_f("opacity", 1);
draw_surface(canvas.getCanvasSurface(), 0, 0);
surface_reset_shader();
canvas.setCanvasSurface(_surf);
canvas.surface_store_buffer();
}
PANEL_PREVIEW.tool_current = noone;
canvas.nodeTool = noone;
surface_free_safe(targetSurface);
cleanUp();
}
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
@ -109,7 +136,10 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
else if(inputJunction.name == "Dimension")
inputJunction.setValue([ sw, sh ]);
}
nodeObject.update();
if(is_instanceof(nodeObject, Node_Collection))
RenderList(nodeObject.nodes);
else
nodeObject.update();
var _surf = outputJunction.getValue();
@ -125,6 +155,7 @@ function canvas_tool_node(canvas, node) : canvas_tool() constructor {
} else
maskedSurface = _surf;
draw_surface_ext_safe(destiSurface, _dx, _dy, _s, _s);
draw_surface_ext_safe(maskedSurface, _dx, _dy, _s, _s);
if(mouse_press(mb_left, active)) { apply(); MOUSE_BLOCK = true; }

View file

@ -22,8 +22,13 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor {
mouse_pre_y = 0;
function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region
if(is_selected)
apply();
else {
createNewSelection(_mask, sel_x0, sel_y0, sel_w, sel_h);
return;
}
if(key_mod_press(SHIFT))
modifySelection(_mask, sel_x0, sel_y0, sel_w, sel_h, true);

View file

@ -62,10 +62,10 @@ function canvas_tool_selection_brush(selector, brush) : canvas_tool_selection(se
sel_x1 = max(sel_x1, mouse_cur_x + brush.brush_size);
sel_y1 = max(sel_y1, mouse_cur_y + brush.brush_size);
if(mouse_release(mb_left)) {
var _sel_w = sel_x1 - sel_x0;
var _sel_h = sel_y1 - sel_y0;
var _sel_w = sel_x1 - sel_x0;
var _sel_h = sel_y1 - sel_y0;
if(mouse_release(mb_left)) {
var _sel = surface_create(_sel_w, _sel_h);
surface_set_shader(_sel);
draw_surface(selection_mask, -sel_x0, -sel_y0);

View file

@ -53,6 +53,10 @@ function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
surface_free_safe(selection_mask);
if(node.selection_tool_after != noone)
node.selection_tool_after.toggle();
node.selection_tool_after = noone;
}
}
}

View file

@ -36,6 +36,8 @@ function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(se
surface_reset_target();
PANEL_PREVIEW.mouse_pos_string = $"[{sel_w}, {sel_h}]";
if(mouse_release(mb_left)) {
is_selecting = false;
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);

View file

@ -0,0 +1,9 @@
function canvas_tool_with_selector(tool) : canvas_tool() constructor {
self.tool = tool;
function init(node) {
node.selection_tool_after = tool;
}
function getTool() { return node.tool_sel_magic; }
}

View file

@ -0,0 +1,13 @@
{
"$GMScript":"",
"%Name":"canvas_tool_with_selector",
"isCompatibility":false,
"isDnD":false,
"name":"canvas_tool_with_selector",
"parent":{
"name":"actions",
"path":"folders/nodes/data/canvas/actions.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",
}

View file

@ -194,3 +194,29 @@ function curveMap(_bz, _prec = 32, _tolr = 0.00001) constructor {
return lerp(map[_indL], map[_indH], _indF);
} #endregion
}
function draw_curve_bezier(x0, y0, cx0, cy0, cx1, cy1, x1, y1, prec = 32) { #region
var ox, oy, nx, ny;
var _st = 1 / prec;
for (var i = 0; i <= prec; i++) {
var _t = _st * i;
var _t1 = 1 - _t;
nx = _t1 * _t1 * _t1 * x0 +
3 * (_t1 * _t1 * _t) * cx0 +
3 * (_t1 * _t * _t) * cx1 +
_t * _t * _t * x1;
ny = _t1 * _t1 * _t1 * y0 +
3 * (_t1 * _t1 * _t) * cy0 +
3 * (_t1 * _t * _t) * cy1 +
_t * _t * _t * y1;
if(i) draw_line(ox, oy, nx, ny);
ox = nx;
oy = ny;
}
} #endregion

View file

@ -53,7 +53,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
frame_renderer_x_max = 0;
frame_renderer_content = surface_create(1, 1);
frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region
frame_renderer = new Inspector_Custom_Renderer(function(_x, _y, _w, _m, _hover, _focus) { #region frame_renderer
var _h = 64;
_y += 8;
@ -182,7 +182,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
preview_draw_mask = surface_create_empty(1, 1);
draw_stack = ds_list_create();
brush = new canvas_brush();
#endregion
#region ++++ tool object ++++
brush = new canvas_brush();
tool_selection = new canvas_tool_selection();
tool_brush = new canvas_tool_brush(brush, false);
tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush);
tool_curve_bez = new canvas_tool_curve_bezier(brush);
tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle);
tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse);
tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush);
tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute);
tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush);
#endregion
@ -196,7 +216,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_attribute.pickColor = c_white;
tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; });
tool_attribute.mirror = [ false, false ];
tool_attribute.mirror = [ false, false, false ];
tool_mirror_edit = new checkBoxGroup( THEME.canvas_mirror, function(ind, val) { tool_attribute.mirror[ind] = val; });
tool_settings = [ [ "", tool_channel_edit, "channel", tool_attribute ],
@ -222,48 +242,52 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_fil8_edit = new checkBox(function() { tool_attribute.fill8 = !tool_attribute.fill8; });
tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ];
tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ]),
tool_attribute.button_apply = [ false, false ];
tool_curve_apply = button( function() { tool_curve_bez.apply(); } ).setIcon(THEME.toolbar_check, 0);
tool_curve_cancel = button( function() { tool_curve_bez.cancel(); } ).setIcon(THEME.toolbar_check, 1);
new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
toolObject_selection_magic = new NodeTool( "Magic Selection", THEME.canvas_tools_magic_selection )
.setSetting(tool_thrs)
.setSetting(tool_fil8),
.setSetting(tool_fil8)
.setToolObject(tool_sel_magic)
tools = [
new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection, THEME.canvas_tools_selection_brush ])
.setToolObject([ tool_sel_rectangle, tool_sel_ellipse, tool_sel_freeform, tool_sel_brush ]),
toolObject_selection_magic,
new NodeTool( "Pencil", THEME.canvas_tools_pencil)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_brush),
new NodeTool( "Eraser", THEME.canvas_tools_eraser)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_eraser),
new NodeTool( "Rectangle", [ THEME.canvas_tools_rect, THEME.canvas_tools_rect_fill ])
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_rectangle),
new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ])
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_ellipse),
new NodeTool( "Curve", THEME.canvas_tool_curve_icon)
.setSetting(tool_size)
.setSetting([ "", tool_curve_apply, 0, tool_attribute ])
.setSetting([ "", tool_curve_cancel, 0, tool_attribute ])
.setToolObject(tool_curve_bez),
new NodeTool( "Freeform", THEME.canvas_tools_freeform)
.setSetting(tool_size),
.setSetting(tool_size)
.setToolObject(tool_freeform),
new NodeTool( "Fill", THEME.canvas_tools_bucket)
.setSetting(tool_thrs)
.setSetting(tool_fil8),
.setSetting(tool_fil8)
.setToolObject(tool_fill),
];
tool_selection = new canvas_tool_selection();
tool_brush = new canvas_tool_brush(brush, false);
tool_eraser = new canvas_tool_brush(brush, true);
tool_rectangle = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.rectangle);
tool_ellipse = new canvas_tool_shape(brush, CANVAS_TOOL_SHAPE.ellipse);
tool_fill = new canvas_tool_fill(tool_attribute);
tool_freeform = new canvas_tool_draw_freeform(brush);
tool_sel_rectangle = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.rectangle);
tool_sel_ellipse = new canvas_tool_selection_shape(tool_selection, CANVAS_TOOL_SHAPE.ellipse);
tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush);
tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute);
tool_sel_brush = new canvas_tool_selection_brush(tool_selection, brush);
#endregion
#region ++++ right tools ++++
@ -313,9 +337,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
new NodeTool( "Make/Reset Brush", THEME.canvas_tools_pencil ).setToolFn( __action_make_brush ),
-1,
new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ),
new NodeTool( [ "Extrude", "Inset" ],
[ THEME.canvas_tools_extrude, THEME.canvas_tools_inset ] )
.setToolObject( [ new canvas_tool_extrude(), new canvas_tool_inset() ] ),
new NodeTool( "Extrude", THEME.canvas_tools_extrude ).setToolObject( new canvas_tool_extrude() ),
new NodeTool( "Inset", THEME.canvas_tools_inset ).setToolObject( new canvas_tool_inset() ),
];
rightTools_not_selection = [
-1,
new NodeTool( "Outline", THEME.canvas_tools_outline, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[3]) ),
new NodeTool( "Extrude", THEME.canvas_tools_extrude, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[4]) ),
new NodeTool( "Inset", THEME.canvas_tools_inset, self ).setToolObject( new canvas_tool_with_selector(rightTools_selection[5]) ),
];
rightTools_brush = [
@ -329,6 +359,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_eraser.rightTools = rightTools_brush;
tool_rectangle.rightTools = rightTools_brush;
tool_ellipse.rightTools = rightTools_brush;
selection_tool_after = noone;
#endregion
function setToolColor(color) { tool_attribute.color = color; }
@ -390,7 +422,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
return hh + ui(4);
} #endregion
function removeFrame(index = 0) { #region
static removeFrame = function(index = 0) { #region
if(attributes.frames <= 1) return;
if(preview_index == attributes.frames)
@ -402,7 +434,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
update();
} #endregion
function refreshFrames() { #region
static refreshFrames = function() { #region
var fr = attributes.frames;
var _dim = attributes.dimension;
@ -428,7 +460,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
function setCanvasSurface(surface, index = preview_index) { INLINE canvas_surface[index] = surface; }
function storeAction() { #region
static storeAction = function() { #region
var action = recordAction(ACTION_TYPE.custom, function(data) {
is_selected = false;
@ -446,7 +478,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
action.clear_action = function(data) { surface_free_safe(data.surface); };
} #endregion
function apply_surfaces() { #region
static apply_surfaces = function() { #region
for( var i = 0; i < attributes.frames; i++ )
apply_surface(i);
} #endregion
@ -501,7 +533,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
apply_surface(index);
} #endregion
function tool_pick_color(_x, _y) { #region
static tool_pick_color = function(_x, _y) { #region
if(tool_selection.is_selected)
tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]);
else
@ -531,9 +563,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
BLEND_ALPHA
if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, -_spy, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, -_spx, _spy * 2 + _sph - _spy, 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _spx * 2 + _spw - _spx, _spy * 2 + _sph - _spy, -1, -1);
BLEND_NORMAL
@ -553,11 +585,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_surface(drawing_surface, 0, 0);
BLEND_ALPHA
if(tool_attribute.mirror[0]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1);
if(tool_attribute.mirror[0] == false) {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, -1);
} else {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], -1, 1, -90);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, 0, 0, -1, 1, 90);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(drawing_surface, _dim[0], _dim[1], 1, 1, 180);
}
BLEND_NORMAL
surface_reset_target();
@ -641,6 +677,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
array_append(rightTools, rightTools_general);
if(tool_selection.is_selected) array_append(rightTools, rightTools_selection);
else array_append(rightTools, rightTools_not_selection);
if(nodeTool != noone)
_tool = nodeTool;
@ -648,37 +685,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
else if(_currTool != noone) {
_tool = _currTool.getToolObject();
switch(_currTool.getName()) {
case "Pencil" : _tool = tool_brush; break;
case "Eraser" : _tool = tool_eraser; break;
case "Fill" : _tool = tool_fill; break;
case "Freeform" : _tool = tool_freeform; break;
case "Rectangle" :
_tool = tool_rectangle;
_tool.fill = _currTool.selecting == 1;
break;
case "Ellipse" :
_tool = tool_ellipse;
_tool.fill = _currTool.selecting == 1;
break;
case "Selection" :
switch(_currTool.selecting) {
case 0 : _tool = tool_sel_rectangle; break;
case 1 : _tool = tool_sel_ellipse; break;
case 2 : _tool = tool_sel_freeform; break;
case 3 : _tool = tool_sel_brush; break;
}
break;
case "Magic Selection" : _tool = tool_sel_magic; break;
}
if(_tool) {
_tool.node = self;
_tool = _tool.getTool();
_tool.subtool = _currTool.selecting;
array_append(rightTools, _tool.rightTools);
}
@ -689,6 +698,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
tool_selection.apply_draw_surface = apply_draw_surface;
if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
tool_mirror_edit.sprs = (!tool_selection.is_selected && tool_attribute.mirror[0])? THEME.canvas_mirror_diag : THEME.canvas_mirror;
}
if(_tool && _tool.override) {
@ -770,14 +781,20 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
var _spw = tool_selection.selection_size[0];
var _sph = tool_selection.selection_size[1];
if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _spy * 2 + _sph, 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _spx * 2 + _spw, _spy * 2 + _sph, -1, -1);
} else {
if(tool_attribute.mirror[0]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[0] && tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1);
if(tool_attribute.mirror[0] == false) {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], 0, -1, 1);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, _dim[1], 1, -1);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, -1);
} else {
if(tool_attribute.mirror[1]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], -1, 1, -90);
if(tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, 0, 0, -1, 1, 90);
if(tool_attribute.mirror[1] && tool_attribute.mirror[2]) draw_surface_ext_safe(_drawing_surface, _dim[0], _dim[1], 1, 1, 180);
}
}
draw_set_color(tool_attribute.color);
@ -785,7 +802,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
canvas_draw_point_size(brush, brush.brush_sizing_dx, brush.brush_sizing_dy);
else if(_tool)
_tool.drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
surface_reset_shader();
draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp);

View file

@ -201,7 +201,7 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc
insp2UpdateIcon = [ THEME.cache, 0, COLORS._main_icon ];
static inspector1Update = function() { onInspector1Update(); }
static onInspector1Update = function() { RenderList(nodes, true); }
static onInspector1Update = function() { RenderList(nodes); }
static hasInspector1Update = function() { INLINE return hasInsp1; }
static inspector2Update = function() { onInspector2Update(); }

View file

@ -78,7 +78,7 @@ function NodeTool(name, spr, context = instanceof(other)) constructor {
onToggle();
var _obj = getToolObject();
if(_obj) _obj.init();
if(_obj) _obj.init(ctx);
}
static toggleKeyboard = function() {

View file

@ -10,8 +10,6 @@ function Panel_Palette() : PanelContent() constructor {
color_dragging = noone;
function onResize() {
PANEL_PADDING
sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding));
}
@ -25,8 +23,9 @@ function Panel_Palette() : PanelContent() constructor {
case 1 : _gs = ui(32); break;
case 2 : _gs = ui(16); break;
}
var yy = _y;
var _height;
var yy = _y;
var cur = COLORS_GLOBAL_GET != noone? COLORS_GLOBAL_GET() : noone;
for(var i = 0; i < array_length(PALETTES); i++) {
var preset = PALETTES[i];
@ -44,7 +43,7 @@ function Panel_Palette() : PanelContent() constructor {
draw_set_text(f_p2, fa_left, fa_top, COLORS._main_text_sub);
draw_text(ui(10), yy + ui(2), preset.name);
drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs);
drawPaletteGrid(preset.palette, ui(10), yy + ui(24), ww - ui(20), _gs, cur);
if(isHover) {
if(mouse_press(mb_left, pFOCUS)) {

View file

@ -99,6 +99,8 @@ function Panel_Preview() : PanelContent() constructor {
tileMode = 0;
bg_color = COLORS.panel_bg_clear;
mouse_pos_string = "";
#endregion
#region ---- tool ----
@ -1071,8 +1073,15 @@ function Panel_Preview() : PanelContent() constructor {
var mpx = floor((mx - canvas_x) / canvas_s);
var mpy = floor((my - canvas_y) / canvas_s);
draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]");
if(mouse_pos_string != "") {
right_menu_y += string_height("l");
draw_text(right_menu_x, right_menu_y, $"{mouse_pos_string}");
}
}
mouse_pos_string = "";
if(_node == noone) return;
right_menu_y += string_height("l");
@ -1477,9 +1486,9 @@ function Panel_Preview() : PanelContent() constructor {
var key = sett[2];
var atr = sett[3];
if(i == 0 && nme != "") {
tolx += ui(8);
tol_max_w += ui(8);
if(nme != "") {
tolx += ui(8) + bool(i == 0) * ui(8);
tol_max_w += ui(8) + bool(i == 0) * ui(8);
}
draw_set_text(f_p2, fa_left, fa_center, COLORS._main_text_sub);
@ -1500,6 +1509,7 @@ function Panel_Preview() : PanelContent() constructor {
case "checkBoxGroup" : tolw = tolh * wdg.size; break;
case "checkBox" : tolw = tolh; break;
case "scrollBox" : tolw = ui(96); break;
case "buttonClass" : tolw = wdg.text == ""? tolh : tolw; break;
}
var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ])
@ -1508,11 +1518,6 @@ function Panel_Preview() : PanelContent() constructor {
wdg.drawParam(params);
if(nme != "") {
tolx += ui(8);
tol_max_w += ui(8);
}
tolx += tolw + ui(8) + (nme != "") * ui(8);
tol_max_w += tolw + ui(8) + (nme != "") * ui(8);
}

View file

@ -37,12 +37,12 @@ function string_real(val, digMax = 999, decMin = 5) { #region
if(is_array(val)) {
var s = "[";
for( var i = 0, n = array_length(val); i < n; i++ )
s += (i? ", " : "") + string_real(val[i]);
var i = 0, n = array_length(val);
repeat( n ) { s += (i? ", " : "") + string_real(val[i]); i++; }
return s + "]";
}
if(val == 0 || !is_real(val)) return "0";
if(val == 0 || !is_numeric(val)) return "0";
var pres, p = 1;
var presMax = min(decMin, digMax - ceil(log10(ceil(abs(val)))));