canvas updates

This commit is contained in:
Tanasart 2024-04-12 16:45:21 +07:00
parent 67780283c1
commit 7a6441bc76
50 changed files with 1768 additions and 953 deletions

View file

@ -33,6 +33,9 @@
{"name":"d3d_modifier","order":6,"path":"folders/nodes/data/3D/d3d_modifier.yy",}, {"name":"d3d_modifier","order":6,"path":"folders/nodes/data/3D/d3d_modifier.yy",},
{"name":"d3d_particle","order":7,"path":"folders/nodes/data/3D/d3d_particle.yy",}, {"name":"d3d_particle","order":7,"path":"folders/nodes/data/3D/d3d_particle.yy",},
{"name":"animation","order":13,"path":"folders/nodes/data/animation.yy",}, {"name":"animation","order":13,"path":"folders/nodes/data/animation.yy",},
{"name":"canvas","order":30,"path":"folders/nodes/data/canvas.yy",},
{"name":"tools","order":5,"path":"folders/nodes/data/canvas/tools.yy",},
{"name":"util","order":7,"path":"folders/nodes/data/canvas/util.yy",},
{"name":"compose","order":14,"path":"folders/nodes/data/compose.yy",}, {"name":"compose","order":14,"path":"folders/nodes/data/compose.yy",},
{"name":"dynasurf","order":15,"path":"folders/nodes/data/dynasurf.yy",}, {"name":"dynasurf","order":15,"path":"folders/nodes/data/dynasurf.yy",},
{"name":"filter","order":16,"path":"folders/nodes/data/filter.yy",}, {"name":"filter","order":16,"path":"folders/nodes/data/filter.yy",},
@ -252,6 +255,8 @@
{"name":"__background_set_element","order":3,"path":"scripts/__background_set_element/__background_set_element.yy",}, {"name":"__background_set_element","order":3,"path":"scripts/__background_set_element/__background_set_element.yy",},
{"name":"__bbox","order":5,"path":"scripts/__bbox/__bbox.yy",}, {"name":"__bbox","order":5,"path":"scripts/__bbox/__bbox.yy",},
{"name":"__bone","order":2,"path":"scripts/__bone/__bone.yy",}, {"name":"__bone","order":2,"path":"scripts/__bone/__bone.yy",},
{"name":"__canvas_brush","order":2,"path":"scripts/__canvas_brush/__canvas_brush.yy",},
{"name":"__canvas_tool","order":1,"path":"scripts/__canvas_tool/__canvas_tool.yy",},
{"name":"__d3d_gizmo","order":2,"path":"scripts/__d3d_gizmo/__d3d_gizmo.yy",}, {"name":"__d3d_gizmo","order":2,"path":"scripts/__d3d_gizmo/__d3d_gizmo.yy",},
{"name":"__d3d11_cbuffer","order":1,"path":"scripts/__d3d11_cbuffer/__d3d11_cbuffer.yy",}, {"name":"__d3d11_cbuffer","order":1,"path":"scripts/__d3d11_cbuffer/__d3d11_cbuffer.yy",},
{"name":"__d3d11_shader","order":2,"path":"scripts/__d3d11_shader/__d3d11_shader.yy",}, {"name":"__d3d11_shader","order":2,"path":"scripts/__d3d11_shader/__d3d11_shader.yy",},
@ -340,6 +345,17 @@
{"name":"buttonGroup","order":3,"path":"scripts/buttonGroup/buttonGroup.yy",}, {"name":"buttonGroup","order":3,"path":"scripts/buttonGroup/buttonGroup.yy",},
{"name":"buttonPalette","order":4,"path":"scripts/buttonPalette/buttonPalette.yy",}, {"name":"buttonPalette","order":4,"path":"scripts/buttonPalette/buttonPalette.yy",},
{"name":"byte_writer","order":8,"path":"scripts/byte_writer/byte_writer.yy",}, {"name":"byte_writer","order":8,"path":"scripts/byte_writer/byte_writer.yy",},
{"name":"canvas_fix_points","order":1,"path":"scripts/canvas_fix_points/canvas_fix_points.yy",},
{"name":"canvas_flood_fill_functions","order":2,"path":"scripts/canvas_flood_fill_functions/canvas_flood_fill_functions.yy",},
{"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_draw_freeform","order":5,"path":"scripts/canvas_tool_draw_freeform/canvas_tool_draw_freeform.yy",},
{"name":"canvas_tool_fill","order":4,"path":"scripts/canvas_tool_fill/canvas_tool_fill.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",},
{"name":"canvas_tool_selection","order":7,"path":"scripts/canvas_tool_selection/canvas_tool_selection.yy",},
{"name":"checkboxActive","order":11,"path":"scripts/checkboxActive/checkboxActive.yy",}, {"name":"checkboxActive","order":11,"path":"scripts/checkboxActive/checkboxActive.yy",},
{"name":"checkboxGroup","order":6,"path":"scripts/checkboxGroup/checkboxGroup.yy",}, {"name":"checkboxGroup","order":6,"path":"scripts/checkboxGroup/checkboxGroup.yy",},
{"name":"collection_data","order":9,"path":"scripts/collection_data/collection_data.yy",}, {"name":"collection_data","order":9,"path":"scripts/collection_data/collection_data.yy",},
@ -643,7 +659,6 @@
{"name":"node_cache_base","order":18,"path":"scripts/node_cache_base/node_cache_base.yy",}, {"name":"node_cache_base","order":18,"path":"scripts/node_cache_base/node_cache_base.yy",},
{"name":"node_cache","order":9,"path":"scripts/node_cache/node_cache.yy",}, {"name":"node_cache","order":9,"path":"scripts/node_cache/node_cache.yy",},
{"name":"node_camera","order":3,"path":"scripts/node_camera/node_camera.yy",}, {"name":"node_camera","order":3,"path":"scripts/node_camera/node_camera.yy",},
{"name":"node_canvas","order":17,"path":"scripts/node_canvas/node_canvas.yy",},
{"name":"node_caustic","order":1,"path":"scripts/node_caustic/node_caustic.yy",}, {"name":"node_caustic","order":1,"path":"scripts/node_caustic/node_caustic.yy",},
{"name":"node_cellular","order":2,"path":"scripts/node_cellular/node_cellular.yy",}, {"name":"node_cellular","order":2,"path":"scripts/node_cellular/node_cellular.yy",},
{"name":"node_chromatic_aberration","order":3,"path":"scripts/node_chromatic_aberration/node_chromatic_aberration.yy",}, {"name":"node_chromatic_aberration","order":3,"path":"scripts/node_chromatic_aberration/node_chromatic_aberration.yy",},
@ -1303,6 +1318,7 @@
{"name":"sh_flip","order":7,"path":"shaders/sh_flip/sh_flip.yy",}, {"name":"sh_flip","order":7,"path":"shaders/sh_flip/sh_flip.yy",},
{"name":"sh_flood_fill_it","order":1,"path":"shaders/sh_flood_fill_it/sh_flood_fill_it.yy",}, {"name":"sh_flood_fill_it","order":1,"path":"shaders/sh_flood_fill_it/sh_flood_fill_it.yy",},
{"name":"sh_flood_fill_replace","order":2,"path":"shaders/sh_flood_fill_replace/sh_flood_fill_replace.yy",}, {"name":"sh_flood_fill_replace","order":2,"path":"shaders/sh_flood_fill_replace/sh_flood_fill_replace.yy",},
{"name":"sh_freeform_fill_cleanup","order":2,"path":"shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy",},
{"name":"sh_freeform_fill_pass2","order":1,"path":"shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy",}, {"name":"sh_freeform_fill_pass2","order":1,"path":"shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy",},
{"name":"sh_FXAA","order":29,"path":"shaders/sh_FXAA/sh_FXAA.yy",}, {"name":"sh_FXAA","order":29,"path":"shaders/sh_FXAA/sh_FXAA.yy",},
{"name":"sh_gamma_map","order":38,"path":"shaders/sh_gamma_map/sh_gamma_map.yy",}, {"name":"sh_gamma_map","order":38,"path":"shaders/sh_gamma_map/sh_gamma_map.yy",},
@ -1444,7 +1460,7 @@
{"name":"sh_widget_rotator_range","order":5,"path":"shaders/sh_widget_rotator_range/sh_widget_rotator_range.yy",}, {"name":"sh_widget_rotator_range","order":5,"path":"shaders/sh_widget_rotator_range/sh_widget_rotator_range.yy",},
{"name":"sh_widget_rotator","order":4,"path":"shaders/sh_widget_rotator/sh_widget_rotator.yy",}, {"name":"sh_widget_rotator","order":4,"path":"shaders/sh_widget_rotator/sh_widget_rotator.yy",},
{"name":"sh_zigzag","order":2,"path":"shaders/sh_zigzag/sh_zigzag.yy",}, {"name":"sh_zigzag","order":2,"path":"shaders/sh_zigzag/sh_zigzag.yy",},
{"name":"sh_freeform_fill_cleanup","order":2,"path":"shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy",}, {"name":"sh_canvas_mask","order":10,"path":"shaders/sh_canvas_mask/sh_canvas_mask.yy",},
{"name":"credit_badge_popular","order":2,"path":"sprites/credit_badge_popular/credit_badge_popular.yy",}, {"name":"credit_badge_popular","order":2,"path":"sprites/credit_badge_popular/credit_badge_popular.yy",},
{"name":"credit_badge_value","order":1,"path":"sprites/credit_badge_value/credit_badge_value.yy",}, {"name":"credit_badge_value","order":1,"path":"sprites/credit_badge_value/credit_badge_value.yy",},
{"name":"s_biterator_b_grey_long","order":7,"path":"sprites/s_biterator_b_grey_long/s_biterator_b_grey_long.yy",}, {"name":"s_biterator_b_grey_long","order":7,"path":"sprites/s_biterator_b_grey_long/s_biterator_b_grey_long.yy",},

View file

@ -129,6 +129,9 @@
{"$GMFolder":"","%Name":"d3d_modifier","folderPath":"folders/nodes/data/3D/d3d_modifier.yy","name":"d3d_modifier","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"d3d_modifier","folderPath":"folders/nodes/data/3D/d3d_modifier.yy","name":"d3d_modifier","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"d3d_particle","folderPath":"folders/nodes/data/3D/d3d_particle.yy","name":"d3d_particle","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"d3d_particle","folderPath":"folders/nodes/data/3D/d3d_particle.yy","name":"d3d_particle","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"animation","folderPath":"folders/nodes/data/animation.yy","name":"animation","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"animation","folderPath":"folders/nodes/data/animation.yy","name":"animation","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"canvas","folderPath":"folders/nodes/data/canvas.yy","name":"canvas","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"tools","folderPath":"folders/nodes/data/canvas/tools.yy","name":"tools","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"util","folderPath":"folders/nodes/data/canvas/util.yy","name":"util","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"compose","folderPath":"folders/nodes/data/compose.yy","name":"compose","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"compose","folderPath":"folders/nodes/data/compose.yy","name":"compose","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"armature","folderPath":"folders/nodes/data/compose/armature.yy","name":"armature","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"armature","folderPath":"folders/nodes/data/compose/armature.yy","name":"armature","resourceType":"GMFolder","resourceVersion":"2.0",},
{"$GMFolder":"","%Name":"dynasurf","folderPath":"folders/nodes/data/dynasurf.yy","name":"dynasurf","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"dynasurf","folderPath":"folders/nodes/data/dynasurf.yy","name":"dynasurf","resourceType":"GMFolder","resourceVersion":"2.0",},
@ -589,6 +592,8 @@
{"id":{"name":"__background_set_element","path":"scripts/__background_set_element/__background_set_element.yy",},}, {"id":{"name":"__background_set_element","path":"scripts/__background_set_element/__background_set_element.yy",},},
{"id":{"name":"__bbox","path":"scripts/__bbox/__bbox.yy",},}, {"id":{"name":"__bbox","path":"scripts/__bbox/__bbox.yy",},},
{"id":{"name":"__bone","path":"scripts/__bone/__bone.yy",},}, {"id":{"name":"__bone","path":"scripts/__bone/__bone.yy",},},
{"id":{"name":"__canvas_brush","path":"scripts/__canvas_brush/__canvas_brush.yy",},},
{"id":{"name":"__canvas_tool","path":"scripts/__canvas_tool/__canvas_tool.yy",},},
{"id":{"name":"__d3d_gizmo","path":"scripts/__d3d_gizmo/__d3d_gizmo.yy",},}, {"id":{"name":"__d3d_gizmo","path":"scripts/__d3d_gizmo/__d3d_gizmo.yy",},},
{"id":{"name":"__d3d11_cbuffer","path":"scripts/__d3d11_cbuffer/__d3d11_cbuffer.yy",},}, {"id":{"name":"__d3d11_cbuffer","path":"scripts/__d3d11_cbuffer/__d3d11_cbuffer.yy",},},
{"id":{"name":"__d3d11_shader","path":"scripts/__d3d11_shader/__d3d11_shader.yy",},}, {"id":{"name":"__d3d11_shader","path":"scripts/__d3d11_shader/__d3d11_shader.yy",},},
@ -698,6 +703,19 @@
{"id":{"name":"buttonPalette","path":"scripts/buttonPalette/buttonPalette.yy",},}, {"id":{"name":"buttonPalette","path":"scripts/buttonPalette/buttonPalette.yy",},},
{"id":{"name":"byte_reader","path":"scripts/byte_reader/byte_reader.yy",},}, {"id":{"name":"byte_reader","path":"scripts/byte_reader/byte_reader.yy",},},
{"id":{"name":"byte_writer","path":"scripts/byte_writer/byte_writer.yy",},}, {"id":{"name":"byte_writer","path":"scripts/byte_writer/byte_writer.yy",},},
{"id":{"name":"canvas_draw_functions","path":"scripts/canvas_draw_functions/canvas_draw_functions.yy",},},
{"id":{"name":"canvas_fix_points","path":"scripts/canvas_fix_points/canvas_fix_points.yy",},},
{"id":{"name":"canvas_flood_fill_functions","path":"scripts/canvas_flood_fill_functions/canvas_flood_fill_functions.yy",},},
{"id":{"name":"canvas_freeform","path":"scripts/canvas_freeform/canvas_freeform.yy",},},
{"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_draw_freeform","path":"scripts/canvas_tool_draw_freeform/canvas_tool_draw_freeform.yy",},},
{"id":{"name":"canvas_tool_fill","path":"scripts/canvas_tool_fill/canvas_tool_fill.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",},},
{"id":{"name":"canvas_tool_selection","path":"scripts/canvas_tool_selection/canvas_tool_selection.yy",},},
{"id":{"name":"checkbox","path":"scripts/checkbox/checkbox.yy",},}, {"id":{"name":"checkbox","path":"scripts/checkbox/checkbox.yy",},},
{"id":{"name":"checkboxActive","path":"scripts/checkboxActive/checkboxActive.yy",},}, {"id":{"name":"checkboxActive","path":"scripts/checkboxActive/checkboxActive.yy",},},
{"id":{"name":"checkboxGroup","path":"scripts/checkboxGroup/checkboxGroup.yy",},}, {"id":{"name":"checkboxGroup","path":"scripts/checkboxGroup/checkboxGroup.yy",},},
@ -1816,6 +1834,7 @@
{"id":{"name":"sh_flood_fill_replace","path":"shaders/sh_flood_fill_replace/sh_flood_fill_replace.yy",},}, {"id":{"name":"sh_flood_fill_replace","path":"shaders/sh_flood_fill_replace/sh_flood_fill_replace.yy",},},
{"id":{"name":"sh_flood_fill_thres","path":"shaders/sh_flood_fill_thres/sh_flood_fill_thres.yy",},}, {"id":{"name":"sh_flood_fill_thres","path":"shaders/sh_flood_fill_thres/sh_flood_fill_thres.yy",},},
{"id":{"name":"sh_fluid_bleach","path":"shaders/sh_fluid_bleach/sh_fluid_bleach.yy",},}, {"id":{"name":"sh_fluid_bleach","path":"shaders/sh_fluid_bleach/sh_fluid_bleach.yy",},},
{"id":{"name":"sh_freeform_fill_cleanup","path":"shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy",},},
{"id":{"name":"sh_freeform_fill_pass1","path":"shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.yy",},}, {"id":{"name":"sh_freeform_fill_pass1","path":"shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.yy",},},
{"id":{"name":"sh_freeform_fill_pass2","path":"shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy",},}, {"id":{"name":"sh_freeform_fill_pass2","path":"shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy",},},
{"id":{"name":"sh_FXAA","path":"shaders/sh_FXAA/sh_FXAA.yy",},}, {"id":{"name":"sh_FXAA","path":"shaders/sh_FXAA/sh_FXAA.yy",},},
@ -1981,7 +2000,7 @@
{"id":{"name":"sh_widget_rotator_range","path":"shaders/sh_widget_rotator_range/sh_widget_rotator_range.yy",},}, {"id":{"name":"sh_widget_rotator_range","path":"shaders/sh_widget_rotator_range/sh_widget_rotator_range.yy",},},
{"id":{"name":"sh_widget_rotator","path":"shaders/sh_widget_rotator/sh_widget_rotator.yy",},}, {"id":{"name":"sh_widget_rotator","path":"shaders/sh_widget_rotator/sh_widget_rotator.yy",},},
{"id":{"name":"sh_zigzag","path":"shaders/sh_zigzag/sh_zigzag.yy",},}, {"id":{"name":"sh_zigzag","path":"shaders/sh_zigzag/sh_zigzag.yy",},},
{"id":{"name":"sh_freeform_fill_cleanup","path":"shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy",},}, {"id":{"name":"sh_canvas_mask","path":"shaders/sh_canvas_mask/sh_canvas_mask.yy",},},
{"id":{"name":"credit_badge_popular","path":"sprites/credit_badge_popular/credit_badge_popular.yy",},}, {"id":{"name":"credit_badge_popular","path":"sprites/credit_badge_popular/credit_badge_popular.yy",},},
{"id":{"name":"credit_badge_value","path":"sprites/credit_badge_value/credit_badge_value.yy",},}, {"id":{"name":"credit_badge_value","path":"sprites/credit_badge_value/credit_badge_value.yy",},},
{"id":{"name":"node_credit","path":"sprites/node_credit/node_credit.yy",},}, {"id":{"name":"node_credit","path":"sprites/node_credit/node_credit.yy",},},

Binary file not shown.

View file

@ -99,6 +99,9 @@ event_inherited();
hovering = pal; hovering = pal;
menuCall("palette_window_preset_menu",,, [ menuCall("palette_window_preset_menu",,, [
menuItem(__txtx("palette_editor_set_default", "Set as default"), function() {
DEF_PALETTE = array_clone(hovering.palette);
}),
menuItem(__txtx("palette_editor_delete", "Delete palette"), function() { menuItem(__txtx("palette_editor_delete", "Delete palette"), function() {
file_delete(hovering.path); file_delete(hovering.path);
__initPalette(); __initPalette();

View file

@ -60,7 +60,7 @@ draw_clear(COLORS.bg);
winManDraw(); winManDraw();
#endregion #endregion
if(APP_SURF_OVERRIDE) { if(APP_SURF_OVERRIDE) { #region
surface_reset_target(); surface_reset_target();
draw_surface(POST_APP_SURF, 0, 0); draw_surface(POST_APP_SURF, 0, 0);
@ -71,4 +71,4 @@ if(APP_SURF_OVERRIDE) {
surface_set_target(POST_APP_SURF); surface_set_target(POST_APP_SURF);
draw_surface(APP_SURF, 0, 0); draw_surface(APP_SURF, 0, 0);
surface_reset_target(); surface_reset_target();
} } #endregion

View file

@ -0,0 +1,82 @@
function canvas_brush() constructor {
brush_sizing = false;
brush_sizing_s = 0;
brush_sizing_mx = 0;
brush_sizing_my = 0;
brush_sizing_dx = 0;
brush_sizing_dy = 0;
brush_surface = noone;
brush_size = 1;
brush_dist_min = 1;
brush_dist_max = 1;
brush_direction = 0;
brush_rand_dir = [ 0, 0, 0, 0, 0 ];
brush_seed = irandom_range(100000, 999999);
brush_next_dist = 0;
mouse_pre_dir_x = undefined;
mouse_pre_dir_y = undefined;
node = noone;
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var _brushSurf = node.getInputData(6);
var _brushDist = node.getInputData(15);
var _brushRotD = node.getInputData(16);
var _brushRotR = node.getInputData(17);
var attr = node.tool_attribute;
var _col = attr.color;
var _siz = attr.size;
brush_size = _siz;
if(brush_size = PEN_USE && attr.pressure)
brush_size = round(lerp(attr.pressure_size[0], attr.pressure_size[1], power(PEN_PRESSURE / 1024, 2)));
brush_dist_min = max(1, _brushDist[0]);
brush_dist_max = max(1, _brushDist[1]);
brush_surface = is_surface(_brushSurf)? _brushSurf : noone;
if(!_brushRotD)
brush_direction = 0;
else if(mouse_pre_dir_x == undefined) {
mouse_pre_dir_x = _mx;
mouse_pre_dir_y = _my;
} else if(point_distance(mouse_pre_dir_x, mouse_pre_dir_y, _mx, _my) > _s) {
brush_direction = point_direction(mouse_pre_dir_x, mouse_pre_dir_y, _mx, _my);
mouse_pre_dir_x = _mx;
mouse_pre_dir_y = _my;
}
brush_rand_dir = _brushRotR;
}
function sizing(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var attr = node.tool_attribute;
var _siz = attr.size;
if(brush_sizing) {
var s = brush_sizing_s + (_mx - brush_sizing_mx) / 16;
s = max(1, s);
attr.size = s;
if(mouse_release(mb_right))
brush_sizing = false;
} else if(mouse_press(mb_right, active) && key_mod_press(SHIFT) && brush_surface == noone) {
brush_sizing = true;
brush_sizing_s = _siz;
brush_sizing_mx = _mx;
brush_sizing_my = _my;
brush_sizing_dx = round((_mx - _x) / _s - 0.5);
brush_sizing_dy = round((_my - _y) / _s - 0.5);
}
}
}

View file

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

View file

@ -0,0 +1,30 @@
function canvas_tool() constructor {
node = noone;
relative = false;
relative_position = [ 0, 0 ];
drawing_surface = noone;
_canvas_surface = noone;
apply_draw_surface = noone;
brush_resizable = false;
mouse_holding = false;
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
function drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
}

View file

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

View file

@ -0,0 +1,159 @@
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) { #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);
} 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

View file

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

View file

@ -0,0 +1,33 @@
#region fix size points
global.FIX_POINTS = [];
global.FIX_POINTS[0] = [];
global.FIX_POINTS[1] = [];
global.FIX_POINTS[2] = [[ 0, 0 ], [ 1, 0 ], [ 0, 1 ], [ 1, 1 ]];
global.FIX_POINTS[3] = [[ 0, 0 ], [ -1, 0 ], [ 0, -1 ], [ 1, 0 ], [ 0, 1 ]];
global.FIX_POINTS[4] = [[ 0, 0 ], [ -1, 0 ], [ 0, -1 ], [ -1, -1 ], [ -2, -1 ], [ -2, 0 ], [ -1, -2 ], [ 0, -2 ], [ 1, -1 ], [ 1, 0 ], [ -1, 1 ], [ 0, 1 ]];
global.FIX_POINTS[5] = [
[ 0, 0 ],
[ -1, -1 ], [ 0, -1 ], [ 1, -1 ], [ -1, 0 ], [ 1, 0 ], [ -1, 1 ], [ 0, 1 ], [ 1, 1 ],
[ -1, -2 ], [ 0, -2 ], [ 1, -2 ], [ -1, 2 ], [ 0, 2 ], [ 1, 2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ],
];
global.FIX_POINTS[6] = [
[ 0, 0 ],
[ -1, -1 ], [ 0, -1 ], [ 1, -1 ], [ -1, 0 ], [ 1, 0 ], [ -1, 1 ], [ 0, 1 ], [ 1, 1 ],
[ -1, -2 ], [ 0, -2 ], [ 1, -2 ], [ -1, 2 ], [ 0, 2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ 2, -1 ], [ 2, 0 ], [ -2, -2 ],
[ -1, -3 ], [ 0, -3 ], [ -3, -1 ], [ -3, 0 ],
];
global.FIX_POINTS[7] = [
[ 0, 0 ],
[ -1, -1 ], [ 0, -1 ], [ 1, -1 ], [ -1, 0 ], [ 1, 0 ], [ -1, 1 ], [ 0, 1 ], [ 1, 1 ],
[ -1, -2 ], [ 0, -2 ], [ 1, -2 ], [ -1, 2 ], [ 0, 2 ], [ 1, 2 ], [ -2, -1 ], [ -2, 0 ], [ -2, 1 ], [ 2, -1 ], [ 2, 0 ], [ 2, 1 ], [ -2, -2 ], [ 2, -2 ], [ -2, 2 ], [ 2, 2 ],
[ -1, -3 ], [ 0, -3 ], [ 1, -3 ], [ -1, 3 ], [ 0, 3 ], [ 1, 3 ], [ -3, -1 ], [ -3, 0 ], [ -3, 1 ], [ 3, -1 ], [ 3, 0 ], [ 3, 1 ],
];
global.FIX_POINTS[8] = array_append(variable_clone(global.FIX_POINTS[7]), [ [-4, -2], [-4, -1], [-4, 0], [-4, 1], [-3, -3], [-3, -2], [-3, 2], [-2, -4], [-2, -3], [-2, 3], [-1, -4], [0, -4], [1, -4], [2, -3], [3, -2] ]);
global.FIX_POINTS[9] = array_append(variable_clone(global.FIX_POINTS[7]), [ [-4, -1], [-4, 0], [-4, 1], [-3, -2], [-3, -2], [-3, 2], [-2, -3], [-2, 3], [-1, -4], [-1, 4], [0, -4], [0, 4], [1, -4], [1, 4], [2, -3], [2, 3], [3, -2], [3, 2], [4, -1], [4, 0], [4, 1] ]);
global.FIX_POINTS_AMOUNT = array_length(global.FIX_POINTS);
#endregion

View file

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

View file

@ -0,0 +1,104 @@
function _ff_getPixel(_x, _y) { return buffer_read_at(_ff_buff, (_y * _ff_w + _x) * 4, buffer_u32); }
function canvas_ff_fillable(colorBase, colorFill, _x, _y, _thres) { #region
var c = _ff_getPixel(_x, _y);
var d = color_diff(colorBase, c, true, true);
return d <= _thres && c != colorFill;
} #endregion
function canvas_flood_fill_scanline(_surf, _x, _y, _thres, _corner = false) { #region
var colorFill = tool_attribute.color;
var colorBase = surface_getpixel_ext(_surf, _x, _y);
if(colorFill == colorBase) return; //Clicking on the same color as the fill color
var _c = tool_attribute.color;
draw_set_color(_c);
_ff_w = surface_get_width(_surf);
_ff_h = surface_get_height(_surf);
_ff_buff = buffer_create(_ff_w * _ff_h * 4, buffer_fixed, 4);
buffer_get_surface(_ff_buff, _surf, 0);
var x1, y1, x_start;
var spanAbove, spanBelow;
var thr = _thres * _thres;
var queue = ds_queue_create();
ds_queue_enqueue(queue, [_x, _y]);
while(!ds_queue_empty(queue)) {
var pos = ds_queue_dequeue(queue);
x1 = pos[0];
y1 = pos[1];
if(_ff_getPixel(x1, y1) == colorFill) continue; //Color in queue is already filled
while(x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1, thr)) //Move to the leftmost connected pixel in the same row.
x1--;
x_start = x1;
spanAbove = false;
spanBelow = false;
while(x1 < surface_w && canvas_ff_fillable(colorBase, colorFill, x1, y1, thr)) {
draw_point(x1, y1);
buffer_seek(_ff_buff, buffer_seek_start, (y1 * _ff_w + x1) * 4)
buffer_write(_ff_buff, buffer_u32, _c);
if(y1 > 0) {
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) //Check top left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 - 1]);
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 - 1, thr)) //Check top pixel
ds_queue_enqueue(queue, [x1, y1 - 1]);
}
if(y1 < surface_h - 1) {
if(_corner && x1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) //Check bottom left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 + 1]);
if(canvas_ff_fillable(colorBase, colorFill, x1, y1 + 1, thr)) //Check bottom pixel
ds_queue_enqueue(queue, [x1, y1 + 1]);
}
if(_corner && x1 < surface_w - 1) {
if(y1 > 0 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) //Check top right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 - 1]);
if(y1 < surface_h - 1 && canvas_ff_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) //Check bottom right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 + 1]);
}
x1++;
}
}
draw_set_alpha(1);
buffer_delete(_ff_buff);
} #endregion
function canvas_fill(_x, _y, _surf, _thres) { #region
var _alp = _color_get_alpha(tool_attribute.color);
var w = surface_get_width_safe(_surf);
var h = surface_get_height_safe(_surf);
var _c1 = surface_getpixel_ext(_surf, _x, _y);
var thr = _thres * _thres;
draw_set_alpha(_alp);
for( var i = 0; i < w; i++ ) {
for( var j = 0; j < h; j++ ) {
if(i == _x && j == _y) {
draw_point(i, j);
continue;
}
var _c2 = surface_getpixel_ext(_surf, i, j);
if(color_diff(_c1, _c2, true) <= thr)
draw_point(i, j);
}
}
draw_set_alpha(1);
} #endregion

View file

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

View file

@ -0,0 +1,71 @@
function canvas_freeform_step(active, _x, _y, _s, _mx, _my, _draw) { #region
var _dim = attributes.dimension;
var _mmx = (_mx - _x) / _s;
var _mmy = (_my - _y) / _s;
if(mouse_holding) {
if(abs(_mmx - mouse_pre_x) + abs(_mmy - mouse_pre_y) >= 1) {
if(_draw) {
surface_set_target(drawing_surface);
canvas_draw_line_size(brush, round(mouse_pre_x - 0.5), round(mouse_pre_y - 0.5), round(_mmx - 0.5), round(_mmy - 0.5), true);
surface_reset_target();
}
mouse_pre_x = _mmx;
mouse_pre_y = _mmy;
array_push(freeform_shape, new __vec2(_mmx, _mmy) );
}
if(mouse_release(mb_left)) {
surface_set_target(drawing_surface);
canvas_draw_line_size(brush, _mmx, _mmy, freeform_shape[0].x, freeform_shape[0].y, true);
surface_reset_target();
if(array_length(freeform_shape) > 3) {
var _triangles = polygon_triangulate(freeform_shape, 1);
var temp_surface = surface_create(_dim[0], _dim[1]);
surface_set_target(temp_surface);
DRAW_CLEAR
draw_primitive_begin(pr_trianglelist);
for( var i = 0, n = array_length(_triangles); i < n; i++ ) {
var p0 = _triangles[i][0];
var p1 = _triangles[i][1];
var p2 = _triangles[i][2];
draw_vertex(round(p0.x), round(p0.y));
draw_vertex(round(p1.x), round(p1.y));
draw_vertex(round(p2.x), round(p2.y));
}
draw_primitive_end();
draw_surface(drawing_surface, 0, 0);
surface_reset_target();
surface_set_shader(drawing_surface, sh_freeform_fill_cleanup);
shader_set_f("dimension", _dim);
draw_surface_ext(temp_surface, 0, 0, 1, 1, 0, draw_get_color(), draw_get_alpha());
surface_reset_shader();
surface_free(temp_surface);
}
mouse_holding = false;
}
} else if(mouse_press(mb_left, active)) {
mouse_pre_x = _mmx;
mouse_pre_y = _mmy;
mouse_holding = true;
freeform_shape = [ new __vec2(_mmx, _mmy) ];
surface_clear(drawing_surface);
}
} #endregion

View file

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

View file

@ -0,0 +1,94 @@
function canvas_ms_fillable(colorBase, colorFill, _x, _y, _thres) { #region
var c = _ff_getPixel(_x, _y);
var d = color_diff(colorBase, c, true, true);
return d <= _thres;
} #endregion
function canvas_magic_selection_scanline(_surf, _x, _y, _thres, _corner = false) { #region
var colorBase = surface_getpixel_ext(_surf, _x, _y);
var colorFill = colorBase;
var x1, y1, x_start;
var spanAbove, spanBelow;
var thr = _thres * _thres;
_ff_w = surface_get_width(_surf);
_ff_h = surface_get_height(_surf);
_ff_buff = buffer_create(_ff_w * _ff_h * 4, buffer_fixed, 4);
buffer_get_surface(_ff_buff, _surf, 0);
var queue = ds_queue_create();
ds_queue_enqueue(queue, [_x, _y]);
var sel_x0 = surface_w;
var sel_y0 = surface_h;
var sel_x1 = 0;
var sel_y1 = 0;
var _arr = array_create(surface_w * surface_h, 0);
draw_set_color(c_white);
while(!ds_queue_empty(queue)) {
var pos = ds_queue_dequeue(queue);
x1 = pos[0];
y1 = pos[1];
if(_arr[y1 * surface_w + x1] == 1) continue; //Color in queue is already filled
while(x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1, thr)) //Move to the leftmost connected pixel in the same row.
x1--;
x_start = x1;
spanAbove = false;
spanBelow = false;
//print($"Searching {x1}, {y1} | {canvas_ms_fillable(colorBase, colorFill, x1, y1, thr)}");
while(x1 < surface_w && canvas_ms_fillable(colorBase, colorFill, x1, y1, thr)) {
draw_point(x1, y1);
if(_arr[y1 * surface_w + x1] == 1) continue;
_arr[y1 * surface_w + x1] = 1;
sel_x0 = min(sel_x0, x1);
sel_y0 = min(sel_y0, y1);
sel_x1 = max(sel_x1, x1);
sel_y1 = max(sel_y1, y1);
//print($"> Filling {x1}, {y1}: {canvas_get_color_buffer(x1, y1)}");
if(y1 > 0) {
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 - 1, thr)) //Check top left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 - 1]);
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 - 1, thr)) //Check top pixel
ds_queue_enqueue(queue, [x1, y1 - 1]);
}
if(y1 < surface_h - 1) {
if(_corner && x1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 - 1, y1 + 1, thr)) //Check bottom left pixel
ds_queue_enqueue(queue, [x1 - 1, y1 + 1]);
if(canvas_ms_fillable(colorBase, colorFill, x1, y1 + 1, thr)) //Check bottom pixel
ds_queue_enqueue(queue, [x1, y1 + 1]);
}
if(_corner && x1 < surface_w - 1) {
if(y1 > 0 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 - 1, thr)) //Check top right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 - 1]);
if(y1 < surface_h - 1 && canvas_ms_fillable(colorBase, colorFill, x1 + 1, y1 + 1, thr)) //Check bottom right pixel
ds_queue_enqueue(queue, [x1 + 1, y1 + 1]);
}
x1++;
}
}
ds_queue_destroy(queue);
buffer_delete(_ff_buff);
return [ sel_x0, sel_y0, sel_x1, sel_y1 ];
} #endregion

View file

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

View file

@ -0,0 +1,86 @@
function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor {
self.brush = brush;
isEraser = eraser;
brush_resizable = true;
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
mouse_pre_draw_x = undefined;
mouse_pre_draw_y = undefined;
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_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT) && key_mod_press(CTRL)) {
var aa = point_direction(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y);
var dd = point_distance(mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y);
var _a = round(aa / 45) * 45;
dd = dd * cos(degtorad(_a - aa));
mouse_cur_x = mouse_pre_draw_x + lengthdir_x(dd, _a);
mouse_cur_y = mouse_pre_draw_y + lengthdir_y(dd, _a);
}
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);
surface_reset_shader();
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;
apply_draw_surface();
}
mouse_pre_draw_x = mouse_cur_x;
mouse_pre_draw_y = mouse_cur_y;
}
if(mouse_holding) {
var _move = mouse_pre_draw_x != mouse_cur_x || mouse_pre_draw_y != mouse_cur_y;
var _1stp = brush.brush_dist_min == brush.brush_dist_max && brush.brush_dist_min == 1;
if(_move || !_1stp) {
surface_set_shader(drawing_surface, noone, false, BLEND.alpha);
if(_1stp) canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y, true);
canvas_draw_line_size(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y, true);
surface_reset_shader();
}
mouse_pre_draw_x = mouse_cur_x;
mouse_pre_draw_y = mouse_cur_y;
if(mouse_release(mb_left)) {
mouse_holding = false;
apply_draw_surface();
}
}
BLEND_NORMAL;
mouse_pre_x = mouse_cur_x;
mouse_pre_y = mouse_cur_y;
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(isEraser) draw_set_color(c_white);
if(mouse_pre_draw_x != undefined && mouse_pre_draw_y != undefined && key_mod_press(SHIFT))
canvas_draw_line_size(brush, mouse_pre_draw_x, mouse_pre_draw_y, mouse_cur_x, mouse_cur_y);
else
canvas_draw_point_size(brush, mouse_cur_x, mouse_cur_y);
}
}

View file

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

View file

@ -0,0 +1,73 @@
enum CANVAS_TOOL_SHAPE {
rectangle,
ellipse
}
function canvas_tool_shape(brush, shape) : canvas_tool() constructor {
self.brush = brush;
self.shape = shape;
self.fill = false;
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, fill);
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);
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;
}
}
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, fill);
if(shape == CANVAS_TOOL_SHAPE.ellipse)
canvas_draw_ellp_size(brush, mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, fill);
}
}

View file

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

View file

@ -0,0 +1,30 @@
function canvas_tool_draw_freeform(brush) : canvas_tool() constructor {
self.brush = brush;
brush_resizable = true;
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
freeform_shape = [];
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);
attributes = node.attributes;
canvas_freeform_step(active, _x, _y, _s, _mx, _my, true);
if(mouse_release(mb_left))
apply_draw_surface();
}
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,13 @@
{
"$GMScript":"",
"%Name":"canvas_tool_draw_freeform",
"isCompatibility":false,
"isDnD":false,
"name":"canvas_tool_draw_freeform",
"parent":{
"name":"tools",
"path":"folders/nodes/data/canvas/tools.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",
}

View file

@ -0,0 +1,37 @@
function canvas_tool_fill(toolAttr) : canvas_tool() constructor {
self.tool_attribute = toolAttr;
relative = true;
mouse_cur_x = 0;
mouse_cur_y = 0;
function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
var _thr = tool_attribute.thres;
var _fill_type = tool_attribute.fill8;
mouse_cur_x = round((_mx - _x) / _s - 0.5);
mouse_cur_y = round((_my - _y) / _s - 0.5);
surface_w = surface_get_width(_canvas_surface);
surface_h = surface_get_height(_canvas_surface);
if(mouse_press(mb_left, active) && point_in_rectangle(mouse_cur_x, mouse_cur_y, 0, 0, surface_w - 1, surface_h - 1)) {
node.storeAction();
surface_set_target(_canvas_surface);
switch(_fill_type) {
case 0 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, false); break;
case 1 : canvas_flood_fill_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, true); break;
}
surface_reset_target();
node.surface_store_buffer();
}
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
}
}

View file

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

View file

@ -0,0 +1,154 @@
function canvas_tool_selection(selector = noone) : canvas_tool() constructor {
self.selector = selector;
selection_surface = surface_create_empty(1, 1);
selection_mask = surface_create_empty(1, 1);
selection_position = [ 0, 0 ];
is_selecting = false;
is_selected = false;
is_select_drag = false;
selection_sx = 0;
selection_sy = 0;
selection_mx = 0;
selection_my = 0;
mouse_cur_x = 0;
mouse_cur_y = 0;
mouse_pre_x = 0;
mouse_pre_y = 0;
function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) {
is_selecting = false;
if(sel_w == 1 && sel_h == 1) return;
is_selected = true;
selection_surface = surface_create(sel_w, sel_h);
selection_mask = surface_create(sel_w, sel_h);
surface_set_target(selection_surface);
DRAW_CLEAR
draw_surface_safe(_canvas_surface, -sel_x0, -sel_y0);
BLEND_MULTIPLY
draw_surface_safe(_mask, 0, 0);
BLEND_NORMAL
surface_reset_target();
surface_set_target(selection_mask);
DRAW_CLEAR
draw_surface_safe(_mask, 0, 0);
surface_reset_target();
node.storeAction();
surface_set_target(_canvas_surface);
gpu_set_blendmode(bm_subtract);
draw_surface_safe(selection_surface, sel_x0, sel_y0);
gpu_set_blendmode(bm_normal);
surface_reset_target();
node.surface_store_buffer();
selection_position = [ sel_x0, sel_y0 ];
}
function copySelection() {
var s = surface_encode(selection_surface);
clipboard_set_text(s);
}
function apply() {
surface_set_target(_canvas_surface);
BLEND_ALPHA
draw_surface_safe(selection_surface, selection_position[0], selection_position[1]);
BLEND_NORMAL
surface_reset_target();
node.surface_store_buffer();
surface_free(selection_surface);
}
function onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(!is_surface(selection_surface)) {
is_selected = false;
return;
}
if(is_select_drag) {
var px = selection_sx + (mouse_cur_x - selection_mx);
var py = selection_sy + (mouse_cur_y - selection_my);
selection_position[0] = px;
selection_position[1] = py;
if(mouse_release(mb_left))
is_select_drag = false;
}
if(mouse_press(mb_left, active)) {
var pos_x = selection_position[0];
var pos_y = selection_position[1];
var sel_w = surface_get_width_safe(selection_surface);
var sel_h = surface_get_height_safe(selection_surface);
if(point_in_rectangle(mouse_cur_x, mouse_cur_y, pos_x, pos_y, pos_x + sel_w, pos_y + sel_h)) {
is_select_drag = true;
selection_sx = pos_x;
selection_sy = pos_y;
selection_mx = mouse_cur_x;
selection_my = mouse_cur_y;
} else {
is_selected = false;
apply();
}
}
if(key_press(vk_delete)) {
is_selected = false;
surface_free(selection_surface);
}
if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection();
}
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(is_selected) { onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); return; }
else if(is_surface(selection_surface)) { apply(); }
}
function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(is_selected)
draw_surface_safe(selection_surface, selection_position[0], selection_position[1]);
else if(is_selecting) {
var sel_x0 = min(selection_sx, mouse_cur_x);
var sel_y0 = min(selection_sy, mouse_cur_y);
draw_surface_safe(selection_mask, sel_x0, sel_y0);
}
}
function drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(!is_selected) return;
var pos_x = _x + selection_position[0] * _s;
var pos_y = _y + selection_position[1] * _s;
var sel_w = surface_get_width_safe(selection_surface) * _s;
var sel_h = surface_get_height_safe(selection_surface) * _s;
draw_surface_ext_safe(selection_surface, pos_x, pos_y, _s, _s, 0, c_white, 1);
draw_set_color(c_black);
draw_rectangle(pos_x, pos_y, pos_x + sel_w, pos_y + sel_h, true);
draw_set_color(c_white);
draw_rectangle_dashed(pos_x, pos_y, pos_x + sel_w, pos_y + sel_h, true, 6, current_time / 100);
}
}

View file

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

View file

@ -0,0 +1,89 @@
function canvas_tool_selection_freeform(selector, brush) : canvas_tool_selection(selector) constructor {
self.brush = brush;
mouse_pre_x = 0;
mouse_pre_y = 0;
freeform_shape = [];
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);
attributes = node.attributes;
var _dim = attributes.dimension;
if(is_selected) { onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); return; }
if(mouse_press(mb_left, active)) {
is_selecting = true;
selection_sx = mouse_cur_x;
selection_sy = mouse_cur_y;
surface_free_safe(selection_mask);
}
if(is_selecting) {
var sel_x0, sel_y0, sel_x1, sel_y1;
var sel_w = 1, sel_h = 1;
draw_set_color(c_white);
canvas_freeform_step(active, _x, _y, _s, _mx, _my, false);
if(mouse_release(mb_left)) {
is_selecting = false;
sel_x0 = _dim[0];
sel_y0 = _dim[1];
sel_x1 = 0;
sel_y1 = 0;
for( var i = 0, n = array_length(freeform_shape); i < n; i++ ) {
var _f = freeform_shape[i];
sel_x0 = min(sel_x0, round(_f.x - 0.5));
sel_y0 = min(sel_y0, round(_f.y - 0.5));
sel_x1 = max(sel_x1, round(_f.x - 0.5));
sel_y1 = max(sel_y1, round(_f.y - 0.5));
}
sel_w = sel_x1 - sel_x0 + 1;
sel_h = sel_y1 - sel_y0 + 1;
if(sel_w > 1 && sel_h > 1) {
selection_mask = surface_verify(selection_mask, sel_w, sel_h);
surface_set_target(selection_mask);
DRAW_CLEAR
draw_surface(drawing_surface, -sel_x0, -sel_y0);
surface_reset_target();
}
surface_clear(drawing_surface);
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
surface_free_safe(selection_mask);
}
}
}
function drawPostOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
if(!is_selecting) return;
var ox, oy, nx, ny;
draw_set_color(c_white);
for( var i = 0, n = array_length(freeform_shape); i < n; i++ ) {
nx = _x + freeform_shape[i].x * _s;
ny = _y + freeform_shape[i].y * _s;
if(i) draw_line(ox, oy, nx, ny);
ox = nx;
oy = ny;
}
}
}

View file

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

View file

@ -0,0 +1,60 @@
function canvas_tool_selection_magic(selector, toolAttr) : canvas_tool_selection(selector) constructor {
self.tool_attribute = toolAttr;
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(is_selected) { onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); return; }
var _thr = tool_attribute.thres;
var _fill_type = tool_attribute.fill8;
if(!selector.is_selected && mouse_press(mb_left, active)) {
canvas_buffer = node.canvas_buffer;
preview_index = node.preview_index;
surface_w = surface_get_width(_canvas_surface);
surface_h = surface_get_height(_canvas_surface);
if(point_in_rectangle(mouse_cur_x, mouse_cur_y, 0, 0, surface_w - 1, surface_h - 1)) {
var bb = [ 0, 0, surface_w, surface_h ];
var _temp_surface = surface_create(surface_w, surface_h);
draw_set_color(c_white);
surface_set_target(_temp_surface);
DRAW_CLEAR
switch(_fill_type) {
case 0 : bb = canvas_magic_selection_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, false); break;
case 1 : bb = canvas_magic_selection_scanline(_canvas_surface, mouse_cur_x, mouse_cur_y, _thr, true); break;
}
surface_reset_target();
var sel_x0 = bb[0];
var sel_y0 = bb[1];
var sel_x1 = bb[2];
var sel_y1 = bb[3];
var sel_w = 1, sel_h = 1;
sel_w = sel_x1 - sel_x0 + 1;
sel_h = sel_y1 - sel_y0 + 1;
selection_mask = surface_verify(selection_mask, sel_w, sel_h);
surface_set_target(selection_mask);
DRAW_CLEAR
draw_surface(_temp_surface, -sel_x0, -sel_y0);
surface_reset_target();
surface_free(_temp_surface);
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
surface_free_safe(selection_mask);
}
}
}
}

View file

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

View file

@ -0,0 +1,54 @@
function canvas_tool_selection_shape(selector, shape) : canvas_tool_selection(selector) constructor {
self.shape = shape;
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(is_selected) { onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); return; }
if(is_selecting) {
var sel_x0, sel_y0, sel_x1, sel_y1;
var sel_w = 1, sel_h = 1;
sel_x0 = min(selection_sx, mouse_cur_x);
sel_y0 = min(selection_sy, mouse_cur_y);
sel_x1 = max(selection_sx, mouse_cur_x);
sel_y1 = max(selection_sy, mouse_cur_y);
sel_w = sel_x1 - sel_x0 + 1;
sel_h = sel_y1 - sel_y0 + 1;
selection_mask = surface_verify(selection_mask, sel_w, sel_h);
surface_set_target(selection_mask);
DRAW_CLEAR
draw_set_color(c_white);
if(shape == CANVAS_TOOL_SHAPE.rectangle)
draw_rectangle(0, 0, sel_w, sel_h, false);
else if(shape == CANVAS_TOOL_SHAPE.ellipse) {
draw_set_circle_precision(32);
draw_ellipse(0, 0, sel_w - 1, sel_h - 1, false);
}
surface_reset_target();
if(mouse_release(mb_left)) {
is_selecting = false;
selector.createSelection(selection_mask, sel_x0, sel_y0, sel_w, sel_h);
surface_free_safe(selection_mask);
}
} else if(!selector.is_selected && mouse_press(mb_left, active)) {
is_selecting = true;
selection_sx = mouse_cur_x;
selection_sy = mouse_cur_y;
surface_free_safe(selection_mask);
}
}
}

View file

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

View file

@ -174,8 +174,8 @@ function color_diff(c1, c2, fast = false, alpha = false) { #region
_c2_g = _c2_g / 255 * _c2_a; _c2_g = _c2_g / 255 * _c2_a;
_c2_b = _c2_b / 255 * _c2_a; _c2_b = _c2_b / 255 * _c2_a;
if(fast) return abs(_c1_r - _c2_r) + abs(_c1_g - _c2_g) + abs(_c1_b - _c2_b) + abs(_c1_a - _c2_a); if(fast) return (abs(_c1_r - _c2_r) + abs(_c1_g - _c2_g) + abs(_c1_b - _c2_b)) / 3;
return sqrt(sqr(_c1_r - _c2_r) + sqr(_c1_g - _c2_g) + sqr(_c1_b - _c2_b) + sqr(_c1_a - _c2_a)); return sqrt(sqr(_c1_r - _c2_r) + sqr(_c1_g - _c2_g) + sqr(_c1_b - _c2_b));
} #endregion } #endregion
#region merge #region merge

View file

@ -1,9 +1,13 @@
#region colors #region colors
globalvar CDEF, COLORS, THEME_VALUE; globalvar CDEF, COLORS, THEME_VALUE;
globalvar COLORS_GLOBAL_GET, COLORS_GLOBAL_SET;
CDEF = new ThemeColorDef(); CDEF = new ThemeColorDef();
COLORS = new ThemeColor(); COLORS = new ThemeColor();
THEME_VALUE = new ThemeValue(); THEME_VALUE = new ThemeValue();
COLORS_GLOBAL_GET = noone;
COLORS_GLOBAL_SET = noone;
#endregion #endregion
function loadColor(theme = "default") { #region function loadColor(theme = "default") { #region

View file

@ -189,6 +189,11 @@
function global_project_close() { CALL("project_close"); PANEL_GRAPH.close(); } function global_project_close() { CALL("project_close"); PANEL_GRAPH.close(); }
function global_theme_reload() { CALL("theme_reload"); loadGraphic(PREFERENCES.theme); resetPanel(); } function global_theme_reload() { CALL("theme_reload"); loadGraphic(PREFERENCES.theme); resetPanel(); }
function reset_global_getset() {
COLORS_GLOBAL_GET = noone;
COLORS_GLOBAL_SET = noone;
}
#endregion #endregion
#region debug #region debug

View file

@ -3,11 +3,13 @@
HOTKEYS_CUSTOM = { HOTKEYS_CUSTOM = {
"Node_Canvas": { "Node_Canvas": {
"Selection": new hotkeySimple("S"), "Selection": new hotkeySimple("S"),
"Magic Selection": new hotkeySimple("W"),
"Pencil": new hotkeySimple("B"), "Pencil": new hotkeySimple("B"),
"Eraser": new hotkeySimple("E"), "Eraser": new hotkeySimple("E"),
"Rectangle": new hotkeySimple("N"), "Rectangle": new hotkeySimple("N"),
"Ellipse": new hotkeySimple("M"), "Ellipse": new hotkeySimple("M"),
"Fill": new hotkeySimple("F"), "Fill": new hotkeySimple("F"),
"Freeform": new hotkeySimple("Q"),
}, },
"Node_Mesh_Warp": { "Node_Mesh_Warp": {
"Edit control point": new hotkeySimple("V"), "Edit control point": new hotkeySimple("V"),

View file

@ -143,7 +143,7 @@ enum MOD_KEY {
alt = 4 alt = 4
} }
function key_press(_key, _mod) { function key_press(_key, _mod = MOD_KEY.none) {
if(WIDGET_CURRENT) return false; if(WIDGET_CURRENT) return false;
if(_mod == MOD_KEY.none && _key == 0) return false; if(_mod == MOD_KEY.none && _key == 0) return false;

File diff suppressed because it is too large Load diff

View file

@ -5,8 +5,8 @@
"isDnD":false, "isDnD":false,
"name":"node_canvas", "name":"node_canvas",
"parent":{ "parent":{
"name":"io", "name":"canvas",
"path":"folders/nodes/data/io.yy", "path":"folders/nodes/data/canvas.yy",
}, },
"resourceType":"GMScript", "resourceType":"GMScript",
"resourceVersion":"2.0", "resourceVersion":"2.0",

View file

@ -268,6 +268,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor {
#region ---- tools ---- #region ---- tools ----
tools = -1; tools = -1;
rightTools = -1;
isTool = false; isTool = false;
tool_settings = []; tool_settings = [];
tool_attribute = {}; tool_attribute = {};

View file

@ -5,9 +5,7 @@ enum COLOR_SELECTOR_MODE {
function Panel_Color() : PanelContent() constructor { function Panel_Color() : PanelContent() constructor {
title = __txt("Color"); title = __txt("Color");
showHeader = false; padding = 8;
title_height = 64;
padding = 24;
w = ui(320); w = ui(320);
h = ui(320); h = ui(320);
@ -29,6 +27,9 @@ function Panel_Color() : PanelContent() constructor {
hue = color_get_hue(color) / 255; hue = color_get_hue(color) / 255;
sat = color_get_saturation(color) / 255; sat = color_get_saturation(color) / 255;
val = color_get_value(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) { static setHSV = function(h = hue, s = sat, v = val) {
@ -37,25 +38,31 @@ function Panel_Color() : PanelContent() constructor {
val = v; val = v;
color = make_color_hsv(h * 255, s * 255, v * 255); color = make_color_hsv(h * 255, s * 255, v * 255);
if(COLORS_GLOBAL_SET != noone)
COLORS_GLOBAL_SET(color);
} }
setHSV(); setHSV();
function drawContent(panel) { function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0); draw_clear_alpha(COLORS.panel_bg_clear, 0);
PANEL_PADDING
PANEL_TITLE
var px = ui(padding); var px = ui(padding);
var py = ui(title_height); var py = ui(padding);
var pw = w - ui(padding + padding); var pw = w - ui(padding + padding);
var ph = h - ui(title_height + 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)); 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_x = ui(padding);
var cont_y = ui(title_height); var cont_y = ui(padding);
var cont_w = w - ui(padding + padding + ui(16 + 8)); var cont_w = w - ui(padding + padding + ui(16 + 8));
var cont_h = h - ui(title_height + padding + ui(24 + 8)); var cont_h = h - ui(padding + padding + ui(24 + 8));
shader_set(sh_color_select_content); shader_set(sh_color_select_content);
shader_set_i("mode", mode); shader_set_i("mode", mode);
@ -64,7 +71,7 @@ function Panel_Color() : PanelContent() constructor {
draw_sprite_stretched(s_fx_pixel, 0, cont_x, cont_y, cont_w, cont_h); 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_x = cont_x + cont_w + ui(8);
var sel_y = ui(title_height); var sel_y = ui(padding);
var sel_w = ui(16); var sel_w = ui(16);
var sel_h = cont_h; var sel_h = cont_h;
@ -115,6 +122,7 @@ function Panel_Color() : PanelContent() constructor {
var cy = cont_y + (1 - val) * cont_h - 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, 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); draw_sprite_stretched_ext(s_ui_base_white, 0, cx, cy, ui(12), ui(12), color, 1);
} else if(mode == 1) { } else if(mode == 1) {
var vy = sel_y + (1 - val) * sel_h; var vy = sel_y + (1 - val) * sel_h;
var cx = cont_x + hue * cont_w - ui(6); var cx = cont_x + hue * cont_w - ui(6);
@ -137,11 +145,17 @@ function Panel_Color() : PanelContent() constructor {
draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 1); draw_sprite_stretched_ext(THEME.ui_panel_active, 0, cx, cy, ui(24), ui(24), c_white, 1);
if(mouse_press(mb_left, pFOCUS)) { if(mouse_press(mb_left, pFOCUS)) {
array_insert(colors, 0, color); array_insert(colors, 0, color);
DRAGGING = {
type: "Color", if(COLORS_GLOBAL_SET != noone) {
data: color COLORS_GLOBAL_SET(color);
} else {
DRAGGING = {
type: "Color",
data: color
}
MESSAGE = DRAGGING;
} }
MESSAGE = DRAGGING;
} }
} }
continue; continue;
@ -159,14 +173,6 @@ function Panel_Color() : PanelContent() constructor {
} }
} }
var bx = w - ui(32 + 16);
var by = title_height / 2 - ui(16 + !in_dialog * 2);
if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txt("Mode"), THEME.color_wheel,, c_white) == 2)
mode = !mode;
bx -= ui(32);
if(DRAGGING && DRAGGING.type == "Color" && pHOVER) { 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); 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)) if(mouse_release(mb_left))

View file

@ -1,8 +1,6 @@
function Panel_Palette() : PanelContent() constructor { function Panel_Palette() : PanelContent() constructor {
title = __txt("Palettes"); title = __txt("Palettes");
showHeader = false; padding = 8;
title_height = 64;
padding = 24;
w = ui(320); w = ui(320);
h = ui(480); h = ui(480);
@ -14,10 +12,10 @@ function Panel_Palette() : PanelContent() constructor {
function onResize() { function onResize() {
PANEL_PADDING PANEL_PADDING
sp_palettes.resize(w - ui(padding + padding), h - ui(title_height + padding)); sp_palettes.resize(w - ui(padding + padding), h - ui(padding + padding));
} }
sp_palettes = new scrollPane(w - ui(padding + padding), h - ui(title_height + padding), function(_y, _m) { sp_palettes = new scrollPane(w - ui(padding + padding), h - ui(padding + padding), function(_y, _m) {
draw_clear_alpha(COLORS.panel_bg_clear, 0); draw_clear_alpha(COLORS.panel_bg_clear, 0);
var ww = sp_palettes.surface_w; var ww = sp_palettes.surface_w;
var hh = ui(28); var hh = ui(28);
@ -48,28 +46,56 @@ function Panel_Palette() : PanelContent() constructor {
draw_text(ui(10), yy + ui(2), preset.name); 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);
if(isHover && mouse_press(mb_left, pFOCUS)) { if(isHover) {
if(point_in_rectangle(_m[0], _m[1], ui(10), yy + ui(24), ww - ui(10), yy + ui(24) + _height)) { if(mouse_press(mb_left, pFOCUS)) {
var m_ax = _m[0] - ui(10); if(point_in_rectangle(_m[0], _m[1], ui(10), yy + ui(24), ww - ui(10), yy + ui(24) + _height)) {
var m_ay = _m[1] - (yy + ui(24)); var m_ax = _m[0] - ui(10);
var m_ay = _m[1] - (yy + ui(24));
var m_gx = floor(m_ax / _gs); var m_gx = floor(m_ax / _gs);
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) {
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 = { DRAGGING = {
type: "Color", type: "Palette",
data: array_safe_get_fast(preset.palette, _index) data: preset.palette
} }
MESSAGE = DRAGGING; MESSAGE = DRAGGING;
} }
} else if(point_in_rectangle(_m[0], _m[1], ui(10), yy, ww - ui(10), yy + ui(24))) { }
DRAGGING = {
type: "Palette", if(mouse_press(mb_right, pFOCUS)) {
data: preset.palette hovering = preset;
}
MESSAGE = DRAGGING; 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();
}),
]);
} }
} }
@ -82,27 +108,16 @@ function Panel_Palette() : PanelContent() constructor {
function drawContent(panel) { function drawContent(panel) {
draw_clear_alpha(COLORS.panel_bg_clear, 0); draw_clear_alpha(COLORS.panel_bg_clear, 0);
PANEL_PADDING
PANEL_TITLE
var px = ui(padding); var px = ui(padding);
var py = ui(title_height); var py = ui(padding);
var pw = w - ui(padding + padding); var pw = w - ui(padding + padding);
var ph = h - ui(title_height + 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)); 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.setFocusHover(pFOCUS, pHOVER);
sp_palettes.draw(px, py, mx - px, my - py); sp_palettes.draw(px, py, mx - px, my - py);
var bx = w - ui(32 + 16);
var by = title_height / 2 - ui(16 + !in_dialog * 2);
if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txt("Refresh"), THEME.refresh_icon, 1, COLORS._main_icon) == 2)
__initPalette();
bx -= ui(32)
if(buttonInstant(THEME.button_hide, bx, by, ui(32), ui(32), [mx, my], pFOCUS, pHOVER, __txtx("palette_change_preview_size", "Change preview size"), THEME.icon_visibility, 1, COLORS._main_icon) == 2)
view_mode = (view_mode + 1) % 3;
} }
} }

View file

@ -1188,6 +1188,8 @@ function Panel_Preview() : PanelContent() constructor {
overlayHover &= !key_mod_press(CTRL); overlayHover &= !key_mod_press(CTRL);
var params = { w, h, toolbar_height }; var params = { w, h, toolbar_height };
reset_global_getset();
if(_node.is_3D) { if(_node.is_3D) {
if(key_mod_press(CTRL) || d3_tool_snap) { if(key_mod_press(CTRL) || d3_tool_snap) {
_snx = d3_tool_snap_position; _snx = d3_tool_snap_position;
@ -1324,6 +1326,57 @@ function Panel_Preview() : PanelContent() constructor {
if(mouse_wheel_up()) tool_y_to = clamp(tool_y_to + ui(64) * SCROLL_SPEED, -tool_y_max, 0); if(mouse_wheel_up()) tool_y_to = clamp(tool_y_to + ui(64) * SCROLL_SPEED, -tool_y_max, 0);
if(mouse_wheel_down()) tool_y_to = clamp(tool_y_to - ui(64) * SCROLL_SPEED, -tool_y_max, 0); if(mouse_wheel_down()) tool_y_to = clamp(tool_y_to - ui(64) * SCROLL_SPEED, -tool_y_max, 0);
} }
if(_node.rightTools != -1) {
var _tbx = w - toolbar_width;
var xx = _tbx + ui(1) + toolbar_width / 2;
var yy = ui(34) + tool_size / 2 + tool_y;
var _sw = -toolbar_width / sprite_get_width(THEME.tool_side);
var _sh = h - toolbar_height - ui(32) / sprite_get_height(THEME.tool_side);
draw_sprite_ext(THEME.tool_side, 1, w + 1, ui(32), _sw, _sh, 0, c_white, aa);
var thov = pHOVER && point_in_rectangle(mx, my, _tbx, toolbar_height, w, h - toolbar_height);
if(thov) canvas_hover = false;
for(var i = 0; i < array_length(_node.rightTools); i++) { #region iterate each tools
var tool = _node.rightTools[i];
var _x0 = xx - tool_size / 2;
var _y0 = yy - tool_size / 2;
var _x1 = xx + tool_size / 2;
var _y1 = yy + tool_size / 2;
if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1))
tool_hovering = tool;
if(tool_hovering == tool) {
draw_sprite_stretched(THEME.button_hide, 1, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2);
TOOLTIP = tool.getDisplayName();
if(mouse_press(mb_left, pFOCUS))
tool.toggle();
}
if(pFOCUS && WIDGET_CURRENT == noone) {
var _key = tool.checkHotkey();
if(_key != "" && keyboard_check_pressed(ord(_key)))
tool.toggleKeyboard();
}
if(tool_current == tool) {
draw_sprite_stretched_ext(THEME.button_hide, 2, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1);
draw_sprite_stretched_ext(THEME.button_hide, 3, _x0 + pd, _y0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1);
}
draw_sprite_colored(tool.spr, 0, xx, yy);
yy += tool_size;
} #endregion
}
} #endregion } #endregion
function drawToolBar(_tool) { #region function drawToolBar(_tool) { #region

View file

@ -557,17 +557,18 @@
return _arr; return _arr;
} #endregion } #endregion
function surface_encode(surface) { #region function surface_encode(surface, stringify = true) { #region
if(!is_real(surface)) return ""; if(!is_surface(surface)) return "";
if(!surface_exists(surface)) return "";
var buff = buffer_create(surface_get_width_safe(surface) * surface_get_height_safe(surface) * 4, buffer_fixed, 1); var buff = buffer_create(surface_get_width_safe(surface) * surface_get_height_safe(surface) * 4, buffer_fixed, 1);
buffer_get_surface(buff, surface, 0); buffer_get_surface(buff, surface, 0);
var comp = buffer_compress(buff, 0, buffer_get_size(buff)); var comp = buffer_compress(buff, 0, buffer_get_size(buff));
var enc = buffer_base64_encode(comp, 0, buffer_get_size(comp)); var enc = buffer_base64_encode(comp, 0, buffer_get_size(comp));
var str = { width: surface_get_width_safe(surface), height: surface_get_height_safe(surface), buffer: enc };
buffer_delete(buff); buffer_delete(buff);
var str = { width: surface_get_width_safe(surface), height: surface_get_height_safe(surface), buffer: enc };
return json_stringify(str); return stringify? json_stringify(str) : str;
} #endregion } #endregion
function surface_decode(struct) { #region function surface_decode(struct) { #region

View file

@ -0,0 +1,12 @@
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D drawSurface;
uniform sampler2D maskSurface;
void main() {
vec4 drw = texture2D( drawSurface, v_vTexcoord );
vec4 msk = texture2D( maskSurface, v_vTexcoord );
gl_FragColor = msk.a > 0.5? drw : texture2D( gm_BaseTexture, v_vTexcoord );
}

View file

@ -0,0 +1,19 @@
//
// Simple passthrough vertex shader
//
attribute vec3 in_Position; // (x,y,z)
//attribute vec3 in_Normal; // (x,y,z) unused in this shader.
attribute vec4 in_Colour; // (r,g,b,a)
attribute vec2 in_TextureCoord; // (u,v)
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
void main()
{
vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
v_vColour = in_Colour;
v_vTexcoord = in_TextureCoord;
}

View file

@ -0,0 +1,12 @@
{
"$GMShader":"",
"%Name":"sh_canvas_mask",
"name":"sh_canvas_mask",
"parent":{
"name":"tools",
"path":"folders/nodes/data/canvas/tools.yy",
},
"resourceType":"GMShader",
"resourceVersion":"2.0",
"type":1,
}