multi-canvas

This commit is contained in:
MakhamDev 2023-10-04 14:49:31 +07:00
parent cb3566cee7
commit ac723d1dca
12 changed files with 373 additions and 109 deletions

View file

@ -327,6 +327,7 @@
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_checkbox_on_start.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_checkbox_on_start.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_circle_12.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_circle_12.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_circle_16.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_circle_16.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_close_16.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_color_picker_dropper.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_color_picker_dropper.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_color_picker_sample_strip2.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_color_picker_sample_strip2.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_color_picker_sample1.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",}, {"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"s_color_picker_sample1.png","CopyToMask":-1,"filePath":"datafiles/data/themes/default/graphics/icon",},

Binary file not shown.

View file

@ -1,11 +1,13 @@
#region save #region save
globalvar LOADING, APPENDING, CLONING, SAFE_MODE; globalvar LOADING, APPENDING, CLONING, SAFE_MODE;
globalvar CONNECTION_CONFLICT, ALWAYS_FULL; globalvar CONNECTION_CONFLICT, ALWAYS_FULL;
globalvar MESSAGE;
LOADING = false; LOADING = false;
CLONING = false; CLONING = false;
APPENDING = false; APPENDING = false;
SAFE_MODE = false; SAFE_MODE = false;
MESSAGE = noone;
CONNECTION_CONFLICT = ds_queue_create(); CONNECTION_CONFLICT = ds_queue_create();

View file

@ -1,7 +1,6 @@
function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
name = "Canvas"; name = "Canvas";
color = COLORS.node_blend_canvas; color = COLORS.node_blend_canvas;
preview_channel = 1;
inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF ) inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF )
.setDisplay(VALUE_DISPLAY.vector); .setDisplay(VALUE_DISPLAY.vector);
@ -35,19 +34,129 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
frame_renderer_x = 0;
frame_renderer_x_to = 0;
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
var _h = 64;
_y += 8;
var _cnt_hover = false;
draw_sprite_stretched(THEME.button, 0, _x, _y, _w, _h);
if(_hover && frame_renderer.parent != noone && point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h)) {
frame_renderer.parent.scroll_lock = true;
_cnt_hover = _hover;
}
var _ww = _w - 4 - 40;
var _hh = _h - 4 - 4;
var _x0 = _x + 4;
var _y0 = _y + 4;
var _x1 = _x0 + _ww;
var _y1 = _y0 + _hh;
draw_sprite_stretched(THEME.ui_panel_bg, 1, _x0, _y0, _ww, _hh);
frame_renderer_x_max = 0;
frame_renderer_content = surface_verify(frame_renderer_content, _ww, _hh);
surface_set_shader(frame_renderer_content);
var _msx = _m[0] - _x0;
var _msy = _m[1] - _y0;
var _fr_h = _hh - 8;
var _fr_w = _fr_h;
var _fr_x = 8 - frame_renderer_x;
var _fr_y = 4;
var surfs = outputs[| 0].getValue();
var _del = noone;
if(!is_array(surfs)) surfs = [ surfs ];
for( var i = 0, n = array_length(surfs); i < n; i++ ) {
var _surf = surfs[i];
if(!is_surface(_surf)) continue;
var _sw = surface_get_width(_surf);
var _sh = surface_get_height(_surf);
var _ss = min(_fr_w / _sw, _fr_h / _sh);
var _sx = _fr_x;
var _sy = _fr_y + _fr_h / 2 - _sh * _ss / 2;
draw_surface_ext(_surf, _sx, _sy, _ss, _ss, 0, c_white, 1);
draw_set_color(i == preview_index? COLORS._main_accent : COLORS.panel_toolbar_outline);
draw_rectangle(_sx, _sy, _sx + _sw * _ss, _sy + _sh * _ss, true);
var _del_x = _sx + _sw * _ss - 8;
var _del_y = _sy + 8;
var _del_a = 0;
if(_hover) {
if(point_in_circle(_msx, _msy, _del_x, _del_y, 8)) {
_del_a = 1;
if(mouse_press(mb_left, _focus))
_del = i;
} else if(point_in_rectangle(_msx, _msy, _sx, _sy, _sx + _sw * _ss, _sy + _sh * _ss)) {
if(mouse_press(mb_left, _focus)) preview_index = i;
}
}
draw_sprite(THEME.close_16, _del_a, _del_x, _del_y);
_fr_x += _sw * _ss + 8;
frame_renderer_x_max += _sw * _ss + 8;
}
if(_del > noone) removeFrame(_del);
surface_reset_shader();
draw_surface(frame_renderer_content, _x0, _y0);
frame_renderer_x_max = max(0, frame_renderer_x_max - 200);
frame_renderer_x = lerp_float(frame_renderer_x, frame_renderer_x_to, 3);
if(_cnt_hover) {
if(mouse_wheel_down()) frame_renderer_x_to = clamp(frame_renderer_x_to + 80, 0, frame_renderer_x_max);
if(mouse_wheel_up()) frame_renderer_x_to = clamp(frame_renderer_x_to - 80, 0, frame_renderer_x_max);
}
var _bs = 32;
var _bx = _x1 + ui(20) - _bs / 2;
var _by = _y + _h / 2 - _bs / 2;
if(buttonInstant(THEME.button_hide, _bx, _by, _bs, _bs, _m, _focus, _hover,, THEME.add,, COLORS._main_value_positive) == 2) {
attributes.frames++;
refreshFrames();
update();
}
return 8 + _h;
}); #endregion
input_display_list = [ input_display_list = [
["Output", false], 0, ["Output", false], 0, frame_renderer,
["Brush", false], 6, 2, 1, 11, ["Brush", false], 6, 2, 1, 11,
["Fill", false], 3, 4, ["Fill", false], 3, 4,
["Display", false], 8, 10, 9, ["Display", false], 8, 10, 9,
]; ];
attributes.frames = 1;
attribute_surface_depth(); attribute_surface_depth();
canvas_surface = surface_create_empty(1, 1); canvas_surface = [ surface_create_empty(1, 1) ];
canvas_buffer = [ buffer_create(1 * 1 * 4, buffer_fixed, 2) ];
drawing_surface = surface_create_empty(1, 1); drawing_surface = surface_create_empty(1, 1);
_drawing_surface = surface_create_empty(1, 1); _drawing_surface = surface_create_empty(1, 1);
canvas_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2);
surface_w = 1; surface_w = 1;
surface_h = 1; surface_h = 1;
@ -66,6 +175,22 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
selection_mx = 0; selection_mx = 0;
selection_my = 0; selection_my = 0;
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
mouse_pre_draw_x = 0;
mouse_pre_draw_y = 0;
mouse_holding = false;
brush_sizing = false;
brush_sizing_s = 0;
brush_sizing_mx = 0;
brush_sizing_my = 0;
brush_sizing_dx = 0;
brush_sizing_dy = 0;
tool_channel_edit = new checkBoxGroup(THEME.tools_canvas_channel, function(ind, val) { tool_attribute.channel[ind] = val; }); tool_channel_edit = new checkBoxGroup(THEME.tools_canvas_channel, function(ind, val) { tool_attribute.channel[ind] = val; });
tool_attribute.channel = [ true, true, true, true ]; tool_attribute.channel = [ true, true, true, true ];
tool_settings = [ tool_settings = [
@ -83,57 +208,111 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_stack = ds_list_create(); draw_stack = ds_list_create();
function storeAction() { function removeFrame(index = 0) { #region
if(attributes.frames <= 1) return;
attributes.frames--;
array_delete(canvas_surface, index, 1);
array_delete(canvas_buffer, index, 1);
update();
} #endregion
function refreshFrames() { #region
var fr = attributes.frames;
if(array_length(canvas_surface) < fr) {
for( var i = array_length(canvas_surface); i < fr; i++ ) {
canvas_surface[i] = surface_create_empty(1, 1);
}
} else
array_resize(canvas_surface, fr);
if(array_length(canvas_buffer) < fr) {
for( var i = array_length(canvas_buffer); i < fr; i++ ) {
canvas_buffer[i] = buffer_create(1 * 1 * 4, buffer_fixed, 2);
}
} else
array_resize(canvas_buffer, fr);
} #endregion
function getCanvasSurface(index = preview_index) { #region
gml_pragma("forceinline");
return array_safe_get(canvas_surface, index);
} #endregion
function setCanvasSurface(surface, index = preview_index) { #region
gml_pragma("forceinline");
canvas_surface[index] = surface;
} #endregion
function storeAction() { #region
var action = recordAction(ACTION_TYPE.custom, function(data) { var action = recordAction(ACTION_TYPE.custom, function(data) {
is_selected = false; is_selected = false;
var _canvas = surface_clone(canvas_surface); var _canvas = surface_clone(getCanvasSurface(data.index));
if(is_surface(data.surface)) if(is_surface(data.surface))
canvas_surface = surface_clone(data.surface); setCanvasSurface(surface_clone(data.surface), data.index);
surface_store_buffer(); surface_store_buffer(data.index);
surface_free(data.surface); surface_free(data.surface);
return { surface: _canvas, tooltip: data.tooltip } return { surface: _canvas, tooltip: data.tooltip, index: preview_index }
}, { surface: surface_clone(canvas_surface), tooltip: "Modify canvas" }); }, { surface: surface_clone(getCanvasSurface()), tooltip: "Modify canvas", index: preview_index });
action.clear_action = function(data) { surface_free_safe(data.surface); }; action.clear_action = function(data) { surface_free_safe(data.surface); };
} } #endregion
function apply_surface() { function apply_surfaces() { #region
for( var i = 0; i < attributes.frames; i++ )
apply_surface(i);
} #endregion
function apply_surface(index = preview_index) { #region
var _dim = getInputData(0); var _dim = getInputData(0);
var cDep = attrDepth(); var cDep = attrDepth();
if(!is_surface(canvas_surface)) { var _canvas_surface = getCanvasSurface(index);
canvas_surface = surface_create_from_buffer(_dim[0], _dim[1], canvas_buffer);
} else if(surface_get_width_safe(canvas_surface) != _dim[0] || surface_get_height_safe(canvas_surface) != _dim[1]) { if(!is_surface(_canvas_surface)) {
buffer_delete(canvas_buffer); setCanvasSurface(surface_create_from_buffer(_dim[0], _dim[1], canvas_buffer[index]));
canvas_buffer = buffer_create(_dim[0] * _dim[1] * 4, buffer_fixed, 4); } else if(surface_get_width_safe(_canvas_surface) != _dim[0] || surface_get_height_safe(_canvas_surface) != _dim[1]) {
canvas_surface = surface_size_to(canvas_surface, _dim[0], _dim[1]); buffer_delete(canvas_buffer[index]);
canvas_buffer[index] = buffer_create(_dim[0] * _dim[1] * 4, buffer_fixed, 4);
setCanvasSurface(surface_size_to(_canvas_surface, _dim[0], _dim[1]), index);
} }
drawing_surface = surface_verify(drawing_surface, _dim[0], _dim[1], cDep); drawing_surface = surface_verify(drawing_surface, _dim[0], _dim[1], cDep);
surface_clear(drawing_surface); surface_clear(drawing_surface);
} } #endregion
function surface_store_buffer() { function surface_store_buffers(index = preview_index) { #region
buffer_delete(canvas_buffer); for( var i = 0; i < attributes.frames; i++ )
surface_store_buffer(i);
} #endregion
surface_w = surface_get_width_safe(canvas_surface); function surface_store_buffer(index = preview_index) { #region
surface_h = surface_get_height_safe(canvas_surface); buffer_delete(canvas_buffer[index]);
canvas_buffer = buffer_create(surface_w * surface_h * 4, buffer_fixed, 4);
buffer_get_surface(canvas_buffer, canvas_surface, 0); var _canvas_surface = getCanvasSurface(index);
surface_w = surface_get_width_safe(_canvas_surface);
surface_h = surface_get_height_safe(_canvas_surface);
canvas_buffer[index] = buffer_create(surface_w * surface_h * 4, buffer_fixed, 4);
buffer_get_surface(canvas_buffer[index], _canvas_surface, 0);
triggerRender(); triggerRender();
apply_surface(); apply_surface(index);
} } #endregion
function apply_draw_surface() { function apply_draw_surface() { #region
var _alp = getInputData(11); var _alp = getInputData(11);
storeAction(); storeAction();
surface_set_target(canvas_surface); surface_set_target(getCanvasSurface());
if(isUsingTool("Eraser")) gpu_set_blendmode(bm_subtract); if(isUsingTool("Eraser")) gpu_set_blendmode(bm_subtract);
else BLEND_ALPHA else BLEND_ALPHA
draw_surface_ext_safe(drawing_surface, 0, 0, 1, 1, 0, c_white, _alp); draw_surface_ext_safe(drawing_surface, 0, 0, 1, 1, 0, c_white, _alp);
@ -143,7 +322,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
BLEND_NORMAL; BLEND_NORMAL;
surface_store_buffer(); surface_store_buffer();
} } #endregion
function draw_point_size(_x, _y, _siz, _brush) { #region function draw_point_size(_x, _y, _siz, _brush) { #region
if(!is_surface(_brush)) { if(!is_surface(_brush)) {
@ -267,14 +446,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
} #endregion } #endregion
function get_color_buffer(_x, _y) { #region function get_color_buffer(_x, _y) { #region
var _cbuffer = canvas_buffer[preview_index];
var pos = (surface_w * _y + _x) * 4; var pos = (surface_w * _y + _x) * 4;
if(pos >= buffer_get_size(canvas_buffer)) { if(pos >= buffer_get_size(_cbuffer)) {
print("Error buffer overflow " + string(pos) + "/" + string(buffer_get_size(canvas_buffer))); print("Error buffer overflow " + string(pos) + "/" + string(buffer_get_size(_cbuffer)));
return 0; return 0;
} }
buffer_seek(canvas_buffer, buffer_seek_start, pos); buffer_seek(_cbuffer, buffer_seek_start, pos);
var c = buffer_read(canvas_buffer, buffer_u32); var c = buffer_read(_cbuffer, buffer_u32);
return c; return c;
} #endregion } #endregion
@ -323,8 +503,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_point(x1, y1); draw_point(x1, y1);
draw_set_alpha(1); draw_set_alpha(1);
buffer_seek(canvas_buffer, buffer_seek_start, (surface_w * y1 + x1) * 4); var _cbuffer = canvas_buffer[preview_index];
buffer_write(canvas_buffer, buffer_u32, colorFill); buffer_seek(_cbuffer, buffer_seek_start, (surface_w * y1 + x1) * 4);
buffer_write(_cbuffer, buffer_u32, colorFill);
//print("> Filling " + string(x1) + ", " + string(y1) + ": " + string(get_color_buffer(x1, y1))); //print("> Filling " + string(x1) + ", " + string(y1) + ": " + string(get_color_buffer(x1, y1)));
@ -399,15 +580,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_set_alpha(1); draw_set_alpha(1);
} #endregion } #endregion
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
mouse_pre_draw_x = 0;
mouse_pre_draw_y = 0;
mouse_holding = false;
static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
mouse_cur_x = round((_mx - _x) / _s - 0.5); mouse_cur_x = round((_mx - _x) / _s - 0.5);
mouse_cur_y = round((_my - _y) / _s - 0.5); mouse_cur_y = round((_my - _y) / _s - 0.5);
@ -422,11 +594,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
if(key_mod_press(ALT)) return; if(key_mod_press(ALT)) return;
if(!surface_exists(canvas_surface)) var _canvas_surface = getCanvasSurface();
surface_store_buffer();
var _surf_w = surface_get_width_safe(canvas_surface); if(!surface_exists(_canvas_surface)) {
var _surf_h = surface_get_height_safe(canvas_surface); surface_store_buffer();
_canvas_surface = getCanvasSurface();
}
var _surf_w = surface_get_width_safe(_canvas_surface);
var _surf_h = surface_get_height_safe(_canvas_surface);
#region drawing surface review #region drawing surface review
_drawing_surface = surface_verify(_drawing_surface, _surf_w, _surf_h); _drawing_surface = surface_verify(_drawing_surface, _surf_w, _surf_h);
@ -440,7 +616,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
var pos_x = selection_position[0]; var pos_x = selection_position[0];
var pos_y = selection_position[1]; var pos_y = selection_position[1];
surface_set_target(canvas_surface); surface_set_target(_canvas_surface);
BLEND_ALPHA BLEND_ALPHA
draw_surface_safe(selection_surface, pos_x, pos_y); draw_surface_safe(selection_surface, pos_x, pos_y);
BLEND_NORMAL BLEND_NORMAL
@ -486,7 +662,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
} else { } else {
is_selected = false; is_selected = false;
surface_set_target(canvas_surface); surface_set_target(_canvas_surface);
BLEND_ALPHA BLEND_ALPHA
draw_surface_safe(selection_surface, pos_x, pos_y); draw_surface_safe(selection_surface, pos_x, pos_y);
BLEND_NORMAL BLEND_NORMAL
@ -529,7 +705,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
surface_set_target(selection_surface); surface_set_target(selection_surface);
DRAW_CLEAR DRAW_CLEAR
draw_surface_safe(canvas_surface, -sel_x0, -sel_y0); draw_surface_safe(_canvas_surface, -sel_x0, -sel_y0);
BLEND_MULTIPLY BLEND_MULTIPLY
draw_surface_safe(selection_mask, 0, 0); draw_surface_safe(selection_mask, 0, 0);
@ -537,7 +713,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
surface_reset_target(); surface_reset_target();
storeAction(); storeAction();
surface_set_target(canvas_surface); surface_set_target(_canvas_surface);
gpu_set_blendmode(bm_subtract); gpu_set_blendmode(bm_subtract);
draw_surface_safe(selection_surface, sel_x0, sel_y0); draw_surface_safe(selection_surface, sel_x0, sel_y0);
gpu_set_blendmode(bm_normal); gpu_set_blendmode(bm_normal);
@ -612,6 +788,23 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
mouse_pre_x = mouse_cur_x; mouse_pre_x = mouse_cur_x;
mouse_pre_y = mouse_cur_y; mouse_pre_y = mouse_cur_y;
if(brush_sizing) {
var s = brush_sizing_s + (_mx - brush_sizing_mx) / 16;
s = max(1, s);
inputs[| 2].setValue(s);
if(mouse_release(mb_right))
brush_sizing = false;
} else if(mouse_press(mb_right, active) && key_mod_press(SHIFT) && !is_surface(_brush)) {
brush_sizing = true;
brush_sizing_s = _siz;
brush_sizing_mx = _mx;
brush_sizing_my = _my;
brush_sizing_dx = mouse_cur_x;
brush_sizing_dy = mouse_cur_y;
}
#endregion #endregion
} else if(isUsingTool("Rectangle") || isUsingTool("Ellipse")) { #region } else if(isUsingTool("Rectangle") || isUsingTool("Ellipse")) { #region
if(mouse_holding && key_mod_press(SHIFT)) { if(mouse_holding && key_mod_press(SHIFT)) {
@ -647,21 +840,21 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
} }
#endregion #endregion
} else if(isUsingTool("Fill") || (DRAGGING && DRAGGING.type == "Color")) { #region } else if(isUsingTool("Fill") || (DRAGGING && DRAGGING.type == "Color")) { #region
var fill = DRAGGING? mouse_release(mb_left) : mouse_press(mb_left); var fill = DRAGGING? mouse_release(mb_left, active) : mouse_press(mb_left, active);
if(fill && point_in_rectangle(mouse_cur_x, mouse_cur_y, 0, 0, _surf_w - 1, _surf_h - 1)) { if(fill && point_in_rectangle(mouse_cur_x, mouse_cur_y, 0, 0, _surf_w - 1, _surf_h - 1)) {
storeAction(); storeAction();
surface_set_target(canvas_surface); surface_set_target(_canvas_surface);
if(DRAGGING) draw_set_color(DRAGGING.data); if(DRAGGING) draw_set_color(DRAGGING.data);
switch(_fill_type) { switch(_fill_type) {
case 0 : case 0 :
flood_fill_scanline(mouse_cur_x, mouse_cur_y, canvas_surface, _thr, false); flood_fill_scanline(mouse_cur_x, mouse_cur_y, _canvas_surface, _thr, false);
break; break;
case 1 : case 1 :
flood_fill_scanline(mouse_cur_x, mouse_cur_y, canvas_surface, _thr, true); flood_fill_scanline(mouse_cur_x, mouse_cur_y, _canvas_surface, _thr, true);
break; break;
case 2 : case 2 :
canvas_fill(mouse_cur_x, mouse_cur_y, canvas_surface, _thr); canvas_fill(mouse_cur_x, mouse_cur_y, _canvas_surface, _thr);
break; break;
} }
surface_store_buffer(); surface_store_buffer();
@ -698,7 +891,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
draw_surface_safe(selection_mask, sel_x0, sel_y0); draw_surface_safe(selection_mask, sel_x0, sel_y0);
} }
} else if(isUsingTool("Pencil") || isUsingTool("Eraser")) { } else if(isUsingTool("Pencil") || isUsingTool("Eraser")) {
if(mouse_holding) { if(brush_sizing) {
draw_point_size(brush_sizing_dx, brush_sizing_dy, _siz, _brush);
} else if(mouse_holding) {
if(isUsingTool("Eraser")) draw_set_color(c_white); if(isUsingTool("Eraser")) draw_set_color(c_white);
if(key_mod_press(SHIFT)) draw_line_size(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, _siz, _brush); if(key_mod_press(SHIFT)) draw_line_size(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, _siz, _brush);
@ -767,42 +962,85 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
var _bgr = getInputData(10); var _bgr = getInputData(10);
var cDep = attrDepth(); var cDep = attrDepth();
apply_surface(); apply_surfaces();
var _outSurf = outputs[| 0].getValue(); var _outSurf = outputs[| 0].getValue();
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1], cDep);
surface_set_shader(_outSurf, noone,, BLEND.alpha); if(attributes.frames == 1) {
if(_bgr && is_surface(_bg)) if(is_array(_outSurf)) {
draw_surface_stretched_ext(_bg, 0, 0, _dim[0], _dim[1], c_white, _bga); if(!array_empty(_outSurf)) _outSurf = _outSurf[0];
draw_surface_safe(canvas_surface, 0, 0); else _outSurf = noone;
surface_reset_shader(); }
var _canvas_surface = getCanvasSurface(0);
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1], cDep);
surface_set_shader(_outSurf, noone,, BLEND.alpha);
if(_bgr && is_surface(_bg))
draw_surface_stretched_ext(_bg, 0, 0, _dim[0], _dim[1], c_white, _bga);
draw_surface_safe(_canvas_surface, 0, 0);
surface_reset_shader();
} else {
if(!is_array(_outSurf))
_outSurf = array_create(attributes.frames);
else if(array_length(_outSurf) != attributes.frames)
array_resize(_outSurf, attributes.frames);
for( var i = 0; i < attributes.frames; i++ ) {
var _canvas_surface = getCanvasSurface(i);
_outSurf[i] = surface_verify(_outSurf[i], _dim[0], _dim[1], cDep);
surface_set_shader(_outSurf[i], noone,, BLEND.alpha);
if(_bgr && is_surface(_bg))
draw_surface_stretched_ext(_bg, 0, 0, _dim[0], _dim[1], c_white, _bga);
draw_surface_safe(_canvas_surface, 0, 0);
surface_reset_shader();
}
}
outputs[| 0].setValue(_outSurf); outputs[| 0].setValue(_outSurf);
} #endregion } #endregion
static doSerialize = function(_map) { #region static doSerialize = function(_map) { #region
surface_store_buffer(); surface_store_buffers();
var comp = buffer_compress(canvas_buffer, 0, buffer_get_size(canvas_buffer)); var _buff = array_create(attributes.frames);
var enc = buffer_base64_encode(comp, 0, buffer_get_size(comp));
_map.surface = enc; for( var i = 0; i < attributes.frames; i++ ) {
var comp = buffer_compress(canvas_buffer[i], 0, buffer_get_size(canvas_buffer[i]));
_buff[i] = buffer_base64_encode(comp, 0, buffer_get_size(comp));
}
_map.surfaces = _buff;
} #endregion } #endregion
static doApplyDeserialize = function() { #region static doApplyDeserialize = function() { #region
if(!struct_has(load_map, "surface")) return;
var buff = buffer_base64_decode(load_map.surface);
canvas_buffer = buffer_decompress(buff);
var _dim = getInputData(0); var _dim = getInputData(0);
var _outSurf = outputs[| 0].getValue();
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth());
canvas_surface = surface_create_from_buffer(_dim[0], _dim[1], canvas_buffer);
apply_surface(); if(!struct_has(load_map, "surfaces")) {
if(struct_has(load_map, "surface")) {
var buff = buffer_base64_decode(load_map.surface);
canvas_buffer[0] = buffer_decompress(buff);
canvas_surface[0] = surface_create_from_buffer(_dim[0], _dim[1], canvas_buffer[0]);
}
return;
}
canvas_buffer = array_create(array_length(load_map.surfaces));
canvas_surface = array_create(array_length(load_map.surfaces));
for( var i = 0, n = array_length(load_map.surfaces); i < n; i++ ) {
var buff = buffer_base64_decode(load_map.surfaces[i]);
canvas_buffer[i] = buffer_decompress(buff);
canvas_surface[i] = surface_create_from_buffer(_dim[0], _dim[1], canvas_buffer[i]);
}
apply_surfaces();
} #endregion } #endregion
static onCleanUp = function() { #region static onCleanUp = function() { #region
surface_free(canvas_surface); surface_array_free(canvas_surface);
} #endregion } #endregion
} }

View file

@ -2,7 +2,7 @@ function Node_Sequence_Anim(_x, _y, _group = noone) : Node(_x, _y, _group) const
name = "Array to Anim"; name = "Array to Anim";
update_on_frame = true; update_on_frame = true;
inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0) inputs[| 0] = nodeValue("Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, [])
.setArrayDepth(1); .setArrayDepth(1);
inputs[| 1] = nodeValue("Speed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1) inputs[| 1] = nodeValue("Speed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1)
@ -23,6 +23,8 @@ function Node_Sequence_Anim(_x, _y, _group = noone) : Node(_x, _y, _group) const
var _ord = getInputData(2); var _ord = getInputData(2);
var _h = ui(64); var _h = ui(64);
if(!is_array(_seq)) return _h;
if(array_length(_ord) == 0) { if(array_length(_ord) == 0) {
_ord = array_create(array_length(_seq)); _ord = array_create(array_length(_seq));
for( var i = 0, n = array_length(_seq); i < n; i++ ) for( var i = 0, n = array_length(_seq); i < n; i++ )

View file

@ -141,6 +141,7 @@ function Panel_Color() : PanelContent() constructor {
type: "Color", type: "Color",
data: color data: color
} }
MESSAGE = DRAGGING;
} }
} }
continue; continue;
@ -154,6 +155,7 @@ function Panel_Color() : PanelContent() constructor {
type: "Color", type: "Color",
data: c data: c
} }
MESSAGE = DRAGGING;
} }
} }

View file

@ -69,6 +69,7 @@ function Panel_Gradient() : PanelContent() constructor {
type: "Gradient", type: "Gradient",
data: preset.gradient data: preset.gradient
} }
MESSAGE = DRAGGING;
} }
} }
yy += hg + ui(8); yy += hg + ui(8);

View file

@ -464,7 +464,7 @@ function Panel_Inspector() : PanelContent() constructor {
continue; continue;
} else if(is_struct(jun_disp) && instanceof(jun_disp) == "Inspector_Custom_Renderer") { } else if(is_struct(jun_disp) && instanceof(jun_disp) == "Inspector_Custom_Renderer") {
if(pFOCUS && is_callable(jun_disp.register)) jun_disp.register(contentPane); jun_disp.register(contentPane);
jun_disp.rx = ui(16) + x; jun_disp.rx = ui(16) + x;
jun_disp.ry = top_bar_h + y; jun_disp.ry = top_bar_h + y;
@ -624,32 +624,44 @@ function Panel_Inspector() : PanelContent() constructor {
} #endregion } #endregion
} }
if(color_picker_selecting == noone) #region color picker
picker_selecting = 0; if(color_picker_selecting == noone)
picker_selecting = 0;
if(key_mod_press(ALT) && color_picker_index) { if(key_mod_press(ALT) && color_picker_index) {
var _p = picker_index; var _p = picker_index;
if(mouse_wheel_down()) picker_index = safe_mod(picker_index + 1 + color_picker_index, color_picker_index); if(mouse_wheel_down()) picker_index = safe_mod(picker_index + 1 + color_picker_index, color_picker_index);
if(mouse_wheel_up()) picker_index = safe_mod(picker_index - 1 + color_picker_index, color_picker_index); if(mouse_wheel_up()) picker_index = safe_mod(picker_index - 1 + color_picker_index, color_picker_index);
if(_p != picker_index) { if(_p != picker_index) {
instance_destroy(o_dialog_color_selector); instance_destroy(o_dialog_color_selector);
pickers[picker_index].editWidget.onColorPick(); pickers[picker_index].editWidget.onColorPick();
} }
}
if(prop_dragging) {
if(DRAGGING == noone && point_distance(prop_sel_drag_x, prop_sel_drag_y, mouse_mx, mouse_my) > 16) {
prop_dragging.dragValue();
prop_dragging = noone;
} }
if(mouse_release(mb_left)) if(MESSAGE != noone && MESSAGE.type == "Color") {
prop_dragging = noone; var inp = array_safe_get(pickers, picker_index, 0);
} if(is_struct(inp)) {
inp.setValue(MESSAGE.data);
MESSAGE = noone;
}
}
color_picking = false; color_picking = false;
#endregion
#region drag
if(prop_dragging) {
if(DRAGGING == noone && point_distance(prop_sel_drag_x, prop_sel_drag_y, mouse_mx, mouse_my) > 16) {
prop_dragging.dragValue();
prop_dragging = noone;
}
if(mouse_release(mb_left))
prop_dragging = noone;
}
#endregion
return hh; return hh;
}); #endregion }); #endregion

View file

@ -75,16 +75,20 @@ function Panel_Palette() : PanelContent() constructor {
var m_gy = floor(m_ay / _gs); var m_gy = floor(m_ay / _gs);
var _index = m_gy * col + m_gx; var _index = m_gy * col + m_gx;
if(_index < pre_amo && _index >= 0) if(_index < pre_amo && _index >= 0) {
DRAGGING = { DRAGGING = {
type: "Color", type: "Color",
data: array_safe_get(preset.palette, _index) data: array_safe_get(preset.palette, _index)
} }
} else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) MESSAGE = DRAGGING;
}
} else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) {
DRAGGING = { DRAGGING = {
type: "Palette", type: "Palette",
data: preset.palette data: preset.palette
} }
MESSAGE = DRAGGING;
}
} }
yy += _height + ui(8); yy += _height + ui(8);

View file

@ -1004,7 +1004,7 @@ function Panel_Preview() : PanelContent() constructor {
var _xx = tool_side_drawing * ui(40); var _xx = tool_side_drawing * ui(40);
var xx = _xx + preview_x + ui(8); var xx = _xx + preview_x + ui(8);
var yy = h - toolbar_height - prev_size - ui(8); var yy = h - toolbar_height - prev_size - ui(8);
if(my > yy) mouse_on_preview = 0; if(my > yy - 8) mouse_on_preview = 0;
var hoverable = pHOVER && point_in_rectangle(mx, my, _xx, ui(32), w, h - toolbar_height); var hoverable = pHOVER && point_in_rectangle(mx, my, _xx, ui(32), w, h - toolbar_height);
for(var i = 0; i < array_length(pseq); i++) { for(var i = 0; i < array_length(pseq); i++) {
@ -1424,17 +1424,16 @@ function Panel_Preview() : PanelContent() constructor {
var tool = noone; var tool = noone;
if(inspect_node) { if(inspect_node) {
tool = inspect_node.getTool(); tool = inspect_node.getTool();
if(tool) drawNodeTools(_mouse_on_preview, tool); if(tool) drawNodeTools(pFOCUS, tool);
} else } else
tool_current = noone; tool_current = noone;
_mouse_on_preview = pFOCUS;
if(do_fullView) { if(do_fullView) {
do_fullView = false; do_fullView = false;
fullView(); fullView();
} }
if(mouse_on_preview && mouse_press(mb_right, pFOCUS)) { if(mouse_on_preview && mouse_press(mb_right, pFOCUS) && !key_mod_press(SHIFT)) {
menuCall("preview_context_menu",,, [ menuCall("preview_context_menu",,, [
menuItem(__txtx("panel_graph_preview_window", "Send to preview window"), function() { create_preview_window(getNodePreview()); }, noone, ["Preview", "Preview window"]), menuItem(__txtx("panel_graph_preview_window", "Send to preview window"), function() { create_preview_window(getNodePreview()); }, noone, ["Preview", "Preview window"]),
-1, -1,

View file

@ -19,6 +19,7 @@ function scrollPane(_w, _h, ondraw) : widget() constructor {
show_scroll = true; show_scroll = true;
scroll_step = 64; scroll_step = 64;
scroll_lock = false;
is_scrolling = false; is_scrolling = false;
scroll_ms = 0; scroll_ms = 0;
@ -54,11 +55,13 @@ function scrollPane(_w, _h, ondraw) : widget() constructor {
scroll_y = round(scroll_y_raw); scroll_y = round(scroll_y_raw);
draw_surface_safe(surface, x, y); draw_surface_safe(surface, x, y);
if(hover && !key_mod_press(SHIFT)) { if(hover && !scroll_lock && !key_mod_press(SHIFT)) {
if(mouse_wheel_down()) scroll_y_to -= scroll_step * SCROLL_SPEED; if(mouse_wheel_down()) scroll_y_to -= scroll_step * SCROLL_SPEED;
if(mouse_wheel_up()) scroll_y_to += scroll_step * SCROLL_SPEED; if(mouse_wheel_up()) scroll_y_to += scroll_step * SCROLL_SPEED;
} }
scroll_lock = false;
if(show_scroll && (abs(content_h) > 0 || always_scroll)) { if(show_scroll && (abs(content_h) > 0 || always_scroll)) {
var scr_w = sprite_get_width(THEME.ui_scrollbar); var scr_w = sprite_get_width(THEME.ui_scrollbar);
draw_scroll(x + w - scr_w, y + ui(6), true, surface_h - ui(12), -scroll_y / content_h, surface_h / (surface_h + content_h), draw_scroll(x + w - scr_w, y + ui(6), true, surface_h - ui(12), -scroll_y / content_h, surface_h / (surface_h + content_h),

View file

@ -3,7 +3,7 @@ function widget() constructor {
hover = false; hover = false;
iactive = false; iactive = false;
ihover = false; ihover = false;
parent = noone; parent = noone;
interactable = true; interactable = true;
lua_thread = noone; lua_thread = noone;