diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index bc90882c9..2580ad5b2 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -34,6 +34,8 @@ {"name":"d3d_particle","order":7,"path":"folders/nodes/data/3D/d3d_particle.yy",}, {"name":"animation","order":13,"path":"folders/nodes/data/animation.yy",}, {"name":"canvas","order":30,"path":"folders/nodes/data/canvas.yy",}, + {"name":"actions","order":8,"path":"folders/nodes/data/canvas/actions.yy",}, + {"name":"shader","order":9,"path":"folders/nodes/data/canvas/shader.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",}, @@ -256,6 +258,7 @@ {"name":"__bbox","order":5,"path":"scripts/__bbox/__bbox.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_shader","order":4,"path":"scripts/__canvas_tool_shader/__canvas_tool_shader.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":"__d3d11_cbuffer","order":1,"path":"scripts/__d3d11_cbuffer/__d3d11_cbuffer.yy",}, @@ -351,7 +354,11 @@ {"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_extrude","order":1,"path":"scripts/canvas_tool_extrude/canvas_tool_extrude.yy",}, {"name":"canvas_tool_fill","order":4,"path":"scripts/canvas_tool_fill/canvas_tool_fill.yy",}, + {"name":"canvas_tool_inset","order":2,"path":"scripts/canvas_tool_inset/canvas_tool_inset.yy",}, + {"name":"canvas_tool_outline","order":3,"path":"scripts/canvas_tool_outline/canvas_tool_outline.yy",}, + {"name":"canvas_tool_resize","order":11,"path":"scripts/canvas_tool_resize/canvas_tool_resize.yy",}, {"name":"canvas_tool_selection_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",}, @@ -1213,6 +1220,8 @@ {"name":"sh_blur_zoom","order":12,"path":"shaders/sh_blur_zoom/sh_blur_zoom.yy",}, {"name":"sh_brush_outline","order":7,"path":"shaders/sh_brush_outline/sh_brush_outline.yy",}, {"name":"sh_bw","order":3,"path":"shaders/sh_bw/sh_bw.yy",}, + {"name":"sh_canvas_extrude","order":1,"path":"shaders/sh_canvas_extrude/sh_canvas_extrude.yy",}, + {"name":"sh_canvas_inset","order":2,"path":"shaders/sh_canvas_inset/sh_canvas_inset.yy",}, {"name":"sh_cell_noise_crystal","order":1,"path":"shaders/sh_cell_noise_crystal/sh_cell_noise_crystal.yy",}, {"name":"sh_cell_noise_edge","order":2,"path":"shaders/sh_cell_noise_edge/sh_cell_noise_edge.yy",}, {"name":"sh_cell_noise_random","order":3,"path":"shaders/sh_cell_noise_random/sh_cell_noise_random.yy",}, @@ -1460,7 +1469,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_canvas_mask","order":10,"path":"shaders/sh_canvas_mask/sh_canvas_mask.yy",}, + {"name":"sh_canvas_apply_draw","order":3,"path":"shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.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 3218029f4..828f504cd 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -130,6 +130,8 @@ {"$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":"canvas","folderPath":"folders/nodes/data/canvas.yy","name":"canvas","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"actions","folderPath":"folders/nodes/data/canvas/actions.yy","name":"actions","resourceType":"GMFolder","resourceVersion":"2.0",}, + {"$GMFolder":"","%Name":"shader","folderPath":"folders/nodes/data/canvas/shader.yy","name":"shader","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",}, @@ -320,10 +322,10 @@ {"$GMIncludedFile":"","%Name":"Collections.zip","CopyToMask":-1,"filePath":"datafiles/data","name":"Collections.zip","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"icon.png","CopyToMask":-1,"filePath":"datafiles/data","name":"icon.png","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"layouts.zip","CopyToMask":-1,"filePath":"datafiles/data","name":"layouts.zip","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, + {"$GMIncludedFile":"","%Name":"Drawing.json","CopyToMask":-1,"filePath":"datafiles/data/layouts","name":"Drawing.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"Horizontal.json","CopyToMask":-1,"filePath":"datafiles/data/layouts","name":"Horizontal.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"Preview.json","CopyToMask":-1,"filePath":"datafiles/data/layouts","name":"Preview.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"Side menu.json","CopyToMask":-1,"filePath":"datafiles/data/layouts","name":"Side menu.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, - {"$GMIncludedFile":"","%Name":"Vertical Ext.json","CopyToMask":-1,"filePath":"datafiles/data/layouts","name":"Vertical Ext.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"Vertical.json","CopyToMask":-1,"filePath":"datafiles/data/layouts","name":"Vertical.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"en.zip","CopyToMask":-1,"filePath":"datafiles/data/locale","name":"en.zip","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, {"$GMIncludedFile":"","%Name":"en.zip","CopyToMask":-1,"filePath":"datafiles/data/Locale","name":"en.zip","resourceType":"GMIncludedFile","resourceVersion":"2.0",}, @@ -593,6 +595,7 @@ {"id":{"name":"__bbox","path":"scripts/__bbox/__bbox.yy",},}, {"id":{"name":"__bone","path":"scripts/__bone/__bone.yy",},}, {"id":{"name":"__canvas_brush","path":"scripts/__canvas_brush/__canvas_brush.yy",},}, + {"id":{"name":"__canvas_tool_shader","path":"scripts/__canvas_tool_shader/__canvas_tool_shader.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":"__d3d11_cbuffer","path":"scripts/__d3d11_cbuffer/__d3d11_cbuffer.yy",},}, @@ -703,6 +706,7 @@ {"id":{"name":"buttonPalette","path":"scripts/buttonPalette/buttonPalette.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":"canvas_actions_transform","path":"scripts/canvas_actions_transform/canvas_actions_transform.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",},}, @@ -711,7 +715,11 @@ {"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_extrude","path":"scripts/canvas_tool_extrude/canvas_tool_extrude.yy",},}, {"id":{"name":"canvas_tool_fill","path":"scripts/canvas_tool_fill/canvas_tool_fill.yy",},}, + {"id":{"name":"canvas_tool_inset","path":"scripts/canvas_tool_inset/canvas_tool_inset.yy",},}, + {"id":{"name":"canvas_tool_outline","path":"scripts/canvas_tool_outline/canvas_tool_outline.yy",},}, + {"id":{"name":"canvas_tool_resize","path":"scripts/canvas_tool_resize/canvas_tool_resize.yy",},}, {"id":{"name":"canvas_tool_selection_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",},}, @@ -1714,6 +1722,9 @@ {"id":{"name":"sh_brush_outline","path":"shaders/sh_brush_outline/sh_brush_outline.yy",},}, {"id":{"name":"sh_bw","path":"shaders/sh_bw/sh_bw.yy",},}, {"id":{"name":"sh_camera","path":"shaders/sh_camera/sh_camera.yy",},}, + {"id":{"name":"sh_canvas_extrude","path":"shaders/sh_canvas_extrude/sh_canvas_extrude.yy",},}, + {"id":{"name":"sh_canvas_inset","path":"shaders/sh_canvas_inset/sh_canvas_inset.yy",},}, + {"id":{"name":"sh_canvas_mask","path":"shaders/sh_canvas_mask/sh_canvas_mask.yy",},}, {"id":{"name":"sh_cell_noise_crystal","path":"shaders/sh_cell_noise_crystal/sh_cell_noise_crystal.yy",},}, {"id":{"name":"sh_cell_noise_edge","path":"shaders/sh_cell_noise_edge/sh_cell_noise_edge.yy",},}, {"id":{"name":"sh_cell_noise_random","path":"shaders/sh_cell_noise_random/sh_cell_noise_random.yy",},}, @@ -2000,7 +2011,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_canvas_mask","path":"shaders/sh_canvas_mask/sh_canvas_mask.yy",},}, + {"id":{"name":"sh_canvas_apply_draw","path":"shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.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 a1fcec56f..e44e0877d 100644 Binary files a/datafiles/data/Theme.zip and b/datafiles/data/Theme.zip differ diff --git a/datafiles/data/layouts.zip b/datafiles/data/layouts.zip index 1ec7ca997..d518b1a3b 100644 Binary files a/datafiles/data/layouts.zip and b/datafiles/data/layouts.zip differ diff --git a/datafiles/data/layouts/Drawing.json b/datafiles/data/layouts/Drawing.json new file mode 100644 index 000000000..8d8237aa1 --- /dev/null +++ b/datafiles/data/layouts/Drawing.json @@ -0,0 +1 @@ +{"panel":{"width":40,"split":"v","content":[{"content":["Panel_Menu"]},{"width":-382,"split":"h","content":[{"width":227,"split":"h","content":[{"width":-241,"split":"v","content":[{"content":["Panel_Palette"]},{"content":["Panel_Color"]}]},{"width":-50,"split":"v","content":[{"content":["Panel_Preview"]},{"content":["Panel_Animation"]}]}]},{"width":40,"split":"v","content":[{"content":["Panel_Workspace"]},{"width":-269,"split":"v","content":[{"content":["Panel_Inspector"]},{"content":["Panel_Graph"]}]}]}]}]}} \ No newline at end of file diff --git a/datafiles/data/layouts/Side menu.json b/datafiles/data/layouts/Side menu.json index 57112f7df..8c0cad5c5 100644 --- a/datafiles/data/layouts/Side menu.json +++ b/datafiles/data/layouts/Side menu.json @@ -1,41 +1 @@ -{ - "panel": { - "content": [{ - "content": [{ - "content": "Panel_Menu" - }, { - "content": "Panel_Animation" - }], - "split": "v", - "width": -84 - }, { - "content": [{ - "content": [{ - "content": [{ - "content": "Panel_Preview" - }, { - "content": "Panel_Preview" - }], - "split": "h", - "width": 480 - }, { - "content": "Panel_Graph" - }], - "split": "v", - "width": -400 - }, { - "content": [{ - "content": "Panel_Workspace" - }, { - "content": "Panel_Inspector" - }], - "split": "v", - "width": 40 - }], - "split": "h", - "width": -360 - }], - "split": "h", - "width": 240 - } -} \ No newline at end of file +{"panel":{"width":136,"split":"h","content":[{"content":["Panel_Menu"]},{"width":-360,"split":"h","content":[{"width":-400,"split":"v","content":[{"width":518,"split":"h","content":[{"content":["Panel_Preview"]},{"content":["Panel_Preview"]}]},{"content":["Panel_Graph"]}]},{"width":40,"split":"v","content":[{"content":["Panel_Workspace"]},{"width":-49,"split":"v","content":[{"content":["Panel_Inspector"]},{"content":["Panel_Animation"]}]}]}]}]}} \ No newline at end of file diff --git a/datafiles/data/layouts/Vertical Ext.json b/datafiles/data/layouts/Vertical Ext.json deleted file mode 100644 index 69e21a81b..000000000 --- a/datafiles/data/layouts/Vertical Ext.json +++ /dev/null @@ -1 +0,0 @@ -{"panel":{"split":"v","width":40,"content":[{"content":["Panel_Menu"]},{"split":"h","width":-400,"content":[{"split":"v","width":-300,"content":[{"split":"h","width":400,"content":[{"content":["Panel_Preview"]},{"content":["Panel_Graph"]}]},{"split":"h","width":533,"content":[{"content":["Panel_Collection","Panel_Color","Panel_Palette","Panel_Gradient"]},{"content":["Panel_Animation","Panel_Notification"]}]}]},{"split":"v","width":40,"content":[{"content":["Panel_Workspace"]},{"content":["Panel_Inspector"]}]}]}]}} \ No newline at end of file diff --git a/scripts/__canvas_tool/__canvas_tool.gml b/scripts/__canvas_tool/__canvas_tool.gml index a0cd59bfb..8608b9e57 100644 --- a/scripts/__canvas_tool/__canvas_tool.gml +++ b/scripts/__canvas_tool/__canvas_tool.gml @@ -1,6 +1,8 @@ function canvas_tool() constructor { node = noone; + + override = false; relative = false; relative_position = [ 0, 0 ]; @@ -11,6 +13,10 @@ function canvas_tool() constructor { brush_resizable = false; mouse_holding = false; + subtool = 0; + + function init() {} + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { } diff --git a/scripts/__canvas_tool_shader/__canvas_tool_shader.gml b/scripts/__canvas_tool_shader/__canvas_tool_shader.gml new file mode 100644 index 000000000..daf7ae2e9 --- /dev/null +++ b/scripts/__canvas_tool_shader/__canvas_tool_shader.gml @@ -0,0 +1,60 @@ +function canvas_tool_shader() : canvas_tool() constructor { + + override = true; + mouse_init = false; + + preview_surface = [ noone, noone ]; + + function init() { mouse_init = true; } + + function onInit(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} + + function stepEffect(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {} + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var _dim = node.attributes.dimension; + var _sel = node.tool_selection; + + var _surf = _sel.selection_surface; + var _pos = _sel.selection_position; + + preview_surface[0] = surface_verify(preview_surface[0], _dim[0], _dim[1]); + preview_surface[1] = surface_verify(preview_surface[1], _dim[0], _dim[1]); + + if(mouse_init) { + onInit(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + mouse_init = false; + return; + } + + surface_set_shader(preview_surface[0], noone); + draw_surface(_surf, _pos[0], _pos[1]); + surface_reset_shader(); + + stepEffect(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + + draw_surface_ext(preview_surface[1], _x, _y, _s, _s, 0, c_white, 1); + + if(mouse_press(mb_right)) { + PANEL_PREVIEW.tool_current = noone; + + } else if(mouse_release(mb_left)) { + + var _newSurf = surface_create(_dim[0], _dim[1]); + surface_set_shader(_newSurf, noone); + draw_surface(preview_surface[1], 0, 0); + surface_reset_shader(); + + surface_free(_sel.selection_surface); + _sel.selection_surface = _newSurf; + _sel.selection_position = [ 0, 0 ]; + _sel.apply(); + + surface_free(_surf); + + PANEL_PREVIEW.tool_current = noone; + MOUSE_BLOCK = true; + } + } + +} \ No newline at end of file diff --git a/scripts/__canvas_tool_shader/__canvas_tool_shader.yy b/scripts/__canvas_tool_shader/__canvas_tool_shader.yy new file mode 100644 index 000000000..a9c858e1c --- /dev/null +++ b/scripts/__canvas_tool_shader/__canvas_tool_shader.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"__canvas_tool_shader", + "isCompatibility":false, + "isDnD":false, + "name":"__canvas_tool_shader", + "parent":{ + "name":"actions", + "path":"folders/nodes/data/canvas/actions.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_actions_transform/canvas_actions_transform.gml b/scripts/canvas_actions_transform/canvas_actions_transform.gml new file mode 100644 index 000000000..9b31e49e7 --- /dev/null +++ b/scripts/canvas_actions_transform/canvas_actions_transform.gml @@ -0,0 +1,41 @@ +function canvas_action_rotate(angle, _resize = true) { + storeAction(); + + var _dim = attributes.dimension; + var _pos = point_rotate(0, 0, _dim[0] / 2, _dim[1] / 2, angle); + + for( var i = 0; i < attributes.frames; i++ ) { + var _canvas_surface = getCanvasSurface(i); + + var _newCanvas = surface_create(_dim[0], _dim[1]); + surface_set_shader(_newCanvas, noone); + draw_surface_ext(_canvas_surface, _pos[0], _pos[1], 1, 1, angle, c_white, 1); + surface_reset_shader(); + + setCanvasSurface(_newCanvas, i); + surface_free(_canvas_surface); + } + + triggerRender(); +} + +function canvas_action_flip(axis) { + storeAction(); + + var _dim = attributes.dimension; + + for( var i = 0; i < attributes.frames; i++ ) { + var _canvas_surface = getCanvasSurface(i); + + var _newCanvas = surface_create(_dim[0], _dim[1]); + surface_set_shader(_newCanvas, noone); + if(axis == 0) draw_surface_ext(_canvas_surface, 0, _dim[1], 1, -1, 0, c_white, 1); + if(axis == 1) draw_surface_ext(_canvas_surface, _dim[0], 0, -1, 1, 0, c_white, 1); + surface_reset_shader(); + + setCanvasSurface(_newCanvas, i); + surface_free(_canvas_surface); + } + + triggerRender(); +} \ No newline at end of file diff --git a/scripts/canvas_actions_transform/canvas_actions_transform.yy b/scripts/canvas_actions_transform/canvas_actions_transform.yy new file mode 100644 index 000000000..0730a41f1 --- /dev/null +++ b/scripts/canvas_actions_transform/canvas_actions_transform.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_actions_transform", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_actions_transform", + "parent":{ + "name":"actions", + "path":"folders/nodes/data/canvas/actions.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_freeform/canvas_freeform.gml b/scripts/canvas_freeform/canvas_freeform.gml index da3dac4d7..30a2e7fd5 100644 --- a/scripts/canvas_freeform/canvas_freeform.gml +++ b/scripts/canvas_freeform/canvas_freeform.gml @@ -65,6 +65,8 @@ function canvas_freeform_step(active, _x, _y, _s, _mx, _my, _draw) { #region mouse_holding = true; freeform_shape = [ new __vec2(_mmx, _mmy) ]; + + node.tool_pick_color(_mmx, _mmy); surface_clear(drawing_surface); } diff --git a/scripts/canvas_tool_brush/canvas_tool_brush.gml b/scripts/canvas_tool_brush/canvas_tool_brush.gml index 82214d09b..e81a4771b 100644 --- a/scripts/canvas_tool_brush/canvas_tool_brush.gml +++ b/scripts/canvas_tool_brush/canvas_tool_brush.gml @@ -43,6 +43,8 @@ function canvas_tool_brush(brush, eraser = false) : canvas_tool() constructor { apply_draw_surface(); } + + node.tool_pick_color(mouse_cur_x, mouse_cur_y); mouse_pre_draw_x = mouse_cur_x; mouse_pre_draw_y = mouse_cur_y; diff --git a/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml b/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml index bbd020882..a661f940d 100644 --- a/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml +++ b/scripts/canvas_tool_brush_shape/canvas_tool_brush_shape.gml @@ -52,6 +52,8 @@ function canvas_tool_shape(brush, shape) : canvas_tool() constructor { mouse_pre_y = mouse_cur_y; mouse_holding = true; + + node.tool_pick_color(mouse_cur_x, mouse_cur_y); } } diff --git a/scripts/canvas_tool_extrude/canvas_tool_extrude.gml b/scripts/canvas_tool_extrude/canvas_tool_extrude.gml new file mode 100644 index 000000000..319e329cd --- /dev/null +++ b/scripts/canvas_tool_extrude/canvas_tool_extrude.gml @@ -0,0 +1,39 @@ +function canvas_tool_extrude() : canvas_tool_shader() constructor { + + mouse_sx = 0; + mouse_sy = 0; + + function init() { mouse_init = true; } + + function onInit(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + mouse_sx = _mx; + mouse_sy = _my; + } + + function stepEffect(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var _dim = node.attributes.dimension; + + var _dx = (_mx - mouse_sx) / _s; + var _dy = (_my - mouse_sy) / _s; + + if(key_mod_press(CTRL)) { + var ang = point_direction(0, 0, _dx, _dy); + var dist = point_distance(0, 0, _dx, _dy); + ang = round(ang / 45) * 45; + + _dx = lengthdir_x(dist, ang); + _dy = lengthdir_y(dist, ang); + } + + surface_set_shader(preview_surface[1], sh_canvas_extrude); + + shader_set_f("dimension", _dim); + shader_set_f("shift", _dx, _dy); + shader_set_f("itr", round(sqrt(_dx * _dx + _dy * _dy))); + shader_set_color("color", node.tool_attribute.color); + + draw_surface(preview_surface[0], 0, 0); + surface_reset_shader(); + + } +} \ No newline at end of file diff --git a/scripts/canvas_tool_extrude/canvas_tool_extrude.yy b/scripts/canvas_tool_extrude/canvas_tool_extrude.yy new file mode 100644 index 000000000..9fd19bae2 --- /dev/null +++ b/scripts/canvas_tool_extrude/canvas_tool_extrude.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_tool_extrude", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_tool_extrude", + "parent":{ + "name":"actions", + "path":"folders/nodes/data/canvas/actions.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_tool_inset/canvas_tool_inset.gml b/scripts/canvas_tool_inset/canvas_tool_inset.gml new file mode 100644 index 000000000..586793bc2 --- /dev/null +++ b/scripts/canvas_tool_inset/canvas_tool_inset.gml @@ -0,0 +1,39 @@ +function canvas_tool_inset() : canvas_tool_shader() constructor { + + mouse_sx = 0; + mouse_sy = 0; + + function init() { mouse_init = true; } + + function onInit(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + mouse_sx = _mx; + mouse_sy = _my; + } + + function stepEffect(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var _dim = node.attributes.dimension; + + var _dx = (_mx - mouse_sx) / _s; + var _dy = (_my - mouse_sy) / _s; + + if(key_mod_press(CTRL)) { + var ang = point_direction(0, 0, _dx, _dy); + var dist = point_distance(0, 0, _dx, _dy); + ang = round(ang / 45) * 45; + + _dx = lengthdir_x(dist, ang); + _dy = lengthdir_y(dist, ang); + } + + surface_set_shader(preview_surface[1], sh_canvas_inset); + + shader_set_f("dimension", _dim); + shader_set_f("shift", _dx, _dy); + shader_set_f("itr", round(sqrt(_dx * _dx + _dy * _dy))); + shader_set_color("color", node.tool_attribute.color); + + draw_surface(preview_surface[0], 0, 0); + surface_reset_shader(); + + } +} \ No newline at end of file diff --git a/scripts/canvas_tool_inset/canvas_tool_inset.yy b/scripts/canvas_tool_inset/canvas_tool_inset.yy new file mode 100644 index 000000000..2342102dd --- /dev/null +++ b/scripts/canvas_tool_inset/canvas_tool_inset.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_tool_inset", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_tool_inset", + "parent":{ + "name":"actions", + "path":"folders/nodes/data/canvas/actions.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_tool_outline/canvas_tool_outline.gml b/scripts/canvas_tool_outline/canvas_tool_outline.gml new file mode 100644 index 000000000..3d47ec28a --- /dev/null +++ b/scripts/canvas_tool_outline/canvas_tool_outline.gml @@ -0,0 +1,29 @@ +function canvas_tool_outline() : canvas_tool_shader() constructor { + + mouse_sx = 0; + + function init() { mouse_init = true; } + + function onInit(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + mouse_sx = _mx; + } + + function stepEffect(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + var _dim = node.attributes.dimension; + + var _thck = abs(round((_mx - mouse_sx) / _s)); + var _side = _mx > mouse_sx; + + surface_set_shader(preview_surface[1], sh_outline); + + shader_set_f("dimension", _dim); + shader_set_f("borderSize", _thck, _thck); + shader_set_f("borderStart", 0, 0); + shader_set_i("side", _side); + shader_set_color("borderColor", node.tool_attribute.color); + + draw_surface(preview_surface[0], 0, 0); + surface_reset_shader(); + } + +} \ No newline at end of file diff --git a/scripts/canvas_tool_outline/canvas_tool_outline.yy b/scripts/canvas_tool_outline/canvas_tool_outline.yy new file mode 100644 index 000000000..d886c3f1d --- /dev/null +++ b/scripts/canvas_tool_outline/canvas_tool_outline.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_tool_outline", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_tool_outline", + "parent":{ + "name":"actions", + "path":"folders/nodes/data/canvas/actions.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_tool_resize/canvas_tool_resize.gml b/scripts/canvas_tool_resize/canvas_tool_resize.gml new file mode 100644 index 000000000..53e3c043e --- /dev/null +++ b/scripts/canvas_tool_resize/canvas_tool_resize.gml @@ -0,0 +1,133 @@ +function canvas_tool_resize() : canvas_tool() constructor { + + override = true; + + dragging = -1; + drag_mx = 0; + drag_my = 0; + drag_sw = 0; + drag_sh = 0; + + drag_display = [ 0, 0, 0, 0 ]; + + __hover_anim = array_create(4); + overlay_surface = noone; + + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + + var _sw = node.attributes.dimension[0]; + var _sh = node.attributes.dimension[1]; + var x0, y0, x1, y1; + + if(dragging >= 0) { + x0 = _x + drag_display[0] * _s; + y0 = _y + drag_display[1] * _s; + x1 = _x + drag_display[2] * _s; + y1 = _y + drag_display[3] * _s; + + } else { + x0 = _x; + y0 = _y; + x1 = _x + _sw * _s; + y1 = _y + _sh * _s; + } + + var _r = 10; + + var _sr = surface_get_target(); + var _srw = surface_get_width(_sr); + var _srh = surface_get_height(_sr); + + overlay_surface = surface_verify(overlay_surface, _srw, _srh); + surface_set_target(overlay_surface); + draw_clear_alpha(0, 0.3); + + BLEND_SUBTRACT + draw_set_color(c_white); + draw_rectangle(x0, y0, x1, y1, false); + BLEND_NORMAL + surface_reset_target(); + + draw_surface(overlay_surface, 0, 0); + + draw_set_color(c_black); + draw_rectangle(x0, y0, x1, y1, true); + + draw_set_color(c_white); + draw_rectangle_dashed(x0, y0, x1, y1, true, 6, current_time / 100); + + var _hovering = -1; + + if(point_in_circle(_mx, _my, x0, y0, _r)) _hovering = 0; + else if(point_in_circle(_mx, _my, x1, y0, _r)) _hovering = 1; + else if(point_in_circle(_mx, _my, x0, y1, _r)) _hovering = 2; + else if(point_in_circle(_mx, _my, x1, y1, _r)) _hovering = 3; + + for( var i = 0; i < 4; i++ ) __hover_anim[i] = lerp_float(__hover_anim[i], i == _hovering, 4); + + draw_anchor(__hover_anim[0], x0, y0, _r); + draw_anchor(__hover_anim[1], x1, y0, _r); + draw_anchor(__hover_anim[2], x0, y1, _r); + draw_anchor(__hover_anim[3], x1, y1, _r); + + if(dragging >= 0) { + var _dx = (_mx - drag_mx) / _s; + var _dy = (_my - drag_my) / _s; + + var _sw = drag_sw; + var _sh = drag_sh; + + if(key_mod_press(SHIFT)) _dy = _dx * (drag_sh / drag_sw); + + switch(dragging) { + case 0 : drag_display = [ round(_dx), round(_dy), _sw, _sh ]; break; + case 1 : drag_display = [ 0, round(_dy), _sw + round(_dx), _sh ]; break; + case 2 : drag_display = [ round(_dx), 0, _sw, _sh + round(_dy) ]; break; + case 3 : drag_display = [ 0, 0, _sw + round(_dx), _sh + round(_dy) ]; break; + } + + if(mouse_release(mb_left)) { + dragging = -1; + + var _sw = drag_display[2] - drag_display[0]; + var _sh = drag_display[3] - drag_display[1]; + + if(_sw > 0 && _sh > 0) { + node.storeAction(); + node.attributes.dimension = [ _sw, _sh ]; + + for( var i = 0; i < node.attributes.frames; i++ ) { + var _canvas_surface = node.getCanvasSurface(i); + + var _cbuff = array_safe_get_fast(node.canvas_buffer, i); + if(buffer_exists(_cbuff)) buffer_delete(_cbuff); + + node.canvas_buffer[i] = buffer_create(_sw * _sh * 4, buffer_fixed, 4); + + var _newCanvas = surface_create(_sw, _sh); + + surface_set_shader(_newCanvas, noone); + draw_surface(_canvas_surface, -drag_display[0], -drag_display[1]); + surface_reset_shader(); + + node.setCanvasSurface(_newCanvas, i); + surface_free(_canvas_surface); + } + + node.inputs[| 0].setValue([_sw, _sh]); + } + } + + } else if(_hovering >= 0 && mouse_click(mb_left, active)) { + dragging = _hovering; + + drag_mx = _mx; + drag_my = _my; + drag_sw = _sw; + drag_sh = _sh; + + drag_display = [ 0, 0, _sw, _sh ]; + } + } + +} \ No newline at end of file diff --git a/scripts/canvas_tool_resize/canvas_tool_resize.yy b/scripts/canvas_tool_resize/canvas_tool_resize.yy new file mode 100644 index 000000000..4ca93b54b --- /dev/null +++ b/scripts/canvas_tool_resize/canvas_tool_resize.yy @@ -0,0 +1,13 @@ +{ + "$GMScript":"", + "%Name":"canvas_tool_resize", + "isCompatibility":false, + "isDnD":false, + "name":"canvas_tool_resize", + "parent":{ + "name":"tools", + "path":"folders/nodes/data/canvas/tools.yy", + }, + "resourceType":"GMScript", + "resourceVersion":"2.0", +} \ No newline at end of file diff --git a/scripts/canvas_tool_selection/canvas_tool_selection.gml b/scripts/canvas_tool_selection/canvas_tool_selection.gml index 5e3d1d1b1..3d29371ef 100644 --- a/scripts/canvas_tool_selection/canvas_tool_selection.gml +++ b/scripts/canvas_tool_selection/canvas_tool_selection.gml @@ -20,7 +20,7 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { mouse_pre_x = 0; mouse_pre_y = 0; - function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { + function createSelection(_mask, sel_x0, sel_y0, sel_w, sel_h) { #region is_selecting = false; @@ -54,25 +54,50 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { node.surface_store_buffer(); selection_position = [ sel_x0, sel_y0 ]; - } + } #endregion - function copySelection() { + function copySelection() { #region var s = surface_encode(selection_surface); clipboard_set_text(s); - } + } #endregion - function apply() { - surface_set_target(_canvas_surface); - BLEND_ALPHA - draw_surface_safe(selection_surface, selection_position[0], selection_position[1]); - BLEND_NORMAL + function apply() { #region + var _drawLay = node.tool_attribute.drawLayer; + var _sw = surface_get_width(_canvas_surface); + var _sh = surface_get_height(_canvas_surface); + + var _drawnSurface = surface_create(_sw, _sh); + + surface_set_target(_drawnSurface); + DRAW_CLEAR + + if(_drawLay == 0 || _drawLay == 2) { + BLEND_OVERRIDE + draw_surface(_canvas_surface, 0, 0); + BLEND_ALPHA + draw_surface_safe(selection_surface, selection_position[0], selection_position[1]); + BLEND_NORMAL + + } else if(_drawLay == 1) { + BLEND_OVERRIDE + draw_surface_safe(selection_surface, selection_position[0], selection_position[1]); + BLEND_ALPHA + draw_surface(_canvas_surface, 0, 0); + BLEND_NORMAL + } + surface_reset_target(); - + + node.setCanvasSurface(_drawnSurface); + surface_free(_canvas_surface); + node.surface_store_buffer(); surface_free(selection_surface); - } + + is_selected = false; + } #endregion - function onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + function onSelected(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region if(!is_surface(selection_surface)) { is_selected = false; return; @@ -113,18 +138,18 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { } if(key_press(ord("C"), MOD_KEY.ctrl)) copySelection(); - } + } #endregion - function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + function step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region 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(); } - } + } #endregion - function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + function drawPreview(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region if(is_selected) draw_surface_safe(selection_surface, selection_position[0], selection_position[1]); @@ -133,9 +158,9 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { var sel_y0 = min(selection_sy, mouse_cur_y); draw_surface_safe(selection_mask, sel_x0, sel_y0); } - } + } #endregion - function drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { + function drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region if(!is_selected) return; var pos_x = _x + selection_position[0] * _s; @@ -150,5 +175,59 @@ function canvas_tool_selection(selector = noone) : canvas_tool() constructor { 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 + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + function rotate90cw() { #region + var _sw = surface_get_width(selection_surface); + var _sh = surface_get_height(selection_surface); + + var _newS = surface_create(_sh, _sw); + surface_set_shader(_newS, noone); + draw_surface_ext(selection_surface, _sh, 0, 1, 1, -90, c_white, 1); + surface_reset_shader(); + + surface_free(selection_surface); + selection_surface = _newS; + } #endregion + + function rotate90ccw() { #region + var _sw = surface_get_width(selection_surface); + var _sh = surface_get_height(selection_surface); + + var _newS = surface_create(_sh, _sw); + surface_set_shader(_newS, noone); + draw_surface_ext(selection_surface, 0, _sw, 1, 1, 90, c_white, 1); + surface_reset_shader(); + + surface_free(selection_surface); + selection_surface = _newS; + } #endregion + + function flipH() { #region + var _sw = surface_get_width(selection_surface); + var _sh = surface_get_height(selection_surface); + + var _newS = surface_create(_sw, _sh); + surface_set_shader(_newS, noone); + draw_surface_ext(selection_surface, _sw, 0, -1, 1, 0, c_white, 1); + surface_reset_shader(); + + surface_free(selection_surface); + selection_surface = _newS; + } #endregion + + function flipV() { #region + var _sw = surface_get_width(selection_surface); + var _sh = surface_get_height(selection_surface); + + var _newS = surface_create(_sw, _sh); + surface_set_shader(_newS, noone); + draw_surface_ext(selection_surface, 0, _sh, 1, -1, 0, c_white, 1); + surface_reset_shader(); + + surface_free(selection_surface); + selection_surface = _newS; + } #endregion } \ No newline at end of file diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index c43a9c3e1..4ccb7621c 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -36,10 +36,10 @@ globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER, LATEST_VERSION; LATEST_VERSION = 11600; - VERSION = 11692; + VERSION = 11700; SAVE_VERSION = 11690; - VERSION_STRING = "1.16.9.2"; - BUILD_NUMBER = 11692; + VERSION_STRING = "1.17.rc1"; + BUILD_NUMBER = 11700; globalvar HOTKEYS, HOTKEY_CONTEXT; HOTKEYS = ds_map_create(); diff --git a/scripts/hotkey_data/hotkey_data.gml b/scripts/hotkey_data/hotkey_data.gml index 3ef3be3d9..e240fbdc4 100644 --- a/scripts/hotkey_data/hotkey_data.gml +++ b/scripts/hotkey_data/hotkey_data.gml @@ -2,14 +2,14 @@ globalvar HOTKEYS_CUSTOM; HOTKEYS_CUSTOM = { "Node_Canvas": { - "Selection": new hotkeySimple("S"), - "Magic Selection": new hotkeySimple("W"), - "Pencil": new hotkeySimple("B"), - "Eraser": new hotkeySimple("E"), - "Rectangle": new hotkeySimple("N"), - "Ellipse": new hotkeySimple("M"), - "Fill": new hotkeySimple("F"), - "Freeform": new hotkeySimple("Q"), + "Selection": new hotkeySimple("S"), + "Magic Selection": new hotkeySimple("W"), + "Pencil": new hotkeySimple("B"), + "Eraser": new hotkeySimple("E"), + "Rectangle": new hotkeySimple("N"), + "Ellipse": new hotkeySimple("M"), + "Fill": new hotkeySimple("F"), + "Freeform": new hotkeySimple("Q"), }, "Node_Mesh_Warp": { "Edit control point": new hotkeySimple("V"), diff --git a/scripts/node_3d_mesh_plane/node_3d_mesh_plane.gml b/scripts/node_3d_mesh_plane/node_3d_mesh_plane.gml index b133378cc..0ceda9962 100644 --- a/scripts/node_3d_mesh_plane/node_3d_mesh_plane.gml +++ b/scripts/node_3d_mesh_plane/node_3d_mesh_plane.gml @@ -10,8 +10,9 @@ function Node_3D_Mesh_Plane(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _grou .setDisplay(VALUE_DISPLAY.enum_button, [ "X", "Y", "Z" ]); inputs[| in_mesh + 2] = nodeValue("Both side", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false ) + .rejectArray(); - inputs[| in_mesh + 3] = nodeValue("Back Material", self, JUNCTION_CONNECT.input, VALUE_TYPE.d3Material, new __d3dMaterial() ) + inputs[| in_mesh + 3] = nodeValue("Back Material", self, JUNCTION_CONNECT.input, VALUE_TYPE.d3Material, new __d3dMaterial() ); input_display_list = [ __d3d_input_list_mesh, in_mesh + 1, @@ -19,8 +20,9 @@ function Node_3D_Mesh_Plane(_x, _y, _group = noone) : Node_3D_Mesh(_x, _y, _grou ["Material", false], in_mesh + 2, in_mesh + 0, in_mesh + 3, ] - static step = function() { - var _both = getSingleValue(in_mesh + 2); + static preGetInputs = function() { + var _both = inputs[| in_mesh + 2].getValue(); + inputs[| in_mesh + 3].setVisible(_both, _both); } diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index 2c2732260..60db8823a 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -190,7 +190,12 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_attribute.channel = [ true, true, true, true ]; tool_channel_edit = new checkBoxGroup(THEME.tools_canvas_channel, function(ind, val) { tool_attribute.channel[ind] = val; }); - tool_settings = [ [ "Channel", tool_channel_edit, "channel", tool_attribute ] ]; + + tool_attribute.drawLayer = 0; + tool_attribute.pickColor = c_white; + tool_drawLayer_edit = new buttonGroup( [ THEME.canvas_draw_layer, THEME.canvas_draw_layer, THEME.canvas_draw_layer ], function(val) { tool_attribute.drawLayer = val; }); + + tool_settings = [ [ "Channel", tool_channel_edit, "channel", tool_attribute ], [ "Draw", tool_drawLayer_edit, "drawLayer", tool_attribute ] ]; tool_attribute.size = 1; tool_size_edit = new textBox(TEXTBOX_INPUT.number, function(val) { tool_attribute.size = max(1, round(val)); }).setSlidable(0.1, true, [ 1, 999999 ]) @@ -251,9 +256,34 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor tool_sel_freeform = new canvas_tool_selection_freeform(tool_selection, brush); tool_sel_magic = new canvas_tool_selection_magic(tool_selection, tool_attribute); - //rightTools = [ - // new NodeTool( "Selection", THEME.canvas_tools_selection_rectangle ), - //]; + #endregion + + #region right tools + __action_rotate_90_cw = method(self, function() { if(tool_selection.is_selected) tool_selection.rotate90cw() else canvas_action_rotate(-90); }); + __action_rotate_90_ccw = method(self, function() { if(tool_selection.is_selected) tool_selection.rotate90ccw() else canvas_action_rotate( 90); }); + __action_flip_h = method(self, function() { if(tool_selection.is_selected) tool_selection.flipH() else canvas_action_flip(1); }); + __action_flip_v = method(self, function() { if(tool_selection.is_selected) tool_selection.flipV() else canvas_action_flip(0); }); + + rightTools_general = [ + new NodeTool( "Resize Canvas", THEME.canvas_resize ).setToolObject( new canvas_tool_resize() ), + + new NodeTool( [ "Rotate 90 CW", "Rotate 90 CCW" ], + [ THEME.canvas_rotate_cw, THEME.canvas_rotate_ccw ] ) + .setToolFn( [ __action_rotate_90_cw, __action_rotate_90_ccw ] ), + + new NodeTool( [ "Flip H", "Flip V" ], + [ THEME.canvas_flip_h, THEME.canvas_flip_v ] ) + .setToolFn( [ __action_flip_h, __action_flip_v ] ), + ]; + + rightTools_selection = [ + new NodeTool( "Outline", THEME.canvas_tools_outline ).setToolObject( new canvas_tool_outline() ), + new NodeTool( [ "Inset", "Extrude" ], + [ THEME.canvas_tools_inset, THEME.canvas_tools_extrude ] ) + .setToolObject( [ new canvas_tool_inset(), new canvas_tool_extrude() ] ), + ]; + + rightTools = rightTools_general; #endregion function setToolColor(color) { tool_attribute.color = color; } @@ -390,7 +420,15 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor if(buffer_exists(_cbuff)) buffer_delete(_cbuff); canvas_buffer[index] = buffer_create(_dim[0] * _dim[1] * 4, buffer_fixed, 4); - setCanvasSurface(surface_size_to(_canvas_surface, _dim[0], _dim[1]), index); + + var _newCanvas = surface_create(_dim[0], _dim[1]); + surface_set_target(_newCanvas); + DRAW_CLEAR + draw_surface(_canvas_surface, 0, 0); + surface_reset_target(); + + setCanvasSurface(_newCanvas, index); + surface_free(_canvas_surface); } drawing_surface = surface_verify(drawing_surface, _dim[0], _dim[1], cDep); @@ -418,8 +456,14 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor apply_surface(index); } #endregion + function tool_pick_color(_x, _y) { #region + if(tool_selection.is_selected) + tool_attribute.pickColor = surface_get_pixel(tool_selection.selection_surface, _x - tool_selection.selection_position[0], _y - tool_selection.selection_position[1]); + else + tool_attribute.pickColor = surface_get_pixel(getCanvasSurface(), _x, _y); + } #endregion + function apply_draw_surface() { #region - var _alp = _color_get_alpha(tool_attribute.color); var _can = getCanvasSurface(); var _drw = drawing_surface; @@ -442,24 +486,35 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor _drw = _tmp; } - surface_set_target(_can); - BLEND_ALPHA - if(isUsingTool("Eraser")) { - gpu_set_blendmode(bm_subtract); - if(tool_attribute.channel[3]) - gpu_set_colorwriteenable(false, false, false, true); - } - draw_surface_ext_safe(_drw, 0, 0, 1, 1, 0, c_white, _alp); - - gpu_set_colorwriteenable(tool_attribute.channel[0], tool_attribute.channel[1], tool_attribute.channel[2], tool_attribute.channel[3]); - surface_reset_target(); - - surface_store_buffer(); + var _sw = surface_get_width(_can); + var _sh = surface_get_height(_can); + var _drawnSurface = surface_create(_sw, _sh); + + surface_set_shader(_drawnSurface, sh_canvas_apply_draw); + shader_set_i("drawLayer", tool_attribute.drawLayer); + shader_set_i("eraser", isUsingTool("Eraser")); + shader_set_f("channels", tool_attribute.channel); + shader_set_f("alpha", _color_get_alpha(tool_attribute.color)); + shader_set_color("pickColor", tool_attribute.pickColor); + + shader_set_surface("back", _can); + shader_set_surface("fore", _drw); + + draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _sw, _sh); + surface_reset_shader(); + + surface_free(_can); surface_clear(drawing_surface); - BLEND_NORMAL; - if(tool_selection.is_selected) surface_free(_tmp); + if(tool_selection.is_selected) { + surface_free(_tmp); + tool_selection.selection_surface = _drawnSurface; + } else { + setCanvasSurface(_drawnSurface); + surface_store_buffer(); + } + } #endregion static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region @@ -480,27 +535,32 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor var _canvas_surface = getCanvasSurface(); if(!surface_exists(_canvas_surface)) return; - var _dim = attributes.dimension; - _drawing_surface = surface_verify(_drawing_surface, _dim[0], _dim[1]); - drawing_surface = surface_verify( drawing_surface, _dim[0], _dim[1], attrDepth()); - - surface_set_target(_drawing_surface); - DRAW_CLEAR - draw_surface_safe(drawing_surface); - surface_reset_target(); - - #region selection - tool_selection.node = self; - tool_selection.drawing_surface = drawing_surface; - tool_selection._canvas_surface = _canvas_surface; - tool_selection.apply_draw_surface = apply_draw_surface; + #region surfaces + var _dim = attributes.dimension; + _drawing_surface = surface_verify(_drawing_surface, _dim[0], _dim[1]); + drawing_surface = surface_verify( drawing_surface, _dim[0], _dim[1], attrDepth()); + + surface_set_target(_drawing_surface); + DRAW_CLEAR + draw_surface_safe(drawing_surface); + surface_reset_target(); #endregion #region tool - var _tool = noone; var _currTool = PANEL_PREVIEW.tool_current; + var _tool = noone; + + rightTools = []; + array_append(rightTools, rightTools_general); + + if(tool_selection.is_selected) { + array_push(rightTools, -1); + array_append(rightTools, rightTools_selection); + } if(_currTool != noone) { + _tool = _currTool.getToolObject(); + switch(_currTool.getName()) { case "Pencil" : _tool = tool_brush; break; case "Eraser" : _tool = tool_eraser; break; @@ -524,21 +584,30 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor case 2 : _tool = tool_sel_freeform; break; } - if(tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); break; - case "Magic Selection" : - _tool = tool_sel_magic; - - if(tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); - break; + case "Magic Selection" : _tool = tool_sel_magic; break; } + + if(_tool) _tool.subtool = _currTool.selecting; + + tool_selection.node = self; + tool_selection.drawing_surface = drawing_surface; + tool_selection._canvas_surface = _canvas_surface; + tool_selection.apply_draw_surface = apply_draw_surface; + + if(is_instanceof(_tool, canvas_tool_selection) && tool_selection.is_selected) tool_selection.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); } #endregion + if(_tool && _tool.override) { + _tool.node = self; + _tool.step(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); + return; + } + draw_set_color(tool_attribute.color); - gpu_set_colorwriteenable(tool_attribute.channel[0], tool_attribute.channel[1], tool_attribute.channel[2], tool_attribute.channel[3]); if(_tool) { #region tool step @@ -573,7 +642,6 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } #endregion draw_set_alpha(1); - gpu_set_colorwriteenable(true, true, true, true); #region preview var _alp = _color_get_alpha(tool_attribute.color); @@ -600,11 +668,8 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor if(_tool) { _tool.drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny); - if(!is_instanceof(_tool, canvas_tool_selection) && (active || _tool.mouse_holding)) { - gpu_set_colorwriteenable(tool_attribute.channel[0], tool_attribute.channel[1], tool_attribute.channel[2], tool_attribute.channel[3]); + if(!is_instanceof(_tool, canvas_tool_selection) && (active || _tool.mouse_holding)) 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); - } surface_set_target(_preview_draw_surface); DRAW_CLEAR diff --git a/scripts/node_color_adjust/node_color_adjust.gml b/scripts/node_color_adjust/node_color_adjust.gml index df16536f1..28af3a59e 100644 --- a/scripts/node_color_adjust/node_color_adjust.gml +++ b/scripts/node_color_adjust/node_color_adjust.gml @@ -23,7 +23,7 @@ function Node_Color_adjust(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro .setDisplay(VALUE_DISPLAY.slider, { range: [ -1, 1, 0.01 ] }) .setMappable(22); - inputs[| 6] = nodeValue("Blend", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, c_white); + inputs[| 6] = nodeValue("Blend", self, JUNCTION_CONNECT.input, VALUE_TYPE.color, cola(c_white)); inputs[| 7] = nodeValue("Blend amount", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) .setDisplay(VALUE_DISPLAY.slider) diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 5922ee6ae..91fe2131d 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -2140,7 +2140,7 @@ function Node(_x, _y, _group = noone) : __Node_Base(_x, _y) constructor { static processDeserialize = function() {} static postDeserialize = function() {} - + static applyDeserialize = function(preset = false) { #region preApplyDeserialize(); diff --git a/scripts/node_functions/node_functions.gml b/scripts/node_functions/node_functions.gml index 408a6d39a..7b02be4e4 100644 --- a/scripts/node_functions/node_functions.gml +++ b/scripts/node_functions/node_functions.gml @@ -208,7 +208,10 @@ var inp = PROJECT.globalNode.getInput(strs[0]); if(inp == 0) return 0; - return inp.getValueRecursive([ 0, 0 ])[0]; + var _arr = [ 0, 0 ]; + inp.getValueRecursive(_arr); + + return _arr[0]; } else if(struct_has(PROJECT_VARIABLES, strs[0])) { var _str_var = PROJECT_VARIABLES[$ strs[0]]; diff --git a/scripts/node_image_grid/node_image_grid.gml b/scripts/node_image_grid/node_image_grid.gml index 855cd0a29..1d2a289b2 100644 --- a/scripts/node_image_grid/node_image_grid.gml +++ b/scripts/node_image_grid/node_image_grid.gml @@ -139,11 +139,11 @@ function Node_Image_Grid(_x, _y, _group = noone) : Node(_x, _y, _group) construc var sw = surface_get_width_safe(_s); var sh = surface_get_height_safe(_s); - array_push(atlas, new SurfaceAtlas(_surf[j], sx, sy)); + array_push(atlas, new SurfaceAtlas(_s, sx, sy)); surface_set_shader(temp_surface[!ppind], sh_draw_surface); shader_set_f("dimension", ww, hh); - shader_set_surface("fore", _surf[j]); + shader_set_surface("fore", _s); shader_set_f("fdimension", sw, sh); shader_set_f("position", sx + _padd[PADDING.left], sy + _padd[PADDING.top]); diff --git a/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml b/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml index 69b0df05f..a1b11071f 100644 --- a/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml +++ b/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml @@ -136,7 +136,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) #region frame var _st, _ed; - var _ln = array_length(inpt) - 1; + var _ln = array_length(inpt); if(rang[0] < 0) _st = _ln + rang[0]; else _st = rang[0]; @@ -148,8 +148,8 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) _st = clamp(_st, 0, _ln); _ed = clamp(_ed, 0, _ln); - if(_ed <= _st) return; - var amo = _ed - _st; + if(_ed < _st) return; + var amo = _ed - _st + 1; #endregion var ww = 0; @@ -157,16 +157,17 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) var _atl = []; #region surface generate + switch(pack) { case SPRITE_STACK.horizontal : - for(var i = _st; i < _ed; i++) { + for(var i = _st; i <= _ed; i++) { ww += surface_get_width_safe(inpt[i]); if(i > _st) ww += spac; hh = max(hh, surface_get_height_safe(inpt[i])); } break; case SPRITE_STACK.vertical : - for(var i = _st; i < _ed; i++) { + for(var i = _st; i <= _ed; i++) { ww = max(ww, surface_get_width_safe(inpt[i])); hh += surface_get_height_safe(inpt[i]); if(i > _st) hh += spac; @@ -211,14 +212,14 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) case SPRITE_STACK.horizontal : var px = padd[2]; var py = padd[1]; - for(var i = _st; i < _ed; i++) { + for(var i = _st; i <= _ed; i++) { var _w = surface_get_width_safe(inpt[i]); var _h = surface_get_height_safe(inpt[i]); var _sx = px; var _sy = py; curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; - if(curr_w != _w || curr_h == _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); switch(alig) { case 1 : _sy = py + (hh - _h) / 2; break; @@ -234,14 +235,14 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) case SPRITE_STACK.vertical : var px = padd[2]; var py = padd[1]; - for(var i = _st; i < _ed; i++) { + for(var i = _st; i <= _ed; i++) { var _w = surface_get_width_safe(inpt[i]); var _h = surface_get_height_safe(inpt[i]); var _sx = px; var _sy = py; curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; - if(curr_w != _w || curr_h == _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); switch(alig) { case 1 : _sx = px + (ww - _w) / 2; break; @@ -277,7 +278,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) var _h = surface_get_height_safe(inpt[index]); curr_w = curr_w == -1? _w : curr_w; curr_h = curr_h == -1? _h : curr_h; - if(curr_w != _w || curr_h == _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + if(curr_w != _w || curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); array_push(_atl, new SurfaceAtlas(inpt[index], px, py)); draw_surface_safe(inpt[index], px, py); @@ -476,7 +477,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) var _w = surface_get_width_safe(_surfi); var _h = surface_get_height_safe(_surfi); - if(anim_curr_w != _w || anim_curr_h == _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); + if(anim_curr_w != _w || anim_curr_h != _h) noti_warning("Spritesheet node does not support different surfaces size. Use Stack, Image grid, or pack sprite."); var px; var _sx = 0; diff --git a/scripts/node_tool/node_tool.gml b/scripts/node_tool/node_tool.gml index 2bcb1fc43..37340db66 100644 --- a/scripts/node_tool/node_tool.gml +++ b/scripts/node_tool/node_tool.gml @@ -8,16 +8,27 @@ function NodeTool(name, spr, context = instanceof(other)) constructor { settings = []; attribute = {}; + toolObject = noone; + toolFn = noone; + toolFnParam = {}; + static checkHotkey = function() { INLINE return getToolHotkey(ctx, name); } - static getName = function(index = 0) { - return is_array(name)? array_safe_get_fast(name, index, "") : name; + static setToolObject = function(toolObject) { self.toolObject = toolObject; return self; } + static setToolFn = function(toolFn, arguments = {}) { + self.toolFn = toolFn; + self.toolFnParam = arguments; + return self; } + static getName = function(index = 0) { return is_array(name)? array_safe_get_fast(name, index, "") : name; } + + static getToolObject = function() { return is_array(toolObject)? toolObject[selecting] : toolObject; } + static getDisplayName = function(index = 0) { var _key = checkHotkey(); @@ -49,6 +60,12 @@ function NodeTool(name, spr, context = instanceof(other)) constructor { } static toggle = function(index = 0) { + if(toolFn != noone) { + if(subtools == 0) toolFn(toolFnParam); + else toolFn[index](toolFnParam); + return; + } + if(subtools == 0) { PANEL_PREVIEW.tool_current = PANEL_PREVIEW.tool_current == self? noone : self; } else { @@ -63,6 +80,9 @@ function NodeTool(name, spr, context = instanceof(other)) constructor { if(PANEL_PREVIEW.tool_current == self) onToggle(); + + var _obj = getToolObject(); + if(_obj) _obj.init(); } static toggleKeyboard = function() { diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index e00694c5d..91931d70a 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -1546,7 +1546,14 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(typeFrom == VALUE_TYPE.text) value = toNumber(value); - return applyUnit? unit.apply(value, arrIndex) : value; + value = applyUnit? unit.apply(value, arrIndex) : value; + + if(value_tag == "dimension") { + for( var i = 0, n = array_length(value); i < n; i++ ) + value[i] = clamp(value[i], 0, 8192); + } + + return value; } #endregion if(type == VALUE_TYPE.surface && connect_type == JUNCTION_CONNECT.input && !is_surface(value) && def_val == USE_DEF) diff --git a/scripts/panel_notification/panel_notification.gml b/scripts/panel_notification/panel_notification.gml index e6b860e65..1637527c3 100644 --- a/scripts/panel_notification/panel_notification.gml +++ b/scripts/panel_notification/panel_notification.gml @@ -51,9 +51,11 @@ function Panel_Notification() : PanelContent() constructor { draw_set_font(f_p3); var timeW = string_width("00:00:00"); - for( var i = 0; i < ds_list_size(STATUSES); i++ ) { + for( var i = 0; i < amo; i++ ) { var index = amo - 1 - i; var noti = STATUSES[| index]; + + if(is_undefined(noti)) continue; if(noti.type & filter == 0) continue; draw_set_font(f_p2); @@ -82,10 +84,11 @@ function Panel_Notification() : PanelContent() constructor { ds_list_remove(STATUSES, o_dialog_menubox.noti); }), ],, noti); + dia.noti = noti; } } - + if(noti.life_max > 0) { var _nwx = sp_noti.w - ui(12) - ui(40); var _nw = _nwx * noti.life / noti.life_max; diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index 9eacf9b0b..6cb2ac5ad 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -81,6 +81,7 @@ function Panel_Preview() : PanelContent() constructor { _preview_sequence = preview_sequence; preview_rate = 10; + right_menu_x = 0; right_menu_y = 8; mouse_on_preview = 0; _mouse_on_preview = 0; @@ -104,9 +105,15 @@ function Panel_Preview() : PanelContent() constructor { tool_x = 0; tool_x_to = 0; tool_x_max = 0; + tool_y = 0; tool_y_to = 0; tool_y_max = 0; + + tool_ry = 0; + tool_ry_to = 0; + tool_ry_max = 0; + tool_current = noone; toolbar_width = ui(40); @@ -1037,9 +1044,11 @@ function Panel_Preview() : PanelContent() constructor { var _node = getNodePreview(); #region status texts (top right) + if(right_menu_x == 0) right_menu_x = w - ui(8); + if(PANEL_PREVIEW == self) { draw_set_text(f_p0, fa_right, fa_top, COLORS._main_text_accent); - draw_text(w - ui(8), right_menu_y, __txt("Active")); + draw_text(right_menu_x, right_menu_y, __txt("Active")); right_menu_y += string_height("l"); } @@ -1048,20 +1057,20 @@ function Panel_Preview() : PanelContent() constructor { txt += $" / {FPS_REAL}"; draw_set_text(f_p0, fa_right, fa_top, fps >= PROJECT.animator.framerate? COLORS._main_text_sub : COLORS._main_value_negative); - draw_text(w - ui(8), right_menu_y, txt); + draw_text(right_menu_x, right_menu_y, txt); right_menu_y += string_height("l"); draw_set_text(f_p0, fa_right, fa_top, COLORS._main_text_sub); - draw_text(w - ui(8), right_menu_y, $"{__txt("Frame")} {CURRENT_FRAME + 1}/{TOTAL_FRAMES}"); + draw_text(right_menu_x, right_menu_y, $"{__txt("Frame")} {CURRENT_FRAME + 1}/{TOTAL_FRAMES}"); right_menu_y += string_height("l"); - draw_text(w - ui(8), right_menu_y, $"x{canvas_s}"); + draw_text(right_menu_x, right_menu_y, $"x{canvas_s}"); if(pHOVER) { right_menu_y += string_height("l"); var mpx = floor((mx - canvas_x) / canvas_s); var mpy = floor((my - canvas_y) / canvas_s); - draw_text(w - ui(8), right_menu_y, $"[{mpx}, {mpy}]"); + draw_text(right_menu_x, right_menu_y, $"[{mpx}, {mpy}]"); } if(_node == noone) return; @@ -1069,9 +1078,10 @@ function Panel_Preview() : PanelContent() constructor { right_menu_y += string_height("l"); var txt = $"{canvas_w} x {canvas_h}px"; if(canvas_a) txt = $"{canvas_a} x {txt}"; - draw_text(w - ui(8), right_menu_y, txt); + draw_text(right_menu_x, right_menu_y, txt); right_menu_y += string_height("l"); + right_menu_x = w - ui(8); #endregion var pseq = getNodePreviewSequence(); @@ -1242,13 +1252,22 @@ function Panel_Preview() : PanelContent() constructor { var thov = pHOVER && point_in_rectangle(mx, my, 0, toolbar_height, toolbar_width, h - toolbar_height); if(thov) canvas_hover = false; - for(var i = 0; i < array_length(_node.tools); i++) { #region iterate each tools + for(var i = 0; i < array_length(_node.tools); i++) { #region left tools var tool = _node.tools[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(tool == -1) { + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); + + yy += ui(8); + tool_y_max += ui(8); + continue; + } + if(thov && point_in_rectangle(_mx, _my, _x0, _y0 + 1, _x1, _y1 - 1)) tool_hovering = tool; @@ -1328,9 +1347,13 @@ function Panel_Preview() : PanelContent() constructor { } if(_node.rightTools != -1) { + right_menu_x = w - toolbar_width - ui(8); + tool_ry_max = 0; + tool_ry = lerp_float(tool_ry, tool_ry_to, 5); + var _tbx = w - toolbar_width; - var xx = _tbx + ui(1) + toolbar_width / 2; - var yy = ui(34) + tool_size / 2 + tool_y; + var xx = _tbx + toolbar_width / 2; + var yy = ui(34) + tool_size / 2 + tool_ry; var _sw = -toolbar_width / sprite_get_width(THEME.tool_side); var _sh = h - toolbar_height - ui(32) / sprite_get_height(THEME.tool_side); @@ -1340,42 +1363,92 @@ function Panel_Preview() : PanelContent() constructor { 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 + for(var i = 0; i < array_length(_node.rightTools); i++) { #region right 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(tool == -1) { + draw_set_color(COLORS._main_icon_dark); + draw_line_round(xx + ui(8), _y0 + ui(3), xx - ui(9), _y0 + ui(3), 2); + + yy += ui(8); + tool_ry_max += ui(8); + continue; + } + 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 - + if(tool.subtools > 0 && _tool == tool) { #region subtools + + var stool = tool.spr; + var s_ww = tool_size * tool.subtools; + var s_hh = tool_size; + var tx = _x0 - s_ww + tool_size; + draw_sprite_stretched(THEME.menu_bg, 0, tx - pd, _y0 - pd, s_ww + pd * 2, s_hh + pd * 2); + + var _am = array_length(stool); + + for( var j = 0; j < _am; j++ ) { + var _sind = _am - 1 - j; + var _sxx = tx + j * tool_size + tool_size / 2; + var _syy = yy; + + var _sx0 = _sxx - tool_size / 2; + var _sy0 = _syy - tool_size / 2; + var _sx1 = _sxx + tool_size / 2; + var _sy1 = _syy + tool_size / 2; + + draw_sprite_colored(stool[_sind], 0, _sxx, _syy); + + if(point_in_rectangle(_mx, _my, _sx0, _sy0 + 1, _sx1, _sy1 - 1)) { + TOOLTIP = tool.getDisplayName(_sind); + draw_sprite_stretched(THEME.button_hide, 1, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2); + + if(mouse_press(mb_left, pFOCUS)) + tool.toggle(_sind); + } + + if(tool_current == tool && tool.selecting == _sind) { + draw_sprite_stretched_ext(THEME.button_hide, 2, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS.panel_preview_grid, 1); + draw_sprite_stretched_ext(THEME.button_hide, 3, _sx0 + pd, _sy0 + pd, tool_size - pd * 2, tool_size - pd * 2, COLORS._main_accent, 1); + } + } + + if(point_in_rectangle(_mx, _my, tx, _y0 + 1, tx + s_ww, _y1 - 1)) + tool_hovering = tool; + #endregion + } else { #region single tools + 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(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); + } + + if(tool.subtools > 0) draw_sprite_colored(tool.spr[tool.selecting], 0, xx, yy); + else draw_sprite_colored(tool.spr, 0, xx, yy); + #endregion + } + + yy += tool_size; + tool_ry_max += tool_size; + } #endregion + + tool_ry_max = max(0, tool_ry_max - h + toolbar_height * 2); + if(thov && !key_mod_press_any()) { + if(mouse_wheel_up()) tool_ry_to = clamp(tool_ry_to + ui(64) * SCROLL_SPEED, -tool_ry_max, 0); + if(mouse_wheel_down()) tool_ry_to = clamp(tool_ry_to - ui(64) * SCROLL_SPEED, -tool_ry_max, 0); + } } } #endregion diff --git a/scripts/preferences/preferences.gml b/scripts/preferences/preferences.gml index 5ad1e8b13..d722a11bd 100644 --- a/scripts/preferences/preferences.gml +++ b/scripts/preferences/preferences.gml @@ -250,7 +250,7 @@ PREFERENCES.theme = "default"; var f = json_load_struct(DIRECTORY + "key_nodes.json"); - struct_override(HOTKEYS_CUSTOM, f); + struct_override_nested(HOTKEYS_CUSTOM, f); LOCALE_DEF = PREFERENCES.local == "en"; THEME_DEF = PREFERENCES.theme == "default"; diff --git a/scripts/preview_overlay_scalar/preview_overlay_scalar.gml b/scripts/preview_overlay_scalar/preview_overlay_scalar.gml index acbd6b40b..176745045 100644 --- a/scripts/preview_overlay_scalar/preview_overlay_scalar.gml +++ b/scripts/preview_overlay_scalar/preview_overlay_scalar.gml @@ -42,7 +42,7 @@ function preview_overlay_scalar(interact, active, _x, _y, _s, _mx, _my, _snx, _s if(!struct_has(self, "__overlay_hover")) __overlay_hover = 0; __overlay_hover = lerp_float(__overlay_hover, index, 4); draw_anchor(__overlay_hover, _ax, _ay, _r); - + draw_set_text(_f_p2b, fa_center, fa_bottom, COLORS._main_accent); draw_text_add(round(_ax), round(_ay - 4), name); diff --git a/scripts/struct_functions/struct_functions.gml b/scripts/struct_functions/struct_functions.gml index 4ed9cf5e0..90520a460 100644 --- a/scripts/struct_functions/struct_functions.gml +++ b/scripts/struct_functions/struct_functions.gml @@ -16,6 +16,24 @@ function struct_override(original, override) { #region return original; } #endregion +function struct_override_nested(original, override) { #region + INLINE + + var args = variable_struct_get_names(override); + + for( var i = 0, n = array_length(args); i < n; i++ ) { + var _key = args[i]; + + if(!struct_has(original, _key)) continue; + if(is_struct(original[$ _key])) + struct_override_nested(original[$ _key], override[$ _key]) + else + original[$ _key] = override[$ _key]; + } + + return original; +} #endregion + function struct_append(original, append) { #region INLINE diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index a9be1fd96..47476849e 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -619,6 +619,13 @@ function surface_save_safe(surface, path) { #region if(!is_surface(surface)) return; + + if(is_instanceof(surface, SurfaceAtlas)) surface = surface.surface.get(); + else if(is_instanceof(surface, SurfaceAtlasFast)) surface = surface.surface; + else if(is_instanceof(surface, dynaSurf)) surface = array_safe_get(surface.surfaces, 0); + + if(!surface_exists(surface)) return; + var f = surface_get_format(surface); if(f == surface_rgba8unorm) { diff --git a/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.fsh b/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.fsh new file mode 100644 index 000000000..29b97c153 --- /dev/null +++ b/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.fsh @@ -0,0 +1,43 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform int drawLayer; +uniform int eraser; +uniform vec4 channels; +uniform vec4 pickColor; +uniform float alpha; + +uniform sampler2D back; +uniform sampler2D fore; + +void main() { + vec4 bc = texture2D( back, v_vTexcoord ); + vec4 fc = texture2D( fore, v_vTexcoord ); + + fc *= channels; + fc.a *= alpha; + + if(eraser == 1) { + bc -= fc; + gl_FragColor = bc; + return; + } + + gl_FragColor = bc; + + if(drawLayer == 1) { + vec4 temp = fc; + fc = bc; + bc = temp; + } + + if(drawLayer == 2) { + if(bc != pickColor) return; + } + + float al = fc.a + bc.a * (1. - fc.a); + vec4 res = ((fc * fc.a) + (bc * bc.a * (1. - fc.a))) / al; + res.a = al; + + gl_FragColor = res; +} diff --git a/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.vsh b/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.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_canvas_apply_draw/sh_canvas_apply_draw.yy b/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.yy new file mode 100644 index 000000000..98b0d3ae0 --- /dev/null +++ b/shaders/sh_canvas_apply_draw/sh_canvas_apply_draw.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_canvas_apply_draw", + "name":"sh_canvas_apply_draw", + "parent":{ + "name":"shader", + "path":"folders/nodes/data/canvas/shader.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_canvas_extrude/sh_canvas_extrude.fsh b/shaders/sh_canvas_extrude/sh_canvas_extrude.fsh new file mode 100644 index 000000000..54a62d8a1 --- /dev/null +++ b/shaders/sh_canvas_extrude/sh_canvas_extrude.fsh @@ -0,0 +1,26 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform vec2 shift; +uniform float itr; +uniform vec4 color; + +void main() { + vec4 c = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = c; + + if(c.a > 0.) return; + + vec2 shiftNorm = normalize(shift) / dimension; + + for(float i = 0.; i < itr; i++) { + vec2 sx = v_vTexcoord - shiftNorm * i; + vec4 sc = texture2D( gm_BaseTexture, sx ); + + if(sc.a > 0.) { + gl_FragColor = color; + return; + } + } +} diff --git a/shaders/sh_canvas_extrude/sh_canvas_extrude.vsh b/shaders/sh_canvas_extrude/sh_canvas_extrude.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_canvas_extrude/sh_canvas_extrude.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_canvas_extrude/sh_canvas_extrude.yy b/shaders/sh_canvas_extrude/sh_canvas_extrude.yy new file mode 100644 index 000000000..8b047ebb2 --- /dev/null +++ b/shaders/sh_canvas_extrude/sh_canvas_extrude.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_canvas_extrude", + "name":"sh_canvas_extrude", + "parent":{ + "name":"shader", + "path":"folders/nodes/data/canvas/shader.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_canvas_inset/sh_canvas_inset.fsh b/shaders/sh_canvas_inset/sh_canvas_inset.fsh new file mode 100644 index 000000000..15154533f --- /dev/null +++ b/shaders/sh_canvas_inset/sh_canvas_inset.fsh @@ -0,0 +1,26 @@ +varying vec2 v_vTexcoord; +varying vec4 v_vColour; + +uniform vec2 dimension; +uniform vec2 shift; +uniform float itr; +uniform vec4 color; + +void main() { + vec4 c = texture2D( gm_BaseTexture, v_vTexcoord ); + gl_FragColor = c; + + if(c.a == 0.) return; + + vec2 shiftNorm = normalize(shift) / dimension; + + for(float i = 0.; i < itr; i++) { + vec2 sx = v_vTexcoord - shiftNorm * i; + vec4 sc = texture2D( gm_BaseTexture, sx ); + + if(sc.a == 0.) { + gl_FragColor = color; + return; + } + } +} diff --git a/shaders/sh_canvas_inset/sh_canvas_inset.vsh b/shaders/sh_canvas_inset/sh_canvas_inset.vsh new file mode 100644 index 000000000..3900c20f4 --- /dev/null +++ b/shaders/sh_canvas_inset/sh_canvas_inset.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_canvas_inset/sh_canvas_inset.yy b/shaders/sh_canvas_inset/sh_canvas_inset.yy new file mode 100644 index 000000000..48c866459 --- /dev/null +++ b/shaders/sh_canvas_inset/sh_canvas_inset.yy @@ -0,0 +1,12 @@ +{ + "$GMShader":"", + "%Name":"sh_canvas_inset", + "name":"sh_canvas_inset", + "parent":{ + "name":"shader", + "path":"folders/nodes/data/canvas/shader.yy", + }, + "resourceType":"GMShader", + "resourceVersion":"2.0", + "type":1, +} \ No newline at end of file diff --git a/shaders/sh_canvas_mask/sh_canvas_mask.yy b/shaders/sh_canvas_mask/sh_canvas_mask.yy index 8c3c0f4fa..e91e89723 100644 --- a/shaders/sh_canvas_mask/sh_canvas_mask.yy +++ b/shaders/sh_canvas_mask/sh_canvas_mask.yy @@ -3,8 +3,8 @@ "%Name":"sh_canvas_mask", "name":"sh_canvas_mask", "parent":{ - "name":"tools", - "path":"folders/nodes/data/canvas/tools.yy", + "name":"shader", + "path":"folders/nodes/data/canvas/shader.yy", }, "resourceType":"GMShader", "resourceVersion":"2.0",