diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index c92a179b0..99b1c2511 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -1157,8 +1157,8 @@ {"name":"sh_active_canvas_ink","order":13,"path":"shaders/sh_active_canvas_ink/sh_active_canvas_ink.yy",}, {"name":"sh_alpha_grey","order":1,"path":"shaders/sh_alpha_grey/sh_alpha_grey.yy",}, {"name":"sh_alpha_hash","order":2,"path":"shaders/sh_alpha_hash/sh_alpha_hash.yy",}, - {"name":"sh_atlas","order":12,"path":"shaders/sh_atlas/sh_atlas.yy",}, {"name":"sh_atlas_scan","order":51,"path":"shaders/sh_atlas_scan/sh_atlas_scan.yy",}, + {"name":"sh_atlas","order":12,"path":"shaders/sh_atlas/sh_atlas.yy",}, {"name":"sh_bend_arc","order":13,"path":"shaders/sh_bend_arc/sh_bend_arc.yy",}, {"name":"sh_bevel_highp","order":3,"path":"shaders/sh_bevel_highp/sh_bevel_highp.yy",}, {"name":"sh_bevel","order":2,"path":"shaders/sh_bevel/sh_bevel.yy",}, @@ -1303,6 +1303,7 @@ {"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_replace","order":2,"path":"shaders/sh_flood_fill_replace/sh_flood_fill_replace.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_gamma_map","order":38,"path":"shaders/sh_gamma_map/sh_gamma_map.yy",}, {"name":"sh_glow","order":18,"path":"shaders/sh_glow/sh_glow.yy",}, @@ -1443,6 +1444,7 @@ {"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_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":"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":"s_biterator_b_grey_long","order":7,"path":"sprites/s_biterator_b_grey_long/s_biterator_b_grey_long.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 9af18b4dd..b0b98772e 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -250,6 +250,7 @@ {"$GMFolder":"","%Name":"legacy","folderPath":"folders/shader/3d/legacy.yy","name":"legacy","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"ssao","folderPath":"folders/shader/3d/ssao.yy","name":"ssao","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"blend","folderPath":"folders/shader/blend.yy","name":"blend","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"canvas","folderPath":"folders/shader/canvas.yy","name":"canvas","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"color_picker","folderPath":"folders/shader/color_picker.yy","name":"color_picker","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"color_selector","folderPath":"folders/shader/color_selector.yy","name":"color_selector","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"draw","folderPath":"folders/shader/draw.yy","name":"draw","resourceType":"GMFolder","resourceVersion":"2.0",}, @@ -274,7 +275,6 @@ {"$GMFolder":"","%Name":"Flag","folderPath":"folders/shader/MK effects/Flag.yy","name":"Flag","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"Tile","folderPath":"folders/shader/MK effects/Tile.yy","name":"Tile","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"pixel_builder","folderPath":"folders/shader/pixel_builder.yy","name":"pixel_builder","resourceType":"GMFolder","resourceVersion":"2.0",}, - {"$GMFolder":"","%Name":"simulation","folderPath":"folders/shader/simulation.yy","name":"simulation","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"sprites","folderPath":"folders/shader/sprites.yy","name":"sprites","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"transition","folderPath":"folders/shader/transition.yy","name":"transition","resourceType":"GMFolder","resourceVersion":"2.0",}, {"$GMFolder":"","%Name":"UI","folderPath":"folders/shader/UI.yy","name":"UI","resourceType":"GMFolder","resourceVersion":"2.0",}, @@ -1650,8 +1650,8 @@ {"id":{"name":"sh_alpha_grey","path":"shaders/sh_alpha_grey/sh_alpha_grey.yy",},}, {"id":{"name":"sh_alpha_hash","path":"shaders/sh_alpha_hash/sh_alpha_hash.yy",},}, {"id":{"name":"sh_ani_noise","path":"shaders/sh_ani_noise/sh_ani_noise.yy",},}, - {"id":{"name":"sh_atlas","path":"shaders/sh_atlas/sh_atlas.yy",},}, {"id":{"name":"sh_atlas_scan","path":"shaders/sh_atlas_scan/sh_atlas_scan.yy",},}, + {"id":{"name":"sh_atlas","path":"shaders/sh_atlas/sh_atlas.yy",},}, {"id":{"name":"sh_average","path":"shaders/sh_average/sh_average.yy",},}, {"id":{"name":"sh_bend_arc","path":"shaders/sh_bend_arc/sh_bend_arc.yy",},}, {"id":{"name":"sh_bevel_highp","path":"shaders/sh_bevel_highp/sh_bevel_highp.yy",},}, @@ -1816,6 +1816,8 @@ {"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_fluid_bleach","path":"shaders/sh_fluid_bleach/sh_fluid_bleach.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_FXAA","path":"shaders/sh_FXAA/sh_FXAA.yy",},}, {"id":{"name":"sh_gamma_map","path":"shaders/sh_gamma_map/sh_gamma_map.yy",},}, {"id":{"name":"sh_glow","path":"shaders/sh_glow/sh_glow.yy",},}, @@ -1979,6 +1981,7 @@ {"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_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":"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":"node_credit","path":"sprites/node_credit/node_credit.yy",},}, diff --git a/datafiles/data/Theme.zip b/datafiles/data/Theme.zip index 28f536a17..bb0d85242 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/scripts/__polygon/__polygon.gml b/scripts/__polygon/__polygon.gml index 5e28e1f4d..d64ce3edc 100644 --- a/scripts/__polygon/__polygon.gml +++ b/scripts/__polygon/__polygon.gml @@ -1,4 +1,4 @@ -function polygon_simplify(points, tolerance = 4) { +function polygon_simplify(points, tolerance = 4) { #region var remSt = ds_stack_create(); var len = array_length(points); @@ -25,9 +25,9 @@ function polygon_simplify(points, tolerance = 4) { ds_stack_destroy(remSt); return points; -} +} #endregion -function polygon_points_classify(points) { +function polygon_points_classify(points) { #region var len = array_length(points); var maxx = -99999; @@ -65,9 +65,9 @@ function polygon_points_classify(points) { } return [ convexs, reflects, _side ]; -} +} #endregion -function polygon_triangulate_convex(points) { +function polygon_triangulate_convex(points) { #region var triangles = []; var len = array_length(points); @@ -81,19 +81,19 @@ function polygon_triangulate_convex(points) { } return triangles; -} +} #endregion -function polygon_triangulate(points, tolerance = 4) { +function polygon_triangulate(points, tolerance = 4) { #region points = polygon_simplify(points, tolerance); var classes = polygon_points_classify(points); var convexes = classes[0]; var reflected = classes[1]; var checkSide = classes[2]; - var pointInd = []; if(array_length(reflected) == 0) return polygon_triangulate_convex(points); + var pointInd = array_create(array_length(points)); for( var i = 0, n = array_length(points); i < n; i++ ) pointInd[i] = i; @@ -104,10 +104,10 @@ function polygon_triangulate(points, tolerance = 4) { if(array_length(convexes) == 0) return triangles; var len = array_length(pointInd); - var c0 = convexes[0]; + var c0 = convexes[0]; var c0i = array_find(pointInd, c0); - var c1 = pointInd[safe_mod(c0i - 1 + len, len)]; - var c2 = pointInd[safe_mod(c0i + 1, len)]; + var c1 = pointInd[safe_mod(c0i - 1 + len, len)]; + var c2 = pointInd[safe_mod(c0i + 1, len)]; var p0 = points[c0]; var p1 = points[c1]; @@ -171,7 +171,7 @@ function polygon_triangulate(points, tolerance = 4) { array_push(convexes, c0); if(repeated++ > len) { - print("mesh error") + //print("mesh error") break; } } @@ -181,9 +181,9 @@ function polygon_triangulate(points, tolerance = 4) { array_push(triangles, [points[pointInd[0]], points[pointInd[1]], points[pointInd[2]]]); return triangles; -} +} #endregion -function polygon_triangulate_convex_fan(points) { +function polygon_triangulate_convex_fan(points) { #region var triangles = []; var amo = array_length(points); @@ -202,4 +202,4 @@ function polygon_triangulate_convex_fan(points) { array_push(triangles, [ points[i], points[(i + 1) % amo], pc ]); } return triangles; -} \ No newline at end of file +} #endregion \ No newline at end of file diff --git a/scripts/control_function/control_function.gml b/scripts/control_function/control_function.gml index 4ec38fa50..7bbd32fc3 100644 --- a/scripts/control_function/control_function.gml +++ b/scripts/control_function/control_function.gml @@ -35,6 +35,12 @@ keyboard_key_release(vk_alt); } + function key_mod_press_any() { + INLINE + + return CTRL == KEYBOARD_STATUS.pressing || ALT == KEYBOARD_STATUS.pressing || SHIFT == KEYBOARD_STATUS.pressing; + } + function key_mod_press(key) { INLINE diff --git a/scripts/draw_shapes/draw_shapes.gml b/scripts/draw_shapes/draw_shapes.gml index 7cf139615..55b950dcb 100644 --- a/scripts/draw_shapes/draw_shapes.gml +++ b/scripts/draw_shapes/draw_shapes.gml @@ -6,12 +6,12 @@ function draw_rectangle_width(x0, y0, x1, y1, th = 1) { draw_line_width(x1, y0 - th / 2, x1, y1 + th / 2, th); } -function draw_rectangle_dashed(x0, y0, x1, y1, th = 1, dash = 8) { - draw_line_dashed(x0 - th / 2, y0, x1 + th / 2, y0, th, dash); - draw_line_dashed(x0 - th / 2, y1, x1 + th / 2, y1, th, dash); +function draw_rectangle_dashed(x0, y0, x1, y1, th = 1, dash = 8, shift = 0) { + draw_line_dashed(x0 - th / 2, y0, x1 + th / 2, y0, th, dash, shift); + draw_line_dashed(x0 - th / 2, y1, x1 + th / 2, y1, th, dash, shift); - draw_line_dashed(x0, y0 - th / 2, x0, y1 + th / 2, th, dash); - draw_line_dashed(x1, y0 - th / 2, x1, y1 + th / 2, th, dash); + draw_line_dashed(x0, y0 - th / 2, x0, y1 + th / 2, th, dash, shift); + draw_line_dashed(x1, y0 - th / 2, x1, y1 + th / 2, th, dash, shift); } function draw_ellipse_width(x0, y0, x1, y1, th = 1) { diff --git a/scripts/gradients_function/gradients_function.gml b/scripts/gradients_function/gradients_function.gml index 0a5209a93..4c1c6c6e8 100644 --- a/scripts/gradients_function/gradients_function.gml +++ b/scripts/gradients_function/gradients_function.gml @@ -199,6 +199,12 @@ function gradientObject(color = c_black) constructor { #region var key_count = ceil(lerp(array_length(keys), array_length(target.keys), amount)); + if(key_count == 0) return grad; + if(key_count == 1) { + grad.keys[0] = new gradientKey(0, merge_color(eval(0), target.eval(0), amount)); + return grad; + } + for( var i = 0; i < key_count; i++ ) { var rat = i / (key_count - 1); diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index ebad4b56f..49a733fc6 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -154,6 +154,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor return 8 + _h; }); #endregion + temp_surface = array_create(1); + input_display_list = [ ["Output", false], 0, frame_renderer, 12, 13, ["Brush", true], 6, 15, 17, 16, @@ -216,7 +218,9 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor brush_rand_dir = [ 0, 0, 0, 0, 0 ]; brush_seed = irandom_range(100000, 999999); brush_next_dist = 0; - + + freeform_shape = []; + draw_stack = ds_list_create(); #endregion @@ -246,7 +250,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_fil8 = [ "Diagonal", tool_fil8_edit, "fill8", tool_attribute ]; tools = [ - new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle ]), + new NodeTool( "Selection", [ THEME.canvas_tools_selection_rectangle, THEME.canvas_tools_selection_circle, THEME.canvas_tools_freeform_selection ]), new NodeTool( "Pencil", THEME.canvas_tools_pencil) .setSetting(tool_size), @@ -260,12 +264,47 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor new NodeTool( "Ellipse", [ THEME.canvas_tools_ellip, THEME.canvas_tools_ellip_fill ]) .setSetting(tool_size), + new NodeTool( "Freefrom", THEME.canvas_tools_freeform) + .setSetting(tool_size), + new NodeTool( "Fill", THEME.canvas_tools_bucket) .setSetting(tool_thrs) .setSetting(tool_fil8), ]; #endregion + #region fix size points + fix_points = []; + + fix_points[0] = []; + fix_points[1] = []; + fix_points[2] = [[ 0, 0 ], [ 1, 0 ], [ 0, 1 ], [ 1, 1 ]]; + fix_points[3] = [[ 0, 0 ], [ -1, 0 ], [ 0, -1 ], [ 1, 0 ], [ 0, 1 ]]; + 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 ]]; + 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 ], + ]; + 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 ], + ]; + 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 ], + ]; + + fix_points[8] = array_append(variable_clone(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] ]); + fix_points[9] = array_append(variable_clone(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] ]); + + fix_points_amount = array_length(fix_points); + #endregion + function setToolColor(color) { tool_attribute.color = color; } static drawTools = function(_mx, _my, xx, yy, tool_size, hover, focus) { #region @@ -336,11 +375,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } #endregion function refreshFrames() { #region - var fr = attributes.frames; + var fr = attributes.frames; + var _dim = attributes.dimension; if(array_length(canvas_surface) < fr) { for( var i = array_length(canvas_surface); i < fr; i++ ) { - canvas_surface[i] = surface_create_empty(1, 1); + canvas_surface[i] = surface_create(_dim[0], _dim[1]); + surface_set_target(canvas_surface[i]); + DRAW_CLEAR + surface_reset_target(); } } else array_resize(canvas_surface, fr); @@ -449,21 +492,18 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor function draw_point_size(_x, _y, _draw = false) { #region if(brush_surface == noone) { + if(brush_size <= 1) draw_point(_x, _y); - else if(brush_size == 2) { - draw_point(_x, _y); - draw_point(_x + 1, _y); - draw_point(_x, _y + 1); - draw_point(_x + 1, _y + 1); - } else if(brush_size == 3) { - draw_point(_x, _y); - draw_point(_x - 1, _y); - draw_point(_x, _y - 1); - draw_point(_x + 1, _y); - draw_point(_x, _y + 1); + + else if(brush_size < fix_points_amount) { + var fx = fix_points[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_size / 2, 0); + } else { var _sw = surface_get_width_safe(brush_surface); var _sh = surface_get_height_safe(brush_surface); @@ -478,13 +518,27 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor function draw_line_size(_x0, _y0, _x1, _y1, _draw = false) { #region - if(brush_size == 1 && brush_surface == noone) { - if(_x1 > _x0) _x0--; - if(_y1 > _y0) _y0--; - if(_y1 < _y0) _y1--; - if(_x1 < _x0) _x1--; - - draw_line(_x0, _y0, _x1, _y1); + if(brush_surface == noone) { + + if(brush_size < fix_points_amount) { + if(_x1 > _x0) _x0--; + if(_y1 > _y0) _y0--; + if(_y1 < _y0) _y1--; + if(_x1 < _x0) _x1--; + } + + if(brush_size == 1) { + draw_line(_x0, _y0, _x1, _y1); + + } else if(brush_size < fix_points_amount) { + + var fx = fix_points[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_size); + } else { var diss = point_distance(_x0, _y0, _x1, _y1); var dirr = point_direction(_x0, _y0, _x1, _y1); @@ -536,15 +590,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor 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); - } else if(brush_size == 1 && brush_surface == noone) + if(_fill) draw_rectangle(_min_x, _min_y, _max_x, _may_y, 0); + + if(brush_size == 1 && brush_surface == noone) draw_rectangle(_min_x + 1, _min_y + 1, _max_x - 1, _may_y - 1, 1); else { - draw_line_size(_min_x, _min_y, _max_x, _min_y); - draw_line_size(_min_x, _min_y, _min_x, _may_y); - draw_line_size(_max_x, _may_y, _max_x, _min_y); - draw_line_size(_max_x, _may_y, _min_x, _may_y); + draw_set_color(c_red); draw_line_size(_min_x, _min_y, _max_x, _min_y); + draw_set_color(c_blue); draw_line_size(_min_x, _min_y, _min_x, _may_y); + draw_set_color(c_green); draw_line_size(_max_x, _may_y, _max_x, _min_y); + draw_set_color(c_yellow); draw_line_size(_max_x, _may_y, _min_x, _may_y); } } #endregion @@ -569,25 +623,23 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _min_y = min(_y0, _y1) - 1; var _max_y = max(_y0, _y1); - if(_fill) { - draw_ellipse(_min_x, _min_y, _max_x, _max_y, 0); - } else { - 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; + if(_fill) 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 = cx + lengthdir_x(rx, 360 / samp * i); - ny = cy + lengthdir_y(ry, 360 / samp * i); + var ox, oy, nx, ny; + for( var i = 0; i <= samp; i++ ) { + nx = cx + lengthdir_x(rx, 360 / samp * i); + ny = cy + lengthdir_y(ry, 360 / samp * i); - if(i) draw_line_size(ox, oy, nx, ny); + if(i) draw_line_size(ox, oy, nx, ny); - ox = nx; - oy = ny; - } + ox = nx; + oy = ny; } } #endregion @@ -708,6 +760,75 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_set_alpha(1); } #endregion + function freeform_step(active, _x, _y, _s, _mx, _my, _draw) { #region + var _dim = attributes.dimension; + + var _mmx = (_mx - _x) / _s; + var _mmy = (_my - _y) / _s; + brush_size = 1; + + if(mouse_holding) { + if(abs(_mmx - mouse_pre_x) + abs(_mmy - mouse_pre_y) >= 1) { + + if(_draw) { + surface_set_target(drawing_surface); + draw_line_size(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); + draw_line_size(_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); + + temp_surface[0] = surface_verify(temp_surface[0], _dim[0], _dim[1]); + + surface_set_target(temp_surface[0]); + 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, 0, 1, 1, 0, draw_get_color(), draw_get_alpha()); + surface_reset_shader(); + } + + 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 + static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region if(instance_exists(o_dialog_color_picker)) return; @@ -726,6 +847,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _brushRotD = getInputData(16); var _brushRotR = getInputData(17); + var _applySelection = false; + if(PEN_USE && tool_attribute.pressure) brush_size = round(lerp(tool_attribute.pressure_size[0], tool_attribute.pressure_size[1], power(PEN_PRESSURE / 1024, 2))); else @@ -786,11 +909,13 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_set_color(_col); - if(!isUsingTool("Selection")) - gpu_set_colorwriteenable(tool_attribute.channel[0], tool_attribute.channel[1], tool_attribute.channel[2], tool_attribute.channel[3]); + if(!isUsingTool("Selection")) gpu_set_colorwriteenable(tool_attribute.channel[0], tool_attribute.channel[1], tool_attribute.channel[2], tool_attribute.channel[3]); + + var _tool_resizable = false; if(isUsingTool("Selection")) { #region - if(is_selected) { + + if(is_selected) { #region selected if(!is_surface(selection_surface)) { is_selected = false; } else { @@ -827,61 +952,107 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_reset_target(); surface_store_buffer(); - surface_free(selection_surface); + _applySelection = true; } } } - } - - if(!is_selected) { - if(is_selecting) { - var sel_x0 = min(selection_sx, mouse_cur_x); - var sel_y0 = min(selection_sy, mouse_cur_y); - var sel_x1 = max(selection_sx, mouse_cur_x); - var sel_y1 = max(selection_sy, mouse_cur_y); + } else { #region selection - var sel_w = sel_x1 - sel_x0 + 1; - var 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(isUsingTool("Selection", 0)) - draw_rectangle(0, 0, sel_w, sel_h, false); - else if(isUsingTool("Selection", 1)) - draw_ellipse(0, 0, sel_w - 1, sel_h - 1, false); - surface_reset_target(); - - if(mouse_release(mb_left)) { - is_selecting = false; + if(isUsingTool("Selection", 2) && mouse_press(mb_left, active)) { + is_selecting = true; + surface_free_safe(selection_mask); + } - if(sel_x0 != sel_x1 && sel_y0 != sel_y1) { - is_selected = true; - - selection_surface = surface_create(sel_w, sel_h); - - surface_set_target(selection_surface); - DRAW_CLEAR - draw_surface_safe(_canvas_surface, -sel_x0, -sel_y0); + if(is_selecting) { + var sel_x0, sel_y0, sel_x1, sel_y1; + var sel_w = 1, sel_h = 1; + + if(isUsingTool("Selection", 2)) { #region freeform + freeform_step(active, _x, _y, _s, _mx, _my, false); + + if(mouse_release(mb_left)) { + is_selecting = false; - BLEND_MULTIPLY - draw_surface_safe(selection_mask, 0, 0); - BLEND_NORMAL - surface_reset_target(); + sel_x0 = _dim[0]; + sel_y0 = _dim[1]; + sel_x1 = 0; + sel_y1 = 0; - 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(); - - surface_store_buffer(); - - selection_position = [ sel_x0, sel_y0 ]; + 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); } + #endregion + + } else { #region shape + 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(isUsingTool("Selection", 0)) + draw_rectangle(0, 0, sel_w, sel_h, false); + + else if(isUsingTool("Selection", 1)) { + draw_set_circle_precision(32); + draw_ellipse(0, 0, sel_w - 1, sel_h - 1, false); + } + surface_reset_target(); + #endregion } + + if(mouse_release(mb_left)) is_selecting = false; + + if(mouse_release(mb_left) && sel_w > 1 && sel_h > 1) { + is_selected = true; + + selection_surface = 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(selection_mask, 0, 0); + BLEND_NORMAL + surface_reset_target(); + + 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(); + + surface_store_buffer(); + + selection_position = [ sel_x0, sel_y0 ]; + } + } else { if(mouse_press(mb_left, active)) { is_selecting = true; @@ -891,9 +1062,11 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_free_safe(selection_mask); } } - } + } #endregion + #endregion } else if(isUsingTool("Pencil") || isUsingTool("Eraser")) { #region + 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); @@ -952,24 +1125,11 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor mouse_pre_x = mouse_cur_x; mouse_pre_y = mouse_cur_y; - if(brush_sizing) { - var s = brush_sizing_s + (_mx - brush_sizing_mx) / 16; - s = max(1, s); - tool_attribute.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 = mouse_cur_x; - brush_sizing_dy = mouse_cur_y; - } + _tool_resizable = true; + #endregion } else if(isUsingTool("Rectangle") || isUsingTool("Ellipse")) { #region + if(mouse_holding && key_mod_press(SHIFT)) { var ww = mouse_cur_x - mouse_pre_x; var hh = mouse_cur_y - mouse_pre_y; @@ -979,13 +1139,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor mouse_cur_y = mouse_pre_y + ss * sign(hh); } - if(mouse_press(mb_left, active)) { - mouse_pre_x = mouse_cur_x; - mouse_pre_y = mouse_cur_y; - - mouse_holding = true; - } - if(mouse_holding) { drawing_surface = surface_verify(drawing_surface, _dim[0], _dim[1], attrDepth()); @@ -1000,26 +1153,25 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor 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; } - 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) && brush_surface == noone) { - brush_sizing = true; - brush_sizing_s = brush_size; - brush_sizing_mx = _mx; - brush_sizing_my = _my; - - brush_sizing_dx = mouse_cur_x; - brush_sizing_dy = mouse_cur_y; - } + _tool_resizable = true; + + #endregion + } else if(isUsingTool("Freefrom")) { #region + freeform_step(active, _x, _y, _s, _mx, _my, true); + + if(mouse_release(mb_left)) + apply_draw_surface(); + #endregion } else if(isUsingTool("Fill") || (DRAGGING && DRAGGING.type == "Color")) { #region + 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)) { @@ -1040,9 +1192,37 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_store_buffer(); surface_reset_target(); } + #endregion } + if(_tool_resizable) { #region tools size + if(hover && key_mod_press(CTRL)) { + if(mouse_wheel_down()) tool_attribute.size = max( 1, tool_attribute.size - 1); + if(mouse_wheel_up()) tool_attribute.size = min(64, tool_attribute.size + 1); + } + + if(brush_sizing) { + var s = brush_sizing_s + (_mx - brush_sizing_mx) / 16; + s = max(1, s); + tool_attribute.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 = mouse_cur_x; + brush_sizing_dy = mouse_cur_y; + } + + } #endregion + draw_set_alpha(1); gpu_set_colorwriteenable(true, true, true, true); @@ -1063,13 +1243,17 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_set_color(_col); if(isUsingTool("Selection")) { - if(is_selected) + if(is_selected || _applySelection) 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); } + + if(_applySelection) surface_free(selection_surface); + } else if(isUsingTool("Pencil") || isUsingTool("Eraser")) { if(isUsingTool("Eraser")) draw_set_color(c_white); @@ -1081,6 +1265,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor else draw_point_size(mouse_cur_x, mouse_cur_y); } + } else if(isUsingTool("Rectangle")) { if(brush_sizing) draw_point_size(brush_sizing_dx, brush_sizing_dy); @@ -1088,6 +1273,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_rect_size(mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, isUsingTool("Rectangle", 1)); else draw_point_size(mouse_cur_x, mouse_cur_y); + } else if(isUsingTool("Ellipse")) { if(brush_sizing) draw_point_size(brush_sizing_dx, brush_sizing_dy); @@ -1095,27 +1281,35 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor draw_ellp_size(mouse_pre_x, mouse_pre_y, mouse_cur_x, mouse_cur_y, isUsingTool("Ellipse", 1)); else draw_point_size(mouse_cur_x, mouse_cur_y); + + } else if(isUsingTool("Freefrom")) { + draw_point_size(mouse_cur_x, mouse_cur_y); } surface_reset_shader(); - if((active || mouse_holding) && isUsingTool()) { - if(isUsingTool("Selection")) { - if(is_selected) { - 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; + if(isUsingTool()) { + var _drawSelection = isUsingTool("Selection") && is_selected; + + if(_drawSelection) { #region + 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, 4); - - draw_surface_ext_safe(selection_surface, pos_x, pos_y, _s, _s, 0, c_white, 1); - } - } else { + 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); + } #endregion + + if(!isUsingTool("Selection") && (active || mouse_holding)) { #region gpu_set_colorwriteenable(tool_attribute.channel[0], tool_attribute.channel[1], tool_attribute.channel[2], tool_attribute.channel[3]); draw_surface_ext_safe(preview_draw_surface, _x, _y, _s, _s, 0, isUsingTool("Eraser")? c_red : c_white, isUsingTool("Eraser")? 0.2 : _alp); gpu_set_colorwriteenable(true, true, true, true); - } + } #endregion surface_set_target(_preview_draw_surface); DRAW_CLEAR @@ -1123,9 +1317,25 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor surface_reset_target(); shader_set(sh_brush_outline); - shader_set_f("dimension", surface_get_width_safe(_preview_draw_surface), surface_get_height_safe(_preview_draw_surface)); + shader_set_f("dimension", surface_get_width(_preview_draw_surface), surface_get_height(_preview_draw_surface)); draw_surface_ext_safe(_preview_draw_surface, 0, 0, 1, 1, 0, c_white, 1); shader_reset(); + + if(isUsingTool("Selection", 2) && mouse_holding) { #region + 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; + } + } #endregion } #endregion diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 743ded918..490fb6c72 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -622,7 +622,8 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { INLINE inputs_data[index] = value; - input_value_map[$ inputs[| index].internalName] = value; + var _inp = inputs[| index]; + if(is_struct(_inp)) input_value_map[$ _inp.internalName] = value; } #endregion static getInputs = function(frame = CURRENT_FRAME) { #region diff --git a/scripts/node_group_input/node_group_input.gml b/scripts/node_group_input/node_group_input.gml index 912f133c0..af709c98c 100644 --- a/scripts/node_group_input/node_group_input.gml +++ b/scripts/node_group_input/node_group_input.gml @@ -63,49 +63,34 @@ function Node_Group_Input(_x, _y, _group = noone) : Node(_x, _y, _group) constru #endregion inputs[| 0] = nodeValue("Display type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) - .setDisplay(VALUE_DISPLAY.enum_scroll, { data: display_list[0], update_hover: false }) - .uncache() - .rejectArray(); + .setDisplay(VALUE_DISPLAY.enum_scroll, { data: display_list[0], update_hover: false }); - inputs[| 1] = nodeValue("Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [0, 1]) + inputs[| 1] = nodeValue("Range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 1 ]) .setDisplay(VALUE_DISPLAY.range) - .uncache() - .setVisible(false) - .rejectArray(); + .setVisible(false); inputs[| 2] = nodeValue("Input type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 11) - .setDisplay(VALUE_DISPLAY.enum_scroll, { data: data_type_list, update_hover: false }) - .uncache() - .rejectArray(); + .setDisplay(VALUE_DISPLAY.enum_scroll, { data: data_type_list, update_hover: false }); inputs[| 3] = nodeValue("Enum label", self, JUNCTION_CONNECT.input, VALUE_TYPE.text, "") - .setVisible(false) - .uncache() - .rejectArray(); + .setVisible(false); inputs[| 4] = nodeValue("Vector size", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) .setDisplay(VALUE_DISPLAY.enum_button, [ "2", "3", "4" ]) - .setVisible(false) - .uncache() - .rejectArray(); + .setVisible(false); - inputs[| 5] = nodeValue("Order", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) - .uncache() - .rejectArray(); - - inputs[| 6] = nodeValue("Display preview gizmo", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true) - .uncache() - .rejectArray(); + inputs[| 5] = nodeValue("Order", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0); + inputs[| 6] = nodeValue("Display preview gizmo", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); + inputs[| 7] = nodeValue("Step", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0.01) - .setVisible(false) - .uncache() - .rejectArray(); - + .setVisible(false); + inputs[| 8] = nodeValue("Button Label", self, JUNCTION_CONNECT.input, VALUE_TYPE.text, "Trigger") - .setVisible(false) - .uncache() - .rejectArray(); + .setVisible(false); + + for( var i = 0, n = ds_list_size(inputs); i < n; i++ ) + inputs[| i].uncache().rejectArray(); input_display_list = [ ["Display", false], 6, diff --git a/scripts/panel_graph/panel_graph.gml b/scripts/panel_graph/panel_graph.gml index eb95742f4..8b8261318 100644 --- a/scripts/panel_graph/panel_graph.gml +++ b/scripts/panel_graph/panel_graph.gml @@ -783,7 +783,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { if(mouse_on_graph && pHOVER && graph_draggable) { var _s = graph_s; - if(mouse_wheel_down()) { //zoom out + if(mouse_wheel_down() && !key_mod_press_any()) { //zoom out for( var i = 1, n = array_length(scale); i < n; i++ ) { if(scale[i - 1] < graph_s_to && graph_s_to <= scale[i]) { graph_s_to = scale[i - 1]; @@ -791,7 +791,7 @@ function Panel_Graph(project = PROJECT) : PanelContent() constructor { } } } - if(mouse_wheel_up()) { // zoom in + if(mouse_wheel_up() && !key_mod_press_any()) { // zoom in for( var i = 1, n = array_length(scale); i < n; i++ ) { if(scale[i - 1] <= graph_s_to && graph_s_to < scale[i]) { graph_s_to = scale[i]; diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index 2d5effdd9..aa28cdd7f 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -462,8 +462,9 @@ function Panel_Preview() : PanelContent() constructor { else if(canvas_s > 3) inc = 0.5; else if(canvas_s > 1) inc = 0.25; - if(mouse_wheel_down()) canvas_s = max(round(canvas_s / inc) * inc - inc, 0.10); - if(mouse_wheel_up()) canvas_s = min(round(canvas_s / inc) * inc + inc, 64); + if(mouse_wheel_down() && !key_mod_press_any()) canvas_s = max(round(canvas_s / inc) * inc - inc, 0.10); + if(mouse_wheel_up() && !key_mod_press_any()) canvas_s = min(round(canvas_s / inc) * inc + inc, 64); + if(_canvas_s != canvas_s) { var dx = (canvas_s - _canvas_s) * ((mx - canvas_x) / _canvas_s); var dy = (canvas_s - _canvas_s) * ((my - canvas_y) / _canvas_s); @@ -1088,8 +1089,8 @@ function Panel_Preview() : PanelContent() constructor { if(pHOVER && my > h - toolbar_height - prev_size - ui(16) && my > toolbar_height) { canvas_hover = false; - if(mouse_wheel_down()) preview_x_to = clamp(preview_x_to - prev_size * SCROLL_SPEED, - preview_x_max, 0); - if(mouse_wheel_up()) preview_x_to = clamp(preview_x_to + prev_size * SCROLL_SPEED, - preview_x_max, 0); + if(mouse_wheel_down() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to - prev_size * SCROLL_SPEED, - preview_x_max, 0); + if(mouse_wheel_up() && !key_mod_press_any()) preview_x_to = clamp(preview_x_to + prev_size * SCROLL_SPEED, - preview_x_max, 0); } #region surface array @@ -1319,7 +1320,7 @@ function Panel_Preview() : PanelContent() constructor { tool_y_max += _h; tool_y_max = max(0, tool_y_max - h + toolbar_height * 2); - if(thov) { + if(thov && !key_mod_press_any()) { 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); } @@ -1369,7 +1370,8 @@ function Panel_Preview() : PanelContent() constructor { } var params = new widgetParam(tolx, toly, tolw, tolh, atr[$ key],, [ mx, my ]) - params.s = tolh; + params.s = tolh; + params.font = f_p3; wdg.drawParam(params); @@ -1378,7 +1380,7 @@ function Panel_Preview() : PanelContent() constructor { } tol_max_w = max(0, tol_max_w - w); - if(point_in_rectangle(mx, my, 0, 0, w, toolbar_height)) { + if(point_in_rectangle(mx, my, 0, 0, w, toolbar_height) && !key_mod_press_any()) { if(mouse_wheel_up()) tool_x_to = clamp(tool_x_to + ui(64) * SCROLL_SPEED, -tol_max_w, 0); if(mouse_wheel_down()) tool_x_to = clamp(tool_x_to - ui(64) * SCROLL_SPEED, -tol_max_w, 0); } diff --git a/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.fsh b/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.fsh new file mode 100644 index 000000000..202ac8441 --- /dev/null +++ b/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.fsh @@ -0,0 +1,20 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; + +void main() { + vec2 tx = 1. / dimension; + + gl_FragColor = texture2D( gm_BaseTexture, v_vTexcoord ); + if(gl_FragColor == v_vColour) return; + + float chk = 0.; + + if(texture2D( gm_BaseTexture, v_vTexcoord + vec2( tx.x, 0.) ) == v_vColour) chk++; + if(texture2D( gm_BaseTexture, v_vTexcoord + vec2(-tx.x, 0.) ) == v_vColour) chk++; + if(texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., tx.y) ) == v_vColour) chk++; + if(texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., -tx.y) ) == v_vColour) chk++; + + if(chk >= 3.) gl_FragColor = v_vColour; +} diff --git a/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.vsh b/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.vsh @@ -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; +} diff --git a/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy b/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy new file mode 100644 index 000000000..e250f7db1 --- /dev/null +++ b/shaders/sh_freeform_fill_cleanup/sh_freeform_fill_cleanup.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_freeform_fill_cleanup", + "name":"sh_freeform_fill_cleanup", + "parent":{ + "name":"canvas", + "path":"folders/shader/canvas.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.fsh b/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.fsh new file mode 100644 index 000000000..d6dbedef3 --- /dev/null +++ b/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.fsh @@ -0,0 +1,95 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform float itr; + +float isInside(vec2 axis) { + vec2 tx = 1. / dimension; + vec2 ax = axis * tx; + + float overlap = 0.; + float filling = 0.; + + for(float i = 1.; i < itr; i++) { + vec2 sx = v_vTexcoord + ax * i; + if(sx.x > 1. || sx.y > 1. || sx.x < 0. || sx.y < 0.) break; + + vec4 cc = texture2D( gm_BaseTexture, sx ); + + if(cc == v_vColour) { + vec2 px_p = sx - ax + ax.yx; + vec2 px_n = sx - ax - ax.yx; + + vec4 cp = texture2D( gm_BaseTexture, px_p ); + vec4 cn = texture2D( gm_BaseTexture, px_n ); + + if(filling == 0.) { + + if(cp == v_vColour && cn == v_vColour) { + filling = 2.; + overlap++; + } else if(cp == v_vColour || cn == v_vColour) { + if(cp == v_vColour) { + filling = 1.; + overlap++; + } + + if(cn == v_vColour) { + filling = -1.; + overlap++; + } + } else { + + vec4 ccp = texture2D( gm_BaseTexture, px_p + ax ); + vec4 ccn = texture2D( gm_BaseTexture, px_n + ax ); + + if(ccp == v_vColour && ccn == v_vColour) { + filling = 2.; + overlap++; + } + } + } + + } else if(filling != 0.) { + vec2 px_p = sx - ax + ax.yx; + vec2 px_n = sx - ax - ax.yx; + + vec4 cp = texture2D( gm_BaseTexture, px_p ); + vec4 cn = texture2D( gm_BaseTexture, px_n ); + + if(filling == 1. && cp == v_vColour) + overlap++; + + if(filling == -1. && cn == v_vColour) + overlap++; + + filling = 0.; + } + } + + return mod(overlap, 2.); +} + +void main() { + vec4 c = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = vec4(0.); + + if(c == v_vColour) { + gl_FragColor = vec4(1.); + return; + } + + float chk = 0.; + + chk += isInside(vec2(-1., 0.)); + chk += isInside(vec2( 1., 0.)); + chk += isInside(vec2( 0., -1.)); + chk += isInside(vec2( 0., 1.)); + + if(chk == 1.) gl_FragColor = vec4(1., 0., 0., 1.); + else if(chk == 2.) gl_FragColor = vec4(0., 1., 0., 1.); + else if(chk == 3.) gl_FragColor = vec4(0., 0., 1., 1.); + else if(chk == 4.) gl_FragColor = vec4(1.); + +} diff --git a/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.vsh b/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.vsh @@ -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; +} diff --git a/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.yy b/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.yy new file mode 100644 index 000000000..68353a48f --- /dev/null +++ b/shaders/sh_freeform_fill_pass1/sh_freeform_fill_pass1.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_freeform_fill_pass1", + "name":"sh_freeform_fill_pass1", + "parent":{ + "name":"canvas", + "path":"folders/shader/canvas.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.fsh b/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.fsh new file mode 100644 index 000000000..f71f44ef0 --- /dev/null +++ b/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.fsh @@ -0,0 +1,97 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform float itr; + +float isInside(vec2 axis) { + vec2 tx = 1. / dimension; + + float overlap = 0.; + bool filling = false; + + for(float i = 1.; i < itr; i++) { + vec2 sx = v_vTexcoord + axis * tx * i; + if(sx.x > 1. || sx.y > 1. || sx.x < 0. || sx.y < 0.) break; + + vec4 cc = texture2D( gm_BaseTexture, sx ); + + if(cc == v_vColour) { + if(!filling) overlap++; + filling = true; + + } else + filling = false; + } + + return mod(overlap, 2.); +} + +void main() { + vec2 tx = 1. / dimension; + vec4 c = texture2D( gm_BaseTexture, v_vTexcoord ); + + gl_FragColor = vec4(0.); + gl_FragColor = c; return; + + if(c == vec4(1.)) { + gl_FragColor = v_vColour; + return; + } + + if(c == vec4(1., 0., 0., 1.)) { + float _chk = 0.; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(-tx.x, 0.) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2( tx.x, 0.) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., -tx.y) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., tx.y) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + if(_chk < 2.) return; + + } else if(c == vec4(0., 1., 0., 1.)) { + float _chk = 0.; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(-tx.x, 0.) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2( tx.x, 0.) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., -tx.y) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., tx.y) ); + if(c == vec4(1.) || c == vec4(0., 1., 0., 1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + if(_chk < 2.) return; + + } else if(c == vec4(0., 0., 1., 1.)) { + float _chk = 0.; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(-tx.x, 0.) ); + if(c == vec4(1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2( tx.x, 0.) ); + if(c == vec4(1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., -tx.y) ); + if(c == vec4(1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + c = texture2D( gm_BaseTexture, v_vTexcoord + vec2(0., tx.y) ); + if(c == vec4(1.) || c == vec4(0., 0., 1., 1.)) _chk++; + + if(_chk < 2.) return; + } else + return; + + gl_FragColor = v_vColour; + +} diff --git a/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.vsh b/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.vsh @@ -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; +} diff --git a/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy b/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy new file mode 100644 index 000000000..510b81827 --- /dev/null +++ b/shaders/sh_freeform_fill_pass2/sh_freeform_fill_pass2.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_freeform_fill_pass2", + "name":"sh_freeform_fill_pass2", + "parent":{ + "name":"canvas", + "path":"folders/shader/canvas.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file