From ff10a807d01c4817ea88bb25b350b582a5083386 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Sun, 2 Feb 2020 21:04:09 -0500 Subject: [PATCH] Update GD Paint demo --- 2d/gd_paint/PaintControl.gd | 198 ++++++++++++++---------------- 2d/gd_paint/PaintTools.png.import | 34 +++++ 2d/gd_paint/Paint_root.tscn | 53 ++++---- 2d/gd_paint/ToolsPanel.gd | 98 +++++++-------- 2d/gd_paint/icon.png.import | 34 +++++ 5 files changed, 239 insertions(+), 178 deletions(-) create mode 100644 2d/gd_paint/PaintTools.png.import create mode 100644 2d/gd_paint/icon.png.import diff --git a/2d/gd_paint/PaintControl.gd b/2d/gd_paint/PaintControl.gd index bd08f548..2372112f 100644 --- a/2d/gd_paint/PaintControl.gd +++ b/2d/gd_paint/PaintControl.gd @@ -1,52 +1,50 @@ extends Control -# The TL position of the canvas +# A constant for whether or not we're needing to undo a shape. +const UNDO_MODE_SHAPE = -2 +# A constant for whether or not we can undo. +const UNDO_NONE = -1 +# How large is the image (it's actually the size of DrawingAreaBG, because that's our background canvas). +const IMAGE_SIZE = Vector2(930, 720) + +# Enums for the various modes and brush shapes that can be applied. +enum BrushModes { + PENCIL, ERASER, CIRCLE_SHAPE, RECTANGLE_SHAPE +} +enum BrushShapes { + RECTANGLE, CIRCLE +} + +# The top-left position of the canvas. var TL_node # A list to hold all of the dictionaries that make up each brush. var brush_data_list = [] # A boolean to hold whether or not the mouse is inside the drawing area, the mouse position last _process call -# and the position of the mouse when the left mouse button was pressed +# and the position of the mouse when the left mouse button was pressed. var is_mouse_in_drawing_area = false var last_mouse_pos = Vector2() var mouse_click_start_pos = null # A boolean to tell whether we've set undo_elements_list_num, which holds the size of draw_elements_list # before a new stroke is added (unless the current brush mode is 'rectangle shape' or 'circle shape', in -# which case we do things a litte differently. See the undo_stroke function for more details) +# which case we do things a litte differently. See the undo_stroke function for more details). var undo_set = false var undo_element_list_num = -1 -# A constant for whether or not we're needing to undo a shape -const UNDO_MODE_SHAPE = -2 -# A constant for whether or not we can undo -const UNDO_NONE = -1 - -# Enums for the various modes and brush shapes that can be applied -enum BRUSH_MODES { - pencil, eraser, circle_shape, rectangle_shape -} -enum BRUSH_SHAPES { - rectangle, circle -} - -# The current brush settings: The mode, size, color, and shape we have currently selected -var brush_mode = BRUSH_MODES.pencil +# The current brush settings: The mode, size, color, and shape we have currently selected. +var brush_mode = BrushModes.PENCIL var brush_size = 32 -var brush_color = Color(1, 1, 1, 1) -var brush_shape = BRUSH_SHAPES.circle; +var brush_color = Color.black +var brush_shape = BrushShapes.CIRCLE; # The color of the background. We need this for the eraser (see the how we handle the eraser -# in the _draw function for more details) -var bg_color = Color(1, 1, 1, 1) - -# How large is the image (it's actually the size of DrawingAreaBG, because that's our background canvas) -const IMAGE_SIZE = Vector2(930, 720) - +# in the _draw function for more details). +var bg_color = Color.white func _ready(): - # Get the top left position node. We need this to find out whether or not the mouse is inside the canvas + # Get the top left position node. We need this to find out whether or not the mouse is inside the canvas. TL_node = get_node("TLPos") set_process(true) @@ -54,92 +52,92 @@ func _ready(): func _process(_delta): var mouse_pos = get_viewport().get_mouse_position() - # Check if the mouse is currently inside the canvas/drawing-area + # Check if the mouse is currently inside the canvas/drawing-area. is_mouse_in_drawing_area = false if mouse_pos.x > TL_node.global_position.x: if mouse_pos.y > TL_node.global_position.y: is_mouse_in_drawing_area = true if Input.is_mouse_button_pressed(BUTTON_LEFT): - # If we do not have a position for when the mouse was first clicked, then this most + # If we do not have a position for when the mouse was first clicked, then this must # be the first time is_mouse_button_pressed has been called since the mouse button was - # released, so we need to store the position + # released, so we need to store the position. if mouse_click_start_pos == null: mouse_click_start_pos = mouse_pos - # If the mouse is inside the canvas and the mouse is 1px away from the position of the mouse last _process call + # If the mouse is inside the canvas and the mouse is 1px away from the position of the mouse last _process call. if check_if_mouse_is_inside_canvas(): if mouse_pos.distance_to(last_mouse_pos) >= 1: - # If we are in pencil or eraser mode, then we need to draw - if brush_mode == BRUSH_MODES.pencil or brush_mode == BRUSH_MODES.eraser: + # If we are in pencil or eraser mode, then we need to draw. + if brush_mode == BrushModes.PENCIL or brush_mode == BrushModes.ERASER: # If undo has not been set, meaning we've started a new stroke, then store the size of the - # draw_elements_list so we can undo from this point in time + # draw_elements_list so we can undo from this point in time. if undo_set == false: undo_set = true undo_element_list_num = brush_data_list.size() - # Add the brush object to draw_elements_array + # Add the brush object to draw_elements_array. add_brush(mouse_pos, brush_mode) else: - # We've finished our stroke, so we can set a new undo (if a new storke is made) + # We've finished our stroke, so we can set a new undo (if a new storke is made). undo_set = false - # If the mouse is inside the canvas + # If the mouse is inside the canvas. if check_if_mouse_is_inside_canvas(): # If we're using either the circle shape mode, or the rectangle shape mode, then - # add the brush object to draw_elements_array - if brush_mode == BRUSH_MODES.circle_shape or brush_mode == BRUSH_MODES.rectangle_shape: + # add the brush object to draw_elements_array. + if brush_mode == BrushModes.CIRCLE_SHAPE or brush_mode == BrushModes.RECTANGLE_SHAPE: add_brush(mouse_pos, brush_mode) # We handle undo's differently than either pencil or eraser mode, so we need to set undo - # element_list_num to -2 so we can tell if we need to undo a shape. See undo_stroke for details + # element_list_num to -2 so we can tell if we need to undo a shape. See undo_stroke for details. undo_element_list_num = UNDO_MODE_SHAPE # Since we've released the left mouse, we need to get a new mouse_click_start_pos next time #is_mouse_button_pressed is true. mouse_click_start_pos = null - # Store mouse_pos as last_mouse_pos now that we're done with _process + # Store mouse_pos as last_mouse_pos now that we're done with _process. last_mouse_pos = mouse_pos func check_if_mouse_is_inside_canvas(): - # Make sure we have a mouse click starting position + # Make sure we have a mouse click starting position. if mouse_click_start_pos != null: # Make sure the mouse click starting position is inside the canvas. # This is so if we start out click outside the canvas (say chosing a color from the color picker) - # and then move our mouse back into the canvas, it won't start painting + # and then move our mouse back into the canvas, it won't start painting. if mouse_click_start_pos.x > TL_node.global_position.x: if mouse_click_start_pos.y > TL_node.global_position.y: - # Make sure the current mouse position is inside the canvas + # Make sure the current mouse position is inside the canvas. if is_mouse_in_drawing_area == true: return true return false func undo_stroke(): - # Only undo a stroke if we have one + # Only undo a stroke if we have one. if undo_element_list_num == UNDO_NONE: return - # If we are undoing a shape, then we can just remove the latest brush + # If we are undoing a shape, then we can just remove the latest brush. if undo_element_list_num == UNDO_MODE_SHAPE: if brush_data_list.size() > 0: brush_data_list.remove(brush_data_list.size() - 1) - # Now that we've undone a shape, we cannot undo again until another stoke is added + # Now that we've undone a shape, we cannot undo again until another stoke is added. undo_element_list_num = UNDO_NONE # NOTE: if we only had shape brushes, then we could remove the above line and could let the user - # undo until we have a empty element list + # undo until we have a empty element list. # Otherwise we're removing a either a pencil stroke or a eraser stroke. else: - # Figure out how many elements/brushes we've added in the last stroke + # Figure out how many elements/brushes we've added in the last stroke. var elements_to_remove = brush_data_list.size() - undo_element_list_num - # Remove all of the elements we've added this in the last stroke + # Remove all of the elements we've added this in the last stroke. #warning-ignore:unused_variable for elment_num in range(0, elements_to_remove): brush_data_list.pop_back() - # Now that we've undone a stoke, we cannot undo again until another stoke is added + # Now that we've undone a stoke, we cannot undo again until another stoke is added. undo_element_list_num = UNDO_NONE # Redraw the brushes @@ -159,12 +157,12 @@ func add_brush(mouse_pos, type): new_brush.brush_color = brush_color # If the new bursh is a rectangle shape, we need to calculate the top left corner of the rectangle and the - # bottom right corner of the rectangle - if type == BRUSH_MODES.rectangle_shape: + # bottom right corner of the rectangle. + if type == BrushModes.RECTANGLE_SHAPE: var TL_pos = Vector2() var BR_pos = Vector2() - # Figure out the left and right positions of the corners and assign them to the proper variable + # Figure out the left and right positions of the corners and assign them to the proper variable. if mouse_pos.x < mouse_click_start_pos.x: TL_pos.x = mouse_pos.x BR_pos.x = mouse_click_start_pos.x @@ -172,7 +170,7 @@ func add_brush(mouse_pos, type): TL_pos.x = mouse_click_start_pos.x BR_pos.x = mouse_pos.x - # Figure out the top and bottom positions of the corners and assign them to the proper variable + # Figure out the top and bottom positions of the corners and assign them to the proper variable. if mouse_pos.y < mouse_click_start_pos.y: TL_pos.y = mouse_pos.y BR_pos.y = mouse_click_start_pos.y @@ -180,80 +178,72 @@ func add_brush(mouse_pos, type): TL_pos.y = mouse_click_start_pos.y BR_pos.y = mouse_pos.y - # Assign the positions to the brush + # Assign the positions to the brush. new_brush.brush_pos = TL_pos new_brush.brush_shape_rect_pos_BR = BR_pos - # If the brush isa circle shape, then we need to calculate the radius of the circle - if type == BRUSH_MODES.circle_shape: - # Get the center point inbetween the mouse position and the position of the mouse when we clicked + # If the brush isa circle shape, then we need to calculate the radius of the circle. + if type == BrushModes.CIRCLE_SHAPE: + # Get the center point inbetween the mouse position and the position of the mouse when we clicked. var center_pos = Vector2((mouse_pos.x + mouse_click_start_pos.x) / 2, (mouse_pos.y + mouse_click_start_pos.y) / 2) # Assign the brush position to the center point, and calculate the radius of the circle using the distance from - # the center to the top/bottom positon of the mouse + # the center to the top/bottom positon of the mouse. new_brush.brush_pos = center_pos new_brush.brush_shape_circle_radius = center_pos.distance_to(Vector2(center_pos.x, mouse_pos.y)) - # Add the brush and update/draw all of the brushes + # Add the brush and update/draw all of the brushes. brush_data_list.append(new_brush) update() func _draw(): - # Go through all of the brushes in brush_data_list + # Go through all of the brushes in brush_data_list. for brush in brush_data_list: - - # If the brush is a pencil - if brush.brush_type == BRUSH_MODES.pencil: - # If the brush shape is a rectangle, then we need to make a Rect2 so we can use draw_rect. - # Draw_rect draws a rectagle at the top left corner, using the scale for the size. - # So we offset the position by half of the brush size so the rectangle's center is at mouse position - if brush.brush_shape == BRUSH_SHAPES.rectangle: - var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size)) + match brush.brush_type: + BrushModes.PENCIL: + # If the brush shape is a rectangle, then we need to make a Rect2 so we can use draw_rect. + # Draw_rect draws a rectagle at the top left corner, using the scale for the size. + # So we offset the position by half of the brush size so the rectangle's center is at mouse position. + if brush.brush_shape == BrushShapes.RECTANGLE: + var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size)) + draw_rect(rect, brush.brush_color) + # If the brush shape is a circle, then we draw a circle at the mouse position, + # making the radius half of brush size (so the circle is brush size pixels in diameter). + elif brush.brush_shape == BrushShapes.CIRCLE: + draw_circle(brush.brush_pos, brush.brush_size / 2, brush.brush_color) + BrushModes.ERASER: + # NOTE: this is a really cheap way of erasing that isn't really erasing! + # However, this gives similar results in a fairy simple way! + + # Erasing works exactly the same was as pencil does for both the rectangle shape and the circle shape, + # but instead of using brush.brush_color, we instead use bg_color instead. + if brush.brush_shape == BrushShapes.RECTANGLE: + var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size)) + draw_rect(rect, bg_color) + elif brush.brush_shape == BrushShapes.CIRCLE: + draw_circle(brush.brush_pos, brush.brush_size / 2, bg_color) + BrushModes.RECTANGLE_SHAPE: + # We make a Rect2 with the postion at the top left. To get the size we take the bottom right position + # and subtract the top left corner's position. + var rect = Rect2(brush.brush_pos, brush.brush_shape_rect_pos_BR - brush.brush_pos) draw_rect(rect, brush.brush_color) - # If the brush shape is a circle, then we draw a circle at the mouse position, - # making the radius half of brush size (so the circle is brush size pixels in diameter) - elif brush.brush_shape == BRUSH_SHAPES.circle: - draw_circle(brush.brush_pos, brush.brush_size / 2, brush.brush_color) - - # If the brush is a eraser - elif brush.brush_type == BRUSH_MODES.eraser: - # NOTE: this is a really cheap way of erasing that isn't really erasing! - # However, this gives similar results in a fairy simple way! - - # Erasing works exactly the same was as pencil does for both the rectangle shape and the circle shape, - # but instead of using brush.brush_color, we instead use bg_color instead. - if brush.brush_shape == BRUSH_SHAPES.rectangle: - var rect = Rect2(brush.brush_pos - Vector2(brush.brush_size / 2, brush.brush_size / 2), Vector2(brush.brush_size, brush.brush_size)) - draw_rect(rect, bg_color) - elif brush.brush_shape == BRUSH_SHAPES.circle: - draw_circle(brush.brush_pos, brush.brush_size / 2, bg_color) - - # If the brush is a rectangle shape - elif brush.brush_type == BRUSH_MODES.rectangle_shape: - # We make a Rect2 with the postion at the top left. To get the size we take the bottom right position - # and subtract the top left corner's position - var rect = Rect2(brush.brush_pos, brush.brush_shape_rect_pos_BR - brush.brush_pos) - draw_rect(rect, brush.brush_color) - - # If the brush is a circle shape - elif brush.brush_type == BRUSH_MODES.circle_shape: - # We simply draw a circle using stored in brush - draw_circle(brush.brush_pos, brush.brush_shape_circle_radius, brush.brush_color) + BrushModes.CIRCLE_SHAPE: + # We simply draw a circle using stored in brush. + draw_circle(brush.brush_pos, brush.brush_shape_circle_radius, brush.brush_color) func save_picture(path): - # Wait a couple frames so the save dialog isn't in the way + # Wait a couple frames so the save dialog isn't in the way. yield (get_tree(), "idle_frame") yield (get_tree(), "idle_frame") - # Get the viewport image + # Get the viewport image. var img = get_viewport().get_texture().get_data() # Crop the image so we only have canvas area. var cropped_image = img.get_rect(Rect2(TL_node.global_position, IMAGE_SIZE)) - # Flip the image on the Y-axis (it's flipped upside down by default) + # Flip the image on the Y-axis (it's flipped upside down by default). cropped_image.flip_y() - # Save the image with the passed in path we got from the save dialog + # Save the image with the passed in path we got from the save dialog. cropped_image.save_png(path) - diff --git a/2d/gd_paint/PaintTools.png.import b/2d/gd_paint/PaintTools.png.import new file mode 100644 index 00000000..8763b5e3 --- /dev/null +++ b/2d/gd_paint/PaintTools.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/PaintTools.png-636e86a6d210b52282c946752bbcc6f1.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://PaintTools.png" +dest_files=[ "res://.import/PaintTools.png-636e86a6d210b52282c946752bbcc6f1.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/2d/gd_paint/Paint_root.tscn b/2d/gd_paint/Paint_root.tscn index af0c2ef8..a9714d62 100644 --- a/2d/gd_paint/Paint_root.tscn +++ b/2d/gd_paint/Paint_root.tscn @@ -37,7 +37,7 @@ margin_left = 20.0 margin_top = 10.0 margin_right = 330.0 margin_bottom = 24.0 -text = "Selected tool: pencil" +text = "Selected tool: Pencil" align = 1 [node name="ButtonToolPencil" type="Button" parent="ToolsPanel"] @@ -105,52 +105,59 @@ margin_left = 20.0 margin_top = 140.0 margin_right = 330.0 margin_bottom = 190.0 -color = Color( 1, 1, 1, 1 ) -[node name="LabelBrushSize" type="Label" parent="ToolsPanel"] +[node name="BrushSettings" type="Control" parent="ToolsPanel"] +margin_top = 200.0 +margin_right = 350.0 +margin_bottom = 375.0 + +[node name="LabelBrushSize" type="Label" parent="ToolsPanel/BrushSettings"] margin_left = 20.0 -margin_top = 210.0 +margin_top = 10.0 margin_right = 330.0 -margin_bottom = 224.0 +margin_bottom = 24.0 text = "Brush size: 32px" align = 1 -[node name="HScrollBarBrushSize" type="HScrollBar" parent="ToolsPanel"] +[node name="HScrollBarBrushSize" type="HScrollBar" parent="ToolsPanel/BrushSettings"] margin_left = 20.0 -margin_top = 230.0 +margin_top = 30.0 margin_right = 330.0 -margin_bottom = 260.0 -min_value = 1.0 +margin_bottom = 60.0 +min_value = 2.0 +step = 1.0 value = 32.0 -[node name="LabelBrushShape" type="Label" parent="ToolsPanel"] +[node name="LabelBrushShape" type="Label" parent="ToolsPanel/BrushSettings"] margin_left = 20.0 -margin_top = 280.0 +margin_top = 80.0 margin_right = 330.0 -margin_bottom = 294.0 -text = "Brush shape: circle" +margin_bottom = 94.0 +text = "Brush shape: Circle" align = 1 -[node name="ButtonShapeBox" type="Button" parent="ToolsPanel"] +[node name="ButtonShapeBox" type="Button" parent="ToolsPanel/BrushSettings"] +editor/display_folded = true margin_left = 100.0 -margin_top = 300.0 +margin_top = 100.0 margin_right = 160.0 -margin_bottom = 360.0 +margin_bottom = 160.0 -[node name="Sprite" type="Sprite" parent="ToolsPanel/ButtonShapeBox"] +[node name="Sprite" type="Sprite" parent="ToolsPanel/BrushSettings/ButtonShapeBox"] position = Vector2( 30, 30 ) scale = Vector2( 2.5, 2.5 ) texture = ExtResource( 3 ) region_enabled = true region_rect = Rect2( 0, 16, 16, 16 ) -[node name="ButtonShapeCircle" type="Button" parent="ToolsPanel"] +[node name="ButtonShapeCircle" type="Button" parent="ToolsPanel/BrushSettings"] +editor/display_folded = true margin_left = 190.0 -margin_top = 300.0 +margin_top = 100.0 margin_right = 250.0 -margin_bottom = 360.0 +margin_bottom = 160.0 -[node name="Sprite" type="Sprite" parent="ToolsPanel/ButtonShapeCircle"] +[node name="Sprite" type="Sprite" parent="ToolsPanel/BrushSettings/ButtonShapeCircle"] position = Vector2( 30, 30 ) scale = Vector2( 2.5, 2.5 ) texture = ExtResource( 3 ) @@ -209,5 +216,5 @@ margin_bottom = 400.0 resizable = true access = 2 filters = PoolStringArray( "*.png" ) -current_dir = "/home/ubuntu_noah/Documents/New_2019_GitHub_Repositories/godot-demo-projects/2d/gd_paint" -current_path = "/home/ubuntu_noah/Documents/New_2019_GitHub_Repositories/godot-demo-projects/2d/gd_paint/" +current_dir = "/home/aaronfranke/workspace/godot-demo-projects/2d/gd_paint" +current_path = "/home/aaronfranke/workspace/godot-demo-projects/2d/gd_paint/" diff --git a/2d/gd_paint/ToolsPanel.gd b/2d/gd_paint/ToolsPanel.gd index e1026a37..894427b1 100644 --- a/2d/gd_paint/ToolsPanel.gd +++ b/2d/gd_paint/ToolsPanel.gd @@ -1,83 +1,80 @@ extends Panel - var paint_control -var label_tools -var label_brush_size -var label_brush_shape -var label_stats +onready var brush_settings = $BrushSettings +onready var label_tools = $LabelTools +onready var label_brush_size = $BrushSettings/LabelBrushSize +onready var label_brush_shape = $BrushSettings/LabelBrushShape +onready var label_stats = $LabelStats var save_dialog - func _ready(): - # Get PaintControl and SaveFileDialog + # Get PaintControl and SaveFileDialog. paint_control = get_parent().get_node("PaintControl") save_dialog = get_parent().get_node("SaveFileDialog") # warning-ignore-all:return_value_discarded - # Assign all of the needed signals for the oppersation buttons - get_node("ButtonUndo").connect("pressed", self, "button_pressed", ["undo_stroke"]) - get_node("ButtonSave").connect("pressed", self, "button_pressed", ["save_picture"]) - get_node("ButtonClear").connect("pressed", self, "button_pressed", ["clear_picture"]) + # Assign all of the needed signals for the oppersation buttons. + $ButtonUndo.connect("pressed", self, "button_pressed", ["undo_stroke"]) + $ButtonSave.connect("pressed", self, "button_pressed", ["save_picture"]) + $ButtonClear.connect("pressed", self, "button_pressed", ["clear_picture"]) - # Assign all of the needed signals for the brush buttons - get_node("ButtonToolPencil").connect("pressed", self, "button_pressed", ["mode_pencil"]) - get_node("ButtonToolEraser").connect("pressed", self, "button_pressed", ["mode_eraser"]) - get_node("ButtonToolRectangle").connect("pressed", self, "button_pressed", ["mode_rectangle"]) - get_node("ButtonToolCircle").connect("pressed", self, "button_pressed", ["mode_circle"]) - get_node("ButtonShapeBox").connect("pressed", self, "button_pressed", ["shape_rectangle"]) - get_node("ButtonShapeCircle").connect("pressed", self, "button_pressed", ["shape_circle"]) + # Assign all of the needed signals for the brush buttons. + $ButtonToolPencil.connect("pressed", self, "button_pressed", ["mode_pencil"]) + $ButtonToolEraser.connect("pressed", self, "button_pressed", ["mode_eraser"]) + $ButtonToolRectangle.connect("pressed", self, "button_pressed", ["mode_rectangle"]) + $ButtonToolCircle.connect("pressed", self, "button_pressed", ["mode_circle"]) + $BrushSettings/ButtonShapeBox.connect("pressed", self, "button_pressed", ["shape_rectangle"]) + $BrushSettings/ButtonShapeCircle.connect("pressed", self, "button_pressed", ["shape_circle"]) - # Assign all of the needed signals for the other brush settings (and ColorPickerBackground) - get_node("ColorPickerBrush").connect("color_changed", self, "brush_color_changed") - get_node("ColorPickerBackground").connect("color_changed", self, "background_color_changed") - get_node("HScrollBarBrushSize").connect("value_changed", self, "brush_size_changed") + # Assign all of the needed signals for the other brush settings (and ColorPickerBackground). + $ColorPickerBrush.connect("color_changed", self, "brush_color_changed") + $ColorPickerBackground.connect("color_changed", self, "background_color_changed") + $BrushSettings/HScrollBarBrushSize.connect("value_changed", self, "brush_size_changed") - # Assign the 'file_selected' signal in SaveFileDialog + # Assign the 'file_selected' signal in SaveFileDialog. save_dialog.connect("file_selected", self, "save_file_selected") - # Get all of the labels so we can update them when settings change - label_tools = get_node("LabelTools") - label_brush_size = get_node("LabelBrushSize") - label_brush_shape = get_node("LabelBrushShape") - label_stats = get_node("LabelStats") - - # Set physics process so we can update the status label + # Set physics process so we can update the status label. set_physics_process(true) func _physics_process(_delta): - # Update the status label with the newest brush element count + # Update the status label with the newest brush element count. label_stats.text = "Brush objects: " + String(paint_control.brush_data_list.size()) func button_pressed(button_name): - # If a brush mode button is pressed + # If a brush mode button is pressed. var tool_name = null var shape_name = null if button_name == "mode_pencil": - paint_control.brush_mode = paint_control.BRUSH_MODES.pencil - tool_name = "pencil" + paint_control.brush_mode = paint_control.BrushModes.PENCIL + brush_settings.modulate = Color(1, 1, 1, 1) + tool_name = "Pencil" elif button_name == "mode_eraser": - paint_control.brush_mode = paint_control.BRUSH_MODES.eraser - tool_name = "eraser" + paint_control.brush_mode = paint_control.BrushModes.ERASER + brush_settings.modulate = Color(1, 1, 1, 1) + tool_name = "Eraser" elif button_name == "mode_rectangle": - paint_control.brush_mode = paint_control.BRUSH_MODES.rectangle_shape - tool_name = "rectangle shape" + paint_control.brush_mode = paint_control.BrushModes.RECTANGLE_SHAPE + brush_settings.modulate = Color(1, 1, 1, 0.5) + tool_name = "Rectangle shape" elif button_name == "mode_circle": - paint_control.brush_mode = paint_control.BRUSH_MODES.circle_shape - tool_name = "circle shape" + paint_control.brush_mode = paint_control.BrushModes.CIRCLE_SHAPE + brush_settings.modulate = Color(1, 1, 1, 0.5) + tool_name = "Circle shape" # If a brush shape button is pressed elif button_name == "shape_rectangle": - paint_control.brush_shape = paint_control.BRUSH_SHAPES.rectangle - shape_name = "rectangle" + paint_control.brush_shape = paint_control.BrushShapes.RECTANGLE + shape_name = "Rectangle" elif button_name == "shape_circle": - paint_control.brush_shape = paint_control.BRUSH_SHAPES.circle - shape_name = "circle"; + paint_control.brush_shape = paint_control.BrushShapes.CIRCLE + shape_name = "Circle"; # If a opperation button is pressed elif button_name == "clear_picture": @@ -88,7 +85,7 @@ func button_pressed(button_name): elif button_name == "undo_stroke": paint_control.undo_stroke() - # Update the labels (in case the brush mode or brush shape has changed) + # Update the labels (in case the brush mode or brush shape has changed). if tool_name != null: label_tools.text = "Selected tool: " + tool_name if shape_name != null: @@ -96,25 +93,24 @@ func button_pressed(button_name): func brush_color_changed(color): - # Change the brush color to whatever color the color picker is + # Change the brush color to whatever color the color picker is. paint_control.brush_color = color func background_color_changed(color): - # Change the background color to whatever colorthe background color picker is + # Change the background color to whatever colorthe background color picker is. get_parent().get_node("DrawingAreaBG").modulate = color paint_control.bg_color = color - # Because of how the eraser works we also need to redraw the paint control + # Because of how the eraser works we also need to redraw the paint control. paint_control.update() func brush_size_changed(value): - # Change the size of the brush, and update the label to reflect the new value + # Change the size of the brush, and update the label to reflect the new value. paint_control.brush_size = ceil(value) label_brush_size.text = "Brush size: " + String(ceil(value)) + "px" func save_file_selected(path): - # Call save_picture in paint_control, passing in the path we recieved from SaveFileDialog + # Call save_picture in paint_control, passing in the path we recieved from SaveFileDialog. paint_control.save_picture(path) - diff --git a/2d/gd_paint/icon.png.import b/2d/gd_paint/icon.png.import new file mode 100644 index 00000000..96cbf462 --- /dev/null +++ b/2d/gd_paint/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0